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
- Derive the account.
GET /account returns the user’s counterfactual
smart-account address (the same on every chain).
- 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.
- Fund the smart account. The user sends USDC to the smart-account address.
Deposits draw from this balance.
- Act, gasless.
POST /buy and POST /sell are relayer-signed — no
per-action signature, no gas. Poll GET /actions/:id for status.
- 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
| Param | Type | Required | Description |
|---|
ownerEoa | string | Yes | The 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"
}
}
| Field | Type | Description |
|---|
accountAddress | string | Counterfactual smart-account address (same on all chains) |
deployedChains | number[] | Chains where the account is already deployed on-chain |
authorizedChainIds | number[] | Chains with an active session grant on the current policy |
grant | object | null | The 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.
| Field | Type | Required | Description |
|---|
ownerEoa | string | Yes | The user’s EOA address |
chainId | number | No | Chain to authorize. Defaults to Base (8453) |
spendCap | string | No | Per-period spend cap in USDC subunits (6dp) baked into the on-chain policy |
expiresAt | number | No | Unix timestamp when the grant expires |
scope | object | No | Advanced: 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.
| Field | Type | Required | Description |
|---|
ownerEoa | string | Yes | The user’s EOA address |
signature | string | Yes | The eth_signTypedData_v4 signature of enableTypedData |
chainId | number | No | The 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
| Field | Type | Required | Description |
|---|
ownerEoa | string | Yes | The user’s EOA address |
instrumentId | string | Yes | Target instrument ID |
amountUsdc | string | Yes | Deposit amount in human-readable USDC, e.g. "100.50" |
sourceChainId | number | No | Force a source chain instead of auto-selecting from the account’s balances |
slippageBps | number | No | Slippage tolerance in basis points. Defaults to 50 |
fastTransfer | boolean | No | Cross-chain only: CCTP fast transfer (~seconds, higher fee) vs standard (free, ~10–30 min). Defaults to false |
maxFee | string | No | Cross-chain fast-transfer max fee in USDC subunits (6dp). Required when fastTransfer is true |
referralFeeBps | number | No | Referral fee in basis points (0–500). Requires referralWallet |
referralWallet | string | No | Address that receives the referral fee |
idempotencyKey | string | No | A 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..."
}
| Field | Type | Description |
|---|
accountAddress | string | The smart account the action ran on |
actionId | string | Pass to GET /actions/:id to track status |
userOpHash | string | The submitted ERC-4337 userOp hash |
idempotent | boolean | Present 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
| Field | Type | Required | Description |
|---|
ownerEoa | string | Yes | The user’s EOA address |
instrumentId | string | Yes | Instrument ID to redeem from |
yieldTokenAmount | string | Yes | Human-readable yield-token amount, e.g. "95.5" |
slippageBps | number | No | Slippage tolerance in basis points. Defaults to 50 |
referralFeeBps | number | No | Referral fee in basis points (0–500). Requires referralWallet |
referralWallet | string | No | Address that receives the referral fee |
idempotencyKey | string | No | Retry-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..."
}
}
status | Meaning |
|---|
success | Completed (same-chain, or cross-chain fully settled) |
confirming_source | Cross-chain userOp landed; awaiting CCTP bridge settlement |
failed | The 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
| Field | Type | Required | Description |
|---|
ownerEoa | string | Yes | The user’s EOA address (also the recipient) |
amountUsdc | string | Yes | Amount in human-readable USDC |
chainId | number | No | Chain 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
| Field | Type | Required | Description |
|---|
ownerEoa | string | Yes | The user’s EOA address |
signature | string | Yes | The 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
GET /account → show the user their smart-account address and which chains
are authorized.
- For each chain the user wants to use:
POST /authorize/prepare → user signs
EIP-712 → POST /authorize/confirm.
- User funds the smart-account address with USDC.
POST /buy → poll GET /actions/:id until success (or confirming_source
then settled, for cross-chain).
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.