{
    "openapi": "3.1.0",
    "info": {
        "title": "Etherfuse FX API",
        "description": "Partner-facing ramp API for onramps, offramps, swaps, and KYC.",
        "license": {
            "name": "Proprietary"
        },
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "https://api.sand.etherfuse.com",
            "description": "Sandbox"
        }
    ],
    "paths": {
        "/auth/token": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Exchange a partner JWT",
                "description": "OAuth 2.0 token endpoint ([RFC 6749 §3.2](https://www.rfc-editor.org/rfc/rfc6749#section-3.2)). Exchanges a partner-signed JWT for an Etherfuse access/refresh token pair, or refreshes an existing session.\n\nCall this from your backend to provision a user ahead of a launch, or to prefetch a `refresh_token` that speeds up the launch redirect. Your backend signs a JWT with the key behind your registered JWKS and posts it here. To drop a user straight into the app in a browser, use [POST /auth/launch](/api-reference/authentication/launch-a-user-into-the-app) instead.\n\n## Grant types\n\n- `urn:ietf:params:oauth:grant-type:jwt-bearer` ([RFC 7523](https://www.rfc-editor.org/rfc/rfc7523)). Put the partner JWT in `assertion`.\n- `refresh_token` ([RFC 6749 §6](https://www.rfc-editor.org/rfc/rfc6749#section-6)). Put a prior `refresh_token` in `refresh_token`.\n\n## The JWT\n\nSign it with the key behind your registered JWKS (see [Sign a user JWT](/guides/jwt-authentication#sign-a-user-jwt) for full detail). Claims:\n\n- **`iss`**: your registered issuer.\n- **`sub`**: the person signing in; a UUID is _strongly recommended_ (for an individual customer it's the same value as `customerId` in the Ramp API). Must name a person, never a business: a business org id is rejected with `invalid_grant`, and a `sub` can't be reused as a business org id ([POST /ramp/organization](/api-reference/organizations/create-child-org) returns 409). A non-UUID `sub` still signs in, but can't be addressed through the Ramp API.\n- **`aud`**: the token endpoint URL, `https://api.etherfuse.com/auth/token` (`https://api.sand.etherfuse.com/auth/token` in sandbox).\n- **`scope`**: required. Names the flow the user may complete (see [User Launch Flows](/guides/user-launch-flows#scopes)); an unrecognized scope is rejected with `invalid_scope`.\n- **`jti`** / **`nonce`**: a fresh value, unique per token, for replay protection. You can send it as `jti` (the standard JWT ID) or `nonce` (the standard OIDC claim).\n- **`exp`, `iat`**: required; keep tokens short-lived.\n- **`email`, `name`**: required; populate the user's profile. `picture` is optional.\n\nThis endpoint is unauthenticated: the signed JWT (or refresh token) is the credential. Do **not** send an API key.",
                "operationId": "auth_token",
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/AuthTokenRequest"
                            }
                        },
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/AuthTokenRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A bearer access token and refresh token",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AuthTokenResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "OAuth error: `invalid_request`, `invalid_grant`, `invalid_scope`, or `unsupported_grant_type` ([RFC 6749 §5.2](https://www.rfc-editor.org/rfc/rfc6749#section-5.2))",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AuthErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/auth/launch": {
            "servers": [
                {
                    "url": "https://sandbox.etherfuse.com",
                    "description": "Sandbox app (NOT the API host)"
                }
            ],
            "get": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Launch a user via postMessage",
                "description": "> ⚠️ **Different host.** Like [POST /auth/launch](/api-reference/authentication/launch-a-user-into-the-app), this lives on the **app host** (`app.etherfuse.com` / `sandbox.etherfuse.com`), **not** the API host. It is a browser-facing page, not a JSON API.\n\nThe `postMessage` variant of launch, for embedding the flow in an **iframe or popup**. Open `/auth/launch` with no body; on load it asks its embedder (your page) for credentials over `postMessage`, and you reply. Use this when you don't want to server-render a [form POST](/api-reference/authentication/launch-a-user-into-the-app). It also lets you handle session expiration and launch into different targets seamlessly, without a redirect page.\n\n## postMessage contract\n\n1. On load, the launch frame posts an `etherfuse:auth:request` message to its embedder.\n2. Your page replies with an `etherfuse:auth:response` carrying the fields below.\n3. If you need a moment to sign a JWT, send `etherfuse:auth:await` first so the frame doesn't time out.\n\n## Fields\n\n- **`grant_type`** and **`assertion`**: a raw partner JWT (`grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer`) or a `refresh_token` from a prior [server-side exchange](/api-reference/authentication/exchange-a-partner-jwt) (`grant_type=refresh_token`).\n- **`target`**: the app path to land on. Must be an allowed target. See [User Launch Flows](/guides/user-launch-flows#targets). Any other path is rejected.\n- **`return_url`** *(optional)*: where to send the user when they leave.\n\nThe JWT's `sub` and `scope` follow the same rules as [POST /auth/launch](/api-reference/authentication/launch-a-user-into-the-app).",
                "operationId": "auth_launch_postmessage",
                "security": [],
                "responses": {
                    "200": {
                        "description": "An HTML page that requests credentials from the embedder over `postMessage`, establishes the session, and redirects the browser to `target`."
                    }
                }
            },
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Launch a user into the app",
                "description": "> ⚠️ **Different host.** Unlike every other endpoint in this reference, `/auth/launch` lives on the **app host** (`app.etherfuse.com` / `sandbox.etherfuse.com`), **not** the API host (`api.etherfuse.com`). It is a browser-facing page, not a JSON API.\n\nDrops one of your users into the Etherfuse app with an authenticated session. Use it for **browser** flows, such as sending a user into KYB. Your server POSTs an HTML form (or redirects the browser) to this URL; the app establishes the session and redirects the user to `target`. To embed the flow in an iframe or popup instead, use the [postMessage variant](/api-reference/launch-via-postmessage).\n\n## Targets\n\nThe `target` and `scope` for every flow you can launch a user into (and what to know about each) are documented in [User Launch Flows](/guides/user-launch-flows). A `target` must be one of those allowed paths (optionally with a query string such as `?org=<org_id>`); any other path is rejected with `invalid_target`.\n\nThe JWT's `sub` is _strongly recommended_ to be a UUID identifying the person signing in (see [Sign a user JWT](/guides/jwt-authentication#sign-a-user-jwt) for how `sub` relates to the Ramp API `customerId` for individuals vs businesses), and its `scope` follows the same rules as [`/auth/token`](/api-reference/authentication/exchange-a-partner-jwt). The endpoint is unauthenticated: the JWT or refresh token is the credential.",
                "operationId": "auth_launch",
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/AuthLaunchRequest"
                            }
                        },
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/AuthLaunchRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "An HTML page that establishes the session and redirects the browser to `target`."
                    }
                }
            }
        },
        "/lookup/bonds/cost": {
            "get": {
                "tags": [
                    "Lookup"
                ],
                "summary": "List stablebond costs",
                "description": "Returns current pricing data for all stablebonds, including the bond cost in\nUSD, fiat, and per-provider exchange rate sources. Each bond entry includes a\n`sources` map showing the exchange rate and derived `bond_cost_in_usd` from\neach FX provider, enabling oracle safety checks.\n\nPublic — no API key required.",
                "operationId": "get_bond_prices",
                "parameters": [
                    {
                        "name": "max_age",
                        "in": "query",
                        "description": "Maximum age of a source in seconds. Sources older than this are excluded.",
                        "required": false,
                        "schema": {
                            "type": [
                                "integer",
                                "null"
                            ],
                            "format": "int64",
                            "minimum": 0
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Pricing data keyed by bond mint address",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "additionalProperties": {
                                        "$ref": "#/components/schemas/PaymentData"
                                    },
                                    "propertyNames": {
                                        "type": "string"
                                    }
                                },
                                "example": {
                                    "CETES7CKqqKQizuSN6iWQwmTeFRjbJR6Vw2XRKfEDR8f": {
                                        "bond_cost_in_fiat": "1.153754",
                                        "bond_cost_in_payment_token": "1.153754",
                                        "bond_cost_in_usd": "0.064785",
                                        "bond_symbol": "CETES",
                                        "currency": "MXN",
                                        "current_basis_points": 578,
                                        "current_time": "2026-03-23T16:50:32.821673099+00:00",
                                        "fiat_exchange_rate_with_usd": "17.80900",
                                        "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
                                        "sources": {
                                            "provider_1": {
                                                "bond_cost_in_usd": "0.064781",
                                                "exchange_rate": "17.81",
                                                "updated_at": 1711212632
                                            },
                                            "provider_2": {
                                                "bond_cost_in_usd": "0.064854",
                                                "exchange_rate": "17.79",
                                                "updated_at": 1711212630
                                            }
                                        },
                                        "symbol": "USDC"
                                    }
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Bond prices not available"
                    }
                },
                "security": [
                    {}
                ]
            }
        },
        "/lookup/bonds/cost/{identifier}": {
            "get": {
                "tags": [
                    "Lookup"
                ],
                "summary": "Get stablebond cost",
                "description": "Returns current pricing data for a single stablebond, including the bond cost\nin USD, fiat, and per-provider exchange rate sources. The `identifier` can be\neither a Solana mint address (e.g. `CETES7CKqqKQizuSN6iWQwmTeFRjbJR6Vw2XRKfEDR8f`)\nor a bond symbol (e.g. `CETES`).\n\nPublic — no API key required.",
                "operationId": "get_bond_price",
                "parameters": [
                    {
                        "name": "identifier",
                        "in": "path",
                        "description": "Bond mint address or symbol (e.g. \"CETES\", \"USTRY\", \"CETES7CKqqKQizuSN6iWQwmTeFRjbJR6Vw2XRKfEDR8f\")",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "max_age",
                        "in": "query",
                        "description": "Maximum age of a source in seconds. Sources older than this are excluded.",
                        "required": false,
                        "schema": {
                            "type": [
                                "integer",
                                "null"
                            ],
                            "format": "int64",
                            "minimum": 0
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Pricing data for the requested bond",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PaymentData"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Bond not found for identifier"
                    }
                },
                "security": [
                    {}
                ]
            }
        },
        "/lookup/country-codes": {
            "get": {
                "tags": [
                    "Lookup"
                ],
                "summary": "List country codes",
                "description": "Returns supported countries with ISO 3166-1 alpha-2 codes, alpha-3 codes, and\nEnglish names. Use these codes for `birthCountryIsoCode` and `countryIsoCode`\nwhen registering bank accounts.\n\nPublic — no API key required.",
                "operationId": "country_codes",
                "responses": {
                    "200": {
                        "description": "Supported countries",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/Country"
                                    }
                                }
                            }
                        }
                    }
                },
                "security": [
                    {}
                ]
            }
        },
        "/lookup/restricted-countries": {
            "get": {
                "tags": [
                    "Lookup"
                ],
                "summary": "List restricted countries",
                "description": "Returns the countries that are effectively restricted for KYC or KYB based on\nexternal consensus and internal overrides. Each entry shows whether KYC, KYB, or both\nare blocked.\n\nPublic — no API key required.",
                "operationId": "restricted_countries",
                "responses": {
                    "200": {
                        "description": "Restricted countries",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RestrictedCountriesResponse"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {}
                ]
            }
        },
        "/lookup/exchange_rate": {
            "get": {
                "tags": [
                    "Lookup"
                ],
                "summary": "List exchange rates",
                "description": "Returns current USD exchange rates for all supported currencies, each keyed by\n`usd_to_<currency>` with a per-provider `sources` breakdown.\n\nPublic — no API key required.",
                "operationId": "exchange_rates",
                "parameters": [
                    {
                        "name": "max_age",
                        "in": "query",
                        "description": "Maximum age of a source in seconds. Sources whose `updated_at` timestamp\nis older than `now - max_age` are excluded from the `sources` map.\nWhen omitted, all sources are returned regardless of age.",
                        "required": false,
                        "schema": {
                            "type": [
                                "integer",
                                "null"
                            ],
                            "format": "int64",
                            "minimum": 0
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "All exchange rates keyed by `usd_to_<currency>`",
                        "content": {
                            "application/json": {
                                "schema": {},
                                "example": {
                                    "usd_to_brl": {
                                        "rate": "4.97",
                                        "sources": {
                                            "provider_1": {
                                                "rate": "4.97",
                                                "updated_at": 1709510400
                                            }
                                        },
                                        "updated_at": 1709510400
                                    },
                                    "usd_to_mxn": {
                                        "rate": "17.15",
                                        "sources": {
                                            "provider_1": {
                                                "rate": "17.15",
                                                "updated_at": 1709510400
                                            }
                                        },
                                        "updated_at": 1709510400
                                    }
                                }
                            }
                        }
                    }
                },
                "security": [
                    {}
                ]
            }
        },
        "/lookup/exchange_rate/usd_to_{currency}": {
            "get": {
                "tags": [
                    "Lookup"
                ],
                "summary": "Get exchange rate",
                "description": "Returns the current USD-to-specified-currency exchange rate, with a\nper-provider `sources` breakdown.\n\nPublic — no API key required.",
                "operationId": "usd_to_currency",
                "parameters": [
                    {
                        "name": "currency",
                        "in": "path",
                        "description": "The target currency code (e.g. \"mxn\", \"brl\", \"eur\")",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "max_age",
                        "in": "query",
                        "description": "Maximum age of a source in seconds. Sources whose `updated_at` timestamp\nis older than `now - max_age` are excluded from the `sources` map.\nWhen omitted, all sources are returned regardless of age.",
                        "required": false,
                        "schema": {
                            "type": [
                                "integer",
                                "null"
                            ],
                            "format": "int64",
                            "minimum": 0
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Exchange rate with per-provider source breakdown",
                        "content": {
                            "application/json": {
                                "schema": {},
                                "example": {
                                    "rate": "17.15",
                                    "sources": {
                                        "provider_1": {
                                            "rate": "17.15",
                                            "updated_at": 1709510400
                                        }
                                    },
                                    "updated_at": 1709510400
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Currency is not supported"
                    }
                },
                "security": [
                    {}
                ]
            }
        },
        "/lookup/stablebonds": {
            "get": {
                "tags": [
                    "Lookup"
                ],
                "summary": "List stablebonds",
                "description": "Returns all stablebonds with current prices, supplies, and multi-chain\nbreakdown. Data is cached for ~5 minutes.\n\nPublic — no API key required.",
                "operationId": "get_stablebonds",
                "responses": {
                    "200": {
                        "description": "All stablebonds with pricing and supply",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StablebondsCachable"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "Stablebonds data not yet available"
                    }
                },
                "security": [
                    {}
                ]
            }
        },
        "/ramp": {
            "get": {
                "tags": [
                    "Organizations"
                ],
                "summary": "Verify API key",
                "description": "Returns the organization ID associated with the API key. Useful for\nverifying credentials and connectivity.",
                "operationId": "test_route",
                "responses": {
                    "200": {
                        "description": "The authenticated organization ID",
                        "content": {
                            "application/json": {
                                "schema": {},
                                "example": {
                                    "org_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/ramp/assets": {
            "get": {
                "tags": [
                    "Assets"
                ],
                "summary": "List assets",
                "description": "Returns all rampable stablecoins (e.g. USDC, EURC) and stablebonds (e.g. CETES)\navailable on the specified blockchain. The `currency` parameter controls sort priority —\nassets matching the requested currency appear first, but all rampable assets for the\nchain are always returned. Use the `identifier` from the response when creating quotes.",
                "operationId": "get_rampable_assets",
                "parameters": [
                    {
                        "name": "blockchain",
                        "in": "query",
                        "description": "The blockchain to get assets for (e.g., \"stellar\", \"solana\")",
                        "required": true,
                        "schema": {
                            "$ref": "#/components/schemas/Blockchain"
                        }
                    },
                    {
                        "name": "currency",
                        "in": "query",
                        "description": "The fiat currency for sort priority (e.g., \"mxn\"). Assets matching this currency appear first.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "wallet",
                        "in": "query",
                        "description": "The wallet address to fetch balances for",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The rampable assets for the chain",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RampableAssetsResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/ramp/bank-account": {
            "post": {
                "tags": [
                    "Bank Accounts"
                ],
                "summary": "Create bank account (presigned)",
                "description": "Registers a customer's Mexican bank account (CLABE) for on/off-ramp transactions. The\n`account` field accepts two variants — Personal or Business — auto-detected from the\nfields present.\n\n**Sandbox:** submit `XEXX010101000` (personal) or `XEX010101000` (business) as the `rfc`\nto skip SPEI provider registration and have the account marked `compliant: true`\nimmediately. Any other RFC in sandbox is sent to the SPEI provider's sandbox as a real\nregistration and will not auto-approve. Both values are rejected in production.\n\n**Note:** this endpoint is for customers onboarding through the Etherfuse UI using a\npresigned URL. For programmatic creation via API key, use\n`POST /ramp/customer/{customer_id}/bank-account` instead.",
                "operationId": "create_bank_account",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateBankAccountPayload"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "The created bank account",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AddBankAccountResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid or expired presigned URL"
                    }
                },
                "security": [
                    {}
                ]
            }
        },
        "/ramp/bank-account/{bank_account_id}": {
            "get": {
                "tags": [
                    "Bank Accounts"
                ],
                "summary": "Get bank account",
                "description": "Retrieves details for a specific bank account accessible to your API key.",
                "operationId": "get_bank_account",
                "parameters": [
                    {
                        "name": "bank_account_id",
                        "in": "path",
                        "description": "The bank account ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The bank account",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BankAccount"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Bank account not found"
                    }
                }
            }
        },
        "/ramp/bank-accounts": {
            "get": {
                "tags": [
                    "Bank Accounts"
                ],
                "summary": "List bank accounts",
                "description": "Returns the first page of bank accounts with defaults (pageSize 30, pageNumber 0, no\nfilters). Use the POST variant for pagination and date filtering.",
                "operationId": "list_bank_accounts",
                "responses": {
                    "200": {
                        "description": "Paginated bank accounts",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedBankAccounts"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Bank Accounts"
                ],
                "summary": "Search bank accounts",
                "description": "Retrieves a paginated list of bank accounts. The request body is optional — omitting it\nreturns the first page with defaults (pageSize 30, pageNumber 0, no filters).",
                "operationId": "get_bank_accounts",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PagedRequest_DateRangeFilter"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Paginated bank accounts",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedBankAccounts"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/ramp/customer/{customer_id}": {
            "get": {
                "tags": [
                    "Customers"
                ],
                "summary": "Get customer",
                "description": "Retrieves details for a specific customer accessible to your API key.",
                "operationId": "get_customer",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The customer",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Customer"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Customer not found"
                    }
                }
            }
        },
        "/ramp/customer/{customer_id}/bank-account": {
            "post": {
                "tags": [
                    "Bank Accounts"
                ],
                "summary": "Create bank account (API)",
                "description": "Programmatically creates a new bank account for a customer using API-key\nauthentication — no presigned URL required. The registration data (name, CURP, RFC,\nCLABE, etc.) is validated and sent to the payment processor. Bank accounts require\nverification before they can be used for transactions.\n\n**Sandbox:** submit `XEXX010101000` (personal) or `XEX010101000` (business) as the `rfc`\nto skip SPEI provider registration and have the account marked `compliant: true`\nimmediately. The hosted onboarding UI uses these RFCs automatically — programmatic\ncallers must opt in by passing them. Any other RFC in sandbox is sent to the SPEI\nprovider's sandbox as a real registration and will not auto-approve. Both values are\nrejected in production.",
                "operationId": "api_create_bank_account",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer (child org) ID. Must belong to the caller's organization or a direct child.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ApiCreateBankAccountPayload"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "201": {
                        "description": "The created bank account",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BankAccount"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid request"
                    }
                }
            }
        },
        "/ramp/customer/{customer_id}/bank-accounts": {
            "get": {
                "tags": [
                    "Bank Accounts"
                ],
                "summary": "List customer accounts",
                "description": "Returns the first page of bank accounts for a specific customer with defaults\n(pageSize 30, pageNumber 0, no filters). Use the POST variant for pagination and\ndate filtering.",
                "operationId": "list_customer_bank_accounts",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer (child org) ID. Must belong to the caller's organization or a direct child.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated bank accounts",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedBankAccounts"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Customer not found"
                    }
                }
            },
            "post": {
                "tags": [
                    "Bank Accounts"
                ],
                "summary": "Search customer accounts",
                "description": "Retrieves bank accounts for a specific customer. The request body is optional —\nomitting it returns the first page with defaults (pageSize 30, pageNumber 0, no filters).",
                "operationId": "get_customer_bank_accounts",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer (child org) ID. Must belong to the caller's organization or a direct child.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PagedRequest_DateRangeFilter"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Paginated bank accounts",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedBankAccounts"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Customer not found"
                    }
                }
            }
        },
        "/ramp/customer/{customer_id}/kyc": {
            "get": {
                "tags": [
                    "KYC"
                ],
                "summary": "Get KYC status",
                "description": "Returns the current KYC verification status for a customer, resolved from the customer's account. The overall `status` matches the logic used for orders, so it stays consistent with whether the customer can transact. Submission details such as rejection reasons and timestamps are visible only to the partner that submitted the data.",
                "operationId": "get_kyc_org",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer (child org) ID. Must belong to the caller's organization or a direct child.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The org-level KYC status for the customer",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/KycStatusResponse"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Customer not found"
                    }
                }
            },
            "post": {
                "tags": [
                    "KYC"
                ],
                "summary": "Submit KYC",
                "description": "Submit identity information (name, address, DOB, tax ID) for a customer\nprogrammatically, an alternative to the presigned-URL flow where users complete KYC in\nthe Etherfuse UI.\n\n**Use case:** partners who want to white-label the KYC experience can collect identity\ndata in their own UI and submit it here.\n\nSubmitted data is reviewed by Etherfuse admins before approval; you'll receive a\n`kyc_updated` webhook when the status changes.\n\n**Sandbox auto-approval:** in sandbox, a `personal` customer auto-approves once all\nagreements have been signed, with no manual review. Submitting KYC alone leaves the customer\n`proposed`; approval lands only after the rest of the programmatic flow (document upload\nand agreement signing) is complete, at which point a `kyc_updated` webhook fires and orders\nunlock for the wallet. This is sandbox-only; production still requires manual review.\n\n**Data isolation:** partners can only query KYC data they submitted; data submitted by\nother partners or directly by users is not visible.",
                "operationId": "submit_kyc",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer (child org) ID. Must belong to the caller's organization or a direct child.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SubmitKycRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "KYC identity data submitted",
                        "content": {
                            "application/json": {
                                "schema": {},
                                "example": {
                                    "message": "KYC data submitted for review",
                                    "status": "proposed"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Customer not found"
                    },
                    "400": {
                        "description": "Validation failed. The plain text body lists every missing or invalid field. Also returned as `Unable to verify model ownership` when the customer id exists but is not a customer of your organization.",
                        "content": {
                            "text/plain": {
                                "schema": {
                                    "type": "string"
                                },
                                "example": "phoneNumber is required; occupation is required; idNumbers may only be provided when address.country is MX"
                            }
                        }
                    }
                }
            }
        },
        "/ramp/customer/{customer_id}/kyc/documents": {
            "post": {
                "tags": [
                    "KYC"
                ],
                "summary": "Upload KYC docs",
                "description": "Upload identity documents (government ID, selfie) for a customer.\n\n**Document requirements:**\n- Formats: JPEG, PNG\n- Max size: 10 MB total per request (the whole body, across all images), not per image\n- Required documents: `id_front`, `id_back` (if applicable), `selfie`\n- Encoding: Base64\n\nUse the `documentType` field: `document` for government ID images (front and back),\n`selfie` for the selfie verification photo.\n\nSubmitted documents are reviewed by Etherfuse admins before approval; you'll receive a\n`kyc_updated` webhook when the status changes.\n\n**Sandbox auto-approval:** in sandbox, a `personal` customer auto-approves once all\nagreements have been signed, with no manual review. Uploading documents is a required step in\nthe programmatic flow, but does not by itself approve the customer; approval lands after\nagreement signing, at which point a `kyc_updated` webhook fires. This is sandbox-only; production\nstill requires manual review.\n\n**Authentication:** use your partner API key. This is a server-side call and cannot be made from a browser.\n\n**documentType** is `document` or `selfie` only. There is no `proof_of_address` type: the customer's address comes from the identity submitted to `POST /ramp/customer/{customer_id}/kyc`, not from a document. Send `document` and `selfie` as separate requests; multiple images of the same type can share one request. Re-submitting a documentType appends new images and does not overwrite a prior upload.\n\n**Image handling:** Etherfuse forwards your image bytes to the identity-verification provider as-is. Stripping EXIF or re-encoding is accepted on our side, but the provider's OCR, face-match, and liveness checks run on those exact bytes, so lossy re-encoding or dropping EXIF orientation can degrade results. Forward originals when you can; if you must scrub metadata, do it losslessly and preserve orientation.",
                "operationId": "upload_kyc_documents",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer (child org) ID. Must belong to the caller's organization or a direct child.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UploadKycDocumentsRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "KYC documents uploaded",
                        "content": {
                            "application/json": {
                                "schema": {},
                                "example": {
                                    "message": "Documents uploaded for review",
                                    "status": "proposed"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Customer not found"
                    }
                }
            }
        },
        "/ramp/customer/{customer_id}/orders": {
            "get": {
                "tags": [
                    "Orders"
                ],
                "summary": "List customer orders",
                "description": "Returns the first page of orders for a specific customer with defaults (pageSize 30,\npageNumber 0, no filters). Use the POST variant for pagination and date filtering.\n\nReturns on/off-ramp orders only — swaps are not included. Track swaps via `swap_updated` webhooks.",
                "operationId": "list_customer_orders",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer (child org) ID. Must belong to the caller's organization or a direct child.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated orders",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedOrders"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Customer not found"
                    }
                }
            },
            "post": {
                "tags": [
                    "Orders"
                ],
                "summary": "Search customer orders",
                "description": "Retrieves orders for a specific customer. The request body is optional — omitting it\nreturns the first page with defaults (pageSize 30, pageNumber 0, no filters).\n\nReturns on/off-ramp orders only — swaps are not included. Track swaps via `swap_updated` webhooks.",
                "operationId": "get_customer_orders",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer (child org) ID. Must belong to the caller's organization or a direct child.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PagedRequest_DateRangeFilter"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Paginated orders",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedOrders"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Customer not found"
                    }
                }
            }
        },
        "/ramp/customer/{customer_id}/wallet": {
            "post": {
                "tags": [
                    "Wallets"
                ],
                "summary": "Register customer wallet",
                "description": "Registers a crypto wallet for a customer that belongs to the caller's organization or a\ndirect child organization. Mirrors `POST /ramp/wallet` but scoped\nto a specific customer within the caller's org hierarchy.\n\nThis endpoint only accepts **bring-your-own (external)** wallets (`publicKey` + `blockchain`). Embedded-wallet provisioning is not supported for customer wallets. Use `POST /ramp/wallet` for the organization instead.\n\nIf the wallet was previously soft-deleted, it is restored. Optionally claims ownership of\nthe wallet on behalf of the customer's organization.\n\nIdempotent: registering an already-active wallet returns the existing record.",
                "operationId": "register_customer_wallet",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer (child org) ID. Must belong to the caller's organization or a direct child.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/RegisterWalletExternal"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "The registered wallet",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Wallet"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Customer not found"
                    }
                }
            }
        },
        "/ramp/customer/{customer_id}/wallets": {
            "get": {
                "tags": [
                    "Wallets"
                ],
                "summary": "List customer wallets",
                "description": "Returns the first page of crypto wallets for a specific customer with defaults\n(pageSize 30, pageNumber 0, no filters). Use the POST variant for pagination and\ndate filtering.",
                "operationId": "list_customer_crypto_wallets",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer (child org) ID. Must belong to the caller's organization or a direct child.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated crypto wallets",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedWallets"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Customer not found"
                    }
                }
            },
            "post": {
                "tags": [
                    "Wallets"
                ],
                "summary": "Search customer wallets",
                "description": "Retrieves crypto wallets for a specific customer. The request body is optional —\nomitting it returns the first page with defaults (pageSize 30, pageNumber 0, no filters).",
                "operationId": "get_customer_crypto_wallets",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer (child org) ID. Must belong to the caller's organization or a direct child.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PagedRequest_DateRangeFilter"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Paginated crypto wallets",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedWallets"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Customer not found"
                    }
                }
            }
        },
        "/ramp/customers": {
            "get": {
                "tags": [
                    "Customers"
                ],
                "summary": "List customers",
                "description": "Returns the first page of customers with defaults (pageSize 30, pageNumber 0, no\nfilters). Use the POST variant for pagination and date filtering.",
                "operationId": "list_customers",
                "responses": {
                    "200": {
                        "description": "Paginated customers",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedCustomers"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Customers"
                ],
                "summary": "Search customers",
                "description": "Retrieves a paginated list of customers. The request body is optional — omitting it\nreturns the first page with defaults (pageSize 30, pageNumber 0, no filters).",
                "operationId": "get_customers",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PagedRequest_DateRangeFilter"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Paginated customers",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedCustomers"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/ramp/evm/approve": {
            "post": {
                "tags": [
                    "Sponsored"
                ],
                "summary": "Approve EVM token",
                "description": "Generates an unsigned ERC20 `approve()` transaction that enables gasless\nofframps on EVM chains. When enabled for your organization, EVM offramp\ntransactions no longer require the user to hold native gas tokens (e.g. ETH on\nBase) — Etherfuse covers the bridging cost and bundles it into the offramp fee.\n\n**This approval must be completed before creating an offramp order** via\n`POST /ramp/order` for EVM wallets with this feature enabled; otherwise the\nofframp transaction fails on-chain.\n\n**Prerequisites:**\n- The feature must be enabled for your organization (contact Etherfuse).\n- The user must have a registered EVM wallet on a supported chain.\n\n**Flow:**\n1. Call this endpoint to get the approval transaction.\n2. Have the user sign and submit it in their wallet.\n3. Once confirmed, create the offramp order via `POST /ramp/order`.\n\n**Approval amount:** omit `amount` (recommended) to approve an unlimited amount\nonce per token per chain; or pass `amount` in base units to approve a specific\namount (consumed after each offramp). If a sufficient allowance already exists,\nthe response has `\"transaction\": null`.",
                "operationId": "evm_approve_proxy",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/EvmApprovePayload"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Approval transaction, or `transaction: null` if already approved",
                        "content": {
                            "application/json": {
                                "schema": {},
                                "examples": {
                                    "already_approved": {
                                        "summary": "Already approved",
                                        "value": {
                                            "currentAllowance": "115792089237316195423570985008687907853269984665640564039457584007913129639935",
                                            "message": "Already approved — no transaction needed",
                                            "transaction": null
                                        }
                                    },
                                    "needs_approval": {
                                        "summary": "Approval needed",
                                        "value": {
                                            "message": "Approve transaction for gasless offramps on base",
                                            "transaction": "{\"to\":\"0xcC77c598...\",\"data\":\"0x095ea7b3...\",\"value\":\"0\",\"chainId\":84532}"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Feature not enabled on this chain, or invalid wallet address"
                    }
                }
            }
        },
        "/ramp/me": {
            "get": {
                "tags": [
                    "Organizations"
                ],
                "summary": "Get organization",
                "description": "Returns the identity of the organization associated with the current API key. Use the response `id` as `customerId` on `POST /ramp/quote` when you transact as your own org.",
                "operationId": "get_me",
                "responses": {
                    "200": {
                        "description": "The authenticated organization",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/MeResponse"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Organization not found"
                    }
                }
            }
        },
        "/ramp/onboarding-url": {
            "post": {
                "tags": [
                    "Onboarding"
                ],
                "summary": "Generate onboarding URL",
                "description": "Generates a presigned URL for customer onboarding. If the customer does not exist, it\nwill be created. This is the primary endpoint for creating customers: you generate a\nUUID for `customerId` and `bankAccountId`, and Etherfuse creates the customer and bank\naccount records associated with your organization.\n\nUpon visiting the URL, the customer has 15 minutes to complete onboarding (KYC\nverification and bank account linking).\n\n## Personal organizations only\n\nThis endpoint always creates a **personal** organization — it forces individual KYC.\nThere is no `accountType` field; pass `business` orgs through\n`POST /ramp/organization` instead.\n\n## userInfo\n\nPass `userInfo` with the end user's email and display name. When provided, Etherfuse\npre-creates the user record so the customer's eventual sign-in attaches to the right\nuser and we can email them on status changes (KYC approved/rejected, bank account\nverified, etc.). `userInfo` is currently optional but **will become required** in a\nfuture release — start sending it now.\n\n## Authenticating as the customer\n\nIf the customer signs in with a JWT (see [JWT User Authentication](/guides/jwt-authentication)), use the **same** value for `customerId` as the JWT `sub`. The shared id links the customer record to the user who signs in.",
                "operationId": "generate_onboarding_url",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/GenerateOnboardingUrlPayload"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "A presigned onboarding URL",
                        "content": {
                            "application/json": {
                                "schema": {},
                                "example": {
                                    "presigned_url": "https://api.sand.etherfuse.com/onboarding?org_id=a1b2c3d4-...&customer_id=a1b2c3d4-...&expires=1748345400&signature=..."
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid request"
                    },
                    "409": {
                        "description": "The `publicKey` is already attached to another customer of your organization. The body names the existing customer id. On retries, reuse the same `customerId` (the call is idempotent for a customer you own) instead of generating a new one.",
                        "content": {
                            "text/plain": {
                                "schema": {
                                    "type": "string"
                                },
                                "example": "You have already added user with this address, see org: b45a5a15-3e4b-4e92-9167-635dd7e95252"
                            }
                        }
                    }
                }
            }
        },
        "/ramp/onboarding/bank-accounts": {
            "post": {
                "tags": [
                    "Onboarding"
                ],
                "summary": "Get onboarding bank accounts",
                "description": "Resolves the customer from a valid presigned onboarding URL and returns\ntheir bank accounts. Public — no API key required.",
                "operationId": "get_onboarding_bank_accounts",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PresignedUrlPayload"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "The customer's bank accounts",
                        "content": {
                            "application/json": {
                                "schema": {},
                                "example": {
                                    "bank_accounts": [
                                        {
                                            "accountLabel": "Ana's SPEI account",
                                            "compliant": true,
                                            "currency": "MXN",
                                            "internalAccountId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
                                            "organizationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                                            "role": "owner",
                                            "status": "active"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid or expired presigned URL"
                    }
                },
                "security": [
                    {}
                ]
            }
        },
        "/ramp/order": {
            "post": {
                "tags": [
                    "Orders"
                ],
                "summary": "Create order",
                "description": "Creates a new order for crypto/fiat conversion using a previously created quote.\n\n**Flow:**\n1. First, call `POST /ramp/quote` to get pricing and create a quote.\n2. Then, call this endpoint with the `quoteId` to execute the order.\n\nThe order inherits the blockchain, direction (onramp/offramp), and amounts from the\nquote. Quotes expire after 2 minutes, so create the order promptly after getting the quote.\n\n**Wallet resolution:** provide either `publicKey` or `cryptoWalletId` (or both). When\n`cryptoWalletId` is provided (typical for embedded wallets), `publicKey`, `blockchain`,\n`direction`, and amount fields are optional — they are derived from the quote and wallet record.\n\nFor onramps, the bank account must belong to your organization or a child organization.",
                "operationId": "order",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateOrderPayload"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "The created order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/CreateOrderResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid request or missing/expired quote"
                    },
                    "409": {
                        "description": "A pending onramp order already exists for this bank account and amount"
                    }
                }
            }
        },
        "/ramp/order/{order_id}": {
            "get": {
                "tags": [
                    "Orders"
                ],
                "summary": "Get order",
                "description": "Retrieves details for a specific order accessible to your API key.",
                "operationId": "get_order",
                "parameters": [
                    {
                        "name": "order_id",
                        "in": "path",
                        "description": "The order ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Order not found"
                    }
                }
            }
        },
        "/ramp/order/{order_id}/cancel": {
            "post": {
                "tags": [
                    "Orders"
                ],
                "summary": "Cancel order",
                "description": "Cancels an order that is in `created` status. Only orders accessible to your API key\ncan be canceled.\n\nOrders left in `created` (unfunded) are also **auto-canceled after 24 hours**, so you don't need to cancel abandoned orders manually.",
                "operationId": "cancel_order_request",
                "parameters": [
                    {
                        "name": "order_id",
                        "in": "path",
                        "description": "The order ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Order cancellation requested"
                    },
                    "400": {
                        "description": "Order cannot be canceled"
                    },
                    "403": {
                        "description": "Not authorized to cancel this order"
                    },
                    "404": {
                        "description": "Order not found or not in a cancelable state"
                    }
                }
            }
        },
        "/ramp/order/{order_id}/regenerate_tx": {
            "post": {
                "tags": [
                    "Orders"
                ],
                "summary": "Regenerate tx",
                "description": "Regenerates a pre-built transaction for an order.\n\n**Offramp orders** (status `Created`): the new transaction is sent over the webhook\nasynchronously. Returns `202 Accepted`.\n\n**Stellar onramp orders with claimable balances** (status `Completed`): if the stored\nclaim transaction has a stale sequence number (e.g. the user transacted on Stellar\nbefore claiming), this rebuilds the unsigned XDR with a fresh sequence number and\nreturns it synchronously, also updating the order's `stellarClaimTransaction` field.\nReturns `200` with the fresh XDR in the body.",
                "operationId": "regenerate_tx",
                "parameters": [
                    {
                        "name": "order_id",
                        "in": "path",
                        "description": "The order ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A regenerated Stellar claim transaction"
                    },
                    "202": {
                        "description": "Regeneration accepted"
                    }
                }
            }
        },
        "/ramp/order/{order_id}/approvals": {
            "get": {
                "tags": [
                    "Orders"
                ],
                "summary": "Get order approval",
                "description": "Returns the pending embedded-wallet approval for an order, if one is awaiting the\nowner's signature. A non-custodial (embedded) wallet can't be signed by Etherfuse\nalone: we build the transaction and the partner-held owner key must approve it.\n\nThe `approvalMessage` bytes are built fresh on each read so they are current when\nsigned. Sign them with the owner's key and submit the signature to\n`POST /ramp/order/{order_id}/approvals`.",
                "operationId": "get_order_approvals",
                "parameters": [
                    {
                        "name": "order_id",
                        "in": "path",
                        "description": "The order ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The pending approval packet",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "approvalMessageId",
                                        "approvalMessage"
                                    ],
                                    "properties": {
                                        "approvalMessageId": {
                                            "type": "string",
                                            "format": "uuid",
                                            "description": "Identifies the proposal being approved. Echoed back on submit so a superseded proposal (re-proposed on expiry) is rejected as stale."
                                        },
                                        "approvalMessage": {
                                            "type": "string",
                                            "description": "The exact bytes the owner signs with their key. Built fresh on each read so the request is current when signed; submitted back verbatim alongside the signature."
                                        },
                                        "summary": {
                                            "type": "string",
                                            "description": "Human-readable description of what is being approved. Present only when set."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No pending approval for this order (or order not found / not visible to your API key)"
                    }
                }
            },
            "post": {
                "tags": [
                    "Orders"
                ],
                "summary": "Submit order approval",
                "description": "Submits the owner's approval for an embedded-wallet order transaction. Sign the\n`approvalMessage` from the order's `approval` with the owner's P-256 key and submit\nthe signature as a **hex string** (Turnkey stamp envelopes are not accepted). One signature per call; an M-of-N quorum is a\nseparate call per signer.\n\nThe `approvalMessage` MUST be byte-identical to what was signed and the\n`approvalMessageId` MUST match the order's current approval, or the call is\nrejected as stale. Server-side signers typically output ~142-character DER-wrapped\nhex; browser WebCrypto outputs 128-character raw `r‖s` hex. Either layout is\naccepted. Invalid hex, wrong length, or a signature that does not verify over\n`approvalMessage` is rejected synchronously with `400`.",
                "operationId": "submit_order_approval",
                "parameters": [
                    {
                        "name": "order_id",
                        "in": "path",
                        "description": "The order ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "approvalMessageId",
                                    "approvalMessage",
                                    "signature"
                                ],
                                "properties": {
                                    "approvalMessageId": {
                                        "type": "string",
                                        "format": "uuid",
                                        "description": "The `approvalMessageId` from the order's `approval`. Echoed back to guard against approving a superseded proposal: a stale id is rejected and the caller re-reads the order for the current one."
                                    },
                                    "approvalMessage": {
                                        "type": "string",
                                        "description": "The exact `approvalMessage` bytes the owner signed, byte-identical to what was signed. Validated against the pending proposal."
                                    },
                                    "signature": {
                                        "type": "string",
                                        "description": "ECDSA P-256 signature over the `approvalMessage`, as a hex string. Most server-side signers output DER-wrapped hex (~142 characters, often starts with `30`); browser WebCrypto outputs raw `r‖s` as 128 hex characters. Either layout is accepted. See the worked example in [Embedded Wallets](/guides/embedded-wallets#sign-the-approval)."
                                    },
                                    "publicKey": {
                                        "type": "string",
                                        "description": "Optional compressed SEC1 signer public key. When omitted, the wallet's registered `signerPublicKey` is used. When provided, it must match."
                                    }
                                }
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Approval accepted",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "approvalMessageId",
                                        "completed"
                                    ],
                                    "properties": {
                                        "approvalMessageId": {
                                            "type": "string",
                                            "format": "uuid",
                                            "description": "Echoed from the request."
                                        },
                                        "completed": {
                                            "type": "boolean",
                                            "description": "Whether the embedded-wallet transaction is now fully approved. Embedded wallets use a single owner key today, so a successful `200` always returns `true`."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid signature format or length, signature does not verify over approvalMessage, publicKey mismatch, or approvalMessage does not match the pending proposal"
                    },
                    "404": {
                        "description": "Order not found or not visible to your API key"
                    },
                    "409": {
                        "description": "The order is dead (canceled/refunded, nothing to approve), or the `approvalMessageId` is stale; re-read the order for the current approval"
                    },
                    "410": {
                        "description": "The proposal expired and was retired; a replacement is minted and surfaces on the order like any refresh"
                    }
                }
            }
        },
        "/ramp/ws-api-token": {
            "post": {
                "tags": [
                    "WebSocket"
                ],
                "summary": "Mint WebSocket token",
                "description": "Mints a short-lived, org-scoped WebSocket authentication token. Use it to\nauthenticate a WebSocket connection for live order and status updates. The org is\ntaken from your verified API key, so the token is org-scoped and user-less.",
                "operationId": "get_ws_api_token",
                "responses": {
                    "200": {
                        "description": "A short-lived WebSocket auth token",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "token"
                                    ],
                                    "properties": {
                                        "token": {
                                            "type": "string",
                                            "description": "Short-lived WebSocket auth token; org-scoped and user-less."
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/ramp/ws": {
            "get": {
                "tags": [
                    "WebSocket"
                ],
                "summary": "Connect to the live update stream",
                "description": "Opens a WebSocket that streams `order_updated` events for your organization. Authenticate with a token from `POST /ramp/ws-api-token` passed as the `token` query parameter; a browser cannot set an `Authorization` header on a WebSocket upgrade. The token is single-use and expires in 30 seconds. Each frame signals that an order changed; re-read the order with `GET /ramp/order/{order_id}` for the authoritative state, including any pending approval package. Connect over `wss` (for example `wss://api.etherfuse.com/ramp/ws?token=...`).",
                "operationId": "ramp_ws_stream",
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "description": "Single-use, org-scoped token from POST /ramp/ws-api-token. Expires in 30 seconds.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "101": {
                        "description": "Switching Protocols: the connection is upgraded to a WebSocket and streams order_updated events."
                    },
                    "400": {
                        "description": "Missing token query parameter."
                    }
                }
            }
        },
        "/ramp/orders": {
            "get": {
                "tags": [
                    "Orders"
                ],
                "summary": "List orders",
                "description": "Returns the first page of orders with defaults (pageSize 30, pageNumber 0, no filters).\nUse the POST variant for pagination and date filtering.\n\nReturns on/off-ramp orders only — swaps are not included. Track swaps via `swap_updated` webhooks.",
                "operationId": "list_orders",
                "responses": {
                    "200": {
                        "description": "Paginated orders",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedOrders"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Orders"
                ],
                "summary": "Search orders",
                "description": "Retrieves a paginated list of orders accessible to your API key. The request body is\noptional — omitting it returns the first page with defaults (pageSize 30, pageNumber 0,\nno filters).\n\nReturns on/off-ramp orders only — swaps are not included. Track swaps via `swap_updated` webhooks.",
                "operationId": "get_orders",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PagedRequest_DateRangeFilter"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Paginated orders",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedOrders"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/ramp/organization": {
            "post": {
                "tags": [
                    "Organizations"
                ],
                "summary": "Create child org",
                "description": "Creates a new child organization under the caller's organization. The child org is\ncreated in an unapproved state; approval happens separately through the Etherfuse\napproval workflow.\n\nCreate the org here first, then add wallets and bank accounts as separate steps with\n[Register customer wallet](/api-reference/wallets/register-customer-wallet) and\n[Create bank account](/api-reference/bank-accounts/create-bank-account-api). Handling each\nstep on its own gives clearer error messages and lets you guide customers through any\nfailures without re-sending everything.\n\nIf the provided `id` collides with an existing record, the request returns 409. All\nfields are optional: sending an empty body `{}` creates a bare organization.\n\n## Account types\n\nEvery organization has an `accountType` of either `personal` (an individual customer\ncompleting KYC) or `business` (a company completing KYB). The two are handled differently\ndownstream: personal orgs go through individual KYC and Plaid; business orgs go through\nKYB and skip per-wallet compliance.\n\n- `personal`: pass `userInfo` so the end user records are created and we can email them on status changes.\n- `business`: `userInfo` is rejected (business orgs do not have a single end user).\n\n`accountType` is currently optional and defaults to `personal`. **It will become required\nin a future release.** Start sending it explicitly now.\n\n## Authenticating as the customer\n\nFor a **personal** org, if the customer signs in with a JWT (see [JWT User Authentication](/guides/jwt-authentication)), pass the **same** id as the JWT `sub` here in `id`; the shared id ties the org to that user. A **business** org is different: it has its own id and isn't tied to one user, and `sub` identifies a person, so never reuse a customer's `sub`/id as a business org `id` (that returns 409). The people who run its KYB sign in with their own `sub` and select the business via `?org=<id>` on launch.\n\n## Business onboarding\n\nFor a **business** org, pass `country` (ISO code) to generate the KYB onboarding at creation so the user drops straight into KYB; omit it and they're prompted for their country when they begin. `country` is rejected on personal orgs.\n\nMembers are added separately: create the org first, then add the people who complete its KYB with [Add organization member](/api-reference/organizations/add-organization-member).",
                "operationId": "create_child_organization",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateChildOrgRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "201": {
                        "description": "The created child organization",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/CreateChildOrgResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid request"
                    },
                    "409": {
                        "description": "A provided UUID collides with an existing record, or the `id` already identifies a customer and `accountType` is `business` (a customer id cannot be reused as a business organization)."
                    }
                }
            }
        },
        "/ramp/organization/{id}/member": {
            "post": {
                "tags": [
                    "Organizations"
                ],
                "summary": "Add organization member",
                "description": "Adds a member to a business organization, by `email` or `customerId`.\n\n- **By `email`**: invite or add by email address. If the email matches a user who has already signed in through your JWT, they become a member immediately; otherwise a pending invite is created and accepted automatically the first time that email signs in via your `kyb` JWT. Pass `emailInviteLink` to have Etherfuse email them an invite URL you control, or omit it to create the invite silently and notify them yourself. Use this when you don't have the person's `customerId` yet, or when you want Etherfuse to send the invite.\n- **By `customerId`**: add an existing customer directly by their `sub`; no email is sent. The `customerId` only exists once that person has exchanged a JWT via [POST /auth/token](/api-reference/authentication/exchange-a-partner-jwt) (or been launched) at least once: an unknown `sub` returns 404, and a business org id (service account) is rejected.\n\nRe-adding someone who was previously removed revives them. The target org must be a business org you own (your own org or a direct child).\n\nThe response has the same shape as [List organization members](/api-reference/organizations/list-organization-members): a person added immediately appears under `members`; an emailed invite appears under `invited`.",
                "operationId": "partner_add_member",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "The business organization to add the member to (your own org or a direct child).",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/AddMemberRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "The added member or pending invite",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/MembersResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid request: missing or both of `email`/`customerId`, missing `role`, the org is not a business org, or `customerId` refers to a service account"
                    },
                    "403": {
                        "description": "Not permitted to manage this organization"
                    },
                    "404": {
                        "description": "Organization not found, or no customer exists for the given `customerId`"
                    },
                    "409": {
                        "description": "The customer is already an active member"
                    }
                }
            },
            "get": {
                "tags": [
                    "Organizations"
                ],
                "summary": "List organization members",
                "description": "Lists the active members and pending invites for a business organization. The org's own service account is never included.\n\nThe target org must be a business org you own (your own org or a direct child).",
                "operationId": "partner_list_members",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "The business organization.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Active members and pending invites",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/MembersResponse"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Not permitted to view this organization"
                    },
                    "404": {
                        "description": "Organization not found"
                    }
                }
            }
        },
        "/ramp/organization/{id}/member/{customer_id}": {
            "delete": {
                "tags": [
                    "Organizations"
                ],
                "summary": "Remove organization member",
                "description": "Removes an active member from a business organization by their `customerId` (the JWT `sub`). To revoke a not-yet-accepted email invite, use [Revoke organization invite](/api-reference/organizations/revoke-organization-invite) instead.\n\nThe target org must be a business org you own (your own org or a direct child).",
                "operationId": "partner_remove_member",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "The business organization.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The member's `sub`.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "204": {
                        "description": "Member removed"
                    },
                    "403": {
                        "description": "Not permitted to manage this organization"
                    },
                    "404": {
                        "description": "Organization not found, or no active membership for this `customerId`"
                    }
                }
            }
        },
        "/ramp/organization/{id}/member/invite/{email}": {
            "delete": {
                "tags": [
                    "Organizations"
                ],
                "summary": "Revoke organization invite",
                "description": "Revokes a pending (not-yet-accepted) email invite for a business organization. To remove a member who has already joined, use [Remove organization member](/api-reference/organizations/remove-organization-member) instead.\n\nThe target org must be a business org you own (your own org or a direct child).",
                "operationId": "partner_revoke_invite",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "The business organization.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "email",
                        "in": "path",
                        "description": "The invited email address.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "204": {
                        "description": "Invite revoked"
                    },
                    "403": {
                        "description": "Not permitted to manage this organization"
                    },
                    "404": {
                        "description": "Organization not found, or no pending invite for this email"
                    }
                }
            }
        },
        "/ramp/organization/{id}/kyb/progress": {
            "get": {
                "tags": [
                    "Organizations"
                ],
                "summary": "Get KYB progress",
                "description": "Returns KYB progress for a business organization so you can track your customer's verification without portal access: requirement completion counts, the overall status, and the approval timestamp.\n\nThe target org must be a business org you own (your own org or a direct child).",
                "operationId": "partner_get_kyb_progress",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "The business organization.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "KYB progress for the organization",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/KybProgressResponse"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Not permitted to view this organization"
                    },
                    "404": {
                        "description": "Organization not found"
                    }
                }
            }
        },
        "/ramp/customer/{customer_id}/organization": {
            "get": {
                "tags": [
                    "Customers"
                ],
                "summary": "List a customer's organizations",
                "description": "Lists the business organizations a customer belongs to, identified by their `customerId` (the JWT `sub`). This is the reverse of [List organization members](/api-reference/organizations/list-organization-members): that returns the members of one org, this returns the orgs one member is in.\n\nScoped to your own child organizations, so it never reveals another partner's orgs. A `customerId` outside your namespace (or one that isn't a member of any of your orgs) returns an empty array.",
                "operationId": "partner_list_customer_organizations",
                "parameters": [
                    {
                        "name": "customer_id",
                        "in": "path",
                        "description": "The customer's `sub` (the value you put in the JWT `sub`).",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The organizations the customer belongs to",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/MemberOrganizationRecord"
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Caller organization not found"
                    }
                }
            }
        },
        "/ramp/organization/{org_id}/name": {
            "put": {
                "tags": [
                    "Organizations"
                ],
                "summary": "Rename organization",
                "description": "Renames the caller's own organization or a direct child organization. The caller's\norganization is resolved from the API key.\n\nThe target `org_id` must be either the caller's own organization, or a direct child\norganization (where `parent_organization_id` equals the caller's org). Grandchild\norganizations cannot be renamed through this endpoint.",
                "operationId": "rename_org",
                "parameters": [
                    {
                        "name": "org_id",
                        "in": "path",
                        "description": "The organization to rename — must be the caller's own org or a direct child (grandchildren cannot be renamed).",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/RenameOrgRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "The renamed organization",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RenameOrgResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid name — empty, whitespace-only, or exceeds 200 characters"
                    },
                    "403": {
                        "description": "Not permitted to rename this organization"
                    },
                    "404": {
                        "description": "Organization not found"
                    }
                }
            }
        },
        "/ramp/partner-fee": {
            "put": {
                "tags": [
                    "Organizations"
                ],
                "summary": "Set partner fee",
                "description": "Sets the default partner fee (in basis points) for the caller's organization. The\ntarget organization is resolved from the API key — the fee always applies to the org\nthat owns the key. The fee is capped at 500 bps (5.00%).\n\nTo configure a different org (for example, a child organization), call this endpoint\nusing an API key issued for that org.\n\nOnce set, this default applies to all new quotes for the organization unless overridden\nper-quote via the `partnerFeeBps` field on the quote request.\n\nPartner fees are layered on top of platform fees and settled offline via finance —\nthere is no on-chain component.",
                "operationId": "set_partner_fee",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SetPartnerFeeRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "The updated default partner fee (echoes the new value)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SetPartnerFeeRequest"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid value — must be between 0 and 500"
                    }
                }
            }
        },
        "/ramp/quote": {
            "post": {
                "tags": [
                    "Quotes"
                ],
                "summary": "Get quote",
                "description": "Retrieves a quote for converting between assets. Supports three quote types:\n- **Onramp**: fiat → crypto (`sourceAsset`: fiat currency code, `targetAsset`: asset identifier)\n- **Offramp**: crypto → fiat (`sourceAsset`: asset identifier, `targetAsset`: fiat currency code)\n- **Swap**: crypto → crypto (`sourceAsset`: asset identifier, `targetAsset`: asset identifier)\n\n**Finding supported assets:** use `GET /ramp/assets` to list the supported\nassets for quotes, ramps, and swaps, along with their `identifier` values.\n\nCrypto assets use the `CODE:ISSUER` format (e.g.\n`USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN`) — use the `identifier`\nfrom the `/ramp/assets` response. Fiat currencies use standard codes (e.g. `MXN`). The\nquote includes exchange rates, fees, and expiration information.\n\n**`customerId`:** the org the quote is for. When you transact as your own org, use the `id` from `GET /ramp/me`. For child customers, use their org UUID.",
                "operationId": "quote",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ApiCreateQuotePayload"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "The created quote",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/CreateQuoteResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid request"
                    }
                }
            }
        },
        "/ramp/swap": {
            "post": {
                "tags": [
                    "Swaps"
                ],
                "summary": "Swap assets",
                "description": "Swaps two different crypto assets. Asynchronous — returns `200 OK` with an\nempty body; track progress via webhooks.\n\n**Flow:**\n1. Call `POST /ramp/quote` with `quoteAssets.type: \"swap\"` to get pricing.\n2. Call this endpoint with the returned `quoteId` to initiate the swap.\n3. Listen for `swap_updated` webhook events to track progress and receive the transaction to sign.\n\n**Webhooks:** because the response body is empty, register a `swap_updated` webhook\n(via `POST /ramp/webhook`) to receive `SwapResponse` payloads as the swap\nprogresses: `swap_created → swap_funded → swap_completed` (or `swap_failed`).",
                "operationId": "swap",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateSwapPayload"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Swap accepted; track completion via `swap_updated` webhooks"
                    },
                    "400": {
                        "description": "Invalid request or missing/expired quote"
                    }
                }
            }
        },
        "/ramp/swap/{order_id}/regenerate_tx": {
            "post": {
                "tags": [
                    "Swaps"
                ],
                "summary": "Regenerate swap tx",
                "description": "Regenerates a transaction for a swap — useful when the transaction was not submitted\nbefore expiration. The updated transaction is returned via the `swap_updated` webhook.\nReturns `202 Accepted` if successful.",
                "operationId": "regenerate_swap_tx",
                "parameters": [
                    {
                        "name": "order_id",
                        "in": "path",
                        "description": "The order ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "202": {
                        "description": "Swap transaction regeneration accepted"
                    }
                }
            }
        },
        "/ramp/wallet": {
            "post": {
                "tags": [
                    "Wallets"
                ],
                "summary": "Register wallet",
                "description": "Registers a crypto wallet for the authenticated organization. If the wallet was\npreviously soft-deleted, it is restored.\n\nOptionally claims ownership of the wallet on behalf of the organization. When an\napproved (KYB'd) organization claims ownership, that wallet is treated as compliant\nwithout requiring individual KYC verification.\n\nIdempotent — registering an already-active wallet returns the existing record.",
                "operationId": "register_wallet",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/RegisterWalletRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "The registered wallet",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Wallet"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Organization not found"
                    }
                }
            }
        },
        "/ramp/wallet/{wallet_id}": {
            "get": {
                "tags": [
                    "Wallets"
                ],
                "summary": "Get wallet",
                "description": "Retrieves details for a specific crypto wallet accessible to your API key.",
                "operationId": "get_crypto_wallet",
                "parameters": [
                    {
                        "name": "wallet_id",
                        "in": "path",
                        "description": "The wallet ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The crypto wallet",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Wallet"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Wallet not found"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Wallets"
                ],
                "summary": "Delete wallet",
                "description": "Soft-deletes a crypto wallet and releases any claimed ownership associated with it. The\nwallet can be re-registered later via `POST /ramp/wallet`.",
                "operationId": "delete_wallet",
                "parameters": [
                    {
                        "name": "wallet_id",
                        "in": "path",
                        "description": "The wallet ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Wallet deleted"
                    },
                    "404": {
                        "description": "Wallet not found"
                    }
                }
            }
        },
        "/ramp/wallets": {
            "get": {
                "tags": [
                    "Wallets"
                ],
                "summary": "List wallets",
                "description": "Returns the first page of crypto wallets with defaults (pageSize 30, pageNumber 0, no\nfilters). Use the POST variant for pagination and date filtering.",
                "operationId": "list_crypto_wallets",
                "responses": {
                    "200": {
                        "description": "Paginated crypto wallets",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedWallets"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Wallets"
                ],
                "summary": "Search wallets",
                "description": "Retrieves a paginated list of crypto wallets. The request body is optional — omitting it\nreturns the first page with defaults (pageSize 30, pageNumber 0, no filters).",
                "operationId": "get_crypto_wallets",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PagedRequest_DateRangeFilter"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Paginated crypto wallets",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedWallets"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/ramp/webhook": {
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Create webhook",
                "description": "The response includes a one-time signing `secret` used to verify webhook\ndeliveries; store it securely.",
                "operationId": "create_webhook",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateWebhookRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "201": {
                        "description": "The created webhook",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/CreateWebhookResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid URL"
                    }
                }
            }
        },
        "/ramp/webhook/{webhook_id}": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Get webhook",
                "operationId": "get_webhook",
                "parameters": [
                    {
                        "name": "webhook_id",
                        "in": "path",
                        "description": "The webhook ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The webhook",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Webhook"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Webhook not found"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Delete webhook",
                "operationId": "delete_webhook",
                "parameters": [
                    {
                        "name": "webhook_id",
                        "in": "path",
                        "description": "The webhook ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "204": {
                        "description": "Webhook deleted"
                    },
                    "404": {
                        "description": "Webhook not found"
                    }
                }
            }
        },
        "/ramp/webhooks": {
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "List webhooks",
                "operationId": "get_webhooks",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PagedRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Paginated webhooks",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PagedWebhooks"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "AuthTokenRequest": {
                "type": "object",
                "required": [
                    "grant_type"
                ],
                "properties": {
                    "grant_type": {
                        "type": "string",
                        "enum": [
                            "urn:ietf:params:oauth:grant-type:jwt-bearer",
                            "refresh_token"
                        ],
                        "description": "The OAuth 2.0 grant type."
                    },
                    "assertion": {
                        "type": "string",
                        "description": "The partner-signed JWT. Required when `grant_type` is `urn:ietf:params:oauth:grant-type:jwt-bearer`."
                    },
                    "refresh_token": {
                        "type": "string",
                        "description": "A refresh token from a prior exchange. Required when `grant_type` is `refresh_token`."
                    }
                },
                "example": {
                    "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
                    "assertion": "eyJhbGciOiJSUzI1NiIsImtpZCI6Imt..."
                }
            },
            "AuthTokenResponse": {
                "type": "object",
                "required": [
                    "access_token",
                    "token_type",
                    "expires_in",
                    "refresh_token"
                ],
                "properties": {
                    "access_token": {
                        "type": "string",
                        "description": "Bearer token for the Ramp API. Send it as `Authorization: Bearer <access_token>`."
                    },
                    "token_type": {
                        "type": "string",
                        "example": "Bearer"
                    },
                    "expires_in": {
                        "type": "integer",
                        "description": "Access token lifetime, in seconds.",
                        "example": 3600
                    },
                    "refresh_token": {
                        "type": "string",
                        "description": "Use with the `refresh_token` grant to obtain a fresh access token without re-signing a JWT."
                    },
                    "scope": {
                        "type": "string",
                        "description": "The granted scope, echoed from the JWT's `scope` claim. Omitted for unrestricted (non-partner) sessions."
                    }
                }
            },
            "AuthErrorResponse": {
                "type": "object",
                "description": "OAuth 2.0 error response ([RFC 6749 §5.2](https://www.rfc-editor.org/rfc/rfc6749#section-5.2)).",
                "required": [
                    "error"
                ],
                "properties": {
                    "error": {
                        "type": "string",
                        "enum": [
                            "invalid_request",
                            "invalid_client",
                            "invalid_grant",
                            "invalid_scope",
                            "unauthorized_client",
                            "unsupported_grant_type",
                            "server_error"
                        ]
                    },
                    "error_description": {
                        "type": "string"
                    },
                    "error_uri": {
                        "type": "string"
                    }
                }
            },
            "AuthLaunchRequest": {
                "type": "object",
                "required": [
                    "grant_type",
                    "target"
                ],
                "properties": {
                    "grant_type": {
                        "type": "string",
                        "enum": [
                            "urn:ietf:params:oauth:grant-type:jwt-bearer",
                            "refresh_token"
                        ]
                    },
                    "assertion": {
                        "type": "string",
                        "description": "The partner-signed JWT. Required when `grant_type` is `urn:ietf:params:oauth:grant-type:jwt-bearer`."
                    },
                    "refresh_token": {
                        "type": "string",
                        "description": "A `refresh_token` from a prior `POST /auth/token` exchange. Required when `grant_type` is `refresh_token`."
                    },
                    "target": {
                        "type": "string",
                        "description": "App path to land the user on after sign-in. Must be an allowed target. See [User Launch Flows](/guides/user-launch-flows#targets). Any other path is rejected.",
                        "example": "/kyb"
                    },
                    "return_url": {
                        "type": "string",
                        "description": "Optional URL to return the user to when they leave the app."
                    }
                },
                "example": {
                    "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
                    "assertion": "eyJhbGciOiJSUzI1NiIsImtpZCI6Imt...",
                    "target": "/kyb"
                }
            },
            "AccountRegistration": {
                "oneOf": [
                    {
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/PersonalAccountRequest"
                            }
                        ],
                        "title": "Personal (MXN / SPEI)"
                    },
                    {
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/BusinessAccountRequest"
                            }
                        ],
                        "title": "Business (MXN / SPEI)"
                    },
                    {
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/BrlPersonalAccountRequest"
                            }
                        ],
                        "title": "Personal (BRL / PIX)"
                    },
                    {
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/BrlBusinessAccountRequest"
                            }
                        ],
                        "title": "Business (BRL / PIX)"
                    }
                ]
            },
            "AddBankAccountResponse": {
                "type": "object",
                "required": [
                    "accountId",
                    "label",
                    "status",
                    "organizationId"
                ],
                "properties": {
                    "accountId": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "label": {
                        "type": "string"
                    },
                    "organizationId": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "status": {
                        "type": "string"
                    }
                },
                "example": {
                    "accountId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
                    "label": "Ana's SPEI account",
                    "organizationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "status": "active"
                }
            },
            "ApiCreateBankAccountPayload": {
                "type": "object",
                "required": [
                    "account"
                ],
                "properties": {
                    "account": {
                        "$ref": "#/components/schemas/AccountRegistration"
                    },
                    "bankAccountId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid"
                    },
                    "label": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "example": {
                    "account": {
                        "birthCountryIsoCode": "MX",
                        "birthDate": "19900515",
                        "clabe": "646180157000000004",
                        "curp": "GALA900515MDFRPN08",
                        "firstName": "Ana",
                        "maternalLastName": "López",
                        "paternalLastName": "García",
                        "rfc": "GALA900515AB1",
                        "transactionId": "c3d4e5f6-a7b8-9012-cdef-123456789012"
                    },
                    "bankAccountId": "e5f6a7b8-c9d0-1234-efab-345678901234",
                    "label": "Ana's SPEI account"
                }
            },
            "ApiCreateQuotePayload": {
                "type": "object",
                "required": [
                    "quoteId",
                    "customerId",
                    "blockchain",
                    "quoteAssets",
                    "sourceAmount"
                ],
                "properties": {
                    "blockchain": {
                        "$ref": "#/components/schemas/Blockchain",
                        "description": "blockchain identifier (stellar, solana)"
                    },
                    "customerId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Organization the quote is for. Use `GET /ramp/me` → `id` when quoting for your own org; use a child customer's org UUID when quoting on their behalf."
                    },
                    "partnerFeeBps": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "format": "int32",
                        "minimum": 0,
                        "maximum": 500,
                        "description": "Optional partner fee override in basis points (0–500). Applied directly as this quote's partner fee — there is no separate enable step. Resolution order: this per-quote override > your organization's default (partnerFeeDefaultBps) > 0. The resulting partner fee is folded into the quote's feeBps/feeAmount; it is not returned as a separate field on the response."
                    },
                    "quoteAssets": {
                        "$ref": "#/components/schemas/QuoteAssets"
                    },
                    "quoteId": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "sourceAmount": {
                        "type": "string"
                    },
                    "walletAddress": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Optional Stellar wallet address. When provided for Stellar onramps, enables\ntrustline check and setup fee calculation."
                    }
                },
                "example": {
                    "blockchain": "stellar",
                    "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "quoteAssets": {
                        "sourceAsset": "MXN",
                        "targetAsset": "USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5",
                        "type": "onramp"
                    },
                    "quoteId": "3f2a1b0c-9d8e-7f6a-5b4c-3d2e1f0a9b8c",
                    "sourceAmount": "1000",
                    "walletAddress": "GDUKMGUGD3V6VXTU2RLAUM7A2FABLMHCPWTMDHKP7HHJ6FCZKEY4PVWL"
                }
            },
            "BankAccount": {
                "type": "object",
                "required": [
                    "bankAccountId",
                    "customerId",
                    "createdAt",
                    "updatedAt",
                    "currency",
                    "abbrClabe",
                    "compliant",
                    "needsWork",
                    "status"
                ],
                "properties": {
                    "abbrClabe": {
                        "type": "string",
                        "description": "Abbreviated CLABE number for the bank account.",
                        "deprecated": true
                    },
                    "bankAccountId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Unique identifier for the bank account. Must be a valid UUID v4."
                    },
                    "compliant": {
                        "type": "boolean",
                        "description": "Whether the bank account is compliant and can be used for orders. A bank becomes\ncompliant once the customer completes the required identity verification (or the\nowning organization is approved). **While `false`, the customer must complete\nadditional verification before the bank can be used** — launch them into the\nIdentity verification flow (`scope: verification`, `target: /idv`); see [User launch\nflows](/guides/user-launch-flows#identity-verification)."
                    },
                    "createdAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Timestamp when the bank account was created."
                    },
                    "currency": {
                        "type": "string",
                        "description": "Settlement currency (ISO 4217, e.g. `MXN`)."
                    },
                    "customerId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "ID of the customer who owns this bank account."
                    },
                    "deletedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "Timestamp when the bank account was deleted (if applicable)."
                    },
                    "etherfuseDepositClabe": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Etherfuse deposit CLABE number."
                    },
                    "label": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Custom label for the bank account."
                    },
                    "needsWork": {
                        "type": "boolean",
                        "description": "Whether the bank account still needs work (e.g. failed verification) before it\ncan be used for transactions."
                    },
                    "status": {
                        "type": "string",
                        "description": "Current status of the bank account."
                    },
                    "updatedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Timestamp when the bank account was last updated."
                    }
                },
                "example": {
                    "abbrClabe": "•••• 0004",
                    "bankAccountId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
                    "compliant": true,
                    "createdAt": "2026-05-01T14:30:00Z",
                    "currency": "MXN",
                    "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "etherfuseDepositClabe": "646180157000000004",
                    "label": "Ana's SPEI account",
                    "needsWork": false,
                    "status": "active",
                    "updatedAt": "2026-05-02T09:15:00Z"
                }
            },
            "Blockchain": {
                "type": "string",
                "description": "Canonical blockchain enum for API serialization.\nUse this type for JSON APIs and WebSocket messages.\nFor database storage, convert to `BlockchainType`.",
                "enum": [
                    "stellar",
                    "solana",
                    "base",
                    "polygon",
                    "monad"
                ]
            },
            "BlockchainSupplyCachable": {
                "type": "object",
                "description": "Per-chain supply breakdown. Uses string blockchain identifier\n(same pattern as BridgeConfig — API converts to typed enum at boundary).",
                "required": [
                    "blockchain",
                    "tokenIdentifier",
                    "totalSupply"
                ],
                "properties": {
                    "blockchain": {
                        "type": "string",
                        "description": "Chain identifier (e.g. `solana`, `stellar`)."
                    },
                    "notCountedVaultedAmount": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Supply held in vaults and excluded from circulating totals, if any."
                    },
                    "tokenIdentifier": {
                        "type": "string",
                        "description": "Token identifier on this chain (mint address or asset code)."
                    },
                    "totalSupply": {
                        "type": "string",
                        "description": "Total supply on this chain."
                    }
                }
            },
            "BondCostSource": {
                "type": "object",
                "description": "A single FX provider's exchange rate and the bond cost it implies. The\n`sources` map on a bond lets clients run oracle-safety checks across providers.",
                "required": [
                    "exchange_rate",
                    "bond_cost_in_usd",
                    "updated_at"
                ],
                "properties": {
                    "bond_cost_in_usd": {
                        "type": "string",
                        "description": "Bond cost in USD derived from this provider's rate."
                    },
                    "exchange_rate": {
                        "type": "string",
                        "description": "Provider's USD↔currency exchange rate."
                    },
                    "updated_at": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Unix timestamp (seconds) of the provider's last update.",
                        "minimum": 0
                    }
                }
            },
            "BrlBusinessAccountRequest": {
                "type": "object",
                "required": [
                    "transactionId",
                    "name",
                    "cnpj",
                    "pixKey",
                    "pixKeyType"
                ],
                "properties": {
                    "cnpj": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "pixKey": {
                        "type": "string"
                    },
                    "pixKeyType": {
                        "type": "string"
                    },
                    "transactionId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Idempotency key for this bank account registration. Generate a stable UUID and keep it; passing the same value makes the call safe to retry and ensures the account is registered only once. This is a value you supply, not one returned by Etherfuse."
                    }
                }
            },
            "BrlPersonalAccountRequest": {
                "type": "object",
                "required": [
                    "transactionId",
                    "firstName",
                    "lastName",
                    "cpf",
                    "pixKey",
                    "pixKeyType"
                ],
                "properties": {
                    "cpf": {
                        "type": "string"
                    },
                    "firstName": {
                        "type": "string"
                    },
                    "lastName": {
                        "type": "string"
                    },
                    "pixKey": {
                        "type": "string"
                    },
                    "pixKeyType": {
                        "type": "string"
                    },
                    "transactionId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Idempotency key for this bank account registration. Generate a stable UUID and keep it; passing the same value makes the call safe to retry and ensures the account is registered only once. This is a value you supply, not one returned by Etherfuse."
                    }
                }
            },
            "BusinessAccountRequest": {
                "type": "object",
                "required": [
                    "transactionId",
                    "name",
                    "incorporatedDate",
                    "rfc",
                    "clabe"
                ],
                "properties": {
                    "clabe": {
                        "type": "string"
                    },
                    "countryId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Numeric country code (legacy)"
                    },
                    "countryIsoCode": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "ISO 3166-1 alpha-2 code (preferred)"
                    },
                    "incorporatedDate": {
                        "type": "string",
                        "description": "Company incorporation date in `YYYYMMDD` format (8 digits, e.g. `20200101`)."
                    },
                    "name": {
                        "type": "string"
                    },
                    "rfc": {
                        "type": "string",
                        "description": "The company's RFC (Registro Federal de Contribuyentes)."
                    },
                    "transactionId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Idempotency key for this bank account registration. Generate a stable UUID and keep it; passing the same value makes the call safe to retry and ensures the account is registered only once. This is a value you supply, not one returned by Etherfuse."
                    }
                }
            },
            "CorporateData": {
                "type": "object",
                "properties": {
                    "company_name": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "company_purpose": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "folio": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "incorporation_date": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "incorporation_deed": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notary_location": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notary_name": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notary_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "registry_date": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "rfc": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "CorporateDataInfo": {
                "type": "object",
                "properties": {
                    "companyName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "companyPurpose": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "folio": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "incorporationDate": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "incorporationDeed": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notaryLocation": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notaryName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notaryNumber": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "registryDate": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "rfc": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "Country": {
                "type": "object",
                "description": "A known country with its ISO 3166-1 alpha-2 code and common English name.\nThis list is focused on Plaid-supported countries and countries relevant to\nour geo-blocking rules. Plaid returns uppercase alpha-2 codes, but manual\nadmin submissions may use full names or mixed case.",
                "required": [
                    "code",
                    "code3",
                    "name"
                ],
                "properties": {
                    "code": {
                        "type": "string",
                        "description": "ISO 3166-1 alpha-2 code (e.g. `MX`)."
                    },
                    "code3": {
                        "type": "string",
                        "description": "ISO 3166-1 alpha-3 code (e.g. `MEX`)."
                    },
                    "name": {
                        "type": "string",
                        "description": "Common English name (e.g. `Mexico`)."
                    }
                },
                "example": {
                    "code": "MX",
                    "code3": "MEX",
                    "name": "Mexico"
                }
            },
            "CreateBankAccountPayload": {
                "type": "object",
                "required": [
                    "presignedUrl",
                    "account"
                ],
                "properties": {
                    "account": {
                        "$ref": "#/components/schemas/AccountRegistration"
                    },
                    "presignedUrl": {
                        "type": "string"
                    }
                },
                "example": {
                    "account": {
                        "birthCountryIsoCode": "MX",
                        "birthDate": "19900515",
                        "clabe": "646180157000000004",
                        "curp": "GALA900515MDFRPN08",
                        "firstName": "Ana",
                        "maternalLastName": "López",
                        "paternalLastName": "García",
                        "rfc": "GALA900515AB1",
                        "transactionId": "c3d4e5f6-a7b8-9012-cdef-123456789012"
                    },
                    "presignedUrl": "https://api.sand.etherfuse.com/ramp/onboarding/bank-accounts?...&signature=..."
                }
            },
            "CreateChildOrgRequest": {
                "type": "object",
                "properties": {
                    "accountType": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "personal",
                            "business"
                        ],
                        "description": "Whether this org is an individual or a company:\n\n- `personal`: an individual customer completing KYC. Pass `userInfo`.\n- `business`: a company completing KYB. `userInfo` is rejected.\n\nOptional today and defaults to `personal`, but it will become required in a\nfuture release once partners have migrated, so send it explicitly now.",
                        "example": "personal"
                    },
                    "displayName": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The organization's display name: the friendly label shown in UIs and API responses. For a `business` org completing KYB, the legal entity name is captured separately via `legalName`."
                    },
                    "id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid"
                    },
                    "userInfo": {
                        "oneOf": [
                            {
                                "type": "null"
                            },
                            {
                                "$ref": "#/components/schemas/UserInfo",
                                "description": "Optional info about the end user. Required eventually for personal\norgs. Rejected on business orgs (those don't have a single end user)."
                            }
                        ]
                    },
                    "country": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "ISO 3166-1 alpha-2 country code (e.g. `MX`). Business orgs only; rejected on personal orgs. When provided, Etherfuse generates the KYB onboarding at creation, seeding the company entity with this country so the user lands straight in KYB. Omit it and the user is prompted for their country when they begin KYB.",
                        "example": "MX"
                    },
                    "legalName": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Legal entity name for the KYB company entity (e.g. the incorporated name on the company's registry documents). Pass it together with `country` when generating the KYB onboarding at creation; rejected without `country`. Independent of `displayName`: renaming the org does not change the legal name, and vice versa.",
                        "example": "Acme Corporation S.A. de C.V."
                    }
                },
                "example": {
                    "accountType": "personal",
                    "displayName": "Ana García",
                    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "userInfo": {
                        "displayName": "Ana García",
                        "email": "ana@example.com"
                    }
                }
            },
            "CreateChildOrgResponse": {
                "type": "object",
                "required": [
                    "organizationId",
                    "displayName",
                    "accountType"
                ],
                "properties": {
                    "accountType": {
                        "type": "string",
                        "enum": [
                            "business",
                            "personal"
                        ],
                        "description": "Account type of the child organization.",
                        "example": "business"
                    },
                    "displayName": {
                        "type": "string"
                    },
                    "organizationId": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "wallets": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Wallet"
                        },
                        "description": "Wallets registered during organization creation. Empty array omitted from response."
                    },
                    "bankAccount": {
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/BankAccount"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "description": "Bank account created during organization creation, if one was provided in the request. Omitted when not present."
                    }
                },
                "example": {
                    "organizationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "displayName": "Acme Inc.",
                    "accountType": "business"
                }
            },
            "AddMemberRequest": {
                "type": "object",
                "required": [
                    "role"
                ],
                "properties": {
                    "email": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Invite or add a member by email address. If the email matches a user who has already signed in through your JWT, they're added as a member immediately; otherwise a pending invite is created and accepted automatically the first time that email signs in via your `kyb` JWT. Use `email` when you don't have the person's `customerId` yet, or when you want Etherfuse to email them an invite (see `emailInviteLink`). Provide exactly one of `email` or `customerId`."
                    },
                    "customerId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Add an existing customer directly by their `sub` (the value you put in the JWT `sub` when they sign in); no email is sent. The customer must already exist, which happens the first time they exchange a JWT via [POST /auth/token](/api-reference/authentication/exchange-a-partner-jwt) (or are launched); an unknown `sub` returns 404. A business org id (service account) is rejected. Provide exactly one of `email` or `customerId`."
                    },
                    "role": {
                        "type": "string",
                        "enum": [
                            "admin",
                            "member"
                        ],
                        "description": "The member's role in the organization."
                    },
                    "emailInviteLink": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Optional. When adding by `email` and a pending invite is created (the email isn't already a member), Etherfuse emails them this URL **as-is** (you control the full link, including any query params) as the call to action. Omit it to create the invite silently and notify the user yourself. Ignored when the email already matches a member who is added immediately."
                    }
                },
                "example": {
                    "email": "alice@acme.com",
                    "role": "admin",
                    "emailInviteLink": "https://partner.example.com/kyb-invite?org=a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                }
            },
            "MemberRecord": {
                "type": "object",
                "required": [
                    "customerId",
                    "role",
                    "joinedAt"
                ],
                "properties": {
                    "customerId": {
                        "type": "string",
                        "description": "The member's `sub`. Empty if the member does not yet have a `sub` in your namespace."
                    },
                    "email": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The member's email, if known."
                    },
                    "role": {
                        "type": "string",
                        "enum": [
                            "admin",
                            "member"
                        ]
                    },
                    "joinedAt": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "InvitedRecord": {
                "type": "object",
                "required": [
                    "email",
                    "role",
                    "invitedAt"
                ],
                "properties": {
                    "email": {
                        "type": "string"
                    },
                    "role": {
                        "type": "string",
                        "enum": [
                            "admin",
                            "member"
                        ]
                    },
                    "invitedAt": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "MemberOrganizationRecord": {
                "type": "object",
                "description": "One organization a customer belongs to, with their role in it.",
                "required": [
                    "organizationId",
                    "displayName",
                    "accountType",
                    "role",
                    "joinedAt"
                ],
                "properties": {
                    "organizationId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The organization's id."
                    },
                    "displayName": {
                        "type": "string",
                        "description": "The organization's name."
                    },
                    "accountType": {
                        "type": "string",
                        "enum": [
                            "personal",
                            "business"
                        ],
                        "description": "Whether the organization completes KYC (`personal`) or KYB (`business`)."
                    },
                    "role": {
                        "type": "string",
                        "enum": [
                            "admin",
                            "member"
                        ],
                        "description": "The customer's role in this organization."
                    },
                    "joinedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "When the customer joined this organization."
                    }
                },
                "example": {
                    "organizationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "displayName": "Acme Inc.",
                    "accountType": "business",
                    "role": "admin",
                    "joinedAt": "2026-06-17T00:00:00Z"
                }
            },
            "MembersResponse": {
                "type": "object",
                "required": [
                    "members",
                    "invited"
                ],
                "properties": {
                    "members": {
                        "type": "array",
                        "description": "Active members. The org's own service account is never listed.",
                        "items": {
                            "$ref": "#/components/schemas/MemberRecord"
                        }
                    },
                    "invited": {
                        "type": "array",
                        "description": "Pending invites that have not been accepted yet.",
                        "items": {
                            "$ref": "#/components/schemas/InvitedRecord"
                        }
                    }
                },
                "example": {
                    "members": [
                        {
                            "customerId": "9f1c4b2a-7d3e-4c5f-8a6b-1e2d3c4b5a6f",
                            "email": "alice@acme.com",
                            "role": "admin",
                            "joinedAt": "2026-06-17T00:00:00Z"
                        }
                    ],
                    "invited": [
                        {
                            "email": "bob@acme.com",
                            "role": "member",
                            "invitedAt": "2026-06-17T00:00:00Z"
                        }
                    ]
                }
            },
            "KybProgressResponse": {
                "type": "object",
                "description": "KYB progress for a business organization. Counts cover the customer-facing requirements only; admin-only requirements are excluded and never affect the status.",
                "required": [
                    "organizationId",
                    "status",
                    "approved",
                    "submitted",
                    "notStarted",
                    "total"
                ],
                "properties": {
                    "organizationId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "ID of the business organization this KYB belongs to."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "not_started",
                            "awaiting_documents",
                            "awaiting_review",
                            "approved",
                            "denied"
                        ],
                        "description": "`not_started`: no requirements answered yet. `awaiting_documents`: the customer has requirements left to fill or upload and nothing is blocking them (the ball is in their court). `awaiting_review`: the ball is in Etherfuse's court (open clarification notes for Etherfuse to answer, or every requirement submitted and awaiting review). `approved`: KYB approved. `denied`: KYB denied."
                    },
                    "approved": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Requirements with an approved answer."
                    },
                    "submitted": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Requirements answered but not yet approved."
                    },
                    "notStarted": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Requirements with no answer yet."
                    },
                    "total": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Total applicable requirements (`approved + submitted + notStarted`)."
                    },
                    "approvedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the org's KYB was approved, or null if not yet approved."
                    }
                },
                "example": {
                    "organizationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "status": "awaiting_review",
                    "approved": 3,
                    "submitted": 6,
                    "notStarted": 0,
                    "total": 9,
                    "approvedAt": null
                }
            },
            "CreateOrderPayload": {
                "type": "object",
                "required": [
                    "orderId",
                    "bankAccountId"
                ],
                "properties": {
                    "bankAccountId": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "blockchain": {
                        "oneOf": [
                            {
                                "type": "null"
                            },
                            {
                                "$ref": "#/components/schemas/Blockchain",
                                "description": "Optional when quote_id is provided - will be derived from quote"
                            }
                        ]
                    },
                    "cryptoWalletId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "Optional wallet UUID — when provided, resolves the wallet by ID instead of public_key lookup"
                    },
                    "direction": {
                        "oneOf": [
                            {
                                "type": "null"
                            },
                            {
                                "$ref": "#/components/schemas/Direction",
                                "description": "Optional when quote_id is provided - will be derived from quote"
                            }
                        ]
                    },
                    "feePayer": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Fee payer G-wallet for C-wallet Stellar offramps. Contract wallets can't be tx source."
                    },
                    "fiatAmount": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "memo": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "orderId": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "publicKey": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Optional when crypto_wallet_id is provided — will be derived from the wallet record"
                    },
                    "quoteId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid"
                    },
                    "tokenAmount": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "useAnchor": {
                        "type": "boolean",
                        "description": "When true, returns anchor address + memo instead of pre-signed TX (SEP-24 anchor mode).\nOnly valid for Stellar offramps."
                    }
                },
                "example": {
                    "bankAccountId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
                    "orderId": "7b9c1e2d-3f4a-5b6c-7d8e-9f0a1b2c3d4e",
                    "quoteId": "3f2a1b0c-9d8e-7f6a-5b4c-3d2e1f0a9b8c",
                    "cryptoWalletId": "1b6e98a2-7c3d-4e5f-9a0b-1c2d3e4f5a6b"
                }
            },
            "CreateOrderResponse": {
                "oneOf": [
                    {
                        "type": "object",
                        "title": "Offramp Response",
                        "required": [
                            "offramp"
                        ],
                        "properties": {
                            "offramp": {
                                "$ref": "#/components/schemas/OfframpOrderDetails"
                            }
                        }
                    },
                    {
                        "type": "object",
                        "title": "Onramp Response",
                        "required": [
                            "onramp"
                        ],
                        "properties": {
                            "onramp": {
                                "$ref": "#/components/schemas/OnrampOrderDetails"
                            }
                        }
                    }
                ]
            },
            "CreateQuoteResponse": {
                "type": "object",
                "required": [
                    "quoteId",
                    "blockchain",
                    "quoteAssets",
                    "sourceAmount",
                    "destinationAmount",
                    "createdAt",
                    "updatedAt",
                    "exchangeRate",
                    "nominalRate",
                    "feeBps",
                    "feeAmount",
                    "requiresSwap"
                ],
                "properties": {
                    "blockchain": {
                        "$ref": "#/components/schemas/Blockchain"
                    },
                    "createdAt": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "destinationAmount": {
                        "type": "string",
                        "description": "The amount of the destination asset the customer receives. Already net of all fees (platform fee plus any partner fee): destinationAmount = sourceAmount × exchangeRate. Do not subtract a fee from it again."
                    },
                    "etherfuseMidMarketRate": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "FX mid-market rate from a currency provider (e.g., USD/MXN). Only\npopulated for cross-currency quotes. Absent on direct stablebond\nramps and wraps — use `nominal_rate` for the pre-fee rate there."
                    },
                    "exchangeRate": {
                        "type": "string",
                        "description": "The effective, fee-inclusive rate the customer receives — all fees (platform and partner) are already reflected. Multiply by sourceAmount to get destinationAmount. For the raw pre-fee rate, use nominalRate."
                    },
                    "expiresAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "Timestamp when the quote expires, as an RFC 3339 / ISO 8601 string (e.g. 2025-12-17T18:31:46Z) — never an epoch number. Quotes are valid for 2 minutes from creation."
                    },
                    "feeAmount": {
                        "type": "string",
                        "description": "Fee amount, equal to sourceAmount × feeBps, denominated in the source asset's currency (e.g., fiat for onramps; the source token for offramps and swaps — USDC when selling USDC, the bond token when selling a bond). Includes any partner fee."
                    },
                    "feeBps": {
                        "type": "string",
                        "description": "Total fee in basis points (e.g., 20 = 0.20%). Combined fee that already includes any partner fee — subtract the partnerFeeBps you sent on the request to get the Etherfuse platform portion. The partner fee is not itemized separately on the quote response."
                    },
                    "nominalRate": {
                        "type": "string",
                        "description": "Pre-fee rate. `exchange_rate` is the effective rate after fees;\n`nominal_rate` is the underlying market rate before any Etherfuse fee\ndeduction. UIs that want to render the raw market relationship cleanly\n(e.g., \"1 MXN = 1 MEXe\" with the fee row shown separately) should read\nthis field. Always populated."
                    },
                    "quoteAssets": {
                        "$ref": "#/components/schemas/QuoteAssets"
                    },
                    "quoteId": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "requiresSwap": {
                        "type": "boolean",
                        "description": "Whether this quote requires an on-chain swap (true for FX ramps, false for stablebond ramps)"
                    },
                    "sourceAmount": {
                        "type": "string"
                    },
                    "updatedAt": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "example": {
                    "blockchain": "stellar",
                    "createdAt": "2026-05-02T09:14:00Z",
                    "destinationAmount": "58.42",
                    "etherfuseMidMarketRate": "17.15",
                    "exchangeRate": "17.12",
                    "expiresAt": "2026-05-02T09:16:00Z",
                    "feeAmount": "2.00",
                    "feeBps": "20",
                    "nominalRate": "17.15",
                    "quoteAssets": {
                        "sourceAsset": "MXN",
                        "targetAsset": "USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5",
                        "type": "onramp"
                    },
                    "quoteId": "3f2a1b0c-9d8e-7f6a-5b4c-3d2e1f0a9b8c",
                    "requiresSwap": true,
                    "sourceAmount": "1000",
                    "updatedAt": "2026-05-02T09:14:00Z"
                }
            },
            "CreateSwapPayload": {
                "type": "object",
                "description": "Request body for initiating an asset swap from a `swap`-type quote.",
                "required": [
                    "orderId",
                    "quoteId",
                    "publicKey",
                    "blockchain"
                ],
                "properties": {
                    "blockchain": {
                        "$ref": "#/components/schemas/Blockchain",
                        "description": "Blockchain the swap executes on."
                    },
                    "orderId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Client-generated order ID (UUID) for this swap."
                    },
                    "publicKey": {
                        "type": "string",
                        "description": "Customer's wallet public key on `blockchain`."
                    },
                    "quoteId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Quote ID from a prior `/ramp/quote` call made with `quoteAssets.type: \"swap\"`."
                    },
                    "targetWallet": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Optional destination wallet; defaults to `publicKey` when omitted."
                    }
                },
                "example": {
                    "blockchain": "solana",
                    "orderId": "9c7b3f1a-2e4d-4b6a-8c1d-0f9e8d7c6b5a",
                    "publicKey": "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN",
                    "quoteId": "3f2a1b0c-9d8e-7f6a-5b4c-3d2e1f0a9b8c",
                    "targetWallet": null
                }
            },
            "CreateWebhookRequest": {
                "type": "object",
                "required": [
                    "id",
                    "eventType",
                    "url"
                ],
                "properties": {
                    "eventType": {
                        "$ref": "#/components/schemas/WebhookEvent"
                    },
                    "id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "url": {
                        "type": "string"
                    }
                },
                "example": {
                    "eventType": "order_updated",
                    "id": "d4e5f6a7-b8c9-0123-defa-234567890123",
                    "url": "https://example.com/webhooks/etherfuse"
                }
            },
            "CreateWebhookResponse": {
                "type": "object",
                "required": [
                    "id",
                    "eventType",
                    "url",
                    "secret",
                    "createdAt",
                    "updatedAt"
                ],
                "properties": {
                    "createdAt": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Unix timestamp in seconds."
                    },
                    "eventType": {
                        "$ref": "#/components/schemas/WebhookEvent"
                    },
                    "id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "secret": {
                        "type": "string"
                    },
                    "updatedAt": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Unix timestamp in seconds."
                    },
                    "url": {
                        "type": "string"
                    }
                },
                "example": {
                    "createdAt": 1748345400,
                    "eventType": "order_updated",
                    "id": "d4e5f6a7-b8c9-0123-defa-234567890123",
                    "secret": "whsec_aJ8s7Df6Gh5Jk4Lm3Np2Qr1St0Uv9Wx8Yz7Ab6Cd5Ef4",
                    "updatedAt": 1748345400,
                    "url": "https://example.com/webhooks/etherfuse"
                }
            },
            "Customer": {
                "type": "object",
                "required": [
                    "customerId",
                    "createdAt",
                    "updatedAt"
                ],
                "properties": {
                    "createdAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Timestamp when the customer was created."
                    },
                    "customerId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Unique identifier for the customer."
                    },
                    "displayName": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Display name of the customer."
                    },
                    "updatedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Timestamp when the customer was last updated."
                    }
                },
                "example": {
                    "createdAt": "2026-05-01T14:30:00Z",
                    "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "displayName": "Ana García",
                    "updatedAt": "2026-05-02T09:15:00Z"
                }
            },
            "DateRangeFilter": {
                "type": "object",
                "required": [
                    "fromDate"
                ],
                "properties": {
                    "fromDate": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "toDate": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                },
                "example": {
                    "fromDate": "2026-01-01T00:00:00Z",
                    "toDate": "2026-06-01T00:00:00Z"
                }
            },
            "Direction": {
                "type": "string",
                "enum": [
                    "onramp",
                    "offramp"
                ]
            },
            "EvmApprovePayload": {
                "type": "object",
                "description": "Request body for generating an EVM token-approval transaction.\n\nDocumentation schema for [`evm_approve_proxy`]. The handler forwards the body\nto the bridge service verbatim; this type only describes the expected shape.",
                "required": [
                    "blockchain",
                    "wallet",
                    "assetId"
                ],
                "properties": {
                    "amount": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Amount to approve in base units (token's smallest denomination). For a\n6-decimal token, `10000000` = 10 tokens. Omit to approve the maximum\n(recommended — a one-time approval covers all future offramps)."
                    },
                    "assetId": {
                        "type": "string",
                        "description": "The token contract address to approve (`0x`-prefixed, 40 hex chars)."
                    },
                    "blockchain": {
                        "type": "string",
                        "description": "The EVM chain to approve on (currently `base`)."
                    },
                    "wallet": {
                        "type": "string",
                        "description": "The user's EVM wallet address (`0x`-prefixed, 40 hex chars)."
                    }
                },
                "example": {
                    "assetId": "0xcC77c598d42f2f78Beb42C91d12B9d4041a5cE29",
                    "blockchain": "base",
                    "wallet": "0xf82567432381D1326484E5A9140ABCa4294f82D0"
                }
            },
            "GeneralLocation": {
                "type": "object",
                "required": [
                    "city",
                    "region",
                    "country",
                    "emoji_flag",
                    "country_flag_url"
                ],
                "properties": {
                    "city": {
                        "type": "string"
                    },
                    "country": {
                        "type": "string"
                    },
                    "country_flag_url": {
                        "type": "string"
                    },
                    "emoji_flag": {
                        "type": "string"
                    },
                    "region": {
                        "type": "string"
                    }
                }
            },
            "GenerateOnboardingUrlPayload": {
                "type": "object",
                "required": [
                    "customerId",
                    "bankAccountId",
                    "publicKey",
                    "blockchain"
                ],
                "properties": {
                    "bankAccountId": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "blockchain": {
                        "$ref": "#/components/schemas/Blockchain"
                    },
                    "customerId": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "publicKey": {
                        "type": "string"
                    },
                    "uiOverride": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "userInfo": {
                        "oneOf": [
                            {
                                "type": "null"
                            },
                            {
                                "$ref": "#/components/schemas/UserInfo",
                                "description": "Optional info about the end user. Recommended — enables personalized\nstatus emails and links the user record to their Firebase identity.\nThe hosted onboarding flow always creates a personal organization."
                            }
                        ]
                    }
                },
                "example": {
                    "bankAccountId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
                    "blockchain": "stellar",
                    "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "publicKey": "GDUKMGUGD3V6VXTU2RLAUM7A2FABLMHCPWTMDHKP7HHJ6FCZKEY4PVWL",
                    "userInfo": {
                        "displayName": "Ana García",
                        "email": "ana@example.com"
                    }
                }
            },
            "ImageInfo": {
                "type": "object",
                "required": [
                    "imageURL",
                    "label"
                ],
                "properties": {
                    "imageURL": {
                        "type": "string"
                    },
                    "label": {
                        "type": "string"
                    }
                }
            },
            "ImageUploadBody": {
                "type": "object",
                "required": [
                    "image",
                    "label"
                ],
                "properties": {
                    "image": {
                        "type": "string",
                        "description": "The image encoded as a base64 data URI (JPEG or PNG, max 10MB), e.g. \"data:image/jpeg;base64,...\"."
                    },
                    "label": {
                        "type": "string",
                        "enum": [
                            "id_front",
                            "id_back",
                            "selfie"
                        ],
                        "description": "Identifies the image. Use \"id_front\" (required) and \"id_back\" (if two-sided) when documentType is \"document\"; use \"selfie\" when documentType is \"selfie\"."
                    }
                }
            },
            "KycStatusResponse": {
                "type": "object",
                "description": "KYC status response",
                "required": [
                    "customerId",
                    "status",
                    "selfies",
                    "documents",
                    "needsWork"
                ],
                "properties": {
                    "approvedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "currentRejectionReason": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "customerId": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "documents": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ProofOfIdentityDocument"
                        }
                    },
                    "needsWork": {
                        "type": "boolean"
                    },
                    "onChainMarked": {
                        "type": [
                            "boolean",
                            "null"
                        ],
                        "description": "Whether KYC is marked on-chain. Only present for Solana wallets.\nFor other blockchain types (Stellar, EVM), this field is omitted as on-chain marking doesn't apply."
                    },
                    "selfies": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ProofOfIdentityContent"
                        }
                    },
                    "status": {
                        "type": "string"
                    },
                    "userMessage": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "walletPublicKey": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "example": {
                    "approvedAt": "2026-05-01T16:00:00Z",
                    "currentRejectionReason": null,
                    "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "documents": [],
                    "needsWork": false,
                    "selfies": [],
                    "status": "approved",
                    "walletPublicKey": "GDUKMGUGD3V6VXTU2RLAUM7A2FABLMHCPWTMDHKP7HHJ6FCZKEY4PVWL"
                }
            },
            "LegalRepresentativeData": {
                "type": "object",
                "properties": {
                    "controlling_beneficiaries": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "curp": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "deed_date": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "identification_type": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "name": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notary_location": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notary_name": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notary_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "occupation": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "position": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "public_deed": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "registry_date": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "rfc": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "LegalRepresentativeDataInfo": {
                "type": "object",
                "properties": {
                    "controllingBeneficiaries": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "curp": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "deedDate": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "identificationType": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "name": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notaryLocation": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notaryName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notaryNumber": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "occupation": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "position": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "publicDeed": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "registryDate": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "rfc": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "MeResponse": {
                "type": "object",
                "required": [
                    "id",
                    "displayName",
                    "partnerFeeDefaultBps"
                ],
                "properties": {
                    "approvedAt": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "displayName": {
                        "type": "string"
                    },
                    "id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "partnerFeeDefaultBps": {
                        "type": "integer",
                        "format": "int32"
                    }
                },
                "example": {
                    "approvedAt": "2026-04-15T12:00:00Z",
                    "displayName": "Acme Inc",
                    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "partnerFeeDefaultBps": 100
                }
            },
            "MexicanInformationUpdate": {
                "type": "object",
                "properties": {
                    "curp": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "rfc": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "ModificationData": {
                "type": "object",
                "properties": {
                    "company_name": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "deed_date": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "folio": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "modification_made": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notary_location": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notary_name": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notary_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "public_deed": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "registry_date": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "ModificationDataInfo": {
                "type": "object",
                "properties": {
                    "companyName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "deedDate": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "folio": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "modificationMade": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notaryLocation": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notaryName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notaryNumber": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "publicDeed": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "registryDate": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "OfframpAssets": {
                "type": "object",
                "title": "Offramp",
                "required": [
                    "sourceAsset",
                    "targetAsset"
                ],
                "properties": {
                    "sourceAsset": {
                        "type": "string",
                        "description": "This should be the asset identifier for the source blockchain that you are originating from"
                    },
                    "targetAsset": {
                        "$ref": "#/components/schemas/QuoteFiat"
                    }
                }
            },
            "OfframpOrderDetails": {
                "type": "object",
                "required": [
                    "orderId"
                ],
                "properties": {
                    "orderId": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "withdrawAnchorAccount": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "withdrawMemo": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "withdrawMemoType": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "example": {
                    "orderId": "7b9c1e2d-3f4a-5b6c-7d8e-9f0a1b2c3d4e",
                    "withdrawAnchorAccount": "GANCHOR7XYZQ635VDIGY6S4ZUF5L6TQ7AA4MWS7LEQDBLUSZXV7UPS4",
                    "withdrawMemo": "3f2a1b0c9d8e",
                    "withdrawMemoType": "hash"
                }
            },
            "OnrampAssets": {
                "type": "object",
                "title": "Onramp",
                "required": [
                    "sourceAsset",
                    "targetAsset"
                ],
                "properties": {
                    "sourceAsset": {
                        "$ref": "#/components/schemas/QuoteFiat"
                    },
                    "targetAsset": {
                        "type": "string",
                        "description": "This should be the asset identifier for the destination blockchain that you are targeting"
                    }
                }
            },
            "OnrampOrderDetails": {
                "type": "object",
                "required": [
                    "orderId",
                    "depositClabe",
                    "depositAmount",
                    "depositBankName",
                    "depositAccountHolder"
                ],
                "properties": {
                    "depositAccountHolder": {
                        "type": "string",
                        "description": "Account holder name for the deposit CLABE. Hardcoded to Etherfuse MX for now."
                    },
                    "depositAmount": {
                        "type": "string"
                    },
                    "depositBankName": {
                        "type": "string",
                        "description": "Name of the bank that holds the deposit CLABE."
                    },
                    "depositClabe": {
                        "type": "string"
                    },
                    "orderId": {
                        "type": "string",
                        "format": "uuid"
                    }
                },
                "example": {
                    "depositAccountHolder": "Etherfuse MX",
                    "depositAmount": "1000.00",
                    "depositBankName": "Example Bank",
                    "depositClabe": "646180157000000004",
                    "orderId": "7b9c1e2d-3f4a-5b6c-7d8e-9f0a1b2c3d4e"
                }
            },
            "Order": {
                "type": "object",
                "description": "Order representation for WebSocket messages",
                "required": [
                    "orderId",
                    "customerId",
                    "createdAt",
                    "updatedAt",
                    "walletId",
                    "bankAccountId",
                    "orderType",
                    "status",
                    "statusPage"
                ],
                "properties": {
                    "amountInFiat": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Amount in fiat currency (e.g. MXN)."
                    },
                    "amountInTokens": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Amount in crypto tokens."
                    },
                    "bankAccountId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "ID of the bank account used for the order."
                    },
                    "blockchain": {
                        "oneOf": [
                            {
                                "type": "null"
                            },
                            {
                                "$ref": "#/components/schemas/Blockchain",
                                "description": "Blockchain the order settles on."
                            }
                        ]
                    },
                    "burnTransaction": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Encoded transaction for the user to sign (bring-your-own-wallet offramp orders). Embedded wallets omit this and instead surface `approval` on the order; sign via POST /ramp/order/{order_id}/approvals. See [Embedded Wallets](/guides/embedded-wallets)."
                    },
                    "completedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "Timestamp when the order was completed."
                    },
                    "confirmedTxSignature": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Blockchain transaction hash, set once the crypto transfer is confirmed."
                    },
                    "trackingCode": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "SPEI tracking key (clave de rastreo) for the order's fiat transfer. On onramps this is the incoming deposit's clave; on offramps it is the outgoing payout's clave. Present once the SPEI transfer settles — use it to look up the CEP (Comprobante Electrónico de Pago) receipt. Absent until then."
                    },
                    "createdAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Timestamp when the order was created."
                    },
                    "customerId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Organization ID associated with the order. In webhook payloads, this is the\nrecipient organization's ID."
                    },
                    "deletedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "Timestamp when the order was deleted (if applicable)."
                    },
                    "depositAccountHolder": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Account holder name for the deposit CLABE. Hardcoded to Etherfuse MX for now."
                    },
                    "depositBankName": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Name of the bank that holds the deposit CLABE."
                    },
                    "depositClabe": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "CLABE number for deposit (onramp orders only)."
                    },
                    "etherfuseMidMarketRate": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Raw mid-market rate before fees"
                    },
                    "exchangeRate": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Fee-inclusive exchange rate between source and target assets"
                    },
                    "feeAmountInFiat": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Quoted fee amount in fiat currency, derived from fee_bps × order amount."
                    },
                    "feeBps": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "format": "int32",
                        "description": "Fee in basis points (e.g., 20 = 0.20%). Always present when order was created with a quote.",
                        "minimum": 0
                    },
                    "isAnchorOrder": {
                        "type": [
                            "boolean",
                            "null"
                        ],
                        "description": "Whether this is an anchor order (SEP-24 mode — no pre-signed TX)"
                    },
                    "memo": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Optional memo for the order."
                    },
                    "orderId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Unique identifier for the order."
                    },
                    "orderType": {
                        "$ref": "#/components/schemas/OrderType",
                        "description": "Type of the order (onramp/offramp/swap)."
                    },
                    "partnerFeeAmountFiat": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Partner fee amount collected in fiat currency, derived from the total fee using the\npartner fee ratio."
                    },
                    "partnerFeeBps": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "format": "int32",
                        "description": "Partner fee in basis points applied to this order (e.g. 100 = 1.00%). Only present\nwhen a partner fee was configured at quote time."
                    },
                    "partnerFeeStatus": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Disbursement status of the partner fee. Only present when `partnerFeeBps` > 0:\n`none` — order not yet completed; `pending` — order completed, fee awaiting offline\ndisbursement; `disbursed` — partner fee has been paid out."
                    },
                    "sourceAsset": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Source asset identifier. For onramps this is the fiat currency (e.g. `MXN`); for\nofframps it is the crypto asset identifier."
                    },
                    "status": {
                        "$ref": "#/components/schemas/OrderStatus",
                        "description": "Current status of the order. For offramps, `completed` means fiat has been sent to\nthe customer; `finalized` means the reversal window has passed and the funds can no\nlonger be returned."
                    },
                    "statusPage": {
                        "type": "string",
                        "description": "URL to an Etherfuse-branded page where the customer can view order status and sign\ntransactions (for offramps). Can be used as an alternative to handling transaction\nsigning in your own application."
                    },
                    "approval": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "Pending embedded-wallet approval. Present only when the order is awaiting the owner's signature. The owner signs `approvalMessage` and submits it to POST /ramp/order/{order_id}/approvals. Re-read the order right before signing: `approvalMessage` embeds a timestamp that re-mints on each read. Delivered on the order read, the `order_updated` webhook, and the WebSocket stream.",
                        "properties": {
                            "approvalMessageId": {
                                "type": "string",
                                "format": "uuid",
                                "description": "Identifies the proposal being approved. Echoed back on submit so a superseded proposal (re-proposed on expiry) is rejected as stale."
                            },
                            "approvalMessage": {
                                "type": "string",
                                "description": "The exact bytes the owner signs with their key. Built fresh on each read so the request is current when signed."
                            },
                            "summary": {
                                "type": "string",
                                "description": "Human-readable description of what is being approved (e.g. `Claim 99.61 CETES`). Present only when set."
                            }
                        }
                    },
                    "stellarClaimTransaction": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Unsigned XDR (base64) for the claim TX (ChangeTrust + ClaimClaimableBalance).\nThe user signs this and submits to Horizon to receive their tokens."
                    },
                    "stellarClaimableBalanceId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Stellar claimable balance ID (hex). Present when tokens were delivered via claimable balance.\nThe user must sign a claim TX to receive their tokens."
                    },
                    "targetAsset": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Target asset identifier. For onramps this is the crypto asset identifier; for\nofframps it is the fiat currency (e.g. `MXN`)."
                    },
                    "updatedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Timestamp when the order was last updated."
                    },
                    "walletId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "ID of the wallet used for the order."
                    },
                    "withdrawAnchorAccount": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Anchor destination account for SEP-24 anchor offramps"
                    },
                    "withdrawMemo": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Memo to include in the anchor payment (derived from transaction_id)"
                    },
                    "withdrawMemoType": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Memo type for the anchor payment (always \"hash\" for anchor orders)"
                    }
                },
                "example": {
                    "amountInFiat": "1000.00",
                    "amountInTokens": "58.42",
                    "bankAccountId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
                    "blockchain": "stellar",
                    "completedAt": "2026-05-02T09:16:30Z",
                    "createdAt": "2026-05-02T09:15:00Z",
                    "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "depositAccountHolder": "Etherfuse MX",
                    "depositBankName": "Example Bank",
                    "depositClabe": "646180157000000004",
                    "etherfuseMidMarketRate": "17.15",
                    "exchangeRate": "17.12",
                    "feeAmountInFiat": "2.00",
                    "feeBps": 20,
                    "orderId": "7b9c1e2d-3f4a-5b6c-7d8e-9f0a1b2c3d4e",
                    "orderType": "onramp",
                    "sourceAsset": "MXN",
                    "status": "completed",
                    "statusPage": "https://pay.etherfuse.com/order/7b9c1e2d-3f4a-5b6c-7d8e-9f0a1b2c3d4e",
                    "stellarClaimTransaction": "AAAAAgAAAABk...base64_xdr...",
                    "stellarClaimableBalanceId": "00000000abc1230000000000000000000000000000000000000000000000000000",
                    "targetAsset": "USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5",
                    "updatedAt": "2026-05-02T09:16:30Z",
                    "walletId": "c3d4e5f6-a7b8-9012-cdef-123456789012"
                }
            },
            "OrderStatus": {
                "type": "string",
                "description": "Order status for JSON serialization in WebSocket messages",
                "enum": [
                    "created",
                    "funded",
                    "completed",
                    "failed",
                    "refunded",
                    "canceled",
                    "finalized"
                ]
            },
            "OrderType": {
                "type": "string",
                "description": "Order type for JSON serialization in WebSocket messages",
                "enum": [
                    "onramp",
                    "offramp"
                ]
            },
            "PagedBankAccounts": {
                "type": "object",
                "description": "A page of bank accounts.",
                "required": [
                    "items",
                    "totalItems",
                    "pageSize",
                    "pageNumber",
                    "totalPages"
                ],
                "properties": {
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/BankAccount"
                        },
                        "description": "The items on this page."
                    },
                    "next": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "URL to fetch the next page of results, if available."
                    },
                    "pageNumber": {
                        "type": "integer",
                        "description": "Zero-based index of this page.",
                        "example": 0,
                        "minimum": 0
                    },
                    "pageSize": {
                        "type": "integer",
                        "description": "Number of items per page.",
                        "example": 30,
                        "minimum": 0
                    },
                    "totalItems": {
                        "type": "integer",
                        "description": "Total number of items across all pages.",
                        "example": 42,
                        "minimum": 0
                    },
                    "totalPages": {
                        "type": "integer",
                        "description": "Total number of pages.",
                        "example": 2,
                        "minimum": 0
                    }
                }
            },
            "PagedCustomers": {
                "type": "object",
                "description": "A page of customers.",
                "required": [
                    "items",
                    "totalItems",
                    "pageSize",
                    "pageNumber",
                    "totalPages"
                ],
                "properties": {
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Customer"
                        },
                        "description": "The items on this page."
                    },
                    "next": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "URL to fetch the next page of results, if available."
                    },
                    "pageNumber": {
                        "type": "integer",
                        "description": "Zero-based index of this page.",
                        "example": 0,
                        "minimum": 0
                    },
                    "pageSize": {
                        "type": "integer",
                        "description": "Number of items per page.",
                        "example": 30,
                        "minimum": 0
                    },
                    "totalItems": {
                        "type": "integer",
                        "description": "Total number of items across all pages.",
                        "example": 42,
                        "minimum": 0
                    },
                    "totalPages": {
                        "type": "integer",
                        "description": "Total number of pages.",
                        "example": 2,
                        "minimum": 0
                    }
                }
            },
            "PagedOrders": {
                "type": "object",
                "description": "A page of orders.",
                "required": [
                    "items",
                    "totalItems",
                    "pageSize",
                    "pageNumber",
                    "totalPages"
                ],
                "properties": {
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Order"
                        },
                        "description": "The items on this page."
                    },
                    "next": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "URL to fetch the next page of results, if available."
                    },
                    "pageNumber": {
                        "type": "integer",
                        "description": "Zero-based index of this page.",
                        "example": 0,
                        "minimum": 0
                    },
                    "pageSize": {
                        "type": "integer",
                        "description": "Number of items per page.",
                        "example": 30,
                        "minimum": 0
                    },
                    "totalItems": {
                        "type": "integer",
                        "description": "Total number of items across all pages.",
                        "example": 42,
                        "minimum": 0
                    },
                    "totalPages": {
                        "type": "integer",
                        "description": "Total number of pages.",
                        "example": 2,
                        "minimum": 0
                    }
                }
            },
            "PagedRequest": {
                "type": "object",
                "properties": {
                    "filters": {
                        "oneOf": [
                            {
                                "type": "null"
                            },
                            {
                                "$ref": "#/components/schemas/NoFilters"
                            }
                        ]
                    },
                    "pageNumber": {
                        "type": "integer",
                        "description": "which page of results to return (starts at 0)",
                        "minimum": 0
                    },
                    "pageSize": {
                        "type": "integer",
                        "description": "The number of items to get back in one page",
                        "minimum": 0
                    }
                },
                "example": {
                    "pageNumber": 0,
                    "pageSize": 30
                }
            },
            "PagedRequest_DateRangeFilter": {
                "type": "object",
                "properties": {
                    "filters": {
                        "type": "object",
                        "required": [
                            "fromDate"
                        ],
                        "properties": {
                            "fromDate": {
                                "type": "string",
                                "format": "date-time"
                            },
                            "toDate": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "date-time"
                            }
                        },
                        "example": {
                            "fromDate": "2026-01-01T00:00:00Z",
                            "toDate": "2026-06-01T00:00:00Z"
                        }
                    },
                    "pageNumber": {
                        "type": "integer",
                        "description": "which page of results to return (starts at 0)",
                        "minimum": 0
                    },
                    "pageSize": {
                        "type": "integer",
                        "description": "The number of items to get back in one page",
                        "minimum": 0
                    }
                },
                "example": {
                    "pageNumber": 0,
                    "pageSize": 30
                }
            },
            "PagedWallets": {
                "type": "object",
                "description": "A page of crypto wallets.",
                "required": [
                    "items",
                    "totalItems",
                    "pageSize",
                    "pageNumber",
                    "totalPages"
                ],
                "properties": {
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Wallet"
                        },
                        "description": "The items on this page."
                    },
                    "next": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "URL to fetch the next page of results, if available."
                    },
                    "pageNumber": {
                        "type": "integer",
                        "description": "Zero-based index of this page.",
                        "example": 0,
                        "minimum": 0
                    },
                    "pageSize": {
                        "type": "integer",
                        "description": "Number of items per page.",
                        "example": 30,
                        "minimum": 0
                    },
                    "totalItems": {
                        "type": "integer",
                        "description": "Total number of items across all pages.",
                        "example": 42,
                        "minimum": 0
                    },
                    "totalPages": {
                        "type": "integer",
                        "description": "Total number of pages.",
                        "example": 2,
                        "minimum": 0
                    }
                }
            },
            "PagedWebhooks": {
                "type": "object",
                "description": "A page of webhooks.",
                "required": [
                    "items",
                    "totalItems",
                    "pageSize",
                    "pageNumber",
                    "totalPages"
                ],
                "properties": {
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Webhook"
                        },
                        "description": "The items on this page."
                    },
                    "next": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "URL to fetch the next page of results, if available."
                    },
                    "pageNumber": {
                        "type": "integer",
                        "description": "Zero-based index of this page.",
                        "example": 0,
                        "minimum": 0
                    },
                    "pageSize": {
                        "type": "integer",
                        "description": "Number of items per page.",
                        "example": 30,
                        "minimum": 0
                    },
                    "totalItems": {
                        "type": "integer",
                        "description": "Total number of items across all pages.",
                        "example": 42,
                        "minimum": 0
                    },
                    "totalPages": {
                        "type": "integer",
                        "description": "Total number of pages.",
                        "example": 2,
                        "minimum": 0
                    }
                }
            },
            "PaymentData": {
                "type": "object",
                "description": "Current pricing for a single stablebond: cost in USD/fiat plus the\nper-provider exchange-rate `sources` used to derive it.",
                "required": [
                    "bond_cost_in_payment_token",
                    "bond_cost_in_usd",
                    "fiat_exchange_rate_with_usd",
                    "bond_cost_in_fiat",
                    "current_basis_points",
                    "bond_symbol",
                    "currency",
                    "current_time",
                    "mint",
                    "symbol",
                    "sources"
                ],
                "properties": {
                    "bond_cost_in_fiat": {
                        "type": "string",
                        "description": "Bond cost denominated in the settlement (fiat) currency."
                    },
                    "bond_cost_in_payment_token": {
                        "type": "string",
                        "description": "Deprecated — use `bond_cost_in_fiat`."
                    },
                    "bond_cost_in_usd": {
                        "type": "string",
                        "description": "Bond cost denominated in USD."
                    },
                    "bond_symbol": {
                        "type": "string",
                        "description": "Bond symbol (e.g. `CETES`)."
                    },
                    "currency": {
                        "type": "string",
                        "description": "Settlement currency (ISO 4217, e.g. `MXN`)."
                    },
                    "current_basis_points": {
                        "type": "integer",
                        "format": "int32",
                        "description": "Current annualized rate of the bond, in basis points (e.g. `578` = 5.78%)."
                    },
                    "current_time": {
                        "type": "string",
                        "description": "Timestamp the price was computed (RFC 3339)."
                    },
                    "fiat_exchange_rate_with_usd": {
                        "type": "string",
                        "description": "FX rate between the settlement currency and USD."
                    },
                    "mint": {
                        "type": "string",
                        "description": "Payment-token mint address."
                    },
                    "sources": {
                        "type": "object",
                        "description": "Per-FX-provider exchange rate and derived USD cost, for oracle safety checks.",
                        "additionalProperties": {
                            "$ref": "#/components/schemas/BondCostSource"
                        },
                        "propertyNames": {
                            "type": "string"
                        }
                    },
                    "symbol": {
                        "type": "string",
                        "description": "Payment-token symbol (e.g. `USDC`)."
                    }
                },
                "example": {
                    "bond_cost_in_fiat": "1.153754",
                    "bond_cost_in_payment_token": "1.153754",
                    "bond_cost_in_usd": "0.064785",
                    "bond_symbol": "CETES",
                    "currency": "MXN",
                    "current_basis_points": 578,
                    "current_time": "2026-03-23T16:50:32.821673099+00:00",
                    "fiat_exchange_rate_with_usd": "17.80900",
                    "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
                    "sources": {
                        "provider_1": {
                            "bond_cost_in_usd": "0.064781",
                            "exchange_rate": "17.81",
                            "updated_at": 1711212632
                        },
                        "provider_2": {
                            "bond_cost_in_usd": "0.064854",
                            "exchange_rate": "17.79",
                            "updated_at": 1711212630
                        }
                    },
                    "symbol": "USDC"
                }
            },
            "PersonalAccountRequest": {
                "type": "object",
                "required": [
                    "transactionId",
                    "firstName",
                    "paternalLastName",
                    "maternalLastName",
                    "birthDate",
                    "curp",
                    "rfc",
                    "clabe"
                ],
                "properties": {
                    "birthCountryId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Numeric country code (legacy, e.g. \"187\" for Mexico)"
                    },
                    "birthCountryIsoCode": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "ISO 3166-1 alpha-2 code (preferred, e.g. \"MX\")"
                    },
                    "birthDate": {
                        "type": "string",
                        "description": "Date of birth in `YYYYMMDD` format (8 digits, e.g. `19900515`)."
                    },
                    "clabe": {
                        "type": "string"
                    },
                    "curp": {
                        "type": "string"
                    },
                    "firstName": {
                        "type": "string"
                    },
                    "maternalLastName": {
                        "type": "string"
                    },
                    "paternalLastName": {
                        "type": "string"
                    },
                    "rfc": {
                        "type": "string",
                        "description": "The individual's RFC (Registro Federal de Contribuyentes)."
                    },
                    "transactionId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Idempotency key for this bank account registration. Generate a stable UUID and keep it; passing the same value makes the call safe to retry and ensures the account is registered only once. This is a value you supply, not one returned by Etherfuse."
                    }
                }
            },
            "PresignedUrlPayload": {
                "type": "object",
                "required": [
                    "presignedUrl"
                ],
                "properties": {
                    "presignedUrl": {
                        "type": "string"
                    }
                },
                "example": {
                    "presignedUrl": "https://api.sand.etherfuse.com/ramp/proof-of-identity?org_id=...&expires=...&signature=..."
                }
            },
            "ProofOfIdentityAddress": {
                "type": "object",
                "required": [
                    "country"
                ],
                "properties": {
                    "city": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "country": {
                        "type": "string"
                    },
                    "postalCode": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "region": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "street": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "street2": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "ProofOfIdentityContent": {
                "type": "object",
                "required": [
                    "id",
                    "type",
                    "status"
                ],
                "properties": {
                    "approvedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "contentLabel": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "createdAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "id": {
                        "type": "string"
                    },
                    "images": {
                        "type": [
                            "array",
                            "null"
                        ],
                        "items": {
                            "$ref": "#/components/schemas/ImageInfo"
                        }
                    },
                    "ipAddress": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "rejectedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "rejectedReason": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "status": {
                        "$ref": "#/components/schemas/ProofOfIdentityStatus"
                    },
                    "type": {
                        "type": "string"
                    },
                    "videoURL": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "ProofOfIdentityDocument": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/ProofOfIdentityContent"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "extractedData": {
                                "oneOf": [
                                    {
                                        "type": "null"
                                    },
                                    {
                                        "$ref": "#/components/schemas/ProofOfIdentityUserInfo"
                                    }
                                ]
                            }
                        }
                    }
                ]
            },
            "ProofOfIdentityIdNumber": {
                "type": "object",
                "required": [
                    "value",
                    "type"
                ],
                "properties": {
                    "type": {
                        "type": "string"
                    },
                    "value": {
                        "type": "string"
                    }
                }
            },
            "ProofOfIdentityName": {
                "type": "object",
                "required": [
                    "givenName",
                    "familyName"
                ],
                "properties": {
                    "familyName": {
                        "type": "string"
                    },
                    "givenName": {
                        "type": "string"
                    },
                    "middleName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "motherMaidenName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "preferredName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "ProofOfIdentityStatus": {
                "type": "string",
                "enum": [
                    "approved",
                    "rejected",
                    "proposed"
                ]
            },
            "ProofOfIdentityUserInfo": {
                "type": "object",
                "required": [
                    "id"
                ],
                "properties": {
                    "address": {
                        "oneOf": [
                            {
                                "type": "null"
                            },
                            {
                                "$ref": "#/components/schemas/ProofOfIdentityAddress"
                            }
                        ]
                    },
                    "dateOfBirth": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "email": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "id": {
                        "type": "string"
                    },
                    "idNumbers": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ProofOfIdentityIdNumber"
                        }
                    },
                    "name": {
                        "oneOf": [
                            {
                                "type": "null"
                            },
                            {
                                "$ref": "#/components/schemas/ProofOfIdentityName"
                            }
                        ]
                    },
                    "occupation": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "organizationId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid"
                    },
                    "phoneNumber": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "sourceOrganizationId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid"
                    },
                    "useEmailForMarketing": {
                        "type": [
                            "boolean",
                            "null"
                        ]
                    },
                    "walletId": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "QuoteAssets": {
                "oneOf": [
                    {
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/OnrampAssets",
                                "description": "Fiat → crypto: pay in fiat, receive a stablecoin/token on-chain."
                            },
                            {
                                "type": "object",
                                "required": [
                                    "type"
                                ],
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "onramp"
                                        ]
                                    }
                                }
                            }
                        ],
                        "title": "Onramp",
                        "description": "Fiat → crypto: pay in fiat, receive a stablecoin/token on-chain."
                    },
                    {
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/OfframpAssets",
                                "description": "Crypto → fiat: send a token on-chain, receive fiat in a bank account."
                            },
                            {
                                "type": "object",
                                "required": [
                                    "type"
                                ],
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "offramp"
                                        ]
                                    }
                                }
                            }
                        ],
                        "title": "Offramp",
                        "description": "Crypto → fiat: send a token on-chain, receive fiat in a bank account."
                    },
                    {
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/SwapAssets",
                                "description": "Crypto → crypto: swap one on-chain asset for another."
                            },
                            {
                                "type": "object",
                                "required": [
                                    "type"
                                ],
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "swap"
                                        ]
                                    }
                                }
                            }
                        ],
                        "title": "Swap",
                        "description": "Crypto → crypto: swap one on-chain asset for another."
                    }
                ]
            },
            "QuoteFiat": {
                "type": "string",
                "enum": [
                    "MXN",
                    "BRL"
                ]
            },
            "RampableAsset": {
                "type": "object",
                "description": "Rampable Assets Endpoint\nReturns a list of assets that can be ramped to/from for a given blockchain and currency",
                "required": [
                    "symbol",
                    "identifier",
                    "name",
                    "metadata"
                ],
                "properties": {
                    "balance": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Human-readable wallet balance scaled by token decimals as a string (e.g., \"100.5\"). Uniform across chains; all chains now return human-decimal strings."
                    },
                    "currency": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The fiat currency this token is backed by (e.g., \"mxn\" for stablebonds, \"usd\" for USDC)"
                    },
                    "identifier": {
                        "type": "string",
                        "description": "Chain-specific identifier (e.g., \"CETES:GCRYUGD5...\" for Stellar, mint address for Solana)"
                    },
                    "image": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Image URL for the asset (mirrors metadata.image)."
                    },
                    "metadata": {
                        "description": "Canonical display metadata sourced from Solana Metaplex regardless of the queried chain. Prefer these fields over the legacy top-level symbol/name/image.",
                        "$ref": "#/components/schemas/RampableAssetMetadata"
                    },
                    "name": {
                        "type": "string",
                        "description": "Display name"
                    },
                    "symbol": {
                        "type": "string",
                        "description": "Token symbol (e.g., \"CETES\")"
                    }
                }
            },
            "RampableAssetsResponse": {
                "type": "object",
                "required": [
                    "assets"
                ],
                "properties": {
                    "assets": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/RampableAsset"
                        }
                    }
                },
                "example": {
                    "assets": [
                        {
                            "balance": "1500.00",
                            "currency": "mxn",
                            "identifier": "CETES:GC3CW7EDYRTWQ635VDIGY6S4ZUF5L6TQ7AA4MWS7LEQDBLUSZXV7UPS4",
                            "image": "https://assets.etherfuse.com/cetes.png",
                            "metadata": {
                                "symbol": "CETES",
                                "name": "Cetes",
                                "image": "https://assets.etherfuse.com/cetes.png"
                            },
                            "name": "Cetes",
                            "symbol": "CETES"
                        },
                        {
                            "balance": "250.00",
                            "currency": "usd",
                            "identifier": "USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5",
                            "image": "https://assets.etherfuse.com/usdc.png",
                            "metadata": {
                                "symbol": "USDC",
                                "name": "USD Coin",
                                "image": "https://assets.etherfuse.com/usdc.png"
                            },
                            "name": "USD Coin",
                            "symbol": "USDC"
                        }
                    ]
                }
            },
            "RampableAssetMetadata": {
                "type": "object",
                "description": "Canonical display metadata for a rampable asset, sourced from Solana Metaplex regardless of the queried chain.",
                "required": [
                    "symbol",
                    "name"
                ],
                "properties": {
                    "symbol": {
                        "type": "string",
                        "description": "Cased display symbol (e.g., \"MEXe\", \"CETES\")."
                    },
                    "name": {
                        "type": "string",
                        "description": "Cased display name (e.g., \"Etherfuse MEXe\")."
                    },
                    "image": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Off-chain image URL from Solana Metaplex. Omitted when the asset has no logo hosted."
                    }
                }
            },
            "RegisterWalletRequest": {
                "description": "Request body for registering a wallet. Two mutually-exclusive shapes: bring-your-own (external): provide `publicKey` and `blockchain`; or embedded (non-custodial): provide `walletId` and a `signer` with the owner's P-256 public key as compressed SEC1 hex (`signerPublicKey`), PEM (`signerPublicKeyPem`), or JWK (`signerPublicKeyJwk`). Only `p256` is supported for embedded wallets. Supply exactly one key encoding. Supplying both external and embedded fields is rejected.",
                "oneOf": [
                    {
                        "$ref": "#/components/schemas/RegisterWalletExternal"
                    },
                    {
                        "type": "object",
                        "title": "Embedded wallet",
                        "required": [
                            "walletId",
                            "signer"
                        ],
                        "properties": {
                            "walletId": {
                                "type": "string",
                                "format": "uuid",
                                "description": "Idempotency key supplied by the caller; becomes the wallet id."
                            },
                            "signer": {
                                "type": "object",
                                "description": "Owner P-256 public key. Provide exactly one of `signerPublicKey` (compressed SEC1 hex), `signerPublicKeyPem` (SPKI PEM), or `signerPublicKeyJwk` (EC JWK with `crv: P-256`). Embedded wallets only support the `p256` curve.",
                                "properties": {
                                    "signerPublicKey": {
                                        "type": "string",
                                        "description": "Owner's compressed SEC1 P-256 public key (hex). The only key that can authorize transactions for this wallet."
                                    },
                                    "signerPublicKeyPem": {
                                        "type": "string",
                                        "description": "Owner's P-256 public key as SPKI PEM (`-----BEGIN PUBLIC KEY-----`)."
                                    },
                                    "signerPublicKeyJwk": {
                                        "type": "object",
                                        "description": "Owner's P-256 public key as an EC JWK (`kty: EC`, `crv: P-256`)."
                                    },
                                    "curve": {
                                        "type": "string",
                                        "enum": [
                                            "p256"
                                        ],
                                        "description": "Curve of the signer key. Only `p256` is supported for embedded wallets.",
                                        "default": "p256"
                                    }
                                }
                            }
                        }
                    }
                ],
                "example": {
                    "walletId": "1b6e98a2-7c3d-4e5f-9a0b-1c2d3e4f5a6b",
                    "signer": {
                        "signerPublicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...\n-----END PUBLIC KEY-----"
                    }
                }
            },
            "RenameOrgRequest": {
                "type": "object",
                "required": [
                    "displayName"
                ],
                "properties": {
                    "displayName": {
                        "type": "string"
                    }
                },
                "example": {
                    "displayName": "Acme Inc"
                }
            },
            "RenameOrgResponse": {
                "type": "object",
                "required": [
                    "organizationId",
                    "displayName"
                ],
                "properties": {
                    "displayName": {
                        "type": "string"
                    },
                    "organizationId": {
                        "type": "string",
                        "format": "uuid"
                    }
                },
                "example": {
                    "displayName": "Acme Inc",
                    "organizationId": "123e4567-e89b-12d3-a456-426614174000"
                }
            },
            "RestrictedCountry": {
                "type": "object",
                "description": "A country with effective KYC or KYB risk marked as restricted/black.",
                "required": [
                    "code",
                    "name",
                    "kyc",
                    "kyb"
                ],
                "properties": {
                    "code": {
                        "type": "string",
                        "description": "ISO 3166-1 alpha-2 country code (e.g., `AF`)."
                    },
                    "name": {
                        "type": "string",
                        "description": "Common English country name (e.g., `Afghanistan`)."
                    },
                    "kyc": {
                        "type": "boolean",
                        "description": "Whether KYC is restricted for this country."
                    },
                    "kyb": {
                        "type": "boolean",
                        "description": "Whether KYB is restricted for this country."
                    }
                }
            },
            "RestrictedCountriesResponse": {
                "type": "object",
                "required": [
                    "countries"
                ],
                "properties": {
                    "countries": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/RestrictedCountry"
                        }
                    }
                },
                "example": {
                    "countries": [
                        {
                            "code": "AF",
                            "name": "Afghanistan",
                            "kyc": true,
                            "kyb": true
                        }
                    ]
                }
            },
            "SetPartnerFeeRequest": {
                "type": "object",
                "required": [
                    "partnerFeeDefaultBps"
                ],
                "properties": {
                    "partnerFeeDefaultBps": {
                        "type": "integer",
                        "format": "int32"
                    }
                },
                "example": {
                    "partnerFeeDefaultBps": 100
                }
            },
            "StablebondInfoCachable": {
                "type": "object",
                "description": "A single stablebond's price, net amounts, and per-chain supply.",
                "required": [
                    "symbol",
                    "netAmountDecimal",
                    "netValueDecimal",
                    "bondCurrency",
                    "tokenPriceDecimal",
                    "purchaseOrderAmount",
                    "redeemOrderAmount",
                    "blockchains",
                    "solanaMintAddress"
                ],
                "properties": {
                    "blockchains": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/BlockchainSupplyCachable"
                        },
                        "description": "Per-chain supply breakdown."
                    },
                    "bondCurrency": {
                        "type": "string",
                        "description": "Bond's settlement currency (ISO 4217)."
                    },
                    "netAmountDecimal": {
                        "type": "string",
                        "description": "Net token amount outstanding."
                    },
                    "netValueDecimal": {
                        "type": "string",
                        "description": "Net value outstanding, in the bond's currency."
                    },
                    "purchaseOrderAmount": {
                        "type": "string",
                        "description": "Open purchase-order amount."
                    },
                    "redeemOrderAmount": {
                        "type": "string",
                        "description": "Open redeem-order amount."
                    },
                    "solanaMintAddress": {
                        "type": "string",
                        "description": "Canonical Solana mint address."
                    },
                    "symbol": {
                        "type": "string",
                        "description": "Bond symbol (e.g. `CETES`)."
                    },
                    "tokenPriceDecimal": {
                        "type": "string",
                        "description": "Current per-token price."
                    }
                }
            },
            "StablebondsCachable": {
                "type": "object",
                "description": "Full stablebonds lookup response, cached as a unit.\nUses string blockchain keys (same pattern as BridgeConfig).",
                "required": [
                    "calculatedAt",
                    "stablebonds"
                ],
                "properties": {
                    "calculatedAt": {
                        "type": "string",
                        "description": "Timestamp (RFC 3339) the snapshot was computed."
                    },
                    "stablebonds": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/StablebondInfoCachable"
                        },
                        "description": "All stablebonds in the snapshot."
                    }
                },
                "example": {
                    "calculatedAt": "2024-01-15T12:00:00Z",
                    "stablebonds": [
                        {
                            "blockchains": [
                                {
                                    "blockchain": "stellar",
                                    "tokenIdentifier": "CETES-GC3CW7EDYRTWQ635VDIGY6S4ZUF5L6TQ7AA4MWS7LEQDBLUSZXV7UPS4",
                                    "totalSupply": "106595.334047"
                                },
                                {
                                    "blockchain": "solana",
                                    "tokenIdentifier": "AvvetPGuuB5FD5m86fpw3LtDKyQoUFT1mG9WarNQLW4q",
                                    "totalSupply": "916496.867925"
                                }
                            ],
                            "bondCurrency": "MXN",
                            "netAmountDecimal": "1309439.053036",
                            "netValueDecimal": "1467139.953242",
                            "purchaseOrderAmount": "283617.373522",
                            "redeemOrderAmount": "0",
                            "solanaMintAddress": "AvvetPGuuB5FD5m86fpw3LtDKyQoUFT1mG9WarNQLW4q",
                            "symbol": "CETES",
                            "tokenPriceDecimal": "1.120434"
                        }
                    ]
                }
            },
            "SubmitKycRequest": {
                "type": "object",
                "description": "Request body for submitting KYC identity data. This endpoint is for personal accounts only; business/KYB fields are not accepted.",
                "required": [
                    "identity"
                ],
                "properties": {
                    "identity": {
                        "type": "object",
                        "description": "Personal identity information for the customer.",
                        "required": [
                            "email",
                            "phoneNumber",
                            "occupation",
                            "name",
                            "dateOfBirth",
                            "address"
                        ],
                        "properties": {
                            "email": {
                                "type": "string",
                                "description": "Customer's email address."
                            },
                            "phoneNumber": {
                                "type": "string",
                                "description": "Customer's phone number in E.164 format, e.g. +525512345678."
                            },
                            "occupation": {
                                "type": "string",
                                "description": "Customer's occupation."
                            },
                            "dateOfBirth": {
                                "type": "string",
                                "description": "Date of birth in YYYY-MM-DD format."
                            },
                            "useEmailForMarketing": {
                                "type": [
                                    "boolean",
                                    "null"
                                ],
                                "description": "Whether the customer consents to marketing emails. Optional."
                            },
                            "name": {
                                "type": "object",
                                "description": "Customer's legal name.",
                                "required": [
                                    "givenName",
                                    "familyName"
                                ],
                                "properties": {
                                    "givenName": {
                                        "type": "string"
                                    },
                                    "familyName": {
                                        "type": "string"
                                    },
                                    "middleName": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "motherMaidenName": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "preferredName": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    }
                                }
                            },
                            "address": {
                                "type": "object",
                                "description": "Customer's residential address. All fields except street2 are required.",
                                "required": [
                                    "street",
                                    "city",
                                    "region",
                                    "postalCode",
                                    "country"
                                ],
                                "properties": {
                                    "street": {
                                        "type": "string"
                                    },
                                    "street2": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "city": {
                                        "type": "string"
                                    },
                                    "region": {
                                        "type": "string",
                                        "description": "State or region."
                                    },
                                    "postalCode": {
                                        "type": "string"
                                    },
                                    "country": {
                                        "type": "string",
                                        "description": "ISO 3166-1 alpha-2 country code, e.g. MX."
                                    }
                                }
                            },
                            "idNumbers": {
                                "type": "array",
                                "description": "Government-issued ID numbers. Required only when address.country is MX: both a CURP and an RFC must be included. For any other country, idNumbers must be omitted.",
                                "items": {
                                    "type": "object",
                                    "required": [
                                        "type",
                                        "value"
                                    ],
                                    "properties": {
                                        "type": {
                                            "type": "string",
                                            "description": "ID type. For Mexico, both CURP and RFC are required."
                                        },
                                        "value": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "example": {
                    "identity": {
                        "email": "ana@example.com",
                        "phoneNumber": "+525512345678",
                        "occupation": "Software Engineer",
                        "dateOfBirth": "1990-05-15",
                        "name": {
                            "givenName": "Ana",
                            "familyName": "García",
                            "motherMaidenName": "López"
                        },
                        "address": {
                            "street": "Av. Reforma 222",
                            "city": "Ciudad de México",
                            "region": "CDMX",
                            "postalCode": "06600",
                            "country": "MX"
                        },
                        "idNumbers": [
                            {
                                "type": "CURP",
                                "value": "GALA900515MDFRPN08"
                            },
                            {
                                "type": "RFC",
                                "value": "GALA900515QX4"
                            }
                        ]
                    }
                }
            },
            "SwapAssets": {
                "type": "object",
                "title": "Swap",
                "required": [
                    "sourceAsset",
                    "targetAsset"
                ],
                "properties": {
                    "sourceAsset": {
                        "type": "string",
                        "description": "This should be the asset identifier for the blockchain that you are using"
                    },
                    "targetAsset": {
                        "type": "string",
                        "description": "This should be the asset identifier for the blockchain that you are using"
                    }
                }
            },
            "UploadKycDocumentsRequest": {
                "type": "object",
                "description": "Request body for uploading KYC document images. This endpoint is for document images only — identity fields (name, address, ID numbers, etc.) are submitted separately via Submit KYC.",
                "required": [
                    "documentType",
                    "images"
                ],
                "properties": {
                    "documentType": {
                        "type": "string",
                        "enum": [
                            "document",
                            "selfie"
                        ],
                        "description": "The kind of image being uploaded: \"document\" for a government-issued ID, or \"selfie\" for a selfie/liveness photo."
                    },
                    "images": {
                        "type": "array",
                        "description": "The image(s) for this document. For a two-sided ID, upload the front and back as separate entries.",
                        "items": {
                            "$ref": "#/components/schemas/ImageUploadBody"
                        }
                    }
                },
                "example": {
                    "documentType": "document",
                    "images": [
                        {
                            "image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...",
                            "label": "id_front"
                        },
                        {
                            "image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...",
                            "label": "id_back"
                        }
                    ]
                }
            },
            "UserInfo": {
                "type": "object",
                "description": "Optional user info collected at org/customer creation time. When provided,\nthe user record is pre-populated with the partner's known display name and\nemail so the customer's eventual Firebase sign-in attaches to the correct\nuser, and so we can send status-change emails. Will eventually be required.",
                "required": [
                    "email",
                    "displayName"
                ],
                "properties": {
                    "displayName": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string"
                    }
                }
            },
            "Wallet": {
                "type": "object",
                "required": [
                    "walletId",
                    "customerId",
                    "createdAt",
                    "updatedAt",
                    "publicKey",
                    "blockchain"
                ],
                "properties": {
                    "blockchain": {
                        "$ref": "#/components/schemas/Blockchain",
                        "description": "Blockchain the wallet is on."
                    },
                    "claimedOwnership": {
                        "type": [
                            "boolean",
                            "null"
                        ],
                        "description": "Whether the wallet has active claimed ownership by the organization. When `true`\nand the organization is approved, the wallet is treated as compliant without\nrequiring individual KYC. Only present when claimed ownership has been set."
                    },
                    "createdAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Timestamp when the wallet was created."
                    },
                    "customerId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "ID of the customer who owns this wallet."
                    },
                    "deletedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "Timestamp when the wallet was deleted (if applicable)."
                    },
                    "displayName": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Display name for the wallet."
                    },
                    "kycOnChain": {
                        "type": [
                            "boolean",
                            "null"
                        ],
                        "description": "Whether KYC is marked on-chain for the wallet. Only present for Solana wallets;\nfor other blockchains this field is omitted as on-chain KYC marking does not apply."
                    },
                    "kycStatus": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Current KYC verification status for the wallet. Only present for individual wallet\ncalls. The `approved_chain_deploying` status indicates the user is approved but\nwaiting for on-chain marking (Solana only)."
                    },
                    "publicKey": {
                        "type": "string",
                        "description": "Public key / address of the wallet."
                    },
                    "signerPublicKey": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "For embedded (non-custodial) wallets, the compressed SEC1 P-256 public key of the owner key that authorizes transactions. Absent for bring-your-own wallets."
                    },
                    "updatedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Timestamp when the wallet was last updated."
                    },
                    "walletId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Unique identifier for the wallet."
                    }
                },
                "example": {
                    "blockchain": "stellar",
                    "claimedOwnership": true,
                    "createdAt": "2026-05-01T14:30:00Z",
                    "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "kycStatus": "approved",
                    "publicKey": "GDUKMGUGD3V6VXTU2RLAUM7A2FABLMHCPWTMDHKP7HHJ6FCZKEY4PVWL",
                    "updatedAt": "2026-05-02T09:15:00Z",
                    "walletId": "c3d4e5f6-a7b8-9012-cdef-123456789012"
                }
            },
            "Webhook": {
                "type": "object",
                "required": [
                    "id",
                    "eventType",
                    "url",
                    "createdAt",
                    "updatedAt"
                ],
                "properties": {
                    "createdAt": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Unix timestamp in seconds."
                    },
                    "eventType": {
                        "$ref": "#/components/schemas/WebhookEvent"
                    },
                    "id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "updatedAt": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Unix timestamp in seconds."
                    },
                    "url": {
                        "type": "string"
                    }
                },
                "example": {
                    "createdAt": 1748345400,
                    "eventType": "order_updated",
                    "id": "d4e5f6a7-b8c9-0123-defa-234567890123",
                    "updatedAt": 1748431800,
                    "url": "https://example.com/webhooks/etherfuse"
                }
            },
            "WebhookEvent": {
                "type": "string",
                "enum": [
                    "bank_account_updated",
                    "customer_updated",
                    "order_updated",
                    "swap_updated",
                    "kyc_updated",
                    "kyb_updated"
                ]
            },
            "WebhookStatus": {
                "type": "string",
                "description": "Status value included in webhook payloads. The prefix identifies the entity type.",
                "enum": [
                    "bank_account_pending",
                    "bank_account_awaiting_deposit_verification",
                    "bank_account_active",
                    "bank_account_inactive",
                    "customer_pending",
                    "customer_verified",
                    "customer_failed",
                    "order_created",
                    "order_funded",
                    "order_completed",
                    "order_failed",
                    "kyc_proposed",
                    "kyc_under_review",
                    "kyc_approved",
                    "kyc_rejected"
                ]
            },
            "SwapWebhookPayload": {
                "type": "object",
                "description": "Payload for `swap_updated` webhooks.",
                "required": [
                    "orderId",
                    "customerId",
                    "sendTransaction",
                    "sendTransactionHash",
                    "status",
                    "createdAt",
                    "updatedAt"
                ],
                "properties": {
                    "orderId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Unique identifier for the swap order."
                    },
                    "customerId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "ID of the customer."
                    },
                    "sendTransaction": {
                        "type": "string",
                        "description": "Encoded transaction for the customer to sign and submit."
                    },
                    "sendTransactionHash": {
                        "type": "string",
                        "description": "Hash of the send transaction once confirmed on-chain."
                    },
                    "receiveTransactionHash": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Hash of the receive transaction (set on completion)."
                    },
                    "status": {
                        "type": "string",
                        "description": "Current swap status.",
                        "enum": [
                            "created",
                            "funded",
                            "completed",
                            "failed"
                        ]
                    },
                    "createdAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Timestamp when the swap was created."
                    },
                    "updatedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Timestamp when the swap was last updated."
                    }
                },
                "example": {
                    "orderId": "e1f2a3b4-c5d6-7890-abcd-ef1234567890",
                    "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "sendTransaction": "AQAAAAAAAA...",
                    "sendTransactionHash": "5KtP...",
                    "receiveTransactionHash": null,
                    "status": "funded",
                    "createdAt": "2026-05-02T09:15:00Z",
                    "updatedAt": "2026-05-02T09:15:30Z"
                }
            },
            "KycWebhookPayload": {
                "type": "object",
                "description": "Payload for `kyc_updated` webhooks.",
                "required": [
                    "customerId",
                    "walletPublicKey",
                    "approved"
                ],
                "properties": {
                    "customerId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "ID of the customer whose KYC status changed."
                    },
                    "walletPublicKey": {
                        "type": "string",
                        "description": "Public key of the wallet the KYC decision applies to."
                    },
                    "approved": {
                        "type": "boolean",
                        "description": "Whether KYC is now approved (`true`) or rejected (`false`)."
                    },
                    "updateReason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Human-readable reason for the status change (present on rejections)."
                    },
                    "needsWork": {
                        "type": [
                            "boolean",
                            "null"
                        ],
                        "description": "Whether the submission has been flagged as needing corrections before re-review."
                    },
                    "userMessage": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "User-facing message explaining what needs to be fixed."
                    }
                },
                "example": {
                    "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "walletPublicKey": "9Qx7rGN1kP2mL3nO4pQ5sR6tU7vW8xY9zA0bC1dE2fG",
                    "approved": true,
                    "updateReason": null,
                    "needsWork": null,
                    "userMessage": null
                }
            },
            "KybWebhookPayload": {
                "type": "object",
                "description": "Payload for `kyb_updated` webhooks: the same shape as the [Get KYB progress](/api-reference/organizations/get-kyb-progress) response. Counts cover the customer-facing requirements only; admin-only requirements are excluded.",
                "required": [
                    "organizationId",
                    "status",
                    "approved",
                    "submitted",
                    "notStarted",
                    "total"
                ],
                "properties": {
                    "organizationId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "ID of the business organization whose KYB status changed."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "not_started",
                            "awaiting_documents",
                            "awaiting_review",
                            "approved",
                            "denied"
                        ],
                        "description": "The new KYB status. `not_started`: no requirements answered yet. `awaiting_documents`: the customer has requirements left to fill or upload. `awaiting_review`: the ball is in Etherfuse's court (open clarification notes, or everything submitted and awaiting review). `approved`: KYB approved. `denied`: KYB denied."
                    },
                    "approved": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Requirements with an approved answer."
                    },
                    "submitted": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Requirements answered but not yet approved."
                    },
                    "notStarted": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Requirements with no answer yet."
                    },
                    "total": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Total applicable requirements (`approved + submitted + notStarted`)."
                    },
                    "approvedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the organization was approved, if approved."
                    }
                },
                "example": {
                    "organizationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "status": "approved",
                    "approved": 12,
                    "submitted": 0,
                    "notStarted": 0,
                    "total": 12,
                    "approvedAt": "2026-05-02T09:15:00Z"
                }
            },
            "OrderUpdatedWebhook": {
                "type": "object",
                "description": "Webhook envelope for order status changes. The payload is keyed by event name.",
                "required": [
                    "order_updated"
                ],
                "properties": {
                    "order_updated": {
                        "$ref": "#/components/schemas/Order"
                    }
                },
                "example": {
                    "order_updated": {
                        "orderId": "7b9c1e2d-3f4a-5b6c-7d8e-9f0a1b2c3d4e",
                        "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                        "createdAt": "2026-05-02T09:15:00Z",
                        "updatedAt": "2026-05-02T09:16:30Z",
                        "amountInFiat": "1000.00",
                        "amountInTokens": "58.42",
                        "walletId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
                        "bankAccountId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
                        "depositClabe": "646180157000000004",
                        "depositBankName": "Example Bank",
                        "depositAccountHolder": "Etherfuse MX",
                        "orderType": "onramp",
                        "status": "completed",
                        "statusPage": "https://pay.etherfuse.com/order/7b9c1e2d-3f4a-5b6c-7d8e-9f0a1b2c3d4e",
                        "confirmedTxSignature": "5KtPn1...",
                        "trackingCode": "2025011540014000000012345678",
                        "sourceAsset": "MXN",
                        "targetAsset": "CETES",
                        "blockchain": "solana",
                        "exchangeRate": "17.12",
                        "etherfuseMidMarketRate": "17.15",
                        "feeBps": 20,
                        "feeAmountInFiat": "2.00"
                    }
                }
            },
            "SwapUpdatedWebhook": {
                "type": "object",
                "description": "Webhook envelope for swap status changes.",
                "required": [
                    "swap_updated"
                ],
                "properties": {
                    "swap_updated": {
                        "$ref": "#/components/schemas/SwapWebhookPayload"
                    }
                },
                "example": {
                    "swap_updated": {
                        "orderId": "e1f2a3b4-c5d6-7890-abcd-ef1234567890",
                        "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                        "sendTransaction": "AQAAAAAAAA...",
                        "sendTransactionHash": "5KtP...",
                        "receiveTransactionHash": "3JmN...",
                        "status": "completed",
                        "createdAt": "2026-05-02T09:15:00Z",
                        "updatedAt": "2026-05-02T09:18:00Z"
                    }
                }
            },
            "CustomerUpdatedWebhook": {
                "type": "object",
                "description": "Webhook envelope for customer verification status changes.",
                "required": [
                    "customer_updated"
                ],
                "properties": {
                    "customer_updated": {
                        "$ref": "#/components/schemas/Customer"
                    }
                },
                "example": {
                    "customer_updated": {
                        "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                        "displayName": "Ana García",
                        "createdAt": "2026-05-01T14:30:00Z",
                        "updatedAt": "2026-05-02T09:15:00Z"
                    }
                }
            },
            "BankAccountUpdatedWebhook": {
                "type": "object",
                "description": "Webhook envelope for bank account status changes.",
                "required": [
                    "bank_account_updated"
                ],
                "properties": {
                    "bank_account_updated": {
                        "$ref": "#/components/schemas/BankAccount"
                    }
                },
                "example": {
                    "bank_account_updated": {
                        "bankAccountId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
                        "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                        "createdAt": "2026-05-01T14:30:00Z",
                        "updatedAt": "2026-05-02T10:00:00Z",
                        "currency": "MXN",
                        "abbrClabe": "••••0004",
                        "etherfuseDepositClabe": "646180157000000004",
                        "label": "Ana's SPEI account",
                        "compliant": true,
                        "needsWork": false,
                        "status": "active"
                    }
                }
            },
            "KycUpdatedWebhook": {
                "type": "object",
                "description": "Webhook envelope for KYC review decisions.",
                "required": [
                    "kyc_updated"
                ],
                "properties": {
                    "kyc_updated": {
                        "$ref": "#/components/schemas/KycWebhookPayload"
                    }
                },
                "example": {
                    "kyc_updated": {
                        "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                        "walletPublicKey": "9Qx7rGN1kP2mL3nO4pQ5sR6tU7vW8xY9zA0bC1dE2fG",
                        "approved": false,
                        "updateReason": "ID document is expired",
                        "needsWork": true,
                        "userMessage": "Please upload a current government-issued ID."
                    }
                }
            },
            "KybUpdatedWebhook": {
                "type": "object",
                "description": "Webhook envelope for KYB status changes.",
                "required": [
                    "kyb_updated"
                ],
                "properties": {
                    "kyb_updated": {
                        "$ref": "#/components/schemas/KybWebhookPayload"
                    }
                },
                "example": {
                    "kyb_updated": {
                        "organizationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                        "status": "approved",
                        "approved": 12,
                        "submitted": 0,
                        "notStarted": 0,
                        "total": 12,
                        "approvedAt": "2026-05-02T09:15:00Z"
                    }
                }
            },
            "RegisterWalletExternal": {
                "type": "object",
                "title": "Bring-your-own wallet",
                "required": [
                    "publicKey",
                    "blockchain"
                ],
                "properties": {
                    "publicKey": {
                        "type": "string",
                        "description": "Wallet public key / address."
                    },
                    "blockchain": {
                        "$ref": "#/components/schemas/Blockchain",
                        "description": "Target blockchain."
                    },
                    "claimOwnership": {
                        "type": "boolean",
                        "description": "Claim org ownership of the wallet for compliance attribution. Defaults to `false`."
                    }
                },
                "example": {
                    "publicKey": "GDUKMGUGD3V6VXTU2RLAUM7A2FABLMHCPWTMDHKP7HHJ6FCZKEY4PVWL",
                    "blockchain": "stellar"
                }
            }
        },
        "securitySchemes": {
            "ApiKeyAuth": {
                "type": "apiKey",
                "in": "header",
                "name": "Authorization",
                "description": "API key sent in the Authorization header."
            }
        }
    },
    "security": [
        {
            "ApiKeyAuth": []
        }
    ],
    "tags": [
        {
            "name": "Authentication",
            "description": "Partner JWT authentication — exchange a JWT for an access token, or launch a user into the app."
        },
        {
            "name": "Lookup",
            "description": "Public reference data: exchange rates, stablebonds, bond costs, country codes."
        },
        {
            "name": "Assets",
            "description": "Rampable stablecoins and stablebonds available per blockchain."
        },
        {
            "name": "Onboarding",
            "description": "Hosted and programmatic customer onboarding."
        },
        {
            "name": "Bank Accounts",
            "description": "Register and retrieve customer bank accounts."
        },
        {
            "name": "Quotes",
            "description": "Price quotes for onramps, offramps, and swaps."
        },
        {
            "name": "Orders",
            "description": "Create, track, and manage ramp orders."
        },
        {
            "name": "Swaps",
            "description": "Crypto-to-crypto swaps."
        },
        {
            "name": "Sponsored",
            "description": "Token approvals for sponsored (gasless) offramps."
        },
        {
            "name": "Customers",
            "description": "Customer (child-organization) records."
        },
        {
            "name": "Wallets",
            "description": "Register and manage customer wallets."
        },
        {
            "name": "KYC",
            "description": "Submit and check customer KYC status."
        },
        {
            "name": "Webhooks",
            "description": "Event notification subscriptions."
        },
        {
            "name": "Organizations",
            "description": "Organization identity, child orgs, and partner fees."
        }
    ],
    "webhooks": {
        "orderUpdated": {
            "post": {
                "summary": "order_updated",
                "operationId": "orderUpdatedWebhook",
                "description": "Fired when an onramp or offramp order changes status.\n\n**Statuses:** `created` → `funded` → `completed` (or `failed`, `refunded`, `canceled`). Offramp orders additionally emit `finalized` after the reversal window closes.\n\nThe `X-Signature` header contains an HMAC-SHA256 signature over the [RFC 8785](https://datatracker.ietf.org/doc/html/rfc8785)-canonicalized JSON body. See [Verifying Webhooks](/guides/verifying-webhooks).",
                "parameters": [
                    {
                        "name": "X-Signature",
                        "in": "header",
                        "required": true,
                        "description": "HMAC-SHA256 signature: `sha256={hex}`. Computed over the canonicalized (RFC 8785) request body using your webhook secret.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "sha256=a1b2c3d4e5f6..."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/OrderUpdatedWebhook"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Return any `2xx` to acknowledge receipt. Process the event asynchronously — a slow handler triggers retries."
                    }
                },
                "tags": [
                    "Webhooks"
                ]
            }
        },
        "swapUpdated": {
            "post": {
                "summary": "swap_updated",
                "operationId": "swapUpdatedWebhook",
                "description": "Fired when a swap changes status.\n\n**Statuses:** `created` → `funded` → `completed` (or `failed`).\n\n`sendTransaction` is always present — it contains the transaction the customer needs to sign and submit. Once signed, the field remains but is no longer actionable. On completion, both `sendTransactionHash` and `receiveTransactionHash` are present.",
                "parameters": [
                    {
                        "name": "X-Signature",
                        "in": "header",
                        "required": true,
                        "description": "HMAC-SHA256 signature: `sha256={hex}`. Computed over the canonicalized (RFC 8785) request body using your webhook secret.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "sha256=a1b2c3d4e5f6..."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SwapUpdatedWebhook"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Return any `2xx` to acknowledge receipt."
                    }
                },
                "tags": [
                    "Webhooks"
                ]
            }
        },
        "customerUpdated": {
            "post": {
                "summary": "customer_updated",
                "operationId": "customerUpdatedWebhook",
                "description": "Fired when a customer's verification status changes.\n\n**Statuses:** `customer_pending` → `customer_verified` (or `customer_failed`).\n\nGate access to transacting behind `customer_verified`.",
                "parameters": [
                    {
                        "name": "X-Signature",
                        "in": "header",
                        "required": true,
                        "description": "HMAC-SHA256 signature: `sha256={hex}`. Computed over the canonicalized (RFC 8785) request body using your webhook secret.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "sha256=a1b2c3d4e5f6..."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CustomerUpdatedWebhook"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Return any `2xx` to acknowledge receipt."
                    }
                },
                "tags": [
                    "Webhooks"
                ]
            }
        },
        "bankAccountUpdated": {
            "post": {
                "summary": "bank_account_updated",
                "operationId": "bankAccountUpdatedWebhook",
                "description": "Fired when a bank account's verification status changes.\n\n**Statuses:** `bank_account_pending` → `bank_account_awaiting_deposit_verification` → `bank_account_active` (or `bank_account_inactive`).\n\nEnable offramps and payouts only after receiving `bank_account_active`.",
                "parameters": [
                    {
                        "name": "X-Signature",
                        "in": "header",
                        "required": true,
                        "description": "HMAC-SHA256 signature: `sha256={hex}`. Computed over the canonicalized (RFC 8785) request body using your webhook secret.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "sha256=a1b2c3d4e5f6..."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/BankAccountUpdatedWebhook"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Return any `2xx` to acknowledge receipt."
                    }
                },
                "tags": [
                    "Webhooks"
                ]
            }
        },
        "kycUpdated": {
            "post": {
                "summary": "kyc_updated",
                "operationId": "kycUpdatedWebhook",
                "description": "Fired when a programmatic KYC submission is reviewed.\n\n**Statuses:** `kyc_proposed` → `kyc_approved` (or `kyc_rejected`).\n\nOn rejection, `updateReason` and `userMessage` explain what needs to be corrected. When `needsWork` is `true`, the customer can resubmit without creating a new KYC request.",
                "parameters": [
                    {
                        "name": "X-Signature",
                        "in": "header",
                        "required": true,
                        "description": "HMAC-SHA256 signature: `sha256={hex}`. Computed over the canonicalized (RFC 8785) request body using your webhook secret.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "sha256=a1b2c3d4e5f6..."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/KycUpdatedWebhook"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Return any `2xx` to acknowledge receipt."
                    }
                },
                "tags": [
                    "Webhooks"
                ]
            }
        },
        "kybUpdated": {
            "post": {
                "summary": "kyb_updated",
                "operationId": "kybUpdatedWebhook",
                "description": "Fired when a business organization's KYB status changes.\n\n**Statuses:** `not_started`, `awaiting_documents` (the customer has documents left to submit), `awaiting_review` (everything submitted or there are open notes, Etherfuse's turn), `approved`, `denied`.\n\nFires only on an actual status transition, never on individual answer edits that leave the status unchanged. The `approved`, `submitted`, `notStarted`, and `total` counts track onboarding progress; `approvedAt` is set once the organization is approved.",
                "parameters": [
                    {
                        "name": "X-Signature",
                        "in": "header",
                        "required": true,
                        "description": "HMAC-SHA256 signature: `sha256={hex}`. Computed over the canonicalized (RFC 8785) request body using your webhook secret.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "sha256=a1b2c3d4e5f6..."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/KybUpdatedWebhook"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Return any `2xx` to acknowledge receipt."
                    }
                },
                "tags": [
                    "Webhooks"
                ]
            }
        }
    }
}
