Appearance
API Reference
Complete reference for the Ezys REST API. All endpoints communicate over HTTP using JSON.
Conventions
- Amounts — integer values in the currency's smallest (minor) unit, encoded as JSON strings (
amountMinor+currency+exponent), with floor rounding. See Money & Amounts for the full contract. - Currencies — ISO 4217 codes for fiat (
KRW,USD); registered tickers for stablecoins (USDC).
Base URL
All endpoints are served under the /v1 prefix:
Production: https://api.ezys.io/v1
Sandbox: https://api.ezys.sh/v1Authentication
All requests require an API key, passed via the X-API-Key header — see Authentication.
Endpoints
Paths are relative to the /v1 base above. Availability refers to the sandbox environment (api.ezys.sh); coming soon surfaces are published here as the contract of record ahead of rollout.
Quote (RFQ)
| Method | Endpoint | Availability | Description |
|---|---|---|---|
| POST | /quotes | Available | Request indicative quotes — returns a synchronous list of scored candidates |
| POST | /quotes/firm | Available | Request a firm, lockable quote — returns quoteId, locked all-in rate, itemized fees, and validUntil |
See the Quote API for request/response fields and lifecycle.
Intent
| Method | Endpoint | Availability | Description |
|---|---|---|---|
| POST | /intents | Available | Submit an Intent — returns accepted or rejected |
Single-step submit — there is no separate
confirmstep. See the Intent API.
Execution status & receipts
| Method | Endpoint | Availability | Description |
|---|---|---|---|
| GET | /executions/{reference} | Coming soon | Aggregate status of one execution — phase, events[] history, failure block |
| GET | /intents/{intentId}/status | Coming soon | Lightweight intent-only status (planned public exposure) |
| GET | /executions/{reference}/receipt | Coming soon | Normalized machine-readable receipt (offramp + payout + fees) |
| GET | /reconciliation | Coming soon | Aggregate reconciliation view over a date range |
See the Status API and Receipts & Reconciliation.
Request Format
Headers
| Header | Required | Description |
|---|---|---|
Content-Type | Yes | Must be application/json |
X-API-Key | Yes | Your API key — see Authentication |
X-Idempotency-Key | Yes (POST) | Canonical RFC 9562 UUID. Required on partner-facing POST for safe retries — see Idempotency |
Body
All request bodies must be valid JSON. The shape is per-endpoint — see the Quote API and Intent API for the exact request bodies the current endpoints accept (the illustrative pair/strategy shape below is not the literal request body of any single current endpoint).
json
{
"pair": {
"source": "USDC",
"target": "KRW"
},
"side": "sell",
"amount": "1000",
"strategy": "instant",
"constraints": {
"maxSlippageBps": 50,
"maxFeeBps": 30
}
}Response Format
The envelope wraps all responses consistently.
Success
json
{
"success": true,
"data": { ... }
}Error
json
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "A human-readable description of the error."
}
}HTTP Status Codes
| Code | Meaning |
|---|---|
200 | Request succeeded |
201 | Resource created |
202 | Accepted for asynchronous processing |
400 | Invalid request — check parameters |
401 | Authentication failed — missing or invalid API key |
403 | Insufficient permissions |
404 | Resource not found |
409 | Idempotency-Key conflict, or a matching request is still in progress — see Idempotency |
429 | Rate limit exceeded |
500 | Internal server error |
503 | Service temporarily unavailable — transient; retry with backoff |
Error Codes
For which of these errors are safe to retry and the recommended action for each, see Error Handling & Retries.
| Code | Description |
|---|---|
INVALID_API_KEY | The provided API key is invalid or revoked |
INVALID_PAIR | The requested currency pair is not supported |
INVALID_PARAMETER | One or more request parameters are malformed |
INVALID_STRATEGY | The specified execution strategy is not recognized |
AMOUNT_OUT_OF_RANGE | The amount exceeds the allowed min/max bounds |
CONSTRAINTS_NOT_MET | 422 — the requested constraints cannot be satisfied (status: "rejected") |
POLICY_DENIED | 422 — blocked by policy (limits or compliance); carries a closed subCode enum, one value conditionally retryable — see Policy subCodes |
INSUFFICIENT_LIQUIDITY | 422 — not enough liquidity to fulfill the request (status: "rejected"; a business outcome, never 200) |
INTENT_NOT_FOUND | No Intent exists with the given ID |
INTENT_EXPIRED | The Intent has expired and can no longer be acted upon |
INTENT_ALREADY_EXECUTING | The Intent is already in execution and cannot be cancelled |
SETTLEMENT_FAILED | The settlement (off-ramp) leg failed terminally — handle by compensation |
PROVIDER_UNAVAILABLE | 5xx — a downstream provider (e.g. oracle) is temporarily unavailable; retry with backoff |
PAYOUT_UNAVAILABLE | 5xx — the payout rail is temporarily unavailable; retry with backoff |
PAYOUT_REJECTED | 400 — the payout was rejected (configuration or request); fix and resubmit |
RATE_LIMIT_EXCEEDED | Too many requests — back off and retry |
IDEMPOTENCY_KEY_REQUIRED | 400 — the X-Idempotency-Key header is missing on a partner-facing POST. See Idempotency |
IDEMPOTENCY_KEY_INVALID | 400 — the key is not a canonical RFC 9562 UUID, or the request could not be fingerprinted |
IDEMPOTENCY_KEY_CONFLICT | 409 — the same key was reused with a different request body |
IDEMPOTENCY_KEY_PROCESSING | 409 — the original request for this key is still being processed |
SERVICE_UNAVAILABLE | 5xx — a dependency or the service is temporarily unavailable; retry with backoff |
INTERNAL_ERROR | 5xx — an unexpected server error; retry with backoff |
Rate Limits
| Tier | Limit |
|---|---|
| Standard | 100 requests / minute |
| Enterprise | Custom — contact sales |
