A series of tutorials to make it easy for non-coders to trade on LN Markets via our API with several programming languages, here with Node.js.

Reference Docs

Our API reference provides information on available endpoints and how to interact with it: https://docs.lnmarkets.com/api/v1/

The API endpoint for mainnet is: https://api.lnmarkets.com/v1

The API endpoint for testnet is: https://api.testnet.lnmarkets.com/v1

Get your JSON Web Token

In order to use LN Markets API, you first need to create your authentication token. We are currently using JSON Web Token (JWT).

Go to your Profile (click on the menu in the upper right corner) and select. You can now generate your token for various scopes: User, Futures, Deposit, Withdraw. It can be valid for a given period of time or indefinitely.

Here we created a token for all the scopes, without expiry. We copy it for later usage (button Copy Token).

Setup your Node.js environment

There is a ton of online resources to help you. To get started and download the latest version of Node.js: https://nodejs.org/en/

For code editing, we recommend Visual Studio Code: https://code.visualstudio.com/

Throughout this tutorial we will use the package fetch: https://www.npmjs.com/package/node-fetch that you can install with:

$ npm install node-fetch

Enter your API Token

Copy your token in JWT = '...':

const fetch = require('node-fetch');

JWT = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MThlNGZlZi1lM2M1LTQ4ZmItODFlOC0yMzc1Yj[...]cDA2bjc5MHdxMzdtcSIsImlhdCI6MTYwNTcyMTIxNX0.D1ifOH1NvIQx0FsbU__Y_vv_Grl-h6ZBgjHexHNY-6M'

We also import the package fetch that we will use throughout the rest of the tutorial.

Get your positions' history

Change ht = 'all', ht = 'open', ht = 'closed' to get the history of all your position, open positions, and closed positions

//Get your positions' history

const ht = 'all';

fetch(`https://api.lnmarkets.com/v1/futures?type=${ht}`, {
  method: 'GET',
  headers: {
       'Content-type': 'application/json',
       'authorization': `Bearer ${JWT}`}
     })
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));

Here is a sample of the JSON file we get for all positions of a particular account:

Create a position

In order to create a position, we must enter in the constant body its type ('m' for market order, 'l' for limit order), its side ('b' for buy, 's' for sell) and the required parameters. Which are either quantity and leverage (quantity of 1 means 1 contract, each contract is worth 1 USD, leverage must be between 1 and 50) or margin and leverage (max margin is currently limited to 0.01 BTC = 100,000,000 satoshis):

// Create a market order

const body = {type: 'm', side: 'b', quantity: 1, leverage: 1 };

fetch('https://api.lnmarkets.com/v1/futures', {
  method: 'POST',
  body:    JSON.stringify(body),
  headers: {
       'Content-type': 'application/json',
       'authorization': `Bearer ${JWT}`}
     },
 )
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));

We run this code to create our new position:

We can also see the position open in our LN Markets account:

Update a position

We can add a take profit and/or stop loss to this position. We just need to enter in the constant body the position id 'pid', the type of update ('takeprofit' or 'stoploss') and its value:

// Update a position

const body = {pid: 'fd0292c8-fb23-4227-9b1d-7f21e536e8c8', type: 'takeprofit', value: 40000};

fetch('https://api.lnmarkets.com/v1/futures', {
  method: 'PUT',
  body:    JSON.stringify(body),
  headers: {
       'Content-type': 'application/json',
       'authorization': `Bearer ${JWT}`}
     },
 )
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));

We get the following output:

And we can check the update for confirmation in our LN Markets account:

Close a position

We can then close this position with our pid in the querystring:

// Close a position

const querystring = require('querystring')
const qs = querystring.stringify({pid: '077e49d0-6e21-4c5c-96b8-159f01082653'})

fetch('https://api.lnmarkets.com/v1/futures?' + qs, {
  method: 'DELETE',
  headers: {
       'Content-type': 'application/json',
       'authorization': `Bearer ${JWT}`}
     },
 )
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));

We get the following output:

And we can check that the position was closed in our LN Markets account.

Cancel a position

Only limit orders that have not yet been filled can be canceled. First, let's create a limit buy order at Price 30,000$ for a Quantity of 1 contract and Leverage of 1:

//Create a limit order

const body = {type: 'l', side: 'b', price: 30000, quantity: 1, leverage: 1 };

fetch('https://api.lnmarkets.com/v1/futures', {
  method: 'POST',
  body:    JSON.stringify(body),
  headers: {
       'Content-type': 'application/json',
       'authorization': `Bearer ${JWT}`}
     },
 )
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));

The limit order is now open:

