openapi: 3.1.0
info:
title: Endpoints
version: 1.0.0
paths:
/v0/auth/token:
post:
operationId: token
summary: Create a Session Token
description: >
<Callout intent="warning">
The endpoints exposed here are currently in **Beta**! As we continue to build our initial offering, these endpoints may implement breaking changes. Be sure to check back for our change log regularly as a precaution.
</Callout>
Exchange your API key for a short-lived bearer JWT. Send the API key as `Authorization: Bearer <api_key>`; no
request body is needed. The returned `sessionJwt` is valid for **15 minutes** (the TTL is not echoed in the
response) and must be sent in the `Authorization` header on every subsequent authenticated request. Refresh by
calling this endpoint again before expiry.
tags:
- Auth
parameters:
- name: Authorization
in: header
description: >-
Agora access key (cleartext), sent as `Authorization: Bearer <accessKey>`. Used only by POST /v0/auth/token
to mint a session JWT.
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/auth_token_Response_200'
'401':
description: Authentication is required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_401_unauthorized'
'429':
description: Too many requests.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_429_rate_limit_exceeded'
'500':
description: An unexpected error occurred.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_500_internal_error'
'503':
description: An upstream service is temporarily unavailable. Please retry.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_503_service_unavailable'
/v0/metrics:
get:
operationId: get
summary: Get Aggregate and Per-Chain Metrics
description: >
<Callout intent="warning">
The endpoints exposed here are currently in **Beta**! As we continue to build our initial offering, these endpoints may implement breaking changes. Be sure to check back for our change log regularly as a precaution.
</Callout>
Returns aggregate and per-chain AUSD supply. A few response-shape details specific to this endpoint:
- **`chainId` is a [CAIP-2](https://chainagnostic.org/CAIPs/caip-2) identifier.** Real values include `eip155:1`
(Ethereum), `eip155:137` (Polygon), `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`, and `sui:mainnet`. Use it to
cross-reference with DeFi Llama, CoinGecko, or on-chain data.
- **Aggregates are omitted on partial responses.** If one or more chains can't be reached, the response sets
`partial: true` and **omits** the top-level `totalSupply` / `circulatingSupply` rather than publishing a
silently-truncated figure. The omitted fields are absent — the keys are not present, not `null` — so guard with
`'totalSupply' in response`, not `response.totalSupply != null`. The `chains[]` array still includes every chain
with a recent cached value.
- **Supply values are decimal strings** (see the API overview for the precision convention). The plain-text
variants `/v0/metrics/total-supply` and `/v0/metrics/circulating-supply` return a single decimal string when you
don't need the per-chain breakdown.
tags:
- Metrics
responses:
'200':
description: >-
Aggregate and per-chain AUSD supply breakdown. When one or more chains are temporarily unavailable, the
response sets `partial: true` and omits aggregate `totalSupply` and `circulatingSupply` rather than
publishing a silently-truncated figure.
content:
application/json:
schema:
$ref: '#/components/schemas/metrics_get_Response_200'
'404':
description: The requested route or resource does not exist. Verify the URL and method.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_404_not_found'
'429':
description: >-
Per-IP rate limit exceeded at the Cloudflare edge. The response includes a `Retry-After` header indicating
the wait period in seconds.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_429_rate_limit_exceeded'
'500':
description: >-
An unexpected server-side failure occurred. Retry with exponential backoff and capture the `Request-Id`
header for support.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_500_internal_error'
/v0/metrics/total-supply:
get:
operationId: totalsupply
summary: Get Aggregate Total Supply
description: |
<Callout intent="warning">
The endpoints exposed here are currently in **Beta**! As we continue to build our initial offering, these endpoints may implement breaking changes. Be sure to check back for our change log regularly as a precaution.
</Callout>
tags:
- Metrics
responses:
'200':
description: Aggregate total AUSD supply across all chains, returned as a plain-text decimal (e.g. `1234567890.123456`).
content:
application/json:
schema:
type: object
properties: {}
'404':
description: The requested route or resource does not exist. Verify the URL and method.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_404_not_found'
'429':
description: >-
Per-IP rate limit exceeded at the Cloudflare edge. The response includes a `Retry-After` header indicating
the wait period in seconds.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_429_rate_limit_exceeded'
'500':
description: >-
An unexpected server-side failure occurred. Retry with exponential backoff and capture the `Request-Id`
header for support.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_500_internal_error'
/v0/metrics/circulating-supply:
get:
operationId: circulatingsupply
summary: Get Aggregate Circulating Supply
description: |
<Callout intent="warning">
The endpoints exposed here are currently in **Beta**! As we continue to build our initial offering, these endpoints may implement breaking changes. Be sure to check back for our change log regularly as a precaution.
</Callout>
tags:
- Metrics
responses:
'200':
description: >-
Aggregate circulating AUSD supply across all chains, returned as a plain-text decimal (e.g.
`987654321.654321`).
content:
application/json:
schema:
type: object
properties: {}
'404':
description: The requested route or resource does not exist. Verify the URL and method.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_404_not_found'
'429':
description: >-
Per-IP rate limit exceeded at the Cloudflare edge. The response includes a `Retry-After` header indicating
the wait period in seconds.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_429_rate_limit_exceeded'
'500':
description: >-
An unexpected server-side failure occurred. Retry with exponential backoff and capture the `Request-Id`
header for support.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_500_internal_error'
/v0/accounts:
get:
operationId: get
summary: List Accounts
description: >
<Callout intent="warning">
The endpoints exposed here are currently in **Beta**! As we continue to build our initial offering, these endpoints may implement breaking changes. Be sure to check back for our change log regularly as a precaution.
</Callout>
List every account registered to the authenticated organization. An account is either a bank account (fiat
source/destination) or a blockchain wallet (on-chain source/destination); both appear in the same paginated
list, distinguished by the `kind` discriminator.
Wallet accounts carry a `networks` array, one entry per network, each with its `entitlements` and their status
(see [Wallet entitlements](/api/endpoints/accounts/overview#wallet-entitlements)). Bank accounts return the full
`accountNumber` alongside `routingNumber`, `bankName`, and the `beneficiary` name on the wire.
tags:
- Accounts
parameters:
- name: cursor
in: query
required: false
schema:
type: string
- name: limit
in: query
required: false
schema:
type: integer
default: 50
- name: Authorization
in: header
description: 'Session JWT from POST /v0/auth/token, sent as `Authorization: Bearer <sessionJwt>`.'
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/accounts_get_Response_200'
'400':
description: One or more request parameters are invalid.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_400_parameter_invalid'
'401':
description: Authentication is required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_401_unauthorized'
'403':
description: The account is not eligible for the requested route direction.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_403_account_not_eligible_forbidden'
'404':
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_404_not_found'
'429':
description: Too many requests.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_429_rate_limit_exceeded'
'500':
description: An unexpected error occurred.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_500_internal_error'
post:
operationId: create
summary: Register an Account
description: >
<Callout intent="warning">
The endpoints exposed here are currently in **Beta**! As we continue to build our initial offering, these endpoints may implement breaking changes. Be sure to check back for our change log regularly as a precaution.
</Callout>
Register a customer-owned account under the authenticated organization. Set `kind` to `wallet` to register a
blockchain address (supply the `networks` it should be registered on; EVM hex is normalized to lowercase, Solana
base58 is kept verbatim) or `bank` to register a fiat account.
Registering a wallet starts `mint` and (where supported) `instant_settlement` entitlements on the requested
networks. See [Wallet entitlements](/api/endpoints/accounts/overview#wallet-entitlements) for how they are
approved and when the wallet is usable. Registering the same address on a network it already holds returns
`409`.
tags:
- Accounts
parameters:
- name: Authorization
in: header
description: 'Session JWT from POST /v0/auth/token, sent as `Authorization: Bearer <sessionJwt>`.'
required: true
schema:
type: string
responses:
'201':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/accounts_create_Response_201'
'400':
description: One or more request parameters are invalid.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_400_parameter_invalid'
'401':
description: Authentication is required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_401_unauthorized'
'403':
description: The account is not eligible for the requested route direction.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_403_account_not_eligible_forbidden'
'404':
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_404_not_found'
'409':
description: An account with these details already exists.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_409_account_already_exists'
'429':
description: Too many requests.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_429_rate_limit_exceeded'
'500':
description: An unexpected error occurred.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_500_internal_error'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/accounts_create_Request'
/v0/accounts/{accountId}:
put:
operationId: update
summary: Update an Account
description: >
<Callout intent="warning">
The endpoints exposed here are currently in **Beta**! As we continue to build our initial offering, these endpoints may implement breaking changes. Be sure to check back for our change log regularly as a precaution.
</Callout>
Apply a single change to an existing account, selected by `operation`:
- **`setName`**: rename a wallet or bank account (send `name`).
- **`addNetwork`**: register an existing wallet on an additional `network`, which starts a new `mint`
entitlement there (see [Wallet entitlements](/api/endpoints/accounts/overview#wallet-entitlements)). Rejected
with `409` if the address is already registered there.
- **`requestEntitlement`**: request an `entitlement` (currently `instant_settlement`) on an existing wallet
`network`. Returns `400` if the entitlement isn't requestable for that network. See [Wallet
entitlements](/api/endpoints/accounts/overview#wallet-entitlements) for how requests are reviewed and approved.
The response is the full updated account, same shape as `GET /v0/accounts`.
tags:
- Accounts
parameters:
- name: accountId
in: path
required: true
schema:
type: string
format: uuid
- name: Authorization
in: header
description: 'Session JWT from POST /v0/auth/token, sent as `Authorization: Bearer <sessionJwt>`.'
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/accounts_update_Response_200'
'400':
description: This entitlement cannot be requested in its current state.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_400_entitlement_not_requestable_parameter_invalid'
'401':
description: Authentication is required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_401_unauthorized'
'403':
description: The account is not eligible for the requested route direction.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_403_account_not_eligible_forbidden'
'404':
description: Account not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_404_account_not_found_not_found'
'409':
description: An account with these details already exists.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_409_account_already_exists'
'429':
description: Too many requests.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_429_rate_limit_exceeded'
'500':
description: An unexpected error occurred.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_500_internal_error'
requestBody:
content:
application/json:
schema:
type: object
properties:
operation:
$ref: '#/components/schemas/V0AccountsAccountIdPutRequestBodyContentApplicationJsonSchemaOperation'
name:
type: string
description: User-set label. Free-form; max 200 characters.
network:
$ref: '#/components/schemas/V0AccountsAccountIdPutRequestBodyContentApplicationJsonSchemaNetwork'
entitlement:
$ref: '#/components/schemas/V0AccountsAccountIdPutRequestBodyContentApplicationJsonSchemaEntitlement'
description: Entitlement to request. Moves to pending_approval; granting stays Agora-side.
required:
- operation
/v0/routes:
get:
operationId: get
summary: List Routes
description: >
<Callout intent="warning">
The endpoints exposed here are currently in **Beta**! As we continue to build our initial offering, these endpoints may implement breaking changes. Be sure to check back for our change log regularly as a precaution.
</Callout>
Return every route on the authenticated organization. Each route includes the full `instructions` block so
callers can resolve memos and mint/redeem addresses without an additional retrieve.
tags:
- Routes
parameters:
- name: cursor
in: query
required: false
schema:
type: string
- name: limit
in: query
required: false
schema:
type: integer
default: 50
- name: Authorization
in: header
description: 'Session JWT from POST /v0/auth/token, sent as `Authorization: Bearer <sessionJwt>`.'
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/routes_get_Response_200'
'400':
description: One or more request parameters are invalid.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_400_parameter_invalid'
'401':
description: Authentication is required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_401_unauthorized'
'403':
description: The account is not eligible for the requested route direction.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_403_account_not_eligible_forbidden'
'404':
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_404_not_found'
'429':
description: Too many requests.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_429_rate_limit_exceeded'
'500':
description: An unexpected error occurred.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_500_internal_error'
post:
operationId: create
summary: Create a Route
description: >
<Callout intent="warning">
The endpoints exposed here are currently in **Beta**! As we continue to build our initial offering, these endpoints may implement breaking changes. Be sure to check back for our change log regularly as a precaution.
</Callout>
Create a persistent source → destination route. The response includes reusable settlement instructions — a wire
memo for fiat sources, or one mint or redeem address per supported chain for blockchain sources — that the
caller uses to initiate transfers. A single set of instructions is valid indefinitely; every inbound transfer
matching them triggers a separate settlement to the route's destination.
The route topology is determined by `from.currency`, `to.currency`, and the destination `to.chain`.
`to.accountId` references a registered account from `GET /v0/accounts`.
<Callout intent="warning">
**Fiat routes need the bank account on file first.** Add the bank account you'll *send from* (mint from `usd`) or *receive into* (redeem to `usd`) before you transact. If a wire arrives from — or a payout is owed to — a bank account Agora hasn't added and verified, settlement is held and processing is delayed until it's on file.
</Callout>
### Supported topologies
| `from.currency` | `to.currency` (+ `to.chain`) | Behavior |
|---|---|---|
| `usd` | `ausd` on a chain | Mint: wire USD with the memo, receive AUSD at the destination |
| `ausd` | `usd` (bank account) | Redeem: send AUSD to the redeem address, receive a USD payout |
| `stablecoin` (wildcard) | `ausd` on a chain | Mint with stablecoins: send any in-scope stablecoin to the mint
address, receive AUSD at the destination. See the `stablecoin` section below for the in-scope asset list. |
| `ausd` | `usdc` on a chain | Redeem to tokens: send AUSD to the redeem address, receive `usdc`. |
### What `stablecoin` means
`stablecoin` is a wildcard source currency standing in for any stablecoin Agora currently accepts — **today,
only `usdc`**. The mint address a mint-from-stablecoin route returns is currency-agnostic, settling AUSD
regardless of which in-scope stablecoin is sent. If you have questions about which currencies can be accepted,
reach out to the [operations team](mailto:support@agora.finance).
tags:
- Routes
parameters:
- name: Authorization
in: header
description: 'Session JWT from POST /v0/auth/token, sent as `Authorization: Bearer <sessionJwt>`.'
required: true
schema:
type: string
responses:
'201':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/routes_create_Response_201'
'400':
description: The requested chain is not supported.
content:
application/json:
schema:
$ref: >-
#/components/schemas/ErrorResponse_400_chain_unsupported_currency_unsupported_direction_unsupported_parameter_invalid
'401':
description: Authentication is required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_401_unauthorized'
'403':
description: The account is not eligible for the requested route direction.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_403_account_not_eligible_forbidden'
'404':
description: Account not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_404_account_not_found_not_found'
'409':
description: A route with these parameters already exists. Use GET /routes to look it up.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_409_route_already_exists'
'429':
description: Too many requests.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_429_rate_limit_exceeded'
'500':
description: An unexpected error occurred.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_500_internal_error'
'503':
description: Route creation temporarily unavailable. Please retry shortly.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_503_route_creation_unavailable'
requestBody:
content:
application/json:
schema:
type: object
properties:
name:
type: string
from:
$ref: '#/components/schemas/V0RoutesPostRequestBodyContentApplicationJsonSchemaFrom'
to:
$ref: '#/components/schemas/V0RoutesPostRequestBodyContentApplicationJsonSchemaTo'
required:
- from
- to
/v0/routes/{routeId}:
get:
operationId: getbyid
summary: Get a Route by ID
description: >
<Callout intent="warning">
The endpoints exposed here are currently in **Beta**! As we continue to build our initial offering, these endpoints may implement breaking changes. Be sure to check back for our change log regularly as a precaution.
</Callout>
Retrieve a single route by its id, including the full reusable `instructions` block. Route ids are deterministic
— the same canonical inputs always derive the same id — so a `404` means no route with those parameters has been
created for your organization.
tags:
- Routes
parameters:
- name: routeId
in: path
required: true
schema:
type: string
format: uuid
- name: Authorization
in: header
description: 'Session JWT from POST /v0/auth/token, sent as `Authorization: Bearer <sessionJwt>`.'
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/routes_getbyid_Response_200'
'400':
description: One or more request parameters are invalid.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_400_parameter_invalid'
'401':
description: Authentication is required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_401_unauthorized'
'403':
description: The account is not eligible for the requested route direction.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_403_account_not_eligible_forbidden'
'404':
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_404_not_found_route_not_found'
'429':
description: Too many requests.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_429_rate_limit_exceeded'
'500':
description: An unexpected error occurred.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_500_internal_error'
/v0/transactions:
get:
operationId: list
summary: List Transactions
description: >
<Callout intent="warning">
The endpoints exposed here are currently in **Beta**! As we continue to build our initial offering, these endpoints may implement breaking changes. Be sure to check back for our change log regularly as a precaution.
</Callout>
List your settled transactions, newest first, with cursor pagination. Each entry summarizes the `source` and
`recipient`, the per-currency totals each side moved, and the `type` (`mint`, `redeem`, `bridge`, `reward`,
`return`). `type` and `status` are open enums; tolerate unknown values. Fetch one transaction's legs with `GET
/v0/transactions/{txnId}`.
tags:
- Transactions
parameters:
- name: cursor
in: query
required: false
schema:
type: string
- name: limit
in: query
required: false
schema:
type: integer
default: 50
- name: Authorization
in: header
description: 'Session JWT from POST /v0/auth/token, sent as `Authorization: Bearer <sessionJwt>`.'
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/transactions_list_Response_200'
'400':
description: One or more request parameters are invalid.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_400_parameter_invalid'
'401':
description: Authentication is required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_401_unauthorized'
'403':
description: The account is not eligible for the requested route direction.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_403_account_not_eligible_forbidden'
'404':
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_404_not_found'
'429':
# --- truncated at 32 KB (150 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/agora/refs/heads/main/openapi/agora-openapi-original.yml