Skip to main content
POST
/
profiles
/
partner-accounts
Create partner sub-account
curl --request POST \
  --url https://api.limitless.exchange/profiles/partner-accounts \
  --header 'Content-Type: application/json' \
  --header 'lmts-api-key: <api-key>' \
  --data '
{
  "displayName": "user-alice",
  "createServerWallet": false
}
'
{
  "profileId": 789,
  "account": "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"
}
Requires HMAC authentication with the account_creation scope. API key auth and Privy auth are not accepted.
Creates a new sub-account profile linked to the authenticated partner.

Server wallet mode

Set createServerWallet: true to create a Privy server wallet for the sub-account. This enables delegated signing — the partner can submit unsigned orders and the server signs them using the managed wallet. Token approvals are provisioned automatically for server wallet accounts.
Server wallet creation requires the delegated_signing scope on your API token (in addition to account_creation). Without it, the request returns "Server wallet creation requires delegated_signing scope".
{
  "displayName": "user-bob",
  "createServerWallet": true
}

EOA mode

Omit createServerWallet (or set it to false) to create an account for an externally-owned address. The end user manages their own keys and signs their own orders. EOA mode requires three additional headers for wallet ownership verification:
HeaderDescription
x-accountChecksummed Ethereum address (EIP-55)
x-signing-messageHex-encoded signing message obtained from GET /auth/signing-message
x-signatureHex-encoded signature produced by signing the message with the wallet

Signing message format

The x-signing-message value is not the raw text — it is the hex-encoded UTF-8 representation of the message returned by GET /auth/signing-message. The raw text (which you sign) looks like:
Welcome to Limitless Exchange!

This request will not trigger a blockchain transaction or cost any gas fees.

Signature is required to authenticate an upcoming API request.

Nonce: 0x<keccak256-hash>
The full flow:
  1. Fetch the signing message: GET /auth/signing-message → returns the plain-text message with a unique nonce.
  2. Sign the plain-text message with the wallet (e.g. personal_sign / eth_sign).
  3. Hex-encode the plain-text message: prepend 0x to the UTF-8 hex representation.
  4. Send all three headers on the request.
import requests
from eth_account import Account
from eth_account.messages import encode_defunct

# 1. Fetch the signing message
signing_message = requests.get(f"{API_BASE_URL}/auth/signing-message").text

# 2. Sign the plain-text message
message = encode_defunct(text=signing_message)
signed = account.sign_message(message)

# 3. Hex-encode the message for the header
hex_message = "0x" + signing_message.encode("utf-8").hex()

# 4. Use in headers
headers = {
    "x-account": account.address,                # checksummed address
    "x-signing-message": hex_message,             # hex-encoded message
    "x-signature": "0x" + signed.signature.hex(), # hex-encoded signature
}
{
  "displayName": "user-alice"
}

Constraints

  • displayName is optional (max 44 characters). Defaults to the wallet address if omitted.
  • Returns 409 Conflict if a profile already exists for the target address.
  • Cannot create a sub-account for the partner’s own address.

Authorizations

lmts-api-key
string
header
required

Scoped API token with HMAC-SHA256 signing. Requires three headers: lmts-api-key (token ID), lmts-timestamp (ISO-8601), lmts-signature (Base64-encoded HMAC). See Authentication docs for details.

Headers

x-account
string

EOA mode only. Checksummed Ethereum address of the sub-account wallet.

x-signing-message
string

EOA mode only. Hex-encoded signing message.

x-signature
string

EOA mode only. Hex-encoded signature from the sub-account wallet.

Body

application/json
displayName
string

Public display name for the sub-account. Defaults to the wallet address if omitted.

Maximum string length: 44
Example:

"user-alice"

createServerWallet
boolean
default:false

If true, creates a Privy server wallet for the sub-account (enables delegated signing). If false or omitted, requires EOA wallet ownership headers.

Response

Sub-account created

profileId
integer
required

Profile ID of the created sub-account

Example:

789

account
string
required

Wallet address of the created sub-account

Example:

"0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"