Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.glider.fi/llms.txt

Use this file to discover all available pages before exploring further.

Enrolling a user into a strategy is a two-stage flow. Stage 1 returns a message for the user to sign with their wallet; stage 2 submits the signature and creates the portfolio. The two stages are linked by three round-trip fields that must be echoed back byte-for-byte unchanged.
  • Scope: enroll:write on both stages.
  • Idempotency anchor: flowId returned by stage 1. Valid for 24 hours.
  • Stage 2 provisions one smart account per requested chain with deterministic CREATE2 addresses. The whole operation is atomic.

Sequence

Integrator          Glider API                 End-user Wallet
    |                    |                           |
    |--1. POST /v2/enroll/signature---------------->|
    |                    |                           |
    |<--200 { message, flowId, accountIndex, agentAccountId }
    |                    |                           |
    |--2. signMessage(message.raw)----------------->|
    |                    |                           |
    |<--signature--------|---------------------------|
    |                    |                           |
    |--3. POST /v2/enroll (echo all round-trip fields + signature)
    |                    |                           |
    |<--201 { portfolioId, strategyId, smartAccounts }|

Stage 1 — Request the signable message

POST /v2/enroll/signature Validates that the strategy belongs to your tenant, peeks the user’s next available account index, and returns the session-key message the user must sign along with the agent wallet that will operate the smart account post-enrollment.
curl -X POST https://api.glider.fi/v2/enroll/signature \
  -H 'x-api-key: gldr_sk_your_api_key' \
  -H 'Content-Type: application/json' \
  -d '{
    "ownerAccountId": "eip155:0:0xabcdef0000000000000000000000000000000001",
    "strategyId": "01JWZEE2MF30KVRMRX53N88VA4",
    "chainIds": [1, 8453]
  }'
Response:
{
  "success": true,
  "data": {
    "message": {
      "kind": "ecdsa",
      "raw": "0xdeadbeef...deadbeef"
    },
    "agentAccountId": "eip155:0:0x1111111111111111111111111111111111111111",
    "accountIndex": "7",
    "flowId": "flow_01JWZEE2MF30KVRMRX53N88VA4"
  }
}

Peek, not reserve

accountIndex is peeked, not reserved. Repeated stage-1 calls for the same user return the same candidate index, and the index only advances when stage 2 commits. Retries, abandoned flows, and tests do not burn indices.

Unsupported chain ids

Unknown chains return 400 with the allowed list in details, so you can surface a helpful error without a second round trip:
{
  "success": false,
  "error": {
    "code": "API_400",
    "message": "Request validation failed",
    "details": [
      "chainIds: Unsupported chainId: [999]. Supported: [1, 8453, 42161]"
    ]
  }
}

Stage 2 — Have the user sign, then submit

The user signs message.raw in their wallet (ECDSA personal_sign). The signed bytes are the only cryptographic input. Then POST /v2/enroll with every round-trip field from stage 1.

Round-trip contract

These fields must be sent back to stage 2 byte-for-byte identical to what stage 1 returned. Any mismatch fails signature verification.
FieldStage 1 returnsStage 2 requires
flowIdYesYes — also the idempotency anchor
accountIndexYes (string)Yes — as a string, not a number
agentAccountIdYesYes
ownerAccountId(input)Same CAIP-10 as stage 1
strategyId(input)Same as stage 1
chainIds(input)Same set, same order
curl -X POST https://api.glider.fi/v2/enroll \
  -H 'x-api-key: gldr_sk_your_api_key' \
  -H 'Content-Type: application/json' \
  -d '{
    "ownerAccountId": "eip155:0:0xabcdef0000000000000000000000000000000001",
    "strategyId": "01JWZEE2MF30KVRMRX53N88VA4",
    "chainIds": [1, 8453],
    "accountIndex": "7",
    "agentAccountId": "eip155:0:0x1111111111111111111111111111111111111111",
    "signature": "0x9412d70d...39e01b",
    "flowId": "flow_01JWZEE2MF30KVRMRX53N88VA4",
    "portfolioName": "Alice Balanced"
  }'
Response:
{
  "success": true,
  "data": {
    "portfolioId": "pf_01JWZG3KH9P4N5QXJVNK7M3WTV",
    "strategyId": "01JWZEE2MF30KVRMRX53N88VA4",
    "smartAccounts": [
      { "accountId": "eip155:1:0x2222222222222222222222222222222222222222" },
      { "accountId": "eip155:8453:0xe3a2d1f49aee887e42655b56371d4d76bbf58058" }
    ]
  }
}

Error Handling

CodeHTTPCauseRetry safe?
API_400400Unknown strategy, expired flowId (past 24h), invalid signature, or malformed CAIP-10No — re-run stage 1
API_007409A previous stage-2 call with this flowId is still executingYes — back off and retry
API_008409Same flowId, different body — replay conflictNo — do not retry with modified body
API_202409User is already enrolled in this strategyNo — terminal
See Idempotency for the full 409 model.

Common Pitfalls

  • Modifying accountIndex between stages. "7" and 7 are different values. The schema requires the decimal string form. Do not parse it to an integer on your side unless you also re-serialize it before stage 2.
  • Generating a fresh flowId on stage-2 retry. This starts a new flow and invalidates the previous one. Always retry with the original flowId unless you have received a terminal error.
  • Sending ownerAccountId in chain-bound form. The enroll surface only accepts chain-agnostic eip155:0:<addr> owners. Use CAIP identifiers to pick the right form.
  • Calling stage 2 more than 24 hours after stage 1. The flowId reservation has expired. Re-run stage 1.