LN Markets API

Documentation

Documentation

Overview

LN Markets offers a REST API to integrate with your program or trading bot. This API reference provides information on available endpoints and how to interact with it. For easier integration, we provide a ready-to-use TypeScript SDK and Python SDK.

Changelog

November 14, 2025

  • Pagination Support: Introduced cursor-based pagination across all list endpoints for improved performance and reliability.
    • Query Parameters: Added support for from (start date), to (end date), limit (1-1000 items, default 1000), and cursor (pagination cursor) parameters
    • Response Format: All paginated endpoints now return a standardized response with data array and nextCursor field
    • Affected Endpoints:
      • GET /account/deposits/lightning
      • GET /account/deposits/on-chain
      • GET /account/deposits/internal
      • GET /account/withdrawals/lightning
      • GET /account/withdrawals/on-chain
      • GET /account/withdrawals/internal
      • GET /account/notifications
      • GET /futures/isolated/trades/closed
      • GET /futures/isolated/trades/canceled
      • GET /futures/isolated/funding-fees
      • GET /futures/cross/orders/filled
      • GET /futures/cross/funding-fees
      • GET /futures/cross/transfers
      • GET /futures/candles
      • GET /futures/funding-settlements
      • GET /synthetic-usd/swaps

REST API

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

If you want to try our API with testnet bitcoin use https://api.testnet4.lnmarkets.com/v3.

GET requests

  • Must not have a body
  • Must not have header Content-Type: application/json
  • Data is URL-encoded in the query string
  • If there is a response body, it is always JSON

POST and PUT requests

  • May have a body
  • If there is a body, must have header Content-Type: application/json
  • If there is a body, body must be valid JSON
  • If there is a response body, it is always JSON

Authentication

Endpoints marked as Private require requests to be authenticated and signed. You can create and activate new API keys on your profile. As a best practice, your API keys should be assigned only permissions that are necessary for your application to function.

Headers

Authenticated requests must contain the following headers:

HeaderDescription
LNM-ACCESS-KEYAPI Key
LNM-ACCESS-PASSPHRASEAPI Key passphrase
LNM-ACCESS-SIGNATURERequest signature
LNM-ACCESS-TIMESTAMPRequest timestamp in milliseconds

Signature

The LNM-ACCESS-SIGNATURE is generated by calculating an HMAC-SHA256 hash using the API secret key. The input to the hash is the string formed by concatenating timestamp, method, path, and data (in that order, without separators). The resulting hash is then encoded in Base64.

Having:

  • timestamp: same as the LNM-ACCESS-TIMESTAMP header (request timestamp in milliseconds). It should be within 30 seconds of our server time
  • method: request method in lowercase (e.g. get, post)
  • path: request path of the URL, e.g.: /v3/account
  • data: depending on the request method, either the request body as a JSON string (no space, no line return, should match Node's JSON.stringify method) or the request query string (e.g. ?key=value&key2=value2). If there is no data, it should be an empty string.

Example in TypeScript:

const url = new URL(request.url)
const data = request.body ? JSON.stringify(request.body) : url.search
const timestamp = Date.now()

const signature = createHmac('sha256', 'API_SECRET')
  .update(`${timestamp}${request.method.toLowerCase()}${url.pathname}${data}`)
  .digest('base64')

const headers = new Headers({
  'LNM-ACCESS-KEY': 'API_KEY',
  'LNM-ACCESS-PASSPHRASE': 'API_PASSPHRASE',
  'LNM-ACCESS-TIMESTAMP': timestamp.toString(),
  'LNM-ACCESS-SIGNATURE': signature,
})

Have a look at our Typescript or Python SDK for more detailed examples.

Rate limit

The API uses a token bucket rate limiter with a refill rate of 20 tokens per second and a maximum capacity of 40 tokens.

Request costs:

  • Authenticated requests: 1 token per request
  • Unauthenticated requests: 5 tokens per request

This means authenticated users can make up to 20 requests per second with burst capacity to 40 and up to 300 requests per minute. While unauthenticated users are effectively limited to 4 request per second and 60 per minute.

The API follows the IETF HTTP API Rate Limit Headers specification (draft-10).

Rate Limit Headers

All responses include the following rate limit headers:

HeaderDescription
RateLimit-PolicyThe static rate limit policy definition. Format: "default";q=<quota>;w=<window>
RateLimitThe dynamic current rate limit state. Format: "default";r=<remaining> or "default";r=<remaining>;t=<reset>
Retry-After(429 responses only) The time in seconds to wait before making another request when rate limited.

Example response headers:

RateLimit-Policy: "default";q=5;w=1
RateLimit: "default";r=3

When rate limited (HTTP 429):

RateLimit-Policy: "default";q=5;w=1
RateLimit: "default";r=0;t=1
Retry-After: 1

Pagination

Endpoints that return lists of data use cursor-based pagination for efficient navigation through large datasets. This approach is more reliable than offset-based pagination.

Query Parameters

Paginated endpoints accept the following query parameters:

ParameterTypeDefaultDescription
fromDateUnix epoch 0Start date for filtering results
toDateCurrent timeEnd date for filtering results
limitNumber1000Maximum number of items to return (min: 1, max: 1000)
cursorDate-Cursor for fetching the next page (timestamp of last item)

Response Format

Paginated responses return an object with two fields:

{
  "data": [...],      // Array of results
  "nextCursor": null  // Cursor for next page, or null if no more results
}
  • data: Array containing the requested items
  • nextCursor: ISO 8601 timestamp to use for fetching the next page. When null, there are no more results.

How It Works

  1. First Request: Call the endpoint without a cursor parameter
  2. Check Response: If nextCursor is not null, more results are available
  3. Next Page: Make a new request with cursor set to the nextCursor value from the previous response
  4. Repeat: Continue until nextCursor is null

Results are ordered by creation date in descending order (newest first). The cursor represents the timestamp of the last item in the current page, and subsequent requests will return items created before that timestamp.

Best Practices

  • Use appropriate limit values to balance performance and number of requests (default 1000 is suitable for most use cases)
  • Store the nextCursor value to resume pagination if needed
  • Use from and to parameters to filter data by specific date ranges

Units

Unless stated otherwise:

  • Bitcoin amounts are denominated in satoshis (1 bitcoin = 100,000,000 satoshis)
  • Dates are returned as ISO 8601 date-time strings (e.g. 2025-09-01T15:04:21.129Z)

Errors

Error CodeHTTP Status CodeMeaning
BAD_REQUEST400Bad Request
UNAUTHORIZED401Unauthorized - Failed authentication or you don’t have access to the requested resource
FORBIDDEN403Forbidden - Your API key may have the wrong scope
NOT_FOUND404Not Found
METHOD_NOT_SUPPORTED405Method Not Supported - You tried to access a resource with an invalid method
NOT_ACCEPTABLE406Not Acceptable
TIMEOUT408Request Timeout
CONFLICT409Conflict
PRECONDITION_FAILED412Precondition Failed
PAYLOAD_TOO_LARGE413Payload Too Large
UNSUPPORTED_MEDIA_TYPE415Unsupported Media Type
UNPROCESSABLE_CONTENT422Unprocessable Content
TOO_MANY_REQUESTS429Too Many Requests - Your connection is being rate limited
CLIENT_CLOSED_REQUEST499Client Closed Request
INTERNAL_SERVER_ERROR500Internal Server Error - Something went wrong, please try again or contact us
NOT_IMPLEMENTED501Not Implemented
BAD_GATEWAY502Bad Gateway
SERVICE_UNAVAILABLE503Service Unavailable - We're temporarily offline for maintenance, please try again later
GATEWAY_TIMEOUT504Gateway Timeout

On this page