> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dollarpe.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Core concepts

> Objects, base URLs, the response envelope, amounts, idempotency and order statuses.

Read this page once before you build. It explains the terms used everywhere else in these docs.

## Products

| Product | Direction | What happens |
| - | - | - |
| **[Payin](/guides/payments/payins)** (onramp) | Fiat in, crypto out | The user sends fiat from their bank account. Zapyd delivers stablecoins to your delivery wallet. |
| **[Payout](/guides/payments/payouts)** (offramp) | Crypto in, fiat out | You send stablecoins to a Zapyd deposit address. Zapyd pays fiat to the beneficiary's bank account. |
| **Remittance payout** | Crypto in, fiat out | Cross-border payout on behalf of a remitter. Needs a remitter record and beneficiary KYC. See the [remittance guide](/guides/payments/remittance). |
| **[Prefunded payout](/guides/payments/prefunded-payouts)** | Balance in, fiat out | Payouts drawn from a balance you pre-fund. You don't send crypto per order. |

## Objects

```text theme={null}
Organization (you)
└── Customer ─────────── KYC status: UNVERIFIED → PROCESSING → VERIFIED / FAILED
    ├── Bank account ─── where payouts land
    ├── Wallet ───────── saved crypto address
    └── Order ────────── Payin or Payout, created from a Quotation
```

| Object | Created with | Key facts |
| - | - | - |
| **Customer** | [`POST /customer/create`](/api-reference-exchange/endpoint/customer/create) | One per end user. Must be `VERIFIED` before any order. |
| **KYC** | [KYC sharing](/guides/customers/kyc-sharing) or [KYC SDK](/guides/customers/kyc-sdk) | Moves the customer to `VERIFIED`. Three attempts per customer. |
| **Bank account** | [`POST /bank/create`](/api-reference-exchange/endpoint/bank/create) | Name must match the KYC name. The fields depend on `bank_account_type` (for example `ACCOUNT_DETAILS` or `UPI`). |
| **Wallet** | [`POST /customer/wallet/add`](/api-reference-exchange/endpoint/wallet/add) | A saved crypto address for the customer. Payin crypto goes to your organization's delivery wallet, not to this one. |
| **Quotation** | `POST /payin/quotation` or `POST /payout/quotation` | Locks the rate and fees until `expiry_time`. Single use. |
| **Order** | `POST /payin/initiate` or `POST /payout/initiate` | Created from a quotation. Reports status by webhook. |

## Environments and base URLs

| | Sandbox | Production |
| - | - | - |
| Host | `https://sandbox.zapyd.com` | `https://api.zapyd.com` |
| Credentials | Sandbox key and secret | Production key and secret |
| Money | None. Mock endpoints set statuses. | Real funds |
| Networks | Includes Sepolia testnet | Mainnets only |

Each API module has its own path prefix. Full URL = host + module prefix + endpoint path.

| Module | Prefix | Endpoints |
| - | - | - |
| Customer | `/cms/api/v1` | `/customer/*`, `/kyc/*`, `/bank/*`, `/customer/wallet/*` |
| Payin | `/pis/api/v1` | `/payin/*` |
| Payout | `/pos/api/v1` | `/payout/*`, `/remittance-payout/*`, `/prefunded/payout/*` |
| Limits and EDD | `/ren/api/v1` | `/payin/limits/*`, `/payout/limits/*`, `/payin/edd/*`, `/payout/edd/*` |
| Organization | `/org/api/v1` | `/organizations/api-webhooks` |

Example: `POST /payout/quotation` in sandbox is `https://sandbox.zapyd.com/pos/api/v1/payout/quotation`.

## Authentication

Every request is signed with your API secret. The signature is Base64 HMAC-SHA256 over `apiKey|timestamp|canonicalJsonBody`. GET requests sign `{}`. See [Authentication](/guides/development-and-testing/authentication) for helpers in three languages and a test vector.

## Response envelope

Every response uses the same envelope. Check `status` first, then read `data` or `err_code`.

<CodeGroup>
  ```json Success theme={null}
  {
    "status": true,
    "message": "Success",
    "data": { "id": "59bf60c3-e9af-40a7-9d5c-2a1aa191e769" }
  }
  ```

  ```json Error theme={null}
  {
    "status": false,
    "message": "Bad Request",
    "data": null,
    "err_code": "REQ_FIELD_MISSING",
    "errors": { "customer_id": ["This field is required."] }
  }
  ```
</CodeGroup>

Branch on `err_code`, not on `message`. Create endpoints for quotations and orders return HTTP `201`. See [Error handling](/guides/development-and-testing/error-handling) for retry rules.

## Amounts and currencies

* Send amounts as **strings** (`"10000"`, `"60.50"`) so you don't lose precision.
* On a quotation, send either `sending_amount` or `receiving_amount`, never both.
* The quotation response returns both amounts, the `rate` and a `fees` breakdown. Show the user these values, not your own calculation.
* Asset and fiat codes are case-insensitive (`usdt` or `USDT`). Networks are lowercase (`tron`, `polygon`, `sepolia`).
* Check supported pairs in [Stablecoins and networks](/guides/support/stablecoins-and-networks) and [Supported geographies](/guides/support/geographies).

## Idempotency and your own IDs

Send `client_reference_id` (your own ID) on customers and orders. Save both your ID and the Zapyd `id` in your database.

* Customer create: if you send a `client_reference_id` that already exists, Zapyd returns the existing customer. You can retry this call safely.
* Orders: a quotation can be used only once, so a retried initiate can't create a second order from the same quotation.
* Webhooks can arrive more than once. Deduplicate them on the object `id` and `event`.

## Order lifecycle

```mermaid theme={null}
flowchart LR
    Q[Quotation] -->|initiate before expiry_time| P[PROCESSING]
    P --> S[SUCCESS]
    P --> F[FAILED]
    P --> R[REFUNDED]
    P --> H[ON_HOLD, payin]
    P --> V[IN_REVIEW, payout]
    V --> S
    V --> F
```

`SUCCESS`, `FAILED` and `REFUNDED` are final. `ON_HOLD` (payin) means the payment is held for review: don't release crypto, and contact support with the payin ID. `IN_REVIEW` (payout) means compliance needs more information. The webhook may include an `rfi_link` for the customer. The [Status reference](/guides/development-and-testing/status-reference) lists every status and what to do in each one.

## Sandbox shortcuts

In sandbox you can set statuses directly, so you don't have to wait for KYC, a bank or a blockchain:

| To test | Call |
| - | - |
| KYC result | [`PATCH /kyc/mock-kyc-status`](/api-reference-exchange/endpoint/kyc/mock-kyc-status) |
| Payin result | [`PATCH /payin/mock-payin-status`](/api-reference-exchange/endpoint/payin/order/mock-payin-status) |
| Payout result | [`PATCH /payout/mock-payout-status`](/api-reference-exchange/endpoint/payout/order/mock-payout-status) |
| EDD result | [Payin EDD](/api-reference-exchange/endpoint/payin/edd/edd-mock-status) and [payout EDD](/api-reference-exchange/endpoint/payout/edd/edd-mock-status) mock status |