As long as the order has not been filled, we can cancel it using its pid:

// Cancel a position

const body = {pid: '1ca9b9ce-0e4f-46f6-9983-cc71f412e7be'};

fetch('https://api.lnmarkets.com/v1/futures/cancel', {
  method: 'POST',
  body:    JSON.stringify(body),
  headers: {
       'Content-type': 'application/json',
       'authorization': `Bearer ${JWT}`}
     },
 )
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));

The position is now cancelled:

We can verify that in our closed positions blotter.

Deposit funds to your account

In order to generate a Lightning Network invoice to fund your account on LN Markets, enter the desired amount (between 1,000 and 1 million sats) and unit ('sat' or 'btc') in body:

// Deposit

const body = {amount: 1000, unit: 'sat'};

fetch('https://api.lnmarkets.com/v1/user/deposit', {
  method: 'POST',
  body:    JSON.stringify(body),
  headers: {
       'Content-type': 'application/json',
       'authorization': `Bearer ${JWT}`}
     },
 )
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));

And you get the invoice, that you need to pay within 45 seconds for your deposit to be successful:

Withdraw funds from your account

You can either withdraw funds via an invoice or via lnurl-withdraw (here is the list of wallets that support it). In order to withdraw via an invoice you enter in the payload the amount, the unit, and your invoice:

// Withdraw via Invoice

  const body = {amount: 1000, unit: 'sat', invoice: 'lnbc10u1psqrsl9pp5hh4nqp5zhn67at4ffuj0zhhjy0xf2ruh0shzyxkjyst6enna5s3sdqqcqzpgxqrrssrzjqvgptfurj3528snx6e3dtwepafxw5fpzdymw9pj20jj09sunnqmwqz0ld5qqfecqqqqqqqlgqqqqqqgq9qsp5q9vpwedge8wvw5f67vnu5kgghq9j3txlsy9w4zpcjt80xh78azas9qy9qsqh9v8hh7s5ktsu29ne9zcaf42xzt64wmyeax2tvt5xpxexdf0v8zrafav3yf9jthp2zqc5qaushy8py32z4v3dr3g7fhlg0gqyg03segqvqmsq6'};

  fetch('https://api.lnmarkets.com/v1/user/withdraw', {
    method: 'POST',
    body:    JSON.stringify(body),
    headers: {
          'Content-type': 'application/json',
          'authorization': `Bearer ${JWT}`}
        },
    )
      .then(res => res.json())
      .then(json => console.log(json))
      .catch(err => console.error(err));

And you get the instant withdrawal confirmation:

{"amount":1000,"paymentsecret":"4e789efcbba7807ceb09886cefa5ec7b544ef8343ef105ea7c48dc017d4d36a1","wid":"0c78f631-a742-467c-ade5-12373f3aded4","paymenthash":"8e3csdf74e014713b5c97916bcd558fa7c031fe362c515ca7aa4b363a4465a04"}

Get the Leaderboard

Now it is time for you to check if you made it to the Leaderboard!

//Get current Leaderboard

fetch('https://api.lnmarkets.com/v1/state/leaderboard', {
  method: 'GET',
  headers: {accept: 'application/json'}
      },
  )
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));

By default, you do not appear in the leaderboard. It's only if you authorize it your profile section that you may appear under your desired pseudonymous. Here is the Top 10:

Create an account

You can either create an account using credentials or with lnurl-auth. Here we show how do it via credentials.

First, you need to request new credentials:

//Request new credentials

fetch('https://api.lnmarkets.com/v1/login/credentials', {
  method: 'GET',
  headers: {accept: 'application/json'}
      },
  )
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));

And you get the 100 sats invoice you need to pay within 90 seconds to create new credentials:

After paying the invoice, we enter in the payload the payment hash of the invoice and the login and password we want to use:

// Register new credentials

const body = {login: 'node_tuto', password: 'mYUNaisdso0r48L3P422w0rd', paymentHash: '3f4c24b41ae11741058364577cee096b8fbe20f28ae6ed723cfa0591b97b6468'};

fetch('https://api.lnmarkets.com/v1/login/credentials/create', {
  method: 'PUT',
  body:    JSON.stringify(body),
  headers: {
       'Content-type': 'application/json',
       'authorization': `Bearer ${JWT}`}
     },
 )
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));

Our account is now created:

There is much more

There are plenty of other actions that we did not cover in this tutorial (account creation and withdraw via lnurl, API tokens revocation, state of LN Markets node and our API, announcements, etc.), but that you will be able to run easily using the previous lines of codes.

Should you have any questions about using the API, feel free to join LN Markets Telegram support group: https://www.t.me/lnmarkets