This page is a condensed, single-file reference for the REST calldata API.
For full documentation with per-language tabs and step-by-step walkthroughs,
see the API Calldata Integration
guide.
Using a skill-aware tool? The same content is exposed as the
amplify-earn-api-calldata Agent Skill and is auto-discovered at
/.well-known/agent-skills/index.json.
Prefer the skill in agents that support them — it loads progressively. Use
this page when you need to paste a single reference into a general-purpose
AI chat.When to Use
- Backend transaction builders in any language (Python, Go, Rust, Java, Node)
- Custodial wallets, HSMs, multisig services — fetch calldata, sign elsewhere
- Non-JS stacks that can’t consume
@paxoslabs/amplify-sdk - Prototyping with
curlbefore application code
Base URL & Authentication
- Obtain a key at https://app.paxoslabs.com.
- Send the key as a header — never as a query param (it ends up in access logs).
OpenAPI Spec
Endpoint Map
Transaction preparation
| Endpoint | Purpose |
|---|---|
GET /v2/core/permit | Detect authorization method (permit / approval / already_approved) |
GET /v2/amplify/deposit | Build deposit calldata |
GET /v2/amplify/withdraw | Build withdrawal order calldata |
GET /v2/amplify/withdraw/cancel | Build cancel-order calldata |
Discovery
| Endpoint | Purpose |
|---|---|
GET /v2/amplify/vaults | Accounts grouped by name with per-chain deployments[]; each deployment carries contract addresses, per-asset flags, fees, supply caps, min order size, SLAs |
Order status
| Endpoint | Purpose |
|---|---|
GET /v2/amplify/withdrawalRequests | Withdrawal orders with orderIndex and status |
Analytics
| Endpoint | Purpose |
|---|---|
GET /v2/amplify/vaultApys | Historical APY time series per vault |
GET /v2/amplify/vaultTvls | Historical TVL time series (+ current on-chain TVL on the final page) |
GET /v2/amplify/vaultAssets | Per-asset depositable/withdrawable flags (paginated, flat) |
GET /v2/amplify/vaultCompositions | Current portfolio composition from the rate provider |
GET /v2/amplify/withdrawalVolumes | Historical withdrawal volumes (requires vaultAddress, startTime, endTime) |
GET /v2/amplify/liquidityShortfalls | Pending withdrawal demand in excess of current vault balance |
Display helpers
| Endpoint | Purpose |
|---|---|
GET /v2/amplify/calculateWithdrawalFee | Preview fee for a specific offerAmount + wantAsset redemption |
/v2/amplify/vaults (no dedicated endpoint needed): depositSupplyCap, minimumWithdrawalOrderSize, assets[].depositFees, assets[].withdrawFees, assets[].withdrawalSLAs.
Response Format (calldata endpoints only)
/v2/amplify/deposit, /v2/amplify/withdraw, and /v2/amplify/withdraw/cancel accept a responseFormat query parameter:
responseFormat | data (hex) | abi / functionName / args | Use when |
|---|---|---|---|
encoded (default) | ✅ | ❌ | Signer consumes raw data (eth_sendTransaction, HSM) |
full | ✅ | ✅ | Debugging; need raw + decoded views |
structured | ❌ | ✅ | Encode locally (viem encodeFunctionData, ethers Interface.encodeFunctionData) |
Filter Syntax (filter query parameter)
- URL-encode once:
%3D==,%20= space. - Separate query params (
chainId=1&inDeprecation=false) are ignored.
Discovery — GET /v2/amplify/vaults
Single aggregated endpoint. Params (all optional): filter (flags: name, chainId, inDeprecation, requiresKyt), pageSize (1–100, default 25), pageToken.
Field → Transaction Parameter Mapping
| Discovery field | Used as |
|---|---|
deployments[].boringVaultAddress | vaultAddress in /v2/core/permit and all calldata endpoints; also the ERC-20 share token |
deployments[].depositorAddress | transaction.to returned by the prepared deposit |
deployments[].withdrawQueueAddress | Spender for the share approval before withdrawal |
deployments[].baseTokenAddress | Default depositAsset / wantAsset |
deployments[].requiresKyt: true | KYT attestation is resolved server-side — no special client handling required |
deployments[].depositSupplyCap | { raw, formatted, decimals, hasCap }; hasCap=false → uncapped |
deployments[].minimumWithdrawalOrderSize | Minimum shareAmount accepted by /v2/amplify/withdraw |
Deposit Flow
Three authorization branches handled by one API:| Method | Meaning |
|---|---|
permit | EIP-2612 off-chain signature — gas-efficient, single on-chain tx |
approval | Standard ERC-20 approve required first, then the deposit |
already_approved | Sufficient allowance exists — deposit directly |
Step 1 — Detect authorization
GET /v2/core/permit
| Param | Required | Notes |
|---|---|---|
vaultAddress | Yes | deployments[].boringVaultAddress from /v2/amplify/vaults |
tokenAddress | Yes | ERC-20 deposit token |
amount | Yes | Decimal string, token base units |
userAddress | Yes | Depositor wallet |
chainId | Yes | EVM chain ID |
Step 2 — Satisfy authorization
| Branch | Action |
|---|---|
permit | Sign domain + types + value via eth_signTypedData_v4 (primaryType: "Permit"). Keep signature and permitData.deadline. |
approval | Send tx with to = tokenAddress, data = approvalTransaction.encoded. Wait for receipt. |
already_approved | Skip to step 3. |
Step 3 — Prepare deposit calldata
GET /v2/amplify/deposit
| Param | Required | Notes |
|---|---|---|
vaultAddress | Yes | boringVaultAddress |
depositAsset | Yes | ERC-20 to deposit |
depositAmount | Yes | Decimal string, token base units |
userAddress | Yes | Wallet that signs and submits; also the default share recipient |
chainId | Yes | EVM chain ID |
to | No | Share recipient override (maps to on-chain to arg). Defaults to userAddress. |
permitSignature | Conditional | Required on permit path |
permitDeadline | Conditional | From permitData.deadline; required with permitSignature |
responseFormat | No | encoded (default), full, structured |
Step 4 — Sign & broadcast
Send{ to, data, value }. value is always "0" for ERC-20 deposits.
Reference implementation (Node / viem)
Withdrawal Flow
Withdrawals are asynchronous. Submitting an order locks shares in theWithdrawQueue; the protocol processes the queue off-cycle and transfers the asset on completion.
Step 1 — Approve share spending
Standard ERC-20approve(spender, amount):
- Token contract (
to):boringVaultAddress spender:withdrawQueueAddressamount: share amount to redeem (always 18 decimals)
Step 2 — Prepare withdrawal calldata
GET /v2/amplify/withdraw
| Param | Required | Notes |
|---|---|---|
vaultAddress | Yes | boringVaultAddress |
wantAsset | Yes | ERC-20 to receive |
shareAmount | Yes | Decimal string, 18 decimals |
userAddress | Yes | Submitter; also the default intendedDepositor/receiver/refundReceiver when those are omitted |
chainId | Yes | EVM chain ID |
intendedDepositor | No | On-chain SubmitOrderParams.intendedDepositor. Defaults to userAddress. |
receiver | No | Address that receives wantAsset on settlement. Defaults to userAddress. |
refundReceiver | No | Address that receives refunded shares if the order is cancelled. Defaults to userAddress. |
responseFormat | No | encoded / full / structured |
submitOrder vs submitOrderAndProcessAll automatically based on the account’s on-chain RolesAuthority configuration — there is no client-side atomic flag.
Response:
Step 3 — Sign & submit
Broadcast. On confirmation, shares are locked under a neworderIndex.
Step 4 — Poll order status
| Status | Meaning |
|---|---|
PENDING | In queue |
COMPLETE | Asset transferred |
PENDING_REFUND | Being refunded |
REFUNDED | Shares returned |
status=PENDING while polling — orders disappear the moment they reach a terminal state and you lose visibility into the outcome. Filter on userAddress + vaultAddress (and optionally chainId).
Reference implementation (Node / viem)
Cancellation Flow
OnlyPENDING orders are cancellable. The wallet submitting the cancel tx must be the same address that submitted the original order (msg.sender enforced on-chain).
Step 1 — Find orderIndex
orderIndex is a decimal string — pass it verbatim; never coerce to a JS number.
Step 2 — Prepare cancel calldata
GET /v2/amplify/withdraw/cancel
| Param | Required | Notes |
|---|---|---|
vaultAddress | Yes | boringVaultAddress |
orderIndex | Yes | Exact string from withdrawalRequests.orderIndex |
chainId | Yes | EVM chain ID |
responseFormat | No | encoded / full / structured |
Step 3 — Sign & broadcast
Send from the same wallet that submitted the order. On confirmation, locked shares return to that wallet.Display Helpers (read-only)
Most display data is returned inline on/v2/amplify/vaults (see Discovery above) — the only standalone helper is fee preview for a specific redemption.
| Endpoint | Required params | Returns |
|---|---|---|
GET /v2/amplify/calculateWithdrawalFee | offerAmount, wantAsset, vaultAddress, chainId | { feeAmount, offerFeePercentage: { bps, percentage }, flatFee } — all decimal strings / integers, scaled to human-readable units |
/v2/amplify/vaults (no dedicated endpoint):
| Field | Shape | Notes |
|---|---|---|
deployments[].depositSupplyCap | { raw, formatted, decimals, hasCap } | hasCap: false → uncapped (maxUint256) |
deployments[].minimumWithdrawalOrderSize | { raw, formatted, decimals } | Minimum shareAmount accepted by /v2/amplify/withdraw |
deployments[].assets[].depositFees / withdrawFees | { bps, percentage } | Per-asset fees |
deployments[].assets[].withdrawalSLAs | Protobuf duration strings (e.g. "86400s") | Queue + rate-update SLAs |
Error Envelope
| HTTP | error.status | Action |
|---|---|---|
| 400 | INVALID_ARGUMENT | Fix request; inspect fieldViolations |
| 401 | UNAUTHENTICATED | Verify x-api-key header |
| 403 | PERMISSION_DENIED | Rotate the key |
| 404 | NOT_FOUND | Re-discover via /v2/amplify/vaults |
| 429 | RESOURCE_EXHAUSTED | Back off (respect Retry-After if present) |
| 503 | INTERNAL | Retry with exponential backoff |
429 and 503 are safe. 400, 401, 403, 404 are deterministic — do not retry without changing inputs.
Common Gotchas
| Gotcha | Consequence | Fix |
|---|---|---|
| Filter passed as separate query params | Predicates silently ignored | Use single filter=field%3Dvalue%20AND%20... |
permitSignature without permitDeadline | 400 INVALID_ARGUMENT | Send both from the permit response |
| Expired permit deadline | On-chain revert | Re-fetch /v2/core/permit |
| Approval tx not mined before deposit | Revert (insufficient allowance) | Wait for receipt before preparing deposit |
Passing a client-side atomic flag to /v2/amplify/withdraw | Ignored | The server chooses submitOrder vs submitOrderAndProcessAll based on on-chain roles |
Deposit amount uses wrong decimals | Revert / rounding | USDC/USDT = 6 decimals; shares always 18 |
shareAmount uses token decimals | Too-small withdrawal or 400 | Share tokens are always 18 decimals |
Polling with status=PENDING | Order “vanishes” at completion | Drop the status predicate from the poll query |
orderIndex coerced to number | Off-by-one for large indices | Keep as string end-to-end |
| Cancel from a different wallet | On-chain revert | Sign from the original submitter |
| Stale address cache | Calls hit deprecated contracts | Respect inDeprecation; refresh on startup |
Supported Chains
| Chain | ID |
|---|---|
| Ethereum | 1 |
| Sepolia | 11155111 |
| Base | 8453 |
| HyperEVM | 999 |
| Stable Testnet | 2201 |
Canonical Docs
- Overview: https://docs.paxoslabs.com/v0.5.3/intro/products/earn/developers/guides/api-calldata/index
- Authentication: https://docs.paxoslabs.com/v0.5.3/intro/products/earn/developers/guides/api-calldata/authentication
- Discovery: https://docs.paxoslabs.com/v0.5.3/intro/products/earn/developers/guides/api-calldata/discovery
- Deposits: https://docs.paxoslabs.com/v0.5.3/intro/products/earn/developers/guides/api-calldata/deposits
- Withdrawals: https://docs.paxoslabs.com/v0.5.3/intro/products/earn/developers/guides/api-calldata/withdrawals
- Cancellations: https://docs.paxoslabs.com/v0.5.3/intro/products/earn/developers/guides/api-calldata/cancellations
- Display helpers: https://docs.paxoslabs.com/v0.5.3/intro/products/earn/developers/guides/api-calldata/display-helpers/index
- OpenAPI spec: https://docs.paxoslabs.com/v0.5.3/api-reference/openapi.yml
- Agent Skill: https://docs.paxoslabs.com/.well-known/agent-skills/index.json