Skip to main content
POST
/
v2
/
enroll
curl --request POST \
  --url 'https://api.glider.fi/v2/enroll' \
  --header 'x-api-key: gldr_sk_your_api_key' \
  --header 'Content-Type: application/json' \
  --data '{
    "userAddress": "0xabcdef0000000000000000000000000000000001",
    "strategyId": "01JWZEE2MF30KVRMRX53N88VA4",
    "chainIds": [1, 8453],
    "accountIndex": "7",
    "agentAddress": "0x1111111111111111111111111111111111111111",
    "signature": "0x9412d70d539f889ecec2d3152b68af758d689a4325a43b07811ee708814527c72256fc749d7fd3745a07f0aaa84813955050c461392d9b9ee1f80e106fac39e01b",
    "flowId": "flow_abc123",
    "portfolioName": "Alice's Portfolio"
  }'
{
  "success": true,
  "data": {
    "portfolioId": "pf_01JWZG3KH9P4N5QXJVNK7M3WTV",
    "strategyId": "01JWZEE2MF30KVRMRX53N88VA4",
    "scheduleId": "999",
    "vaults": [
      {
        "chainId": 1,
        "address": "0x2222222222222222222222222222222222222222"
      },
      {
        "chainId": 8453,
        "address": "0x3333333333333333333333333333333333333333"
      }
    ]
  }
}
Stage 2 of the v2 enrollment flow. Takes the flowId, accountIndex, and agentAddress returned by POST /v2/enroll/signature, plus the user’s signature over the merkle root, and creates the full v2 portfolio state in a single atomic transaction:
  • Strategy instance row
  • One vault per chain (with deterministic CREATE2 addresses)
  • Smart account config rows for each vault
  • Wildcard agent row + per-vault session key rows for the v2 rebalance engine
  • Rebalance schedule row (cadence resolved from your tenant execution config or the system default)
After the transaction commits, the server mirrors the enrollment into the legacy vaults table so the rebalance engine can find session-key bytes for the freshly enrolled vaults.
  • Auth: x-api-key header (required)
  • Scope: enroll:write
The endpoint is idempotent on (tenantId, apiKeyId, "POST /v2/enroll", flowId) via the v2_idempotency_keys store, with a 24-hour TTL:
  • Replaying the same flowId with the same body returns the cached response.
  • Replaying with a different body returns 409 IDEMPOTENCY_KEY_CONFLICT.
  • Replaying while the original is still in-flight returns 409 IDEMPOTENCY_IN_PROGRESS.
  • Replaying after a typed error (e.g., signature mismatch) returns the same typed error, not an in-flight 409 — the server caches the error so retries don’t get stuck.
The signature must be computed by signing message.raw from the stage-1 response with the user’s wallet, using viem’s signMessage({ message: { raw } }) or the equivalent wallet primitive (the message is a raw 32-byte merkle root; EIP-191 prefix is applied by the verifier on the server side). Common error responses:
  • 400 for an invalid request body, expired flow, mismatched signature, or invalid strategy ownership
  • 401 when x-api-key header is missing or the key is invalid
  • 403 when the API key lacks the enroll:write scope
  • 409 IDEMPOTENCY_IN_PROGRESS when an earlier request with the same flowId is still running
  • 409 IDEMPOTENCY_KEY_CONFLICT when the same flowId is reused with a different request body
  • 409 PORTFOLIO_ALREADY_EXISTS when the user is already enrolled at the given accountIndex
  • 500 on unexpected server errors
curl --request POST \
  --url 'https://api.glider.fi/v2/enroll' \
  --header 'x-api-key: gldr_sk_your_api_key' \
  --header 'Content-Type: application/json' \
  --data '{
    "userAddress": "0xabcdef0000000000000000000000000000000001",
    "strategyId": "01JWZEE2MF30KVRMRX53N88VA4",
    "chainIds": [1, 8453],
    "accountIndex": "7",
    "agentAddress": "0x1111111111111111111111111111111111111111",
    "signature": "0x9412d70d539f889ecec2d3152b68af758d689a4325a43b07811ee708814527c72256fc749d7fd3745a07f0aaa84813955050c461392d9b9ee1f80e106fac39e01b",
    "flowId": "flow_abc123",
    "portfolioName": "Alice's Portfolio"
  }'
{
  "success": true,
  "data": {
    "portfolioId": "pf_01JWZG3KH9P4N5QXJVNK7M3WTV",
    "strategyId": "01JWZEE2MF30KVRMRX53N88VA4",
    "scheduleId": "999",
    "vaults": [
      {
        "chainId": 1,
        "address": "0x2222222222222222222222222222222222222222"
      },
      {
        "chainId": 8453,
        "address": "0x3333333333333333333333333333333333333333"
      }
    ]
  }
}