Build a signed canonical payload to create/provision the user’s account on a perpetual DEX (e.g., register a Lighter sub-account or API key).
Documentation Index
Fetch the complete documentation index at: https://docs.mobula.io/llms.txt
Use this file to discover all available pages before exploring further.
(L1 address, accountIndex) after the user’s first deposit so subsequent trades, withdrawals, etc. can authenticate against Lighter.
accountIndex to that L1 address. The integrator must then call this endpoint with the discovered accountIndex to provision an API key + auth token — without it, every other Lighter perp endpoint (create-order, close-position, withdraw, …) will fail.
End-to-end first-time setup:
/2/perp/payloads/deposit → submit via /2/perp/execute-v2 → poll /2/perp/check-process until success.accountIndex by polling Lighter’s account-lookup endpoint (the bridge takes a few seconds to settle on L2):
{ "code": 200, "accounts": [{ "account_index": <number>, ... }] }. Poll every ~1s until accounts[0].account_index is present.
accountIndex and submitting via /2/perp/execute-v2. The response payload may carry payload.MessageToSign — sign it, set payload.L1Sig, delete payload.MessageToSign, re-stringify, and sign execute-v2 over the new string.lighter.lighter:304 (the only chain that accepts Lighter create-account today)./api/v1/account?by=l1_address&value=<EOA> lookup after the first deposit settles./2/perp/payloads/<action> endpoint verifies the caller by requiring two extra fields in the request body alongside the action parameters:
personal_sign) of the message `${endpoint}-${timestamp}`, where endpoint is the path of this endpoint without the leading slash (e.g., for this page: api/2/perp/payloads/<this-action>). The recovered signer address becomes the user for the request. Single-use — replay returns 403 signature already used.| Status | message |
|---|---|
| 403 | timestamp expired — timestamp older than 30s |
| 403 | signature already used — replay attempt |
| 400 | zod validation failed — timestamp/signature shape invalid |
/2/perp/payloads/<action> endpoint returns the same envelope shape. You pass these fields verbatim into POST /2/perp/execute-v2 to execute the action.
| Status | message |
|---|---|
| 400 | accountIndex must be a non-negative integer for lighter create-account — missing or invalid accountIndex |
| 400 | Invalid chainId "<value>" for lighter create-account — chainId other than lighter:304 |
| 400 | create-account payload generation failed — Lighter rejected provisioning (e.g., slot already in use) |
| 501 | payload action "create-account" not implemented yet — dex other than lighter |
accountIndex. Snippet shows step 3 of the lifecycle above.
accountIndex after a depositUnix ms timestamp; must be within 30s of server time.
Hex signature of {endpoint}-{timestamp}. Recovered signer becomes the request user.
lighter Must be lighter:304 (only chain that accepts Lighter create-account today).
lighter:304 Lighter sub-account index. Discover via Lighter's /api/v1/account?by=l1_address&value= after the first deposit settles.
x >= 0Lighter API key slot to provision. Pick any unused slot. Defaults server-side if omitted.
x >= 0