{
    "schemes": ["https"],
    "swagger": "2.0",
    "info": {
        "description": "Rach CaaS is the stablecoin infrastructure layer for African fintechs and financial institutions. It enables any business to offer their customers non-custodial USDC wallets, instant on-chain transfers, and XOF ↔ USDC conversion — without building blockchain infrastructure.\n\n**Network:** Polygon PoS (Chain ID 137). All smart contract wallets, transfers, and withdrawals settle on Polygon mainnet. Test environments use Sepolia (Chain ID 11155111).\n\n## Authentication\n**B2B API endpoints** (`/v1/users/*`, `/v1/transfers/*`, `/v1/fx/*`) use API Key authentication. Pass your key in the `X-API-Key` header. Keys are prefixed `rach_sk_live_` (mainnet) or `rach_sk_test_` (sandbox — no on-chain execution).\n\n**Dashboard endpoints** (`/v1/dashboard/*`) use JWT Bearer authentication. Your JWT must include `business_id` and the `waas` permission scope.\n\n## Sandbox Mode\nAll B2B endpoints honour test-mode API keys (`rach_sk_test_*`). In sandbox mode every operation returns an immediate success response (`SANDBOX_SIMULATED`) without touching the blockchain or debiting your treasury balance. Use sandbox keys for integration testing and CI.\n\n## Typical Integration Flow\n1. `POST /v1/users/provision` — create a non-custodial SCW for each end-user (offline, no gas)\n2. Collect fiat from customer → deposit to Rach bank account → `POST /v1/dashboard/treasury/topup`\n3. Rach confirms XOF receipt → `POST /v1/dashboard/treasury/topup/{id}/confirm` (credits your USDC balance)\n4. `POST /v1/users/fund` — transfer USDC from your treasury balance to the customer SCW on-chain\n5. `GET /v1/users/balance` — read live on-chain USDC balance via Polygon RPC\n6. `POST /v1/transfers/send` — instant peer-to-peer USDC transfer between customer SCWs (ERC-4337 UserOp)\n7. `POST /v1/users/withdraw` — off-ramp: sweep USDC from SCW back to Rach treasury; Rach pays out XOF via mobile money\n\n## Status Lifecycles\n**Deposit:** `QUEUED` → `SETTLED`\n**Transfer:** `QUEUED` → `SUBMITTED` → `SETTLED`\n**Withdrawal:** `PENDING` → `SUBMITTED` → `CRYPTO_RECEIVED` → `COMPLETED`",
        "title": "Rach CaaS — Crypto-as-a-Service API",
        "contact": {
            "name": "Rach Finance Support",
            "url": "https://rach.finance"
        },
        "version": "1.0.1"
    },
    "host": "rach-caas-api-dx75yvdhaq-nw.a.run.app",
    "basePath": "/",
    "paths": {
        "/v1/dashboard/apikeys": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns active API keys.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Developer"
                ],
                "summary": "List API Keys",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                }
            },
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Generates a new secure API key for server-to-server integration. The key_secret is returned only once — store it securely. Use mode=test for sandbox (no real blockchain), mode=live for production.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Developer"
                ],
                "summary": "Generate API Key",
                "parameters": [
                    {
                        "description": "Optional: specify mode (test|live, defaults to live)",
                        "name": "request",
                        "in": "body",
                        "schema": {
                            "$ref": "#/definitions/api.CreateAPIKeyRequest"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/apikeys/{id}": {
            "delete": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Hard-revokes an active API key.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Developer"
                ],
                "summary": "Revoke API Key",
                "parameters": [
                    {
                        "type": "string",
                        "description": "API Key ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/deposits": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns paginated USSD / fiat-to-crypto deposits for the tenant. Use ?page=1\u0026limit=20.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard"
                ],
                "summary": "List Deposits",
                "parameters": [
                    {
                        "type": "integer",
                        "description": "Page number (default 1)",
                        "name": "page",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "description": "Page size (default 20, max 100)",
                        "name": "limit",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/deposits/{id}": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns the full record for a single deposit, scoped to the authenticated tenant.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard"
                ],
                "summary": "Get Deposit Detail",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Deposit ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/metrics": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Fetches total active wallets, processed volume, and 24h operational status for the active tenant.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard"
                ],
                "summary": "Get Dashboard Overview Metrics",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/api.DashboardMetrics"
                        }
                    }
                }
            }
        },
        "/v1/dashboard/team": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns RBAC configurations.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Governance"
                ],
                "summary": "List Team Members",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                }
            },
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Provisions a new RBAC role.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Governance"
                ],
                "summary": "Invite Team Member",
                "parameters": [
                    {
                        "description": "Team Member Details",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/api.CreateTeamMemberRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/team/{id}": {
            "delete": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Revokes access for a specific team member.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Governance"
                ],
                "summary": "Remove Team Member",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Team Member ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/transfers": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Retrieves a paginated list of all asynchronous ERC-4337 transfers associated with the business.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard"
                ],
                "summary": "List Asynchronous Ledger",
                "parameters": [
                    {
                        "type": "integer",
                        "default": 50,
                        "description": "Number of records to return",
                        "name": "limit",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "default": 0,
                        "description": "Number of records to skip",
                        "name": "offset",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/api.ExtendedTransactionInstance"
                            }
                        }
                    }
                }
            }
        },
        "/v1/dashboard/transfers/{id}": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Fetches the deep forensics details for the right-side inspection drawer.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard"
                ],
                "summary": "Get Granular Transfer Details",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Transfer ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/api.ExtendedTransactionInstance"
                        }
                    }
                }
            }
        },
        "/v1/dashboard/treasury/paymaster": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Queries the Base Network EntryPoint for the live native token balance backing the business paymaster.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard"
                ],
                "summary": "Get Live Paymaster Gas Tank",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/api.LivePaymasterGasCapacity"
                        }
                    }
                }
            }
        },
        "/v1/dashboard/treasury/tenant-balance": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns the tenant's current internal USDC balance held within the Rach treasury. This balance is credited by Rach when it confirms receipt of fiat (XOF/NGN/etc.) in its settlement account and completes the conversion. It is debited each time POST /v1/users/fund is called.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Treasury"
                ],
                "summary": "Get Tenant USDC Balance",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/api.TenantBalanceResponse"
                        }
                    }
                }
            }
        },
        "/v1/dashboard/treasury/topup": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Notifies Rach that fiat has been deposited into the Rach settlement account (bank transfer or HUB2 settlement) and requests a USDC credit to this tenant's internal balance. The topup is created with status PENDING and must be confirmed by a Rach operator or the automated confirmation endpoint before the balance is credited.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Treasury"
                ],
                "summary": "Submit Treasury Topup",
                "parameters": [
                    {
                        "description": "Topup details",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/api.TreasuryTopupRequest"
                        }
                    }
                ],
                "responses": {
                    "202": {
                        "description": "Accepted",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/treasury/topup/{id}/confirm": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Marks a pending topup as CONFIRMED and immediately credits the tenant's USDC balance. This is called by Rach operators after verifying fiat receipt in the Ivory Coast bank account, or by the automated HUB2 settlement reconciliation system.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Treasury"
                ],
                "summary": "Confirm Topup and Credit Balance (Rach Operator / Internal)",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Topup ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Operator attribution",
                        "name": "request",
                        "in": "body",
                        "schema": {
                            "$ref": "#/definitions/api.ConfirmTopupRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/treasury/topups": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns the history of all USDC credit events (topups) for this tenant, including their confirmation status.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Treasury"
                ],
                "summary": "List Treasury Topups",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                }
            }
        },
        "/v1/dashboard/treasury/usdc": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Queries the live USDC stablecoin balance held by the treasury wallet on-chain.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard"
                ],
                "summary": "Get USDC Treasury Balance",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/api.TreasuryUsdcBalanceResponse"
                        }
                    }
                }
            }
        },
        "/v1/dashboard/users": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Fetches the provisioned users connected to the tenant.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard"
                ],
                "summary": "List SCW User Directory",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/api.UserAccountResponse"
                            }
                        }
                    }
                }
            }
        },
        "/v1/dashboard/users/lookup": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Finds the user record associated with a Smart Contract Wallet address. Useful for operators recovering a user account after a phone number change.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard"
                ],
                "summary": "Lookup User by Wallet Address (SCW Recovery)",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Wallet address (0x...)",
                        "name": "wallet",
                        "in": "query",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/users/{blind_index}": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns the profile and transaction summary for a single end-user, scoped to the authenticated tenant.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard"
                ],
                "summary": "Get User Detail",
                "parameters": [
                    {
                        "type": "string",
                        "description": "User Blind Index",
                        "name": "blind_index",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/api.UserDetailResponse"
                        }
                    }
                }
            }
        },
        "/v1/dashboard/users/{blind_index}/freeze": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Hard-freezes a user's account, preventing further transactions.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Compliance"
                ],
                "summary": "Freeze User SCW",
                "parameters": [
                    {
                        "type": "string",
                        "description": "User Blind Index",
                        "name": "blind_index",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/users/{blind_index}/update-phone": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Allows an admin to update the phone_hash for a user (e.g. after a mobile number change). The blind_index and wallet_address remain unchanged, preserving the user's SCW. The new_phone_hash must be the server-side HMAC of the new phone number.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard"
                ],
                "summary": "Admin: Update User Phone Hash (SCW Recovery)",
                "parameters": [
                    {
                        "type": "string",
                        "description": "User Blind Index",
                        "name": "blind_index",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "New phone hash",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/api.AdminUpdatePhoneRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/webhooks": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns configured webhook targets.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Developer"
                ],
                "summary": "List Webhooks",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                }
            },
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Registers a new webhook target URL.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Developer"
                ],
                "summary": "Create Webhook",
                "parameters": [
                    {
                        "description": "Webhook config",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/api.CreateWebhookRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/webhooks/logs": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns granular logs of recent HTTP callbacks.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Developer"
                ],
                "summary": "List Webhook Logs",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                }
            }
        },
        "/v1/dashboard/webhooks/{id}": {
            "delete": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Deactivates a webhook target.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Developer"
                ],
                "summary": "Delete Webhook",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Webhook ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/withdrawals": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns a paginated list of all off-ramp withdrawal requests for the authenticated tenant. Use status filter to find requests awaiting payout (CRYPTO_RECEIVED).",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard - Withdrawals"
                ],
                "summary": "List withdrawals for tenant",
                "parameters": [
                    {
                        "type": "integer",
                        "description": "Page number (default 1)",
                        "name": "page",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "description": "Results per page (default 20)",
                        "name": "limit",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/withdrawals/pending-payouts": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns all withdrawals across all tenants in CRYPTO_RECEIVED status — these are the ones where USDC has arrived in the Rach treasury and the XOF payout via HUB2 is pending.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard - Withdrawals"
                ],
                "summary": "List all withdrawals awaiting XOF payout (super admin only)",
                "parameters": [
                    {
                        "type": "integer",
                        "description": "Page number (default 1)",
                        "name": "page",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "403": {
                        "description": "Forbidden",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/withdrawals/{id}": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns the full detail of a withdrawal record scoped to the authenticated tenant.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard - Withdrawals"
                ],
                "summary": "Get a single withdrawal",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Withdrawal ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/dashboard/withdrawals/{id}/confirm-payout": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Marks a withdrawal as COMPLETED after a Rach operator has disbursed XOF to the customer via HUB2 or another mobile money rail. Requires is_super_admin: true. The withdrawal must be in CRYPTO_RECEIVED status.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Dashboard - Withdrawals"
                ],
                "summary": "Confirm XOF payout sent (super admin only)",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Withdrawal ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Optional note",
                        "name": "request",
                        "in": "body",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "403": {
                        "description": "Forbidden",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/fx/quote": {
            "post": {
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ],
                "description": "Returns a locked exchange rate for converting local fiat (XOF, NGN, KES, etc.) to USDC. The returned quote_id must be passed to POST /v1/transfers/send for fiat-denominated transfers. Quotes expire in 60 seconds — check expires_at before use. For direct crypto-to-crypto transfers without FX conversion use the DIRECT_CRYPTO:{TOKEN}:{AMOUNT} quote_id format instead.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "B2B - FX"
                ],
                "summary": "Get FX Conversion Quote",
                "parameters": [
                    {
                        "description": "Quote request",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/main.QuoteRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/main.QuoteResponse"
                        }
                    },
                    "400": {
                        "description": "Invalid currency or missing fields",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "500": {
                        "description": "FX engine error or unsupported trading pair",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/transfers/send": {
            "post": {
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ],
                "description": "Moves USDC between two customer SCWs on Polygon PoS via an ERC-4337 UserOperation. Settlement is on-chain and final within seconds — no banks, no correspondents, no cut-off times. Both sender and recipient must be provisioned users under your tenant. For fiat-denominated transfers supply a valid quote_id from POST /v1/fx/quote. For direct crypto amounts use quote_id format `DIRECT_CRYPTO:USDC:{amount}` (e.g. `DIRECT_CRYPTO:USDC:10.50`). AML daily/monthly limits apply per sender.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "B2B - Transfers"
                ],
                "summary": "Send Instant On-Chain Transfer",
                "parameters": [
                    {
                        "description": "Transfer payload",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/main.TransferRequest"
                        }
                    }
                ],
                "responses": {
                    "202": {
                        "description": "Accepted",
                        "schema": {
                            "$ref": "#/definitions/main.TransferResponse"
                        }
                    },
                    "400": {
                        "description": "Invalid payload or expired FX quote",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "404": {
                        "description": "Sender or recipient wallet not provisioned",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "409": {
                        "description": "Duplicate idempotency key",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "410": {
                        "description": "FX quote expired",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "429": {
                        "description": "AML block: daily or monthly limit exceeded",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/users/balance": {
            "get": {
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ],
                "description": "Returns the live on-chain USDC balance for a customer's Smart Contract Wallet, read directly from the Polygon PoS network via eth_call. The balance reflects settled on-chain state — there is no caching or internal ledger. Phone number must be URL-encoded (use %2B for +).",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "B2B - Users"
                ],
                "summary": "Get Customer USDC Balance",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Customer E.164 phone number (URL-encoded, e.g. %2B2250700000001)",
                        "name": "phone_number",
                        "in": "query",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/main.BalanceResponse"
                        }
                    },
                    "400": {
                        "description": "Missing phone_number parameter",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "404": {
                        "description": "Wallet not provisioned for this phone number",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/users/fund": {
            "post": {
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ],
                "description": "Credits a customer's Smart Contract Wallet with USDC on Polygon PoS. This triggers an ERC-20 transfer from the Rach treasury EOA to the customer's SCW address. Debits your internal tenant USDC balance atomically before dispatching — returns 402 if your balance is insufficient. Idempotent: supply a stable deposit_id to safely retry without double-crediting.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "B2B - Users"
                ],
                "summary": "Fund Customer SCW (On-Ramp)",
                "parameters": [
                    {
                        "description": "Deposit payload",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/main.FundUserRequest"
                        }
                    }
                ],
                "responses": {
                    "202": {
                        "description": "Accepted",
                        "schema": {
                            "$ref": "#/definitions/main.FundUserResponse"
                        }
                    },
                    "400": {
                        "description": "Invalid payload or missing fields",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "402": {
                        "description": "Insufficient tenant USDC balance — top up via /v1/dashboard/treasury/topup",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "404": {
                        "description": "Customer wallet not provisioned — call /v1/users/provision first",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "409": {
                        "description": "Duplicate deposit_id — already processed",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/users/provision": {
            "post": {
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ],
                "description": "Registers a customer by computing their unique deterministic ERC-4337 smart contract wallet (SCW) address on Polygon PoS. The address is derived offline from a cryptographic identity salt — no gas, no on-chain transaction. Safe to call multiple times; returns ALREADY_EXISTS with the same address if the customer already has a wallet.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "B2B - Users"
                ],
                "summary": "Provision User SCW Address",
                "parameters": [
                    {
                        "description": "Phone Number Payload",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/main.ProvisionUserRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/main.ProvisionUserResponse"
                        }
                    },
                    "400": {
                        "description": "Invalid phone number (must be E.164)",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "500": {
                        "description": "Factory address computation failed",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/users/update-phone": {
            "post": {
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ],
                "description": "Migrates a customer's identity to a new phone number while preserving their exact SCW address, on-chain USDC balance, and full transaction history. Use when a customer loses their SIM or changes their number. Only the phone lookup index is updated — the wallet address is immutable.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "B2B - Users"
                ],
                "summary": "Update Customer Phone Number",
                "parameters": [
                    {
                        "description": "Phone Update Payload",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/main.UpdatePhoneRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/main.ProvisionUserResponse"
                        }
                    },
                    "400": {
                        "description": "Invalid phone format (must be E.164)",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "404": {
                        "description": "Original phone number not found",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "409": {
                        "description": "New phone number already registered to another wallet",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/users/withdraw": {
            "post": {
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ],
                "description": "Sweeps USDC from a customer SCW to the Rach treasury via an ERC-4337 UserOperation on Polygon PoS. Once USDC is confirmed on-chain (CRYPTO_RECEIVED), Rach disburses XOF to the customer via the specified mobile money network. Monitor status via GET /v1/dashboard/withdrawals/{id}. Status lifecycle: PENDING → SUBMITTED → CRYPTO_RECEIVED → COMPLETED.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "B2B - Users"
                ],
                "summary": "Initiate Off-Ramp Withdrawal",
                "parameters": [
                    {
                        "description": "Withdrawal request",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/main.WithdrawRequest"
                        }
                    }
                ],
                "responses": {
                    "202": {
                        "description": "Accepted",
                        "schema": {
                            "$ref": "#/definitions/main.WithdrawResponse"
                        }
                    },
                    "400": {
                        "description": "Invalid payload or phone format",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "404": {
                        "description": "Customer wallet not found",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "500": {
                        "description": "Failed to create withdrawal record or enqueue task",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            }
        },
        "/v1/ussd/callback/at": {
            "post": {
                "description": "Decodes standard Africa's Talking API payloads to advance the inner wallet state machine.",
                "consumes": [
                    "application/x-www-form-urlencoded"
                ],
                "produces": [
                    "text/plain"
                ],
                "tags": [
                    "telecom"
                ],
                "summary": "Process Africa's Talking USSD Webhook",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Unique session ID",
                        "name": "sessionId",
                        "in": "formData",
                        "required": true
                    },
                    {
                        "type": "string",
                        "description": "Subscriber phone number",
                        "name": "phoneNumber",
                        "in": "formData",
                        "required": true
                    },
                    {
                        "type": "string",
                        "description": "Full concatenated input string separated by asterisks (*)",
                        "name": "text",
                        "in": "formData"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Plaintext response starting with CON or END",
                        "schema": {
                            "type": "string"
                        }
                    }
                }
            }
        },
        "/v1/ussd/callback/mtn": {
            "post": {
                "description": "Handles the stateful session lifecycle for MTN USSD interactions. Auto-provisions counterfactual SCWs on first dial.",
                "consumes": [
                    "application/x-www-form-urlencoded"
                ],
                "produces": [
                    "text/plain"
                ],
                "tags": [
                    "telecom"
                ],
                "summary": "Process MTN Nigeria USSD Webhook",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Unique session identifier generated by telecom switch",
                        "name": "SessionId",
                        "in": "formData",
                        "required": true
                    },
                    {
                        "type": "string",
                        "description": "The subscriber's MSISDN (Phone number in E.164 format)",
                        "name": "Mobile",
                        "in": "formData",
                        "required": true
                    },
                    {
                        "type": "string",
                        "description": "The text payload entered by the user on their keypad",
                        "name": "UserData",
                        "in": "formData"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Returns 'CON \u003cmsg\u003e' to continue or 'END \u003cmsg\u003e' to close session",
                        "schema": {
                            "type": "string"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "type": "string"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "api.AdminUpdatePhoneRequest": {
            "type": "object",
            "required": [
                "new_phone_hash"
            ],
            "properties": {
                "new_phone_hash": {
                    "type": "string"
                }
            }
        },
        "api.ConfirmTopupRequest": {
            "type": "object",
            "properties": {
                "credited_by": {
                    "description": "operator email or system label",
                    "type": "string"
                }
            }
        },
        "api.CreateAPIKeyRequest": {
            "type": "object",
            "properties": {
                "mode": {
                    "type": "string",
                    "enum": [
                        "test",
                        "live"
                    ]
                }
            }
        },
        "api.CreateTeamMemberRequest": {
            "type": "object",
            "required": [
                "email",
                "role"
            ],
            "properties": {
                "email": {
                    "type": "string"
                },
                "role": {
                    "type": "string",
                    "enum": [
                        "Admin",
                        "Developer",
                        "Finance",
                        "Viewer"
                    ]
                }
            }
        },
        "api.CreateWebhookRequest": {
            "type": "object",
            "required": [
                "secret",
                "url"
            ],
            "properties": {
                "secret": {
                    "type": "string"
                },
                "url": {
                    "type": "string"
                }
            }
        },
        "api.DashboardMetrics": {
            "type": "object",
            "properties": {
                "failed_user_ops_24h": {
                    "type": "integer"
                },
                "successful_user_ops_24h": {
                    "type": "integer"
                },
                "total_active_wallets": {
                    "type": "integer"
                },
                "total_processing_volume_crypto": {
                    "type": "number"
                }
            }
        },
        "api.Erc4337Context": {
            "type": "object",
            "properties": {
                "gas_paid_eth": {
                    "type": "string"
                },
                "nonce": {
                    "type": "integer"
                },
                "user_op_hash": {
                    "type": "string"
                }
            }
        },
        "api.ExtendedTransactionInstance": {
            "type": "object",
            "properties": {
                "created_at": {
                    "type": "string"
                },
                "erc4337_context": {
                    "$ref": "#/definitions/api.Erc4337Context"
                },
                "financials": {
                    "$ref": "#/definitions/api.TransactionFinancials"
                },
                "id": {
                    "type": "string"
                },
                "masked_sender": {
                    "type": "string"
                },
                "recipient_address": {
                    "type": "string"
                },
                "settled_at": {
                    "type": "string"
                },
                "status": {
                    "type": "string"
                },
                "tx_hash": {
                    "type": "string"
                },
                "user_index": {
                    "type": "string"
                }
            }
        },
        "api.LivePaymasterGasCapacity": {
            "type": "object",
            "properties": {
                "alert_threshold_eth": {
                    "type": "number"
                },
                "critical_threshold_eth": {
                    "type": "number"
                },
                "current_balance_eth": {
                    "type": "number"
                },
                "entrypoint_address": {
                    "type": "string"
                },
                "estimated_tx_runway": {
                    "type": "integer"
                },
                "paymaster_address": {
                    "type": "string"
                },
                "status": {
                    "type": "string"
                }
            }
        },
        "api.TenantBalanceResponse": {
            "type": "object",
            "properties": {
                "available_usdc": {
                    "type": "string"
                },
                "mmo_id": {
                    "type": "string"
                },
                "reserved_usdc": {
                    "type": "string"
                },
                "total_funded_usdc": {
                    "type": "string"
                }
            }
        },
        "api.TransactionFinancials": {
            "type": "object",
            "properties": {
                "applied_bps_markup": {
                    "type": "integer"
                },
                "crypto_ticker": {
                    "type": "string"
                },
                "fx_quote_id": {
                    "type": "string"
                },
                "local_amount": {
                    "type": "number"
                },
                "local_currency": {
                    "type": "string"
                },
                "stablecoin_settled": {
                    "type": "number"
                }
            }
        },
        "api.TreasuryTopupRequest": {
            "type": "object",
            "required": [
                "amount",
                "reference",
                "token"
            ],
            "properties": {
                "amount": {
                    "type": "string"
                },
                "note": {
                    "type": "string"
                },
                "reference": {
                    "description": "HUB2 settlement ID, bank ref, or on-chain tx hash",
                    "type": "string"
                },
                "token": {
                    "type": "string",
                    "enum": [
                        "USDC",
                        "USDT"
                    ]
                }
            }
        },
        "api.TreasuryUsdcBalanceResponse": {
            "type": "object",
            "properties": {
                "status": {
                    "type": "string"
                },
                "treasury_address": {
                    "type": "string"
                },
                "usdc_balance": {
                    "type": "number"
                }
            }
        },
        "api.UserAccountResponse": {
            "type": "object",
            "properties": {
                "account_status": {
                    "type": "string"
                },
                "date_provisioned": {
                    "type": "string"
                },
                "user_index": {
                    "type": "string"
                },
                "wallet_address": {
                    "type": "string"
                }
            }
        },
        "api.UserDetailResponse": {
            "type": "object",
            "properties": {
                "account_status": {
                    "type": "string"
                },
                "blind_index": {
                    "type": "string"
                },
                "daily_limit": {
                    "type": "string"
                },
                "date_provisioned": {
                    "type": "string"
                },
                "monthly_limit": {
                    "type": "string"
                },
                "total_transfers": {
                    "type": "integer"
                },
                "total_volume": {
                    "type": "string"
                },
                "wallet_address": {
                    "type": "string"
                }
            }
        },
        "main.BalanceResponse": {
            "type": "object",
            "properties": {
                "balance_usdc": {
                    "type": "string"
                },
                "wallet_address": {
                    "type": "string"
                }
            }
        },
        "main.FundUserRequest": {
            "type": "object",
            "required": [
                "deposit_id",
                "local_fiat_amount",
                "phone_number",
                "stablecoin_amount",
                "target_token"
            ],
            "properties": {
                "deposit_id": {
                    "type": "string",
                    "example": "dep_001_20240601"
                },
                "local_fiat_amount": {
                    "type": "string",
                    "example": "11000.00"
                },
                "phone_number": {
                    "type": "string",
                    "example": "+2250700000001"
                },
                "stablecoin_amount": {
                    "type": "string",
                    "example": "1.000000"
                },
                "target_token": {
                    "type": "string",
                    "enum": [
                        "USDC",
                        "USDT"
                    ],
                    "example": "USDC"
                }
            }
        },
        "main.FundUserResponse": {
            "type": "object",
            "properties": {
                "created_at": {
                    "type": "string"
                },
                "deposit_id": {
                    "type": "string"
                },
                "message": {
                    "type": "string"
                },
                "status": {
                    "type": "string"
                }
            }
        },
        "main.ProvisionUserRequest": {
            "type": "object",
            "required": [
                "phone_number"
            ],
            "properties": {
                "phone_number": {
                    "type": "string",
                    "example": "+2250700000001"
                }
            }
        },
        "main.ProvisionUserResponse": {
            "type": "object",
            "properties": {
                "blind_index": {
                    "type": "string"
                },
                "created_at": {
                    "type": "string"
                },
                "status": {
                    "type": "string"
                },
                "wallet_address": {
                    "type": "string"
                }
            }
        },
        "main.QuoteRequest": {
            "type": "object",
            "required": [
                "fiat_amount",
                "local_currency"
            ],
            "properties": {
                "fiat_amount": {
                    "type": "number",
                    "example": 20000
                },
                "local_currency": {
                    "type": "string",
                    "example": "XOF"
                },
                "target_token": {
                    "type": "string",
                    "example": "USDC"
                }
            }
        },
        "main.QuoteResponse": {
            "type": "object",
            "properties": {
                "currency_pair": {
                    "type": "string",
                    "example": "XOF_USDC"
                },
                "expected_out": {
                    "type": "string",
                    "example": "35.67"
                },
                "expires_at": {
                    "type": "string",
                    "example": "2026-06-24T21:25:25Z"
                },
                "fiat_amount": {
                    "type": "string",
                    "example": "20000.00"
                },
                "quote_id": {
                    "type": "string",
                    "example": "fx_b3d8a1c2-..."
                },
                "rate": {
                    "type": "string",
                    "example": "560.77"
                },
                "target_token": {
                    "type": "string",
                    "example": "USDC"
                }
            }
        },
        "main.TransferRequest": {
            "type": "object",
            "required": [
                "idempotency_key",
                "local_fiat_amount",
                "quote_id",
                "recipient_phone",
                "sender_phone",
                "target_token"
            ],
            "properties": {
                "idempotency_key": {
                    "type": "string",
                    "example": "txn_ref_abc123"
                },
                "local_fiat_amount": {
                    "type": "string",
                    "example": "5500.00"
                },
                "quote_id": {
                    "type": "string",
                    "example": "DIRECT_CRYPTO:USDC:0.50"
                },
                "recipient_phone": {
                    "type": "string",
                    "example": "+2250700000002"
                },
                "sender_phone": {
                    "type": "string",
                    "example": "+2250700000001"
                },
                "target_token": {
                    "type": "string",
                    "enum": [
                        "USDT",
                        "USDC"
                    ],
                    "example": "USDC"
                }
            }
        },
        "main.TransferResponse": {
            "type": "object",
            "properties": {
                "created_at": {
                    "type": "string"
                },
                "message": {
                    "type": "string"
                },
                "status": {
                    "type": "string"
                },
                "transfer_id": {
                    "type": "string"
                }
            }
        },
        "main.UpdatePhoneRequest": {
            "type": "object",
            "required": [
                "new_phone_number",
                "old_phone_number"
            ],
            "properties": {
                "new_phone_number": {
                    "type": "string"
                },
                "old_phone_number": {
                    "type": "string"
                }
            }
        },
        "main.WithdrawRequest": {
            "type": "object",
            "required": [
                "amount",
                "payout_mobile",
                "payout_network",
                "phone"
            ],
            "properties": {
                "amount": {
                    "type": "string",
                    "example": "0.500000"
                },
                "idempotency_key": {
                    "type": "string",
                    "example": "wdrl_ref_001"
                },
                "payout_mobile": {
                    "type": "string",
                    "example": "+2250700000002"
                },
                "payout_network": {
                    "type": "string",
                    "example": "orange_money"
                },
                "phone": {
                    "type": "string",
                    "example": "+2250700000002"
                },
                "token": {
                    "type": "string",
                    "example": "USDC"
                }
            }
        },
        "main.WithdrawResponse": {
            "type": "object",
            "properties": {
                "message": {
                    "type": "string"
                },
                "status": {
                    "type": "string"
                },
                "withdrawal_id": {
                    "type": "string"
                }
            }
        }
    },
    "securityDefinitions": {
        "ApiKeyAuth": {
            "description": "Your Rach B2B API key. Use `rach_sk_live_*` for production (on-chain) or `rach_sk_test_*` for sandbox (no-chain simulation).",
            "type": "apiKey",
            "name": "X-API-Key",
            "in": "header"
        },
        "BearerAuth": {
            "description": "JWT Bearer token from the Rach payments platform. Claims must include `business_id` (or `org_id`) and `waas` in the permissions field. Format: `Bearer \u003ctoken\u003e`.",
            "type": "apiKey",
            "name": "Authorization",
            "in": "header"
        }
    }
}