Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

API Reference

Download OpenAPI Spec

Authentication

The API accepts two types of Bearer tokens:

  • JWT — Obtain one instantly by completing the Sign-In with Ethereum (SIWE) flow below (GET /nonce → POST /verify). JWTs are short-lived session tokens.
  • API Key — Long-lived platform keys for server-to-server integrations. Contact us at support@clkd.xyz to request one.

Pass either token in the Authorization header — the server auto-detects the format.

Important: The address used for authentication must be the address derived from your private spending key (privateKeyToAccount(p_spend)), NOT your connected wallet address. The server identity is this derived auth address — your wallet address never touches the server.

Endpoints marked with 🔒 require a valid Bearer token.

Get HPKE public key

GET/v1/.well-known/hpke-public-key

Retrieve the server's HPKE public key. Clients must encrypt stealth key material with this key before submitting it during account creation or signer enrollment.

Responses
200Default Response
Schema
publicKeyrequiredstring
e.g. "0x..."
publicKeyBase64requiredstring
e.g. "..."
formatrequiredstring
e.g. "hex"
kemrequiredstring
e.g. "X25519-HKDF-SHA256"
aeadrequiredstring
e.g. "AES-128-GCM"
json
{
  "publicKey": "0x...",
  "publicKeyBase64": "...",
  "format": "hex",
  "kem": "X25519-HKDF-SHA256",
  "aead": "AES-128-GCM"
}
Try it
curl -X GET \
  "https://api-stg.clkd.xyz/v1/.well-known/hpke-public-key"

Get nonce

GET/v1/nonce

Generate a one-time nonce tied to the given address. This is the first step of Sign-In with Ethereum (SIWE) — the nonce must be included in the SIWE message passed to verifySignin. Nonces expire after 5 minutes.

Parameters
NameInTypeDescription
address*querystringThe auth address to tie the nonce to. This must be the address derived from your private spending key (i.e. `privateKeyToAccount(p_spend).address`), not your connected wallet address.
Responses
200Random nonce string
Schema
string — Random nonce string
json
"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
429Default Response
Schema
errorrequiredstring
e.g. "Too Many Requests"
messagerequiredstring
e.g. "Rate limit exceeded. Maximum 20 requests per 1 minute."
json
{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded. Maximum 20 requests per 1 minute."
}
Try it
Query Parameters
address
curl -X GET \
  "https://api-stg.clkd.xyz/v1/nonce"

Verify sign-in

POST/v1/verify

Complete Sign-In with Ethereum by submitting the signed SIWE message. Returns a JWT session token and the associated accountId if the address already has an account, or null if the user still needs to register.

Request Body
messagerequiredstring
SIWE message string
signaturerequiredstring
Signature from wallet
Responses
200Default Response
Schema
okrequiredboolean
e.g. true
addressrequiredstring
e.g. "0x..."
tokenrequiredstring
JWT authentication token
accountIdrequiredstring | null
Account ID if user is registered, null otherwise
json
{
  "ok": true,
  "address": "0x...",
  "token": "string",
  "accountId": "string"
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
422Default Response
Schema
errorrequiredstring
e.g. "Unprocessable Entity"
messagerequiredstring
codestring
e.g. "UNPROCESSABLE_ENTITY"
json
{
  "error": "Unprocessable Entity",
  "message": "string",
  "code": "UNPROCESSABLE_ENTITY"
}
429Default Response
Schema
errorrequiredstring
e.g. "Too Many Requests"
messagerequiredstring
e.g. "Rate limit exceeded. Maximum 10 requests per 1 minute."
json
{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded. Maximum 10 requests per 1 minute."
}
Try it
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "message": "",
  "signature": ""
}' \
  "https://api-stg.clkd.xyz/v1/verify"

Logout

POST/v1/logout

Clear the server-side cache for the authenticated user. JWT tokens are stateless, so the client should also discard the token. Auth is optional — unauthenticated calls succeed without clearing any cache.

Responses
200Default Response
Schema
okrequiredboolean
e.g. true
json
{
  "ok": true
}
Try it
curl -X POST \
  "https://api-stg.clkd.xyz/v1/logout"

Account Management

Account creation, signers, subdomains, and setup

Check subdomain availability

GET/v1/subdomain/check

Check whether a subdomain name is available for registration. Public endpoint — no authentication required. Use before calling setSubdomain to avoid conflicts.

Parameters
NameInTypeDescription
name*querystring
inviteCodequerystring
Responses
200Default Response
Schema
availablerequiredboolean
reason"taken" | "blocked"
json
{
  "available": true,
  "reason": "string"
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
Try it
Query Parameters
name
inviteCode
curl -X GET \
  "https://api-stg.clkd.xyz/v1/subdomain/check"

Create account

POST/v1/accounts/🔒

Register a new account by submitting HPKE-encrypted key material. The caller must already have a JWT from the SIWE sign-in flow, which proves ownership of the Ethereum address. The server decrypts and stores the keys, enabling payment address generation for this account. Requires an invite code when gated access is enabled. Returns the new accountId, or indicates if the address already has an account.

Request Body
ciphertextrequiredstring
Base64-encoded encrypted payload
encapsulatedKeyrequiredstring
Base64-encoded HPKE encapsulated key
inviteCodestring
Invite code for gated access
Responses
201Default Response
Schema
accountIdrequiredstring | null
Created account ID (null if already existed)
alreadyExistedrequiredboolean
json
{
  "accountId": "string",
  "alreadyExisted": true
}
Try it
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "ciphertext": "",
  "encapsulatedKey": "",
  "inviteCode": ""
}' \
  "https://api-stg.clkd.xyz/v1/accounts/"

Get account

GET/v1/accounts/{accountId}🔒

Retrieve account metadata including the owner address, registration status, and ENS subdomain. Useful for determining onboarding state (e.g., whether the user still needs to claim a subdomain).

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
Responses
200Default Response
Schema
accountIdrequiredstring
addressrequiredstring | null
isRegisteredrequiredboolean
subdomainrequiredstring | null
lastConsumedNoncerequirednumber | null
Last consumed stealth address nonce (0-indexed). null if no addresses generated yet.
cloakieobject | null
hasPoolDepositsboolean
True if the account has any pool commitment rows. Used to trigger eager pool balance discovery at login.
json
{
  "accountId": "string",
  "address": "string",
  "isRegistered": true,
  "subdomain": "string",
  "lastConsumedNonce": 0,
  "cloakie": {
    "active": true,
    "deposits": [
      {
        "tokenId": "string",
        "imageUrl": "string",
        "depositAddress": "string"
      }
    ]
  },
  "hasPoolDeposits": true
}
Try it
Path Parameters
accountId
curl -X GET \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}"

Get funded addresses

GET/v1/accounts/{accountId}/funded-addresses🔒

List stealth addresses with non-zero balances, enriched with token metadata and dApp usage history.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
Responses
200Default Response
Schema
addressesrequiredobject[]
addressrequiredstring
noncerequiredstring
usedOriginsrequiredstring[]
balancesrequiredobject[]
chainIdrequirednumber
chainNamerequiredstring
tokenrequiredstring
tokenSymbolrequiredstring
decimalsrequirednumber
logoUrlrequiredstring | null
amountrequiredstring
Raw amount in smallest unit
usdAmountrequirednumber | null
pricePerTokenrequirednumber | null
json
{
  "addresses": [
    {
      "address": "string",
      "nonce": "string",
      "usedOrigins": [
        "string"
      ],
      "balances": [
        {
          "chainId": 0,
          "chainName": "string",
          "token": "string",
          "tokenSymbol": "string",
          "decimals": 0,
          "logoUrl": "string",
          "amount": "string",
          "usdAmount": 0,
          "pricePerToken": 0
        }
      ]
    }
  ]
}
Try it
Path Parameters
accountId
curl -X GET \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/funded-addresses"

Claim subdomain

POST/v1/accounts/{accountId}/subdomain🔒

Claim an ENS subdomain (e.g. alice.clkd.eth) for this account so senders can pay via a human-readable name instead of a raw address. Each account may claim one subdomain.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
Request Body
subdomainrequiredstring
Subdomain name (will be normalized and stored as {subdomain}.clkd.eth)
Responses
200Default Response
Schema
successrequiredboolean
messagerequiredstring
subdomainrequiredstring
json
{
  "success": true,
  "message": "string",
  "subdomain": "string"
}
Try it
Path Parameters
accountId
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "subdomain": ""
}' \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/subdomain"

Generate subdomain

GET/v1/accounts/{accountId}/subdomain/generate🔒

Generate a random available subdomain for the user to preview during onboarding. The name is not reserved — call setSubdomain to claim it.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
Responses
200Default Response
Schema
subdomainrequiredstring
e.g. "example-123.clkd.eth"
json
{
  "subdomain": "example-123.clkd.eth"
}
Try it
Path Parameters
accountId
curl -X GET \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/subdomain/generate"

Receive

Payment address generation and ENS resolution

Create payment address

POST/v1/accounts/{accountId}/payment-address🔒

Derive a one-time payment address so a sender can transfer tokens to this account without revealing the recipient on-chain.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
idempotency-keyheaderstringClient-generated unique key (e.g. UUID). If the server has already processed a request with this key for the same account and body, it returns the cached response instead of re-executing. Keys expire after 24 hours.
Request Body
Responses
201Default Response
Schema
addressrequiredstring
noncerequiredstring
Nonce used for derivation (stringified bigint)
json
{
  "address": "string",
  "nonce": "string"
}
Try it
Path Parameters
accountId
Headers
idempotency-key
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{}' \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/payment-address"

Balance & Activity

Balance queries, transaction history, and supported tokens

List supported chains

GET/v1/supported-chains

List every chain the platform supports, including explorer URLs, logo base names, and testnet/mainnet mapping. Use to populate chain pickers or build explorer links.

Responses
200Default Response
Schema (item)
namerequiredstring
chainIdrequirednumber
isTestnetrequiredboolean
explorerUrlrequiredstring
explorerTxPathrequiredstring
mainnetChainIdrequirednumber
logoBaseNamerequiredstring
isSquareLogorequiredboolean
json
[
  {
    "name": "string",
    "chainId": 0,
    "isTestnet": true,
    "explorerUrl": "string",
    "explorerTxPath": "string",
    "mainnetChainId": 0,
    "logoBaseName": "string",
    "isSquareLogo": true
  }
]
Try it
curl -X GET \
  "https://api-stg.clkd.xyz/v1/supported-chains"

Get token catalog

GET/v1/token-catalog

Return the full curated token list (Uniswap default list + native ETH + testnet extras), pinned symbols for the swap picker, and testnet-to-mainnet chain-ID mapping.

Responses
200Default Response
Schema
tokensrequiredobject[]
addressrequiredstring
symbolrequiredstring
namerequiredstring
decimalsrequirednumber
chainIdrequirednumber
logoURIstring
isClankerboolean
pinnedSymbolsrequiredstring[]
testnetToMainnetrequiredobject
json
{
  "tokens": [
    {
      "address": "string",
      "symbol": "string",
      "name": "string",
      "decimals": 0,
      "chainId": 0,
      "logoURI": "string",
      "isClanker": true
    }
  ],
  "pinnedSymbols": [
    "string"
  ],
  "testnetToMainnet": null
}
Try it
curl -X GET \
  "https://api-stg.clkd.xyz/v1/token-catalog"

Lookup token

GET/v1/token-lookup

Look up token metadata by contract address. Checks cached sources first, then queries the Clanker API and on-chain ERC-20 metadata.

Parameters
NameInTypeDescription
address*querystring
chainId*querynumber
Responses
200Default Response
Schema
addressrequiredstring
symbolrequiredstring
namerequiredstring
decimalsrequirednumber
chainIdrequirednumber
logoURIstring
isClankerboolean
json
{
  "address": "string",
  "symbol": "string",
  "name": "string",
  "decimals": 0,
  "chainId": 0,
  "logoURI": "string",
  "isClanker": true
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
404Default Response
Schema
errorrequiredstring
e.g. "Not found"
messagerequiredstring
json
{
  "error": "Not found",
  "message": "string"
}
Try it
Query Parameters
address
chainId
curl -X GET \
  "https://api-stg.clkd.xyz/v1/token-lookup"

Get balances

GET/v1/accounts/{accountId}/balance🔒

Retrieve token balances across every supported chain for this account. Each balance contains visible (standard on-chain) available and pending amounts. Returns a totalUsdAmount summarizing all holdings.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
Responses
200Default Response
Schema
balancesrequiredobject[]
One entry per token per chain, each with tiered balance breakdown
chainIdrequirednumber
Chain ID where this token resides
chainNamerequiredstring
Human-readable chain name
tokenrequiredstring
Token contract address (EIP-55 checksummed)
tokenSymbolrequiredstring
Token ticker symbol
decimalsrequirednumber
Token decimal places
logoUrlrequiredstring | null
Token logo URL, or null if unavailable
visiblerequiredobject
Standard on-chain balances held in stealth addresses. These funds have no privacy pool provenance — they arrived via receives, swaps, or on-ramps.
availablerequiredstring
Balance available to spend immediately — not locked by any pending transaction (stringified bigint, smallest unit)
pendingrequiredstring
Balance locked by an outbound transaction that has not yet confirmed on-chain (stringified bigint, smallest unit)
incognitorequiredobject
Incognito balances from privacy pools. The server tracks all three tiers — available, pending approval, and declined.
pooledrequiredobject
Privacy pool balances. Available is the authoritative withdrawable amount tracked by the server.
availablerequiredstring
Sum of ASP-approved, unspent, unlocked commitment values — how much the user can withdraw right now. (stringified bigint, smallest unit)
pendingApprovalrequiredstring
Deposits awaiting ASP compliance approval. Will become available automatically once approved. Includes inflight deposits confirmed on-chain but not yet indexed. (stringified bigint, smallest unit)
declinedrequiredstring
Deposits that were not allowed to join the pool by the compliance check. Recoverable back to the visible wallet balance via the recovery flow. Distinct from pendingApproval so clients can prompt the recovery action instead of leaving the user waiting on a state that will never resolve on its own. (stringified bigint, smallest unit)
usdAmountrequirednumber | null
Total USD value of visible balance. Null when pricing data is unavailable for a token that has a non-zero balance.
pricePerTokenrequirednumber | null
USD price for one whole token (e.g. 1 ETH). Null when pricing data is unavailable. Use this to compute USD values on the client: amount * pricePerToken.
priceStalerequiredboolean
True when all live price sources failed and the price was served from an expired cache entry
spamrequiredboolean
True if the token is flagged as potential spam or a phishing token
totalUsdAmountrequirednumber | null
Sum of usdAmount across all balance items. Null when no pricing data is available for any token.
json
{
  "balances": [
    {
      "chainId": 8453,
      "chainName": "Base",
      "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "tokenSymbol": "USDC",
      "decimals": 6,
      "logoUrl": "https://assets.coingecko.com/coins/images/6319/small/usdc.png",
      "visible": {
        "available": "1000000",
        "pending": "500000"
      },
      "incognito": {
        "pooled": {
          "available": "750000",
          "pendingApproval": "250000",
          "declined": "0"
        }
      },
      "usdAmount": 1.5,
      "pricePerToken": 2000.42,
      "priceStale": false,
      "spam": false
    }
  ],
  "totalUsdAmount": 1.5
}
401Default Response
Schema
errorrequiredstring
e.g. "Unauthorized"
messagerequiredstring
codestring
e.g. "UNAUTHORIZED"
json
{
  "error": "Unauthorized",
  "message": "string",
  "code": "UNAUTHORIZED"
}
404Default Response
Schema
errorrequiredstring
e.g. "Not found"
messagerequiredstring
json
{
  "error": "Not found",
  "message": "string"
}
429Default Response
Schema
errorrequiredstring
e.g. "Too Many Requests"
messagerequiredstring
e.g. "Rate limit exceeded. Maximum 60 requests per 1 minute."
json
{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded. Maximum 60 requests per 1 minute."
}
Try it
Path Parameters
accountId
curl -X GET \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/balance"

Get chain balances

GET/v1/accounts/{accountId}/balance/{chainId}🔒

Retrieve token balances filtered to a single chain. Same response shape as getBalances (visible available/pending) but scoped to the given chainId.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
chainId*pathstringChain ID (e.g., 8453 for Base)
Responses
200Default Response
Schema
balancesrequiredobject[]
One entry per token per chain, each with tiered balance breakdown
chainIdrequirednumber
Chain ID where this token resides
chainNamerequiredstring
Human-readable chain name
tokenrequiredstring
Token contract address (EIP-55 checksummed)
tokenSymbolrequiredstring
Token ticker symbol
decimalsrequirednumber
Token decimal places
logoUrlrequiredstring | null
Token logo URL, or null if unavailable
visiblerequiredobject
Standard on-chain balances held in stealth addresses. These funds have no privacy pool provenance — they arrived via receives, swaps, or on-ramps.
availablerequiredstring
Balance available to spend immediately — not locked by any pending transaction (stringified bigint, smallest unit)
pendingrequiredstring
Balance locked by an outbound transaction that has not yet confirmed on-chain (stringified bigint, smallest unit)
incognitorequiredobject
Incognito balances from privacy pools. The server tracks all three tiers — available, pending approval, and declined.
pooledrequiredobject
Privacy pool balances. Available is the authoritative withdrawable amount tracked by the server.
availablerequiredstring
Sum of ASP-approved, unspent, unlocked commitment values — how much the user can withdraw right now. (stringified bigint, smallest unit)
pendingApprovalrequiredstring
Deposits awaiting ASP compliance approval. Will become available automatically once approved. Includes inflight deposits confirmed on-chain but not yet indexed. (stringified bigint, smallest unit)
declinedrequiredstring
Deposits that were not allowed to join the pool by the compliance check. Recoverable back to the visible wallet balance via the recovery flow. Distinct from pendingApproval so clients can prompt the recovery action instead of leaving the user waiting on a state that will never resolve on its own. (stringified bigint, smallest unit)
usdAmountrequirednumber | null
Total USD value of visible balance. Null when pricing data is unavailable for a token that has a non-zero balance.
pricePerTokenrequirednumber | null
USD price for one whole token (e.g. 1 ETH). Null when pricing data is unavailable. Use this to compute USD values on the client: amount * pricePerToken.
priceStalerequiredboolean
True when all live price sources failed and the price was served from an expired cache entry
spamrequiredboolean
True if the token is flagged as potential spam or a phishing token
totalUsdAmountrequirednumber | null
Sum of usdAmount across all balance items. Null when no pricing data is available for any token.
json
{
  "balances": [
    {
      "chainId": 8453,
      "chainName": "Base",
      "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "tokenSymbol": "USDC",
      "decimals": 6,
      "logoUrl": "https://assets.coingecko.com/coins/images/6319/small/usdc.png",
      "visible": {
        "available": "1000000",
        "pending": "500000"
      },
      "incognito": {
        "pooled": {
          "available": "750000",
          "pendingApproval": "250000",
          "declined": "0"
        }
      },
      "usdAmount": 1.5,
      "pricePerToken": 2000.42,
      "priceStale": false,
      "spam": false
    }
  ],
  "totalUsdAmount": 1.5
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
401Default Response
Schema
errorrequiredstring
e.g. "Unauthorized"
messagerequiredstring
codestring
e.g. "UNAUTHORIZED"
json
{
  "error": "Unauthorized",
  "message": "string",
  "code": "UNAUTHORIZED"
}
404Default Response
Schema
errorrequiredstring
e.g. "Not found"
messagerequiredstring
json
{
  "error": "Not found",
  "message": "string"
}
429Default Response
Schema
errorrequiredstring
e.g. "Too Many Requests"
messagerequiredstring
e.g. "Rate limit exceeded. Maximum 60 requests per 1 minute."
json
{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded. Maximum 60 requests per 1 minute."
}
Try it
Path Parameters
accountId
chainId
curl -X GET \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/balance/{chainId}"

Get token balance

GET/v1/accounts/{accountId}/balance/{chainId}/{token}🔒

Retrieve the balance for a single token on a specific chain. Returns visible available and pending amounts. Returns a zero-balance object if the token has never been received.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
chainId*pathstringChain ID
token*pathstringToken address (0x...)
Responses
200Balance for a single token on a single chain. Contains visible available and pending amounts for standard on-chain stealth address holdings.
Schema
chainIdrequirednumber
Chain ID where this token resides
chainNamerequiredstring
Human-readable chain name
tokenrequiredstring
Token contract address (EIP-55 checksummed)
tokenSymbolrequiredstring
Token ticker symbol
decimalsrequirednumber
Token decimal places
logoUrlrequiredstring | null
Token logo URL, or null if unavailable
visiblerequiredobject
Standard on-chain balances held in stealth addresses. These funds have no privacy pool provenance — they arrived via receives, swaps, or on-ramps.
availablerequiredstring
Balance available to spend immediately — not locked by any pending transaction (stringified bigint, smallest unit)
pendingrequiredstring
Balance locked by an outbound transaction that has not yet confirmed on-chain (stringified bigint, smallest unit)
incognitorequiredobject
Incognito balances from privacy pools. The server tracks all three tiers — available, pending approval, and declined.
pooledrequiredobject
Privacy pool balances. Available is the authoritative withdrawable amount tracked by the server.
availablerequiredstring
Sum of ASP-approved, unspent, unlocked commitment values — how much the user can withdraw right now. (stringified bigint, smallest unit)
pendingApprovalrequiredstring
Deposits awaiting ASP compliance approval. Will become available automatically once approved. Includes inflight deposits confirmed on-chain but not yet indexed. (stringified bigint, smallest unit)
declinedrequiredstring
Deposits that were not allowed to join the pool by the compliance check. Recoverable back to the visible wallet balance via the recovery flow. Distinct from pendingApproval so clients can prompt the recovery action instead of leaving the user waiting on a state that will never resolve on its own. (stringified bigint, smallest unit)
usdAmountrequirednumber | null
Total USD value of visible balance. Null when pricing data is unavailable for a token that has a non-zero balance.
pricePerTokenrequirednumber | null
USD price for one whole token (e.g. 1 ETH). Null when pricing data is unavailable. Use this to compute USD values on the client: amount * pricePerToken.
priceStalerequiredboolean
True when all live price sources failed and the price was served from an expired cache entry
spamrequiredboolean
True if the token is flagged as potential spam or a phishing token
json
{
  "chainId": 8453,
  "chainName": "Base",
  "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  "tokenSymbol": "USDC",
  "decimals": 6,
  "logoUrl": "https://assets.coingecko.com/coins/images/6319/small/usdc.png",
  "visible": {
    "available": "1000000",
    "pending": "500000"
  },
  "incognito": {
    "pooled": {
      "available": "750000",
      "pendingApproval": "250000",
      "declined": "0"
    }
  },
  "usdAmount": 1.5,
  "pricePerToken": 2000.42,
  "priceStale": false,
  "spam": false
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
401Default Response
Schema
errorrequiredstring
e.g. "Unauthorized"
messagerequiredstring
codestring
e.g. "UNAUTHORIZED"
json
{
  "error": "Unauthorized",
  "message": "string",
  "code": "UNAUTHORIZED"
}
404Default Response
Schema
errorrequiredstring
e.g. "Not found"
messagerequiredstring
json
{
  "error": "Not found",
  "message": "string"
}
429Default Response
Schema
errorrequiredstring
e.g. "Too Many Requests"
messagerequiredstring
e.g. "Rate limit exceeded. Maximum 60 requests per 1 minute."
json
{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded. Maximum 60 requests per 1 minute."
}
Try it
Path Parameters
accountId
chainId
token
curl -X GET \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/balance/{chainId}/{token}"

Get activities

GET/v1/accounts/{accountId}/activities🔒

List confirmed (on-chain) transactions for the account with cursor-based pagination. The response uses a discriminated union on kind: SEND/RECEIVE/SELF/INCOGNITO_*/NFT_WITHDRAW include a transfer object, SWAP includes a swap object with source and dest token info, BRIDGE includes a bridge object with source, dest, and chain info. For in-flight transactions, use GET /activities/pending.

Parameters
NameInTypeDescription
limitquerystringMaximum number of activities to return (1-500, default: 100)
cursorquerystringBase64-encoded cursor for pagination
accountId*pathstring (uuid)Account ID
Responses
200Default Response
Schema
activityrequiredobject[]
txHashrequiredstring | null
quoteIdstring (uuid)
Quote ID that produced this transaction, for correlating pending → confirmed
chainIdrequirednumber
e.g. 8453
chainNamerequiredstring
e.g. "Base"
daterequiredstring (date-time)
kindrequired"SEND" | "RECEIVE" | "SELF" | "SWAP" | "BRIDGE" | "POOL_DEPOSIT" | "POOL_RECOVER" | "INCOGNITO_SEND" | "INCOGNITO_SELF_SEND" | "NFT_WITHDRAW" | "DAPP_CALL" | "OFF_RAMP" | "OFF_RAMP_CANCEL"
lifecyclerequiredobject | object | object
isLikelySpamrequiredboolean
e.g. false
feerequiredobject | null
transferobject
tokenAddressrequiredstring
e.g. "0x..."
decimalsrequirednumber
e.g. 6
tokenSymbolrequiredstring
e.g. "USDC"
logoUrlrequiredstring | null
fromAddressrequiredstring
e.g. "0x..."
toAddressrequiredstring
e.g. "0x..."
valuerequiredstring
e.g. "1000000"
usdAmountrequirednumber
e.g. 1
swapobject
sourceTokenAddressrequiredstring
e.g. "0x..."
sourceDecimalsrequirednumber
e.g. 6
sourceTokenSymbolrequiredstring
e.g. "USDC"
sourceLogoUrlrequiredstring | null
sourceAmountrequiredstring
e.g. "1000000"
sourceUsdAmountrequirednumber
e.g. 1
destTokenAddressrequiredstring
e.g. "0x..."
destTokenSymbolrequiredstring
e.g. "WETH"
destDecimalsrequirednumber
e.g. 18
destLogoUrlrequiredstring | null
destAmountrequiredstring
e.g. "500000000000000"
destUsdAmountrequirednumber
e.g. 0.5
outputRecipientrequiredstring
e.g. "0x..."
bridgeobject
sourceTokenAddressrequiredstring
e.g. "0x..."
sourceDecimalsrequirednumber
e.g. 6
sourceTokenSymbolrequiredstring
e.g. "USDC"
sourceLogoUrlrequiredstring | null
sourceAmountrequiredstring
e.g. "1000000"
sourceUsdAmountrequirednumber
e.g. 1
destTokenAddressrequiredstring
e.g. "0x..."
destTokenSymbolrequiredstring
e.g. "USDC"
destDecimalsrequirednumber
e.g. 6
destLogoUrlrequiredstring | null
destAmountrequiredstring
e.g. "1000000"
destUsdAmountrequirednumber
e.g. 1
outputRecipientrequiredstring
e.g. "0x..."
bridgeStatusrequiredstring
e.g. "pending"
destChainIdrequirednumber
e.g. 8453
destChainNamerequiredstring
e.g. "Base"
estimatedFillTimeMsrequirednumber | null
destTxHashrequiredstring | null
poolobject
poolAddressrequiredstring
e.g. "0x..."
tokenAddressrequiredstring
e.g. "0x..."
decimalsrequirednumber
e.g. 18
tokenSymbolrequiredstring
e.g. "ETH"
logoUrlrequiredstring | null
amountrequiredstring
e.g. "1000000000000000"
usdAmountrequirednumber
e.g. 1
aspStatus"pending" | "approved" | "declined" | "failed" | "cancelled"
commitmentIdstring
vettingFeestring
vettingFeeUsdnumber
depositFeestring
depositFeeUsdnumber
dappMetaobject
originstring
descriptionstring
connectedAddressstring
calldatastring
Raw calls JSON for dapp-call activities: [{ to, value, data }]
offRampobject
peerDepositIdrequiredstring
DB row UUID of the peer_deposit
paymentMethodrequiredstring
e.g. "venmo"
escrowStatusrequired"pending_deposit" | "active" | "intent_matched" | "completed" | "cancelling" | "cancelled" | "failed" | "failed_bridge_fallback"
depositIdrequiredstring | null
escrowAmountrequiredstring
Stringified bigint
usdAmountrequirednumber
estimatedFiatAmountrequirednumber | null
tokenAddressrequiredstring
decimalsrequirednumber
tokenSymbolrequiredstring
logoUrlrequiredstring | null
filledAmountrequiredstring | null
serviceFeestring
Stringified bigint — service fee
serviceFeeUsdnumber
paginationrequiredobject
limitrequirednumber
e.g. 100
nextCursorrequiredstring | null
Base64-encoded cursor for next page
json
{
  "activity": [
    {
      "txHash": "0x...",
      "quoteId": "string",
      "chainId": 8453,
      "chainName": "Base",
      "date": "string",
      "kind": "string",
      "lifecycle": {
        "state": "string"
      },
      "isLikelySpam": false,
      "fee": {
        "tokenAddress": "0x...",
        "decimals": 18,
        "tokenSymbol": "ETH",
        "logoUrl": "string",
        "value": "1000000000000000",
        "usdAmount": 0.001
      },
      "transfer": {
        "tokenAddress": "0x...",
        "decimals": 6,
        "tokenSymbol": "USDC",
        "logoUrl": "string",
        "fromAddress": "0x...",
        "toAddress": "0x...",
        "value": "1000000",
        "usdAmount": 1
      },
      "swap": {
        "sourceTokenAddress": "0x...",
        "sourceDecimals": 6,
        "sourceTokenSymbol": "USDC",
        "sourceLogoUrl": "string",
        "sourceAmount": "1000000",
        "sourceUsdAmount": 1,
        "destTokenAddress": "0x...",
        "destTokenSymbol": "WETH",
        "destDecimals": 18,
        "destLogoUrl": "string",
        "destAmount": "500000000000000",
        "destUsdAmount": 0.5,
        "outputRecipient": "0x..."
      },
      "bridge": {
        "sourceTokenAddress": "0x...",
        "sourceDecimals": 6,
        "sourceTokenSymbol": "USDC",
        "sourceLogoUrl": "string",
        "sourceAmount": "1000000",
        "sourceUsdAmount": 1,
        "destTokenAddress": "0x...",
        "destTokenSymbol": "USDC",
        "destDecimals": 6,
        "destLogoUrl": "string",
        "destAmount": "1000000",
        "destUsdAmount": 1,
        "outputRecipient": "0x...",
        "bridgeStatus": "pending",
        "destChainId": 8453,
        "destChainName": "Base",
        "estimatedFillTimeMs": 0,
        "destTxHash": "0x..."
      },
      "pool": {
        "poolAddress": "0x...",
        "tokenAddress": "0x...",
        "decimals": 18,
        "tokenSymbol": "ETH",
        "logoUrl": "string",
        "amount": "1000000000000000",
        "usdAmount": 1,
        "aspStatus": "string",
        "commitmentId": "string",
        "vettingFee": "string",
        "vettingFeeUsd": 0,
        "depositFee": "string",
        "depositFeeUsd": 0
      },
      "dappMeta": {
        "origin": "string",
        "description": "string",
        "connectedAddress": "string"
      },
      "calldata": "string",
      "offRamp": {
        "peerDepositId": "string",
        "paymentMethod": "venmo",
        "escrowStatus": "string",
        "depositId": "string",
        "escrowAmount": "string",
        "usdAmount": 0,
        "estimatedFiatAmount": 0,
        "tokenAddress": "string",
        "decimals": 0,
        "tokenSymbol": "string",
        "logoUrl": "string",
        "filledAmount": "string",
        "serviceFee": "string",
        "serviceFeeUsd": 0
      }
    }
  ],
  "pagination": {
    "limit": 100,
    "nextCursor": "string"
  }
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
401Default Response
Schema
errorrequiredstring
e.g. "Unauthorized"
messagerequiredstring
codestring
e.g. "UNAUTHORIZED"
json
{
  "error": "Unauthorized",
  "message": "string",
  "code": "UNAUTHORIZED"
}
404Default Response
Schema
errorrequiredstring
e.g. "Not found"
messagerequiredstring
json
{
  "error": "Not found",
  "message": "string"
}
Try it
Path Parameters
accountId
Query Parameters
limit
cursor
curl -X GET \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/activities"

Get pending activities

GET/v1/accounts/{accountId}/activities/pending🔒

List in-flight relay transactions (queued, pending, stuck) and recently confirmed/failed transactions for the account. The response uses the same shape as GET /activities: same kind values, same payload sub-objects. The lifecycle.state discriminates between 'in_flight', 'indexed', and 'failed'. Recently confirmed transactions are included for up to 5 minutes so the client can show continuous state while the transaction is indexed.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
Responses
200Default Response
Schema
pendingrequiredobject[]
txHashrequiredstring | null
quoteIdstring (uuid)
Quote ID that produced this transaction, for correlating pending → confirmed
chainIdrequirednumber
e.g. 8453
chainNamerequiredstring
e.g. "Base"
daterequiredstring (date-time)
kindrequired"SEND" | "RECEIVE" | "SELF" | "SWAP" | "BRIDGE" | "POOL_DEPOSIT" | "POOL_RECOVER" | "INCOGNITO_SEND" | "INCOGNITO_SELF_SEND" | "NFT_WITHDRAW" | "DAPP_CALL" | "OFF_RAMP" | "OFF_RAMP_CANCEL"
lifecyclerequiredobject | object | object
isLikelySpamrequiredboolean
e.g. false
feerequiredobject | null
transferobject
tokenAddressrequiredstring
e.g. "0x..."
decimalsrequirednumber
e.g. 6
tokenSymbolrequiredstring
e.g. "USDC"
logoUrlrequiredstring | null
fromAddressrequiredstring
e.g. "0x..."
toAddressrequiredstring
e.g. "0x..."
valuerequiredstring
e.g. "1000000"
usdAmountrequirednumber
e.g. 1
swapobject
sourceTokenAddressrequiredstring
e.g. "0x..."
sourceDecimalsrequirednumber
e.g. 6
sourceTokenSymbolrequiredstring
e.g. "USDC"
sourceLogoUrlrequiredstring | null
sourceAmountrequiredstring
e.g. "1000000"
sourceUsdAmountrequirednumber
e.g. 1
destTokenAddressrequiredstring
e.g. "0x..."
destTokenSymbolrequiredstring
e.g. "WETH"
destDecimalsrequirednumber
e.g. 18
destLogoUrlrequiredstring | null
destAmountrequiredstring
e.g. "500000000000000"
destUsdAmountrequirednumber
e.g. 0.5
outputRecipientrequiredstring
e.g. "0x..."
bridgeobject
sourceTokenAddressrequiredstring
e.g. "0x..."
sourceDecimalsrequirednumber
e.g. 6
sourceTokenSymbolrequiredstring
e.g. "USDC"
sourceLogoUrlrequiredstring | null
sourceAmountrequiredstring
e.g. "1000000"
sourceUsdAmountrequirednumber
e.g. 1
destTokenAddressrequiredstring
e.g. "0x..."
destTokenSymbolrequiredstring
e.g. "USDC"
destDecimalsrequirednumber
e.g. 6
destLogoUrlrequiredstring | null
destAmountrequiredstring
e.g. "1000000"
destUsdAmountrequirednumber
e.g. 1
outputRecipientrequiredstring
e.g. "0x..."
bridgeStatusrequiredstring
e.g. "pending"
destChainIdrequirednumber
e.g. 8453
destChainNamerequiredstring
e.g. "Base"
estimatedFillTimeMsrequirednumber | null
destTxHashrequiredstring | null
poolobject
poolAddressrequiredstring
e.g. "0x..."
tokenAddressrequiredstring
e.g. "0x..."
decimalsrequirednumber
e.g. 18
tokenSymbolrequiredstring
e.g. "ETH"
logoUrlrequiredstring | null
amountrequiredstring
e.g. "1000000000000000"
usdAmountrequirednumber
e.g. 1
aspStatus"pending" | "approved" | "declined" | "failed" | "cancelled"
commitmentIdstring
vettingFeestring
vettingFeeUsdnumber
depositFeestring
depositFeeUsdnumber
dappMetaobject
originstring
descriptionstring
connectedAddressstring
calldatastring
Raw calls JSON for dapp-call activities: [{ to, value, data }]
offRampobject
peerDepositIdrequiredstring
DB row UUID of the peer_deposit
paymentMethodrequiredstring
e.g. "venmo"
escrowStatusrequired"pending_deposit" | "active" | "intent_matched" | "completed" | "cancelling" | "cancelled" | "failed" | "failed_bridge_fallback"
depositIdrequiredstring | null
escrowAmountrequiredstring
Stringified bigint
usdAmountrequirednumber
estimatedFiatAmountrequirednumber | null
tokenAddressrequiredstring
decimalsrequirednumber
tokenSymbolrequiredstring
logoUrlrequiredstring | null
filledAmountrequiredstring | null
serviceFeestring
Stringified bigint — service fee
serviceFeeUsdnumber
json
{
  "pending": [
    {
      "txHash": "0x...",
      "quoteId": "string",
      "chainId": 8453,
      "chainName": "Base",
      "date": "string",
      "kind": "string",
      "lifecycle": {
        "state": "string"
      },
      "isLikelySpam": false,
      "fee": {
        "tokenAddress": "0x...",
        "decimals": 18,
        "tokenSymbol": "ETH",
        "logoUrl": "string",
        "value": "1000000000000000",
        "usdAmount": 0.001
      },
      "transfer": {
        "tokenAddress": "0x...",
        "decimals": 6,
        "tokenSymbol": "USDC",
        "logoUrl": "string",
        "fromAddress": "0x...",
        "toAddress": "0x...",
        "value": "1000000",
        "usdAmount": 1
      },
      "swap": {
        "sourceTokenAddress": "0x...",
        "sourceDecimals": 6,
        "sourceTokenSymbol": "USDC",
        "sourceLogoUrl": "string",
        "sourceAmount": "1000000",
        "sourceUsdAmount": 1,
        "destTokenAddress": "0x...",
        "destTokenSymbol": "WETH",
        "destDecimals": 18,
        "destLogoUrl": "string",
        "destAmount": "500000000000000",
        "destUsdAmount": 0.5,
        "outputRecipient": "0x..."
      },
      "bridge": {
        "sourceTokenAddress": "0x...",
        "sourceDecimals": 6,
        "sourceTokenSymbol": "USDC",
        "sourceLogoUrl": "string",
        "sourceAmount": "1000000",
        "sourceUsdAmount": 1,
        "destTokenAddress": "0x...",
        "destTokenSymbol": "USDC",
        "destDecimals": 6,
        "destLogoUrl": "string",
        "destAmount": "1000000",
        "destUsdAmount": 1,
        "outputRecipient": "0x...",
        "bridgeStatus": "pending",
        "destChainId": 8453,
        "destChainName": "Base",
        "estimatedFillTimeMs": 0,
        "destTxHash": "0x..."
      },
      "pool": {
        "poolAddress": "0x...",
        "tokenAddress": "0x...",
        "decimals": 18,
        "tokenSymbol": "ETH",
        "logoUrl": "string",
        "amount": "1000000000000000",
        "usdAmount": 1,
        "aspStatus": "string",
        "commitmentId": "string",
        "vettingFee": "string",
        "vettingFeeUsd": 0,
        "depositFee": "string",
        "depositFeeUsd": 0
      },
      "dappMeta": {
        "origin": "string",
        "description": "string",
        "connectedAddress": "string"
      },
      "calldata": "string",
      "offRamp": {
        "peerDepositId": "string",
        "paymentMethod": "venmo",
        "escrowStatus": "string",
        "depositId": "string",
        "escrowAmount": "string",
        "usdAmount": 0,
        "estimatedFiatAmount": 0,
        "tokenAddress": "string",
        "decimals": 0,
        "tokenSymbol": "string",
        "logoUrl": "string",
        "filledAmount": "string",
        "serviceFee": "string",
        "serviceFeeUsd": 0
      }
    }
  ]
}
401Default Response
Schema
errorrequiredstring
e.g. "Unauthorized"
messagerequiredstring
codestring
e.g. "UNAUTHORIZED"
json
{
  "error": "Unauthorized",
  "message": "string",
  "code": "UNAUTHORIZED"
}
404Default Response
Schema
errorrequiredstring
e.g. "Not found"
messagerequiredstring
json
{
  "error": "Not found",
  "message": "string"
}
Try it
Path Parameters
accountId
curl -X GET \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/activities/pending"

Send, Swap, Bridge, Convert

Sending, swapping, bridging, and converting to incognito all follow the same flow: get a quote, then submit.

Get quote signer public key

GET/v1/.well-known/quote-signer-public-key

Retrieve the server's P-256 ECDSA public key so clients can verify that quote responses were authentically signed by the server and haven't been tampered with.

Responses
200Default Response
Schema
publicKeyrequiredstring
e.g. "04..."
formatrequiredstring
e.g. "hex"
curverequiredstring
e.g. "P-256"
algorithmrequiredstring
e.g. "ECDSA"
json
{
  "publicKey": "04...",
  "format": "hex",
  "curve": "P-256",
  "algorithm": "ECDSA"
}
Try it
curl -X GET \
  "https://api-stg.clkd.xyz/v1/.well-known/quote-signer-public-key"

List supported pools

GET/v1/supported-pools🔒

List privacy pools available to the authenticated user, including pool contract addresses, accepted tokens, deposit limits, and ASP (Association Set Provider) details. Feature-flagged pools are only included when the flag is enabled for the account.

Responses
200Default Response
Schema (item)
poolAddressrequiredstring
e.g. "0x..."
chainIdrequirednumber
e.g. 1
chainNamerequiredstring
e.g. "Ethereum"
tokenrequiredstring
e.g. "0x..."
tokenSymbolrequiredstring
e.g. "ETH"
decimalsrequirednumber
e.g. 18
logoUrlrequiredstring | null
e.g. "https://..."
minDepositrequiredstring
e.g. "10000000000000000"
maxDepositrequiredstring
e.g. "100000000000000000000"
totalBalancerequiredstring | null
Total pool balance in smallest unit (stringified bigint), or null if unavailable
scoperequiredstring
Pool scope as a stringified bigint — keccak256(poolAddress, chainId, asset) mod SNARK_SCALAR_FIELD. Used by the client to derive deposit precommitments.
asprequiredobject
namerequiredstring
e.g. "0xbow"
policyUrlrequiredstring
e.g. "https://0xbow.io/policy"
maxRelayFeeBPSrequirednumber
On-chain contract maximum for relayFeeBPS on withdrawals
withdrawalFeePerProofWeirequiredstring
Estimated gas cost in wei for relaying one ZK proof withdrawal (stringified bigint). Refreshed periodically.
json
[
  {
    "poolAddress": "0x...",
    "chainId": 1,
    "chainName": "Ethereum",
    "token": "0x...",
    "tokenSymbol": "ETH",
    "decimals": 18,
    "logoUrl": "https://...",
    "minDeposit": "10000000000000000",
    "maxDeposit": "100000000000000000000",
    "totalBalance": "2659000000000000000000",
    "scope": "12345678901234567890",
    "asp": {
      "name": "0xbow",
      "policyUrl": "https://0xbow.io/policy"
    },
    "maxRelayFeeBPS": 1000,
    "withdrawalFeePerProofWei": "95000000000000"
  }
]
Try it
curl -X GET \
  "https://api-stg.clkd.xyz/v1/supported-pools"

Create quote

POST/v1/accounts/{accountId}/quote🔒

Unified quote endpoint. For type=send: reserves balances and returns signing data. For type=swap: reserves balances and returns swap intents via Uniswap.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
idempotency-keyheaderstringClient-generated unique key (e.g. UUID). If the server has already processed a request with this key for the same account and body, it returns the cached response instead of re-executing. Keys expire after 24 hours.
Request Body
Send Quote Request
typerequired"send"
chainIdrequirednumber
Chain ID (must support Porto)
tokenrequiredstring
Token address (0x...)
amountstring
Amount in smallest unit (stringified bigint). Required unless maxSend is true.
decimalsrequirednumber
Token decimals (0-255)
destinationAddressrequiredstring
Destination address (0x... or ENS)
maxSendboolean
When true, server computes the maximum sendable amount. Amount field is ignored.
ttlnumber
Lock TTL in seconds (default: 86400, max: 86400)
Swap Quote Request
typerequired"swap"
chainIdrequirednumber
Chain ID
tokenInrequiredstring
Token address being sold
tokenOutrequiredstring
Token address being bought
amountInstring
Amount to swap in smallest unit (stringified bigint). Required unless maxSend is true.
slippageBpsrequirednumber
Slippage tolerance in basis points (e.g. 50 = 0.5%, max: 500 = 5%)
tokenOutChainIdnumber
Destination chain ID for cross-chain swaps
maxSendboolean
When true, server computes max swappable amount. amountIn is ignored.
Convert Request
typerequired"pool-deposit"
chainIdrequirednumber
Chain ID where the privacy pool lives
tokenrequiredstring
Token address to deposit (0x...)
amountstring
Deposit amount in smallest unit (stringified bigint). Required unless maxSend is true.
decimalsrequirednumber
Token decimals (0-255)
precommitmentrequiredstring
Precommitment hash (stringified bigint) binding the deposit secrets without revealing them
nullifierHashrequiredstring
Hash of the commitment nullifier (stringified bigint). Lets the server cross-reference on-chain spends.
depositIndexnumber
Client-derived deposit index used for precommitment derivation. Falls back to server-computed index if omitted.
maxSendboolean
When true, server computes max deposit amount atomically. Amount field is ignored.
Pool Withdraw Quote Request
typerequired"pool-withdraw"
chainIdrequirednumber
Chain ID where the privacy pool lives
tokenrequiredstring
Token address to withdraw (0x...)
amountrequiredstring
Withdrawal amount in smallest unit (stringified bigint)
decimalsrequirednumber
Token decimals (0-255)
destinationAddressrequiredstring
Where to send withdrawn funds (0x... or ENS)
Conversion Recover Request
typerequired"pool-recover"
chainIdrequirednumber
Chain ID where the privacy pool lives
tokenrequiredstring
Token address (0x...)
commitmentIdrequiredstring
DB ID of the declined commitment to recover
Dapp Call Quote Request
typerequired"dapp-call"
chainIdrequirednumber
Chain ID to execute on
addressrequiredstring
Stealth address to execute from (0x...)
callsrequiredobject[]
torequiredstring
Target contract address
valuerequiredstring
ETH value in wei (hex or decimal string)
datarequiredstring
Calldata (hex string)
dappOriginstring
Origin hostname of the dApp (e.g. app.uniswap.org)
Off Ramp Quote Request
typerequired"off-ramp"
chainIdrequirednumber
Source chain ID (8453 for Base, 1 for Ethereum)
tokenrequiredstring
Source token address (0x...)
amountrequiredstring
Desired escrow deposit amount in smallest unit (USDC, 6 decimals)
decimalsrequirednumber
Token decimals
fromIncognitorequiredboolean
True if source is an incognito (pool) balance
escrowParamsrequiredobject
EscrowV2 CreateDepositParams — passed through to the escrow contract
paymentMethodrequiredstring
Payment method (venmo, revolut, wise, etc.)
payeeDetailsHashrequiredstring
Hashed curator payee ID (no raw PII)
conversionRatenumber
USDC-to-fiat conversion rate
Off Ramp Cancel Quote Request
typerequired"off-ramp-cancel"
peerDepositIdrequiredstring
UUID of the peer_deposit to cancel
Responses
200Default Response
Schema
Swap Quote Response
intentsrequiredobject[]
chainIdrequirednumber
eoarequiredstring
executionDatarequiredstring
noncerequiredstring
derivationNoncerequiredstring
payerrequiredstring
paymentTokenrequiredstring
paymentMaxAmountrequiredstring
combinedGasrequiredstring
encodedPreCallsrequiredstring[]
encodedFundTransfersrequiredstring[]
settlerrequiredstring
expiryrequiredstring
isMultichainrequiredboolean
funderrequiredstring
funderSignaturerequiredstring
settlerContextrequiredstring
paymentAmountrequiredstring
paymentRecipientrequiredstring
paymentSignaturerequiredstring
supportedAccountImplementationrequiredstring
domainrequiredobject
namerequiredstring
versionrequiredstring
chainIdrequirednumber
verifyingContractrequiredstring
typesrequiredany
EIP-712 type definitions
primaryTyperequired"Intent"
delegationsrequiredobject[]
chainIdrequirednumber
addressrequiredstring
contractAddressrequiredstring
derivationNoncerequirednumber
authorizationNoncerequirednumber
quoteIdrequiredstring
expiresAtrequiredstring
signaturerequiredstring
expectedOutputrequiredstring
minimumOutputrequiredstring
outputTokenrequiredstring
outputDecimalsrequirednumber
outputSymbolrequiredstring
outputRecipientrequiredstring
slippageBpsrequirednumber
routingrequiredstring
protocolFeeBpsrequirednumber
protocolFeeAmountrequiredstring
amountInrequiredstring
priceImpactnumber
estimatedFillTimeMsnumber
fillDeadlinenumber
planIdstring
Bridge routing plan identifier from Across protocol, present only for cross-chain (CHAINED) quotes
feesrequiredobject
networkrequiredstring
Gas/relay fee in wei (gas cost only, excludes dust)
duststring
Residual balance below the dust threshold swept into the relayer payment. Not a gas fee — included in total but not in network.
servicerequiredstring
Protocol fees in wei (vetting + cloaked, or swap protocol fee)
vettingstring
On-chain vetting fee in wei (pool deposits only)
depositstring
Cloaked deposit fee in wei (pool deposits only)
totalrequiredstring
Total fees in wei (network + dust + service)
waivedboolean
True when fees are waived (e.g. Cloakie holder on swaps)
Conversion Recover Response
quoteIdrequiredstring
expiresAtrequiredstring
signaturerequiredstring
poolAddressrequiredstring
commitmentrequiredobject
idrequiredstring
depositIndexrequirednumber
withdrawalIndexrequirednumber
commitmentrequiredstring
labelrequiredstring
valuerequiredstring
depositorAddressrequiredstring
Stealth address that made the original deposit (msg.sender for ragequit).
Incognito Send Response
quoteIdrequiredstring
expiresAtrequiredstring
signaturerequiredstring
poolAddressrequiredstring
resolvedDestinationrequiredstring
selfSendrequiredboolean
feeRecipientrequiredstring
Address to receive relay fees
relayFeeBPSrequirednumber
Definitive relay fee BPS for this set of commitments. Client bakes into each proof.
feePerProofrequiredstring
Estimated fee per ZK proof relay in the pool token units (stringified bigint)
maxRelayFeeBPSrequirednumber
On-chain contract maximum for relayFeeBPS
commitmentsrequiredobject[]
idrequiredstring
depositIndexrequirednumber
withdrawalIndexrequirednumber
commitmentrequiredstring
labelrequiredstring
valuerequiredstring
withdrawalAmountrequiredstring
pooledSincerequiredstring
ISO timestamp when the ASP approved this commitment (entered the anonymity set)
feesrequiredobject
networkrequiredstring
Gas/relay fee in wei (gas cost only, excludes dust)
duststring
Residual balance below the dust threshold swept into the relayer payment. Not a gas fee — included in total but not in network.
servicerequiredstring
Protocol fees in wei (vetting + cloaked, or swap protocol fee)
vettingstring
On-chain vetting fee in wei (pool deposits only)
depositstring
Cloaked deposit fee in wei (pool deposits only)
totalrequiredstring
Total fees in wei (network + dust + service)
waivedboolean
True when fees are waived (e.g. Cloakie holder on swaps)
Convert Response
intentsrequiredobject[]
chainIdrequirednumber
eoarequiredstring
executionDatarequiredstring
noncerequiredstring
derivationNoncerequiredstring
payerrequiredstring
paymentTokenrequiredstring
paymentMaxAmountrequiredstring
combinedGasrequiredstring
encodedPreCallsrequiredstring[]
encodedFundTransfersrequiredstring[]
settlerrequiredstring
expiryrequiredstring
isMultichainrequiredboolean
funderrequiredstring
funderSignaturerequiredstring
settlerContextrequiredstring
paymentAmountrequiredstring
paymentRecipientrequiredstring
paymentSignaturerequiredstring
supportedAccountImplementationrequiredstring
domainrequiredobject
namerequiredstring
versionrequiredstring
chainIdrequirednumber
verifyingContractrequiredstring
typesrequiredany
EIP-712 type definitions
primaryTyperequired"Intent"
delegationsrequiredobject[]
chainIdrequirednumber
addressrequiredstring
contractAddressrequiredstring
derivationNoncerequirednumber
authorizationNoncerequirednumber
quoteIdrequiredstring
expiresAtrequiredstring
signaturerequiredstring
poolAddressrequiredstring
depositIndexrequirednumber
grossAmountrequiredstring
Total ETH sent to entrypoint (amount + vetting fee)
feeAmountrequiredstring
Vetting fee deducted by the pool
feeBpsrequirednumber
Vetting fee in basis points
netPoolValuerequiredstring
Net value credited to the pool commitment
cloakedFeeBpsrequirednumber
Cloaked protocol fee rate in basis points
cloakedFlatFeerequiredstring
Flat fee floor in wei for the Cloaked deposit fee
cloakieFeeModerequired"flat" | "standard"
Fee mode: flat (Cloakie holder) or standard (max of flat and percentage)
feesrequiredobject
networkrequiredstring
Gas/relay fee in wei (gas cost only, excludes dust)
duststring
Residual balance below the dust threshold swept into the relayer payment. Not a gas fee — included in total but not in network.
servicerequiredstring
Protocol fees in wei (vetting + cloaked, or swap protocol fee)
vettingstring
On-chain vetting fee in wei (pool deposits only)
depositstring
Cloaked deposit fee in wei (pool deposits only)
totalrequiredstring
Total fees in wei (network + dust + service)
waivedboolean
True when fees are waived (e.g. Cloakie holder on swaps)
Off Ramp Quote Response
quoteIdrequiredstring
signaturerequiredstring
routerequired"direct" | "swap" | "bridge" | "withdraw"
feesrequiredobject
networkrequiredstring
servicerequiredstring
totalrequiredstring
escrowAmountrequiredstring
conversionRaterequirednumber | null
estimatedFiatAmountrequiredstring
intentsobject[]
chainIdrequirednumber
eoarequiredstring
executionDatarequiredstring
noncerequiredstring
derivationNoncerequiredstring
payerrequiredstring
paymentTokenrequiredstring
paymentMaxAmountrequiredstring
combinedGasrequiredstring
encodedPreCallsrequiredstring[]
encodedFundTransfersrequiredstring[]
settlerrequiredstring
expiryrequiredstring
isMultichainrequiredboolean
funderrequiredstring
funderSignaturerequiredstring
settlerContextrequiredstring
paymentAmountrequiredstring
paymentRecipientrequiredstring
paymentSignaturerequiredstring
supportedAccountImplementationrequiredstring
domainrequiredobject
namerequiredstring
versionrequiredstring
chainIdrequirednumber
verifyingContractrequiredstring
typesrequiredany
EIP-712 type definitions
primaryTyperequired"Intent"
delegationsobject[]
chainIdrequirednumber
addressrequiredstring
contractAddressrequiredstring
derivationNoncerequirednumber
authorizationNoncerequirednumber
commitmentDataobject[]
idrequiredstring
depositIndexrequirednumber
withdrawalIndexrequirednumber
commitmentrequiredstring
labelrequiredstring
valuerequiredstring
withdrawalAmountrequiredstring
pooledSincerequiredstring
poolContextobject
poolAddressrequiredstring
resolvedDestinationrequiredstring
feeRecipientrequiredstring
relayFeeBPSrequirednumber
Off Ramp Cancel Quote Response
intentsrequiredobject[]
chainIdrequirednumber
eoarequiredstring
executionDatarequiredstring
noncerequiredstring
derivationNoncerequiredstring
payerrequiredstring
paymentTokenrequiredstring
paymentMaxAmountrequiredstring
combinedGasrequiredstring
encodedPreCallsrequiredstring[]
encodedFundTransfersrequiredstring[]
settlerrequiredstring
expiryrequiredstring
isMultichainrequiredboolean
funderrequiredstring
funderSignaturerequiredstring
settlerContextrequiredstring
paymentAmountrequiredstring
paymentRecipientrequiredstring
paymentSignaturerequiredstring
supportedAccountImplementationrequiredstring
domainrequiredobject
namerequiredstring
versionrequiredstring
chainIdrequirednumber
verifyingContractrequiredstring
typesrequiredany
EIP-712 type definitions
primaryTyperequired"Intent"
delegationsrequiredobject[]
chainIdrequirednumber
addressrequiredstring
contractAddressrequiredstring
derivationNoncerequirednumber
authorizationNoncerequirednumber
quoteIdrequiredstring
expiresAtrequiredstring
signaturerequiredstring
feesrequiredobject
networkrequiredstring
Gas/relay fee in wei (gas cost only, excludes dust)
duststring
Residual balance below the dust threshold swept into the relayer payment. Not a gas fee — included in total but not in network.
servicerequiredstring
Protocol fees in wei (vetting + cloaked, or swap protocol fee)
vettingstring
On-chain vetting fee in wei (pool deposits only)
depositstring
Cloaked deposit fee in wei (pool deposits only)
totalrequiredstring
Total fees in wei (network + dust + service)
waivedboolean
True when fees are waived (e.g. Cloakie holder on swaps)
remainingAmountrequiredstring
Withdrawable amount (remainingDeposits)
Send Quote Response
intentsrequiredobject[]
chainIdrequirednumber
eoarequiredstring
executionDatarequiredstring
noncerequiredstring
derivationNoncerequiredstring
payerrequiredstring
paymentTokenrequiredstring
paymentMaxAmountrequiredstring
combinedGasrequiredstring
encodedPreCallsrequiredstring[]
encodedFundTransfersrequiredstring[]
settlerrequiredstring
expiryrequiredstring
isMultichainrequiredboolean
funderrequiredstring
funderSignaturerequiredstring
settlerContextrequiredstring
paymentAmountrequiredstring
paymentRecipientrequiredstring
paymentSignaturerequiredstring
supportedAccountImplementationrequiredstring
domainrequiredobject
namerequiredstring
versionrequiredstring
chainIdrequirednumber
verifyingContractrequiredstring
typesrequiredany
EIP-712 type definitions
primaryTyperequired"Intent"
delegationsrequiredobject[]
chainIdrequirednumber
addressrequiredstring
contractAddressrequiredstring
derivationNoncerequirednumber
authorizationNoncerequirednumber
quoteIdrequiredstring
expiresAtrequiredstring
signaturerequiredstring
resolvedDestinationrequiredstring
selfSendrequiredboolean
feesrequiredobject
networkrequiredstring
Gas/relay fee in wei (gas cost only, excludes dust)
duststring
Residual balance below the dust threshold swept into the relayer payment. Not a gas fee — included in total but not in network.
servicerequiredstring
Protocol fees in wei (vetting + cloaked, or swap protocol fee)
vettingstring
On-chain vetting fee in wei (pool deposits only)
depositstring
Cloaked deposit fee in wei (pool deposits only)
totalrequiredstring
Total fees in wei (network + dust + service)
waivedboolean
True when fees are waived (e.g. Cloakie holder on swaps)
Dapp Call Quote Response
intentsrequiredobject[]
chainIdrequirednumber
eoarequiredstring
executionDatarequiredstring
noncerequiredstring
derivationNoncerequiredstring
payerrequiredstring
paymentTokenrequiredstring
paymentMaxAmountrequiredstring
combinedGasrequiredstring
encodedPreCallsrequiredstring[]
encodedFundTransfersrequiredstring[]
settlerrequiredstring
expiryrequiredstring
isMultichainrequiredboolean
funderrequiredstring
funderSignaturerequiredstring
settlerContextrequiredstring
paymentAmountrequiredstring
paymentRecipientrequiredstring
paymentSignaturerequiredstring
supportedAccountImplementationrequiredstring
domainrequiredobject
namerequiredstring
versionrequiredstring
chainIdrequirednumber
verifyingContractrequiredstring
typesrequiredany
EIP-712 type definitions
primaryTyperequired"Intent"
delegationsrequiredobject[]
chainIdrequirednumber
addressrequiredstring
contractAddressrequiredstring
derivationNoncerequirednumber
authorizationNoncerequirednumber
quoteIdrequiredstring
expiresAtrequiredstring
signaturerequiredstring
feesrequiredobject
networkrequiredstring
Gas/relay fee in wei (gas cost only, excludes dust)
duststring
Residual balance below the dust threshold swept into the relayer payment. Not a gas fee — included in total but not in network.
servicerequiredstring
Protocol fees in wei (vetting + cloaked, or swap protocol fee)
vettingstring
On-chain vetting fee in wei (pool deposits only)
depositstring
Cloaked deposit fee in wei (pool deposits only)
totalrequiredstring
Total fees in wei (network + dust + service)
waivedboolean
True when fees are waived (e.g. Cloakie holder on swaps)
Group Send Quote Response
quoteIdrequiredstring
intentsrequiredobject[]
chainIdrequirednumber
eoarequiredstring
executionDatarequiredstring
noncerequiredstring
derivationNoncerequiredstring
payerrequiredstring
paymentTokenrequiredstring
paymentMaxAmountrequiredstring
combinedGasrequiredstring
encodedPreCallsrequiredstring[]
encodedFundTransfersrequiredstring[]
settlerrequiredstring
expiryrequiredstring
isMultichainrequiredboolean
funderrequiredstring
funderSignaturerequiredstring
settlerContextrequiredstring
paymentAmountrequiredstring
paymentRecipientrequiredstring
paymentSignaturerequiredstring
supportedAccountImplementationrequiredstring
domainrequiredobject
namerequiredstring
versionrequiredstring
chainIdrequirednumber
verifyingContractrequiredstring
typesrequiredany
EIP-712 type definitions
primaryTyperequired"Intent"
expiresAtrequiredstring
json
{
  "intents": [
    {
      "chainId": 0,
      "eoa": "string",
      "executionData": "string",
      "nonce": "string",
      "derivationNonce": "string",
      "payer": "string",
      "paymentToken": "string",
      "paymentMaxAmount": "string",
      "combinedGas": "string",
      "encodedPreCalls": [
        "string"
      ],
      "encodedFundTransfers": [
        "string"
      ],
      "settler": "string",
      "expiry": "string",
      "isMultichain": true,
      "funder": "string",
      "funderSignature": "string",
      "settlerContext": "string",
      "paymentAmount": "string",
      "paymentRecipient": "string",
      "paymentSignature": "string",
      "supportedAccountImplementation": "string",
      "domain": {
        "name": "string",
        "version": "string",
        "chainId": 0,
        "verifyingContract": "string"
      },
      "types": null,
      "primaryType": "string"
    }
  ],
  "delegations": [
    {
      "chainId": 0,
      "address": "string",
      "contractAddress": "string",
      "derivationNonce": 0,
      "authorizationNonce": 0
    }
  ],
  "quoteId": "string",
  "expiresAt": "string",
  "signature": "string",
  "expectedOutput": "string",
  "minimumOutput": "string",
  "outputToken": "string",
  "outputDecimals": 0,
  "outputSymbol": "string",
  "outputRecipient": "string",
  "slippageBps": 0,
  "routing": "string",
  "protocolFeeBps": 0,
  "protocolFeeAmount": "string",
  "amountIn": "string",
  "priceImpact": 0,
  "estimatedFillTimeMs": 0,
  "fillDeadline": 0,
  "planId": "string",
  "fees": {
    "network": "string",
    "dust": "string",
    "service": "string",
    "vetting": "string",
    "deposit": "string",
    "total": "string",
    "waived": true
  }
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
401Default Response
Schema
errorrequiredstring
e.g. "Unauthorized"
messagerequiredstring
codestring
e.g. "UNAUTHORIZED"
json
{
  "error": "Unauthorized",
  "message": "string",
  "code": "UNAUTHORIZED"
}
403Default Response
Schema
errorrequiredstring
e.g. "Forbidden"
messagerequiredstring
json
{
  "error": "Forbidden",
  "message": "string"
}
409Default Response
Schema
errorrequiredstring
e.g. "Conflict"
messagerequiredstring
codestring
e.g. "QUOTE_LOCK_CONFLICT"
json
{
  "error": "Conflict",
  "message": "string",
  "code": "QUOTE_LOCK_CONFLICT"
}
429Default Response
Schema
errorrequiredstring
e.g. "Too Many Requests"
messagerequiredstring
e.g. "Rate limit exceeded. Maximum 30 requests per 1 minute."
json
{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded. Maximum 30 requests per 1 minute."
}
502Default Response
Schema
errorrequiredstring
e.g. "Bad Gateway"
messagerequiredstring
codestring
e.g. "SWAP_UNAVAILABLE"
json
{
  "error": "Bad Gateway",
  "message": "string",
  "code": "SWAP_UNAVAILABLE"
}
503Default Response
Schema
errorrequiredstring
e.g. "Service Unavailable"
messagerequiredstring
json
{
  "error": "Service Unavailable",
  "message": "string"
}
Try it
Path Parameters
accountId
Headers
idempotency-key
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "type": "",
  "chainId": 0,
  "token": "",
  "amount": "",
  "decimals": 0,
  "destinationAddress": "",
  "maxSend": true,
  "ttl": 0
}' \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/quote"

Submit transaction

POST/v1/accounts/{accountId}/submit🔒

Submit client-signed intents and delegations from a quote to relay the transaction on-chain. Validates signatures, checks price slippage, and submits via the server relayer so the user pays no gas directly.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
idempotency-keyheaderstringClient-generated unique key (e.g. UUID). If the server has already processed a request with this key for the same account and body, it returns the cached response instead of re-executing. Keys expire after 24 hours.
Request Body
Porto Submit Request
intentsrequiredobject[]
chainIdrequirednumber
eoarequiredstring
executionDatarequiredstring
noncerequiredstring
derivationNoncerequiredstring
payerrequiredstring
paymentTokenrequiredstring
paymentMaxAmountrequiredstring
combinedGasrequiredstring
encodedPreCallsrequiredstring[]
encodedFundTransfersrequiredstring[]
settlerrequiredstring
expiryrequiredstring
isMultichainrequiredboolean
funderrequiredstring
funderSignaturerequiredstring
settlerContextrequiredstring
paymentAmountrequiredstring
paymentRecipientrequiredstring
paymentSignaturerequiredstring
supportedAccountImplementationrequiredstring
domainrequiredobject
namerequiredstring
versionrequiredstring
chainIdrequirednumber
verifyingContractrequiredstring
typesrequiredany
EIP-712 type definitions
primaryTyperequired"Intent"
signaturerequiredstring
delegationsrequiredobject[]
chainIdrequirednumber
addressrequiredstring
contractAddressrequiredstring
derivationNoncerequirednumber
authorizationNoncerequirednumber
signaturerequiredstring
quoteIdrequiredstring
Quote ID from quote response
Pool Withdraw Submit Request
quoteIdrequiredstring
Quote ID from pool-withdraw quote response
withdrawalsrequiredobject[]
commitmentIdrequiredstring
Pool commitment DB ID
calldatarequiredstring
Encoded Entrypoint.relay() calldata (hex)
changeNullifierHashstring
Nullifier hash of the change commitment created by a partial withdrawal (stringified bigint)
Conversion Recover Submit Request
quoteIdrequiredstring
Quote ID from pool-recover quote response
recoverCalldatarequiredstring
Encoded Pool.recover(proof) calldata (hex)
intentsrequiredobject[]
chainIdrequirednumber
eoarequiredstring
executionDatarequiredstring
noncerequiredstring
derivationNoncerequiredstring
payerrequiredstring
paymentTokenrequiredstring
paymentMaxAmountrequiredstring
combinedGasrequiredstring
encodedPreCallsrequiredstring[]
encodedFundTransfersrequiredstring[]
settlerrequiredstring
expiryrequiredstring
isMultichainrequiredboolean
funderrequiredstring
funderSignaturerequiredstring
settlerContextrequiredstring
paymentAmountrequiredstring
paymentRecipientrequiredstring
paymentSignaturerequiredstring
supportedAccountImplementationrequiredstring
domainrequiredobject
namerequiredstring
versionrequiredstring
chainIdrequirednumber
verifyingContractrequiredstring
typesrequiredany
EIP-712 type definitions
primaryTyperequired"Intent"
signaturerequiredstring
delegationsrequiredobject[]
chainIdrequirednumber
addressrequiredstring
contractAddressrequiredstring
derivationNoncerequirednumber
authorizationNoncerequirednumber
signaturerequiredstring
Responses
200Default Response
Schema
successrequiredboolean
quoteIdrequiredstring
statusrequiredstring
messagerequiredstring
json
{
  "success": true,
  "quoteId": "string",
  "status": "string",
  "message": "string"
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
401Default Response
Schema
errorrequiredstring
e.g. "Unauthorized"
messagerequiredstring
codestring
e.g. "UNAUTHORIZED"
json
{
  "error": "Unauthorized",
  "message": "string",
  "code": "UNAUTHORIZED"
}
404Default Response
Schema
errorrequiredstring
e.g. "Not found"
messagerequiredstring
json
{
  "error": "Not found",
  "message": "string"
}
409Default Response
Schema
errorrequiredstring
e.g. "Conflict"
messagerequiredstring
codestring
e.g. "QUOTE_LOCK_CONFLICT"
json
{
  "error": "Conflict",
  "message": "string",
  "code": "QUOTE_LOCK_CONFLICT"
}
Try it
Path Parameters
accountId
Headers
idempotency-key
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "intents": [
    {
      "chainId": 0,
      "eoa": "",
      "executionData": "",
      "nonce": "",
      "derivationNonce": "",
      "payer": "",
      "paymentToken": "",
      "paymentMaxAmount": "",
      "combinedGas": "",
      "encodedPreCalls": [
        ""
      ],
      "encodedFundTransfers": [
        ""
      ],
      "settler": "",
      "expiry": "",
      "isMultichain": true,
      "funder": "",
      "funderSignature": "",
      "settlerContext": "",
      "paymentAmount": "",
      "paymentRecipient": "",
      "paymentSignature": "",
      "supportedAccountImplementation": "",
      "domain": {
        "name": "",
        "version": "",
        "chainId": 0,
        "verifyingContract": ""
      },
      "types": null,
      "primaryType": "",
      "signature": ""
    }
  ],
  "delegations": [
    {
      "chainId": 0,
      "address": "",
      "contractAddress": "",
      "derivationNonce": 0,
      "authorizationNonce": 0,
      "signature": ""
    }
  ],
  "quoteId": ""
}' \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/submit"

Get relay status

GET/v1/accounts/{accountId}/relay-status/{quoteId}🔒

Get the relay transaction status and hash for a submitted quote.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)
quoteId*pathstring
Responses
200Default Response
Schema
statusrequiredstring
txHashrequiredstring | null
confirmedTxHashrequiredstring | null
json
{
  "status": "string",
  "txHash": "string",
  "confirmedTxHash": "string"
}
404Default Response
Schema
errorrequiredstring
e.g. "Not found"
messagerequiredstring
json
{
  "error": "Not found",
  "message": "string"
}
Try it
Path Parameters
accountId
quoteId
curl -X GET \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/relay-status/{quoteId}"

Unlock quote

POST/v1/accounts/{accountId}/unlock🔒

Release the lock held by a quote so the funds become available for a new transaction. Use when the user cancels a send or the client decides not to submit.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
Request Body
quoteIdrequiredstring
Quote ID from quote response
Responses
200Default Response
Schema
successrequiredboolean
messagerequiredstring
json
{
  "success": true,
  "message": "string"
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
404Default Response
Schema
errorrequiredstring
e.g. "Not found"
messagerequiredstring
json
{
  "error": "Not found",
  "message": "string"
}
Try it
Path Parameters
accountId
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "quoteId": ""
}' \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/unlock"

Get max spendable

POST/v1/accounts/{accountId}/max-spendable🔒

Calculate the maximum spendable amount for a token, accounting for relay fees, swap gas, and pool fees when applicable. Use this to power the "max" button in send, swap, and pool UIs.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
Request Body
chainIdrequirednumber
Chain ID (must support Porto)
tokenrequiredstring
Token address (0x...)
typerequired"send" | "swap" | "pool-deposit"
Transaction type — swap and pool-deposit subtract additional gas/service fees
tokenOutstring
Token address to buy (required for type=swap)
slippageBpsnumber
Slippage tolerance in bps (required for type=swap, 1-500)
tokenOutChainIdnumber
Destination chain ID for cross-chain swaps
Responses
200Default Response
Schema
maxAmountrequiredstring
Maximum spendable amount in smallest unit
feeEstimaterequiredstring
Estimated fee in smallest unit
spendableCountrequirednumber
Number of spendable UTXOs that will be consumed
grossAmountstring
Gross deposit amount including vetting fee (pool-deposit only)
feesobject
networkrequiredstring
Gas/relay fee estimate
vettingrequiredstring
On-chain vetting fee
depositrequiredstring
Cloaked service fee (0 if waived)
servicerequiredstring
Vetting + deposit combined
totalrequiredstring
Network + service total
protocolFeeBpsnumber
Protocol fee rate in bps (swap only)
protocolFeeAmountstring
Protocol fee amount in smallest unit (swap only)
json
{
  "maxAmount": "string",
  "feeEstimate": "string",
  "spendableCount": 0,
  "grossAmount": "string",
  "fees": {
    "network": "string",
    "vetting": "string",
    "deposit": "string",
    "service": "string",
    "total": "string"
  },
  "protocolFeeBps": 0,
  "protocolFeeAmount": "string"
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
Try it
Path Parameters
accountId
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "chainId": 0,
  "token": "",
  "type": "",
  "tokenOut": "",
  "slippageBps": 0,
  "tokenOutChainId": 0
}' \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/max-spendable"

Create swap preview

POST/v1/accounts/{accountId}/swap-preview🔒

Get a swap preview (price discovery) without reserving balances.

Parameters
NameInTypeDescription
accountId*pathstring (uuid)Account ID
Request Body
chainIdrequirednumber
Chain ID
tokenInrequiredstring
Token address being sold
tokenOutrequiredstring
Token address being bought
amountInrequiredstring
Amount to swap in smallest unit (stringified bigint)
slippageBpsrequirednumber
Slippage tolerance in basis points (e.g. 50 = 0.5%, max: 500 = 5%)
tokenOutChainIdnumber
Destination chain ID for cross-chain swaps
Responses
200Default Response
Schema
expectedOutputrequiredstring
minimumOutputrequiredstring
outputTokenrequiredstring
outputDecimalsrequirednumber
outputSymbolrequiredstring
routingrequiredstring
slippageBpsrequirednumber
feeEstimaterequiredstring
estimatedFillTimeMsnumber
protocolFeeBpsrequirednumber
protocolFeeAmountrequiredstring
priceImpactnumber
rateOnlyboolean
json
{
  "expectedOutput": "string",
  "minimumOutput": "string",
  "outputToken": "string",
  "outputDecimals": 0,
  "outputSymbol": "string",
  "routing": "string",
  "slippageBps": 0,
  "feeEstimate": "string",
  "estimatedFillTimeMs": 0,
  "protocolFeeBps": 0,
  "protocolFeeAmount": "string",
  "priceImpact": 0,
  "rateOnly": true
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
401Default Response
Schema
errorrequiredstring
e.g. "Unauthorized"
messagerequiredstring
codestring
e.g. "UNAUTHORIZED"
json
{
  "error": "Unauthorized",
  "message": "string",
  "code": "UNAUTHORIZED"
}
429Default Response
Schema
errorrequiredstring
e.g. "Too Many Requests"
messagerequiredstring
e.g. "Rate limit exceeded. Maximum 30 requests per 1 minute."
json
{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded. Maximum 30 requests per 1 minute."
}
502Default Response
Schema
errorrequiredstring
e.g. "Bad Gateway"
messagerequiredstring
codestring
e.g. "SWAP_UNAVAILABLE"
json
{
  "error": "Bad Gateway",
  "message": "string",
  "code": "SWAP_UNAVAILABLE"
}
503Default Response
Schema
errorrequiredstring
e.g. "Service Unavailable"
messagerequiredstring
json
{
  "error": "Service Unavailable",
  "message": "string"
}
Try it
Path Parameters
accountId
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "chainId": 0,
  "tokenIn": "",
  "tokenOut": "",
  "amountIn": "",
  "slippageBps": 0,
  "tokenOutChainId": 0
}' \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/swap-preview"

Recover conversion prepare

POST/v1/accounts/{accountId}/pool-recover/prepare🔒

Build an unsigned Porto intent and delegation for a pool recover (ragequit). The client calls this after generating the commitment proof, signs the returned intent and delegation, then submits via the standard submit endpoint.

Parameters
NameInTypeDescription
accountId*pathstring
Request Body
quoteIdrequiredstring
Quote ID from pool-recover quote response
recoverCalldatarequiredstring
Encoded Pool.ragequit(proof) calldata (hex)
Responses
200Default Response
Try it
Path Parameters
accountId
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "quoteId": "",
  "recoverCalldata": ""
}' \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/pool-recover/prepare"

Cashout withdraw prepare

POST/v1/accounts/{accountId}/cashout/prepare🔒

Build an unsigned Porto intent and delegation for an incognito cashout. The single intent contains pool withdrawal proofs + Across bridge calls. Client signs and submits via the standard submit endpoint.

Parameters
NameInTypeDescription
accountId*pathstring
Request Body
quoteIdrequiredstring
Quote ID from off-ramp quote response
withdrawalsrequiredobject[]
ZK proof calldata per commitment
commitmentIdrequiredstring
calldatarequiredstring
Entrypoint.relay(proof) calldata (hex)
changeNullifierHashstring
Responses
200Default Response
Try it
Path Parameters
accountId
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "quoteId": "",
  "withdrawals": [
    {
      "commitmentId": "",
      "calldata": "",
      "changeNullifierHash": ""
    }
  ]
}' \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/cashout/prepare"

Get pool state

GET/v1/accounts/{accountId}/pool/state🔒

Get the current incognito pool state for an account and token. Returns the Merkle tree, ASP leaves, and your commitments — everything the client needs to build ZK withdrawal proofs.

Parameters
NameInTypeDescription
chainId*querynumberChain ID of the pool
token*querystringToken address accepted by the pool (0x...)
accountId*pathstring (uuid)Account ID
Responses
200Default Response
Schema
leavesrequiredstring[]
State tree leaves in insertion order (stringified bigints)
currentRootrequiredstring
Current Merkle root (stringified bigint)
treeSizerequirednumber
Number of leaves in the tree
aspLeavesstring[]
ASP-approved labels. In dev: from DB. In staging/production: from cached 0xbow API response. Absent only if poller cache is cold.
spentNullifiersrequiredobject[]
All spent nullifiers from Withdrawn events — used for reconciliation
nullifierHashrequiredstring
Spent nullifier hash (stringified bigint)
withdrawnValuerequiredstring
Withdrawn amount in wei (stringified bigint)
newCommitmentrequiredstring
Change commitment hash (stringified bigint)
nextDepositIndexrequirednumber
Next available deposit index for this account — use for precommitment derivation
commitmentsrequiredobject[]
This account's unspent pool commitments
idrequiredstring
Commitment DB ID
depositIndexrequirednumber
withdrawalIndexrequirednumber
commitmentrequiredstring
On-chain commitment hash
labelrequiredstring
On-chain label
valuerequiredstring
Commitment value in wei
aspStatusrequired"pending" | "approved" | "declined"
ASP approval status
json
{
  "leaves": [
    "string"
  ],
  "currentRoot": "string",
  "treeSize": 0,
  "aspLeaves": [
    "string"
  ],
  "spentNullifiers": [
    {
      "nullifierHash": "string",
      "withdrawnValue": "string",
      "newCommitment": "string"
    }
  ],
  "nextDepositIndex": 0,
  "commitments": [
    {
      "id": "string",
      "depositIndex": 0,
      "withdrawalIndex": 0,
      "commitment": "string",
      "label": "string",
      "value": "string",
      "aspStatus": "string"
    }
  ]
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
401Default Response
Schema
errorrequiredstring
e.g. "Unauthorized"
messagerequiredstring
codestring
e.g. "UNAUTHORIZED"
json
{
  "error": "Unauthorized",
  "message": "string",
  "code": "UNAUTHORIZED"
}
Try it
Path Parameters
accountId
Query Parameters
chainId
token
curl -X GET \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/pool/state"

Cloakie

Cloakie NFT verification and withdrawal

Verify cloakie deposit

POST/v1/accounts/{accountId}/cloakie/verify🔒

Scan recent unused stealth addresses for Cloakie NFTs on Base. Records any newly discovered deposits and activates the fee waiver.

Parameters
NameInTypeDescription
accountId*pathstring
Responses
200Default Response
Schema
activerequiredboolean
depositsrequiredobject[]
depositAddressrequiredstring
tokenIdrequiredstring | null
imageUrlrequiredstring | null
json
{
  "active": true,
  "deposits": [
    {
      "depositAddress": "string",
      "tokenId": "string",
      "imageUrl": "string"
    }
  ]
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
401Default Response
Schema
errorrequiredstring
e.g. "Unauthorized"
messagerequiredstring
codestring
e.g. "UNAUTHORIZED"
json
{
  "error": "Unauthorized",
  "message": "string",
  "code": "UNAUTHORIZED"
}
Try it
Path Parameters
accountId
curl -X POST \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/cloakie/verify"

Withdraw cloakie

POST/v1/accounts/{accountId}/cloakie/withdraw🔒

Build an intent to transfer a Cloakie NFT from a deposit address back to the user. Returns intents and delegations for client signing.

Parameters
NameInTypeDescription
accountId*pathstring
Request Body
depositAddressrequiredstring
Stealth address holding the Cloakie
recipientAddressrequiredstring
Address to send the Cloakie to
tokenIdstring
Token ID of the Cloakie to withdraw (required if multiple at same address)
Responses
200Default Response
Schema
quoteIdrequiredstring
intentsrequiredobject[]
chainIdrequirednumber
eoarequiredstring
executionDatarequiredstring
noncerequiredstring
derivationNoncerequiredstring
payerrequiredstring
paymentTokenrequiredstring
paymentMaxAmountrequiredstring
combinedGasrequiredstring
encodedPreCallsrequiredstring[]
encodedFundTransfersrequiredstring[]
settlerrequiredstring
expiryrequiredstring
isMultichainrequiredboolean
funderrequiredstring
funderSignaturerequiredstring
settlerContextrequiredstring
paymentAmountrequiredstring
paymentRecipientrequiredstring
paymentSignaturerequiredstring
supportedAccountImplementationrequiredstring
domainrequiredobject
namerequiredstring
versionrequiredstring
chainIdrequirednumber
verifyingContractrequiredstring
typesrequiredany
EIP-712 type definitions
primaryTyperequired"Intent"
delegationsrequiredobject[]
chainIdrequirednumber
addressrequiredstring
contractAddressrequiredstring
derivationNoncerequirednumber
authorizationNoncerequirednumber
expiresAtrequiredstring
signaturerequiredstring
depositAddressrequiredstring
recipientAddressrequiredstring
tokenIdrequiredstring
json
{
  "quoteId": "string",
  "intents": [
    {
      "chainId": 0,
      "eoa": "string",
      "executionData": "string",
      "nonce": "string",
      "derivationNonce": "string",
      "payer": "string",
      "paymentToken": "string",
      "paymentMaxAmount": "string",
      "combinedGas": "string",
      "encodedPreCalls": [
        "string"
      ],
      "encodedFundTransfers": [
        "string"
      ],
      "settler": "string",
      "expiry": "string",
      "isMultichain": true,
      "funder": "string",
      "funderSignature": "string",
      "settlerContext": "string",
      "paymentAmount": "string",
      "paymentRecipient": "string",
      "paymentSignature": "string",
      "supportedAccountImplementation": "string",
      "domain": {
        "name": "string",
        "version": "string",
        "chainId": 0,
        "verifyingContract": "string"
      },
      "types": null,
      "primaryType": "string"
    }
  ],
  "delegations": [
    {
      "chainId": 0,
      "address": "string",
      "contractAddress": "string",
      "derivationNonce": 0,
      "authorizationNonce": 0
    }
  ],
  "expiresAt": "string",
  "signature": "string",
  "depositAddress": "string",
  "recipientAddress": "string",
  "tokenId": "string"
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
401Default Response
Schema
errorrequiredstring
e.g. "Unauthorized"
messagerequiredstring
codestring
e.g. "UNAUTHORIZED"
json
{
  "error": "Unauthorized",
  "message": "string",
  "code": "UNAUTHORIZED"
}
404Default Response
Schema
errorrequiredstring
e.g. "Not found"
messagerequiredstring
json
{
  "error": "Not found",
  "message": "string"
}
Try it
Path Parameters
accountId
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "depositAddress": "",
  "recipientAddress": "",
  "tokenId": ""
}' \
  "https://api-stg.clkd.xyz/v1/accounts/{accountId}/cloakie/withdraw"

Relayer

Relayer details

GET/relayer/details

Get relayer fee info for a given chain and asset

Parameters
NameInTypeDescription
chainId*querynumberChain ID
assetAddress*querystringAsset address
Responses
200Default Response
Schema
feeBPSrequiredstring
feeReceiverAddressrequiredstring
chainIdrequirednumber
assetAddressrequiredstring
minWithdrawAmountrequiredstring
maxGasPricerequiredstring
json
{
  "feeBPS": "string",
  "feeReceiverAddress": "string",
  "chainId": 0,
  "assetAddress": "string",
  "minWithdrawAmount": "string",
  "maxGasPrice": "string"
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
503Default Response
Schema
errorrequiredstring
e.g. "Service Unavailable"
messagerequiredstring
json
{
  "error": "Service Unavailable",
  "message": "string"
}
Try it
Query Parameters
chainId
assetAddress
curl -X GET \
  "https://api-stg.clkd.xyz/relayer/details"

Relayer quote

POST/relayer/quote

Get a fee commitment for relaying a privacy pool withdrawal

Request Body
chainIdrequirednumber
Chain ID
amountrequiredstring
Withdrawal amount in smallest token unit
assetrequiredstring
Asset address
recipientrequiredstring
Recipient address
extraGasboolean
Fund recipient with gas
Responses
200Default Response
Schema
baseFeeBPSrequiredstring
feeBPSrequiredstring
gasPricerequiredstring
feeCommitmentrequiredobject
expirationrequirednumber
assetrequiredstring
withdrawalDatarequiredstring
signedRelayerCommitmentrequiredstring
extraGasrequiredboolean
amountrequiredstring
detailrequiredobject
relayTxCostrequiredobject
gasrequiredstring
ethrequiredstring
extraGasFundAmountobject
gasrequiredstring
ethrequiredstring
extraGasTxCostobject
gasrequiredstring
ethrequiredstring
json
{
  "baseFeeBPS": "string",
  "feeBPS": "string",
  "gasPrice": "string",
  "feeCommitment": {
    "expiration": 0,
    "asset": "string",
    "withdrawalData": "string",
    "signedRelayerCommitment": "string",
    "extraGas": true,
    "amount": "string"
  },
  "detail": {
    "relayTxCost": {
      "gas": "string",
      "eth": "string"
    },
    "extraGasFundAmount": {
      "gas": "string",
      "eth": "string"
    },
    "extraGasTxCost": {
      "gas": "string",
      "eth": "string"
    }
  }
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
503Default Response
Schema
errorrequiredstring
e.g. "Service Unavailable"
messagerequiredstring
json
{
  "error": "Service Unavailable",
  "message": "string"
}
Try it
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "chainId": 0,
  "amount": "",
  "asset": "",
  "recipient": "",
  "extraGas": true
}' \
  "https://api-stg.clkd.xyz/relayer/quote"

Relayer request

POST/relayer/request

Submit a privacy pool withdrawal for relay

Request Body
withdrawalrequiredobject
processooorrequiredstring
datarequiredstring
proofrequiredobject
pi_arequiredstring[]
pi_brequiredarray[]
pi_crequiredstring[]
protocolrequired"groth16"
curverequired"bn128"
publicSignalsrequiredstring[]
scoperequiredstring
chainIdrequirednumber
feeCommitmentrequiredobject
expirationrequirednumber
assetrequiredstring
withdrawalDatarequiredstring
signedRelayerCommitmentrequiredstring
extraGasrequiredboolean
amountrequiredstring
Responses
200Default Response
Schema
successrequiredboolean
txHashrequiredstring
timestamprequirednumber
requestIdrequiredstring
json
{
  "success": true,
  "txHash": "string",
  "timestamp": 0,
  "requestId": "string"
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
500Default Response
Schema
errorrequiredstring
messagerequiredstring
json
{
  "error": "string",
  "message": "string"
}
503Default Response
Schema
errorrequiredstring
e.g. "Service Unavailable"
messagerequiredstring
json
{
  "error": "Service Unavailable",
  "message": "string"
}
Try it
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "withdrawal": {
    "processooor": "",
    "data": ""
  },
  "proof": {
    "pi_a": [
      ""
    ],
    "pi_b": [
      [
        ""
      ]
    ],
    "pi_c": [
      ""
    ],
    "protocol": "",
    "curve": ""
  },
  "publicSignals": [
    ""
  ],
  "scope": "",
  "chainId": 0,
  "feeCommitment": {
    "expiration": 0,
    "asset": "",
    "withdrawalData": "",
    "signedRelayerCommitment": "",
    "extraGas": true,
    "amount": ""
  }
}' \
  "https://api-stg.clkd.xyz/relayer/request"

Simulation

Simulate transaction

POST/v1/simulate🔒

Simulate a transaction via Tenderly to preview asset changes before signing.

Request Body
chainIdrequirednumber
Chain ID
fromrequiredstring
Sender address
torequiredstring
Target address
valuerequiredstring
Value in wei (decimal string)
datarequiredstring
Calldata (hex string)
Responses
200Default Response
Schema
successrequiredboolean
gasUsednumber
assetChangesrequiredobject[]
typerequiredstring
tokenobject
addressrequiredstring
symbolstring
decimalsnumber
namestring
fromrequiredstring
torequiredstring
amountrequiredstring
rawAmountrequiredstring
errorstring
json
{
  "success": true,
  "gasUsed": 0,
  "assetChanges": [
    {
      "type": "string",
      "token": {
        "address": "string",
        "symbol": "string",
        "decimals": 0,
        "name": "string"
      },
      "from": "string",
      "to": "string",
      "amount": "string",
      "rawAmount": "string"
    }
  ],
  "error": "string"
}
400Default Response
Schema
errorrequiredstring
e.g. "Bad request"
messagerequiredstring
codestring
e.g. "BAD_REQUEST"
availablestring
Available balance in smallest unit (for INSUFFICIENT_BALANCE)
minAmountstring
Human-readable minimum amount (for WITHDRAWAL_AMOUNT_TOO_SMALL)
maxSendablestring
Maximum net amount withdrawable at current gas (for WITHDRAWAL_AMOUNT_TOO_SMALL)
json
{
  "error": "Bad request",
  "message": "string",
  "code": "BAD_REQUEST",
  "available": "0",
  "minAmount": "0.00036 ETH",
  "maxSendable": "0.018 ETH"
}
403Default Response
Schema
errorrequiredstring
e.g. "Forbidden"
messagerequiredstring
json
{
  "error": "Forbidden",
  "message": "string"
}
Try it
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "chainId": 0,
  "from": "",
  "to": "",
  "value": "",
  "data": ""
}' \
  "https://api-stg.clkd.xyz/v1/simulate"

Utilities

Lookup function signatures

POST/v1/function-signatures🔒

Batch-resolve 4-byte function selectors to human-readable signatures. Uses a server-side cache backed by openchain.xyz.

Request Body
selectorsrequiredstring[]
Array of 4-byte hex selectors (e.g. ["0xa9059cbb"])
Responses
200Default Response
Schema
signaturesrequiredobject
Map of selector → signature (null if unknown)
json
{
  "signatures": null
}
403Default Response
Schema
errorrequiredstring
e.g. "Forbidden"
messagerequiredstring
json
{
  "error": "Forbidden",
  "message": "string"
}
Try it
Request Body
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "selectors": [
    ""
  ]
}' \
  "https://api-stg.clkd.xyz/v1/function-signatures"