Skip to main content

Overview

The Smart Accounts API lets you give your users a gasless deposit and redemption experience without ever handling a private key or paying gas on their behalf. Each user gets a deterministic smart account (Kernel v3.1) derived from their EOA; once the user signs a one-time, per-chain authorization, you submit buy / sell / withdraw actions through 1tx and a relayer executes and sponsors the gas. This is the white-label / relay integration: your server authenticates with an x-api-key and names the ownerEoa it is acting for. The same routes also back the first-party 1tx app (Privy bearer token); this page documents the API-key path.
All Smart Accounts endpoints require an x-api-key header. No bearer token is needed. An action can only target an ownerEoa your key has authorized — the session grant created at authorize time is bound to your API key.

How it works

  1. Derive the account. GET /account returns the user’s counterfactual smart-account address (the same on every chain).
  2. Authorize, once per chain. POST /authorize/prepare returns an EIP-712 message; your user signs it with their EOA wallet; POST /authorize/confirm stores the scoped session grant. The user signs once per chain, not per action.
  3. Fund the smart account. The user sends USDC to the smart-account address. Deposits draw from this balance.
  4. Act, gasless. POST /buy and POST /sell are relayer-signed — no per-action signature, no gas. Poll GET /actions/:id for status.
  5. Withdraw. POST /withdraw/prepare + confirm return idle USDC to the user’s EOA. The recipient is always pinned to the owner EOA.
The owner signs only at authorize and withdraw time. Buy and sell never require a user signature once a chain is authorized.

Base URL

https://api.1tx.fi/api/v1

Look Up Account

GET /account Resolve a user’s smart-account address and authorization state.

Query Parameters

ParamTypeRequiredDescription
ownerEoastringYesThe user’s EOA address
curl "https://api.1tx.fi/api/v1/account?ownerEoa=0x59F84Af036712AFe2fD0Ec77f4D9a6F0a612f1fE" \
  -H "x-api-key: <your_api_key>"

Response

{
  "accountAddress": "0x8a3...c21",
  "deployedChains": [8453],
  "authorizedChainIds": [8453, 42161],
  "grant": {
    "status": "active",
    "scope": { "policyVersion": 3 },
    "expiresAt": "2026-09-01T00:00:00.000Z"
  }
}
FieldTypeDescription
accountAddressstringCounterfactual smart-account address (same on all chains)
deployedChainsnumber[]Chains where the account is already deployed on-chain
authorizedChainIdsnumber[]Chains with an active session grant on the current policy
grantobject | nullThe active grant summary, or null if the user must (re)authorize

Authorize a Chain

Establish a scoped session grant so the relayer can submit gasless actions for the user on a given chain. One signature per chain.

Prepare

POST /authorize/prepare Returns an EIP-712 message for the user to sign with their EOA wallet.
FieldTypeRequiredDescription
ownerEoastringYesThe user’s EOA address
chainIdnumberNoChain to authorize. Defaults to Base (8453)
spendCapstringNoPer-period spend cap in USDC subunits (6dp) baked into the on-chain policy
expiresAtnumberNoUnix timestamp when the grant expires
scopeobjectNoAdvanced: override the default call-policy scope
curl -X POST "https://api.1tx.fi/api/v1/authorize/prepare" \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{ "ownerEoa": "0x59F8...f1fE", "chainId": 8453 }'
{
  "accountAddress": "0x8a3...c21",
  "chainId": 8453,
  "enableTypedData": {
    "domain": { "name": "Kernel", "version": "0.3.1", "chainId": 8453, "verifyingContract": "0x..." },
    "types": { "Enable": [ /* ... */ ] },
    "primaryType": "Enable",
    "message": { /* ... */ }
  }
}
Have the user sign enableTypedData with eth_signTypedData_v4 on the EOA wallet. The wallet must be connected to chainId when signing.

Confirm

POST /authorize/confirm Submit the signature to activate the grant.
FieldTypeRequiredDescription
ownerEoastringYesThe user’s EOA address
signaturestringYesThe eth_signTypedData_v4 signature of enableTypedData
chainIdnumberNoThe chain that was authorized (matches prepare)
curl -X POST "https://api.1tx.fi/api/v1/authorize/confirm" \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{ "ownerEoa": "0x59F8...f1fE", "chainId": 8453, "signature": "0x..." }'
{ "accountAddress": "0x8a3...c21" }

Revoke

DELETE /authorize/:ownerEoa Off-chain revoke: the relayer stops replaying the session approval. Optionally scope to one chain with ?chainId=.
curl -X DELETE "https://api.1tx.fi/api/v1/authorize/0x59F8...f1fE?chainId=8453" \
  -H "x-api-key: <your_api_key>"
{ "accountAddress": "0x8a3...c21" }

Buy (Gasless Deposit)

POST /buy Submit a relayer-signed, gas-sponsored deposit into an instrument. Requires an active grant on the source chain and sufficient USDC in the smart account. For a cross-chain buy the relayer bridges via CCTP automatically.

Request Body

FieldTypeRequiredDescription
ownerEoastringYesThe user’s EOA address
instrumentIdstringYesTarget instrument ID
amountUsdcstringYesDeposit amount in human-readable USDC, e.g. "100.50"
sourceChainIdnumberNoForce a source chain instead of auto-selecting from the account’s balances
slippageBpsnumberNoSlippage tolerance in basis points. Defaults to 50
fastTransferbooleanNoCross-chain only: CCTP fast transfer (~seconds, higher fee) vs standard (free, ~10–30 min). Defaults to false
maxFeestringNoCross-chain fast-transfer max fee in USDC subunits (6dp). Required when fastTransfer is true
referralFeeBpsnumberNoReferral fee in basis points (0–500). Requires referralWallet
referralWalletstringNoAddress that receives the referral fee
idempotencyKeystringNoA retry with the same key returns the original action instead of submitting a second userOp
curl -X POST "https://api.1tx.fi/api/v1/buy" \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "ownerEoa": "0x59F84Af036712AFe2fD0Ec77f4D9a6F0a612f1fE",
    "instrumentId": "0x0000a4b194d4938ed6aab5bdbac7ca4b622f3639b1bca1b8b9c3271403d3b1b5",
    "amountUsdc": "100.50",
    "idempotencyKey": "user-123-deposit-7f3a"
  }'

Response

{
  "accountAddress": "0x8a3...c21",
  "actionId": "op_7f3a9c2e",
  "userOpHash": "0x..."
}
FieldTypeDescription
accountAddressstringThe smart account the action ran on
actionIdstringPass to GET /actions/:id to track status
userOpHashstringThe submitted ERC-4337 userOp hash
idempotentbooleanPresent and true when a prior action with the same key was returned

Sell (Gasless Redeem)

POST /sell Submit a relayer-signed redemption of a position. Same-chain only; USDC proceeds land in the smart account (use /withdraw to send them to the EOA).

Request Body

FieldTypeRequiredDescription
ownerEoastringYesThe user’s EOA address
instrumentIdstringYesInstrument ID to redeem from
yieldTokenAmountstringYesHuman-readable yield-token amount, e.g. "95.5"
slippageBpsnumberNoSlippage tolerance in basis points. Defaults to 50
referralFeeBpsnumberNoReferral fee in basis points (0–500). Requires referralWallet
referralWalletstringNoAddress that receives the referral fee
idempotencyKeystringNoRetry-safe key, as in /buy
curl -X POST "https://api.1tx.fi/api/v1/sell" \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "ownerEoa": "0x59F84Af036712AFe2fD0Ec77f4D9a6F0a612f1fE",
    "instrumentId": "0x00002105c053a3e1290845e12a3eea14926472ce7f15da324cdf0700056fc04b",
    "yieldTokenAmount": "95.5"
  }'
{
  "accountAddress": "0x8a3...c21",
  "actionId": "op_be21d4f0",
  "userOpHash": "0x..."
}

Get Action Status

GET /actions/:id Track a submitted buy, sell, or withdraw by its actionId.
curl "https://api.1tx.fi/api/v1/actions/op_7f3a9c2e" \
  -H "x-api-key: <your_api_key>"

Response

{
  "operationId": "op_7f3a9c2e",
  "type": "buy",
  "status": "success",
  "createdAt": 1775747400,
  "updatedAt": 1775747460,
  "sourceChainId": 8453,
  "destinationChainId": 8453,
  "isCrossChain": false,
  "userOpHash": "0x...",
  "sourceTxHash": "0x...",
  "destinationTxHash": null,
  "error": null,
  "result": {
    "amountIn": "100500000",
    "amountOut": "100500000",
    "instrumentId": "0x0000a4b1...",
    "finalTxHash": "0x..."
  }
}
statusMeaning
successCompleted (same-chain, or cross-chain fully settled)
confirming_sourceCross-chain userOp landed; awaiting CCTP bridge settlement
failedThe userOp reverted. error carries the reason; the idempotency key is freed for retry
For cross-chain buys, after confirming_source you can also follow the bridge via the CCTP API using sourceTxHash.

Withdraw to Owner EOA

Return idle USDC from the smart account to the user’s own EOA. The recipient is always the owner EOA — it is never caller-supplied — so the user signs a userOp digest that commits to that calldata.

Prepare

POST /withdraw/prepare
FieldTypeRequiredDescription
ownerEoastringYesThe user’s EOA address (also the recipient)
amountUsdcstringYesAmount in human-readable USDC
chainIdnumberNoChain to withdraw on. Defaults to Base (8453)
curl -X POST "https://api.1tx.fi/api/v1/withdraw/prepare" \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{ "ownerEoa": "0x59F8...f1fE", "amountUsdc": "50.00", "chainId": 8453 }'
{
  "accountAddress": "0x8a3...c21",
  "chainId": 8453,
  "digest": "0x...",
  "signingMethod": "personal_sign"
}
Have the user sign the raw digest with an EIP-191 personal_sign (e.g. signMessage({ message: { raw: digest } })) and return the 65-byte signature unchanged.

Confirm

POST /withdraw/confirm
FieldTypeRequiredDescription
ownerEoastringYesThe user’s EOA address
signaturestringYesThe personal_sign signature of digest
curl -X POST "https://api.1tx.fi/api/v1/withdraw/confirm" \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{ "ownerEoa": "0x59F8...f1fE", "signature": "0x..." }'
{ "actionId": "op_c93b71a2", "userOpHash": "0x..." }
Track completion with GET /actions/:id.

End-to-End Flow

  1. GET /account → show the user their smart-account address and which chains are authorized.
  2. For each chain the user wants to use: POST /authorize/prepare → user signs EIP-712 → POST /authorize/confirm.
  3. User funds the smart-account address with USDC.
  4. POST /buy → poll GET /actions/:id until success (or confirming_source then settled, for cross-chain).
  5. POST /sell to redeem; POST /withdraw/prepare + confirm to move USDC back to the EOA.
Cross-chain sell is not supported. To move a position across chains, redeem on its chain and withdraw, or buy fresh on the target chain.