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

# API introduction

> Base URL, authentication, conventions, and when you need the API at all.

Most merchants never touch the API — the [embedded checkout](/integration/embed) calls it for you. Use it directly if you're building a custom payment flow, a mobile app, or server-side order creation.

## Base URL

Your API base URL is shown in **API & SDK** in the dashboard, alongside your keys. It is tied to your account, so read it from there rather than copying one from a guide.

Every example on these pages uses an environment variable for it:

```bash theme={null}
export CC_API_BASE="…"          # from API & SDK in the dashboard
export CC_PUBLISHABLE_KEY="…"   # same place
```

All endpoints are `POST` and accept and return JSON.

<Tip>
  Keep the base URL in configuration rather than hardcoding it. It is infrastructure, not part of the contract, and pinning it into source is the thing that makes a future change painful.
</Tip>

## Authentication

<ParamField path="header.apikey" type="string" required>
  Your publishable key, from **API & SDK** in the dashboard.
</ParamField>

<ParamField path="header.Content-Type" type="string" required>
  `application/json`
</ParamField>

```bash theme={null}
curl -X POST $CC_API_BASE/create-quote \
  -H "apikey: $CC_PUBLISHABLE_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "merchantId": "…", "cart": { "total": 49.00, "currency": "EUR" }, "token": "EURC", "chainId": 8453 }'
```

<Note>
  The publishable key identifies your account for quoting. It is not a secret in the way a webhook secret is — it appears in browser traffic by design. It cannot move funds or change your settings.
</Note>

## Conventions

<AccordionGroup>
  <Accordion title="Amounts are base units" icon="calculator" defaultOpen>
    Token amounts are strings in the token's smallest unit. On most chains USDC, USDT, and EURC use 6 decimals, so `"49000000"` is 49.00.

    **Do not hardcode 6.** Decimals vary by chain — on BNB Chain these tokens are 18-decimal. Use the `tokenDecimals` field returned with the payment.

    Strings, not numbers — a large amount would lose precision as a float.
  </Accordion>

  <Accordion title="Fiat amounts are decimals" icon="money-bill">
    Cart totals are ordinary decimal numbers: `49.00`.
  </Accordion>

  <Accordion title="Chains are numeric IDs" icon="link">
    `1` Ethereum, `8453` Base, `42161` Arbitrum, `10` Optimism, `137` Polygon, `56` BNB, `43114` Avalanche. Testnets have their own IDs.
  </Accordion>

  <Accordion title="Timestamps are ISO 8601" icon="clock">
    UTC, for example `2026-08-09T14:32:11.204Z`.
  </Accordion>

  <Accordion title="Addresses are checksummed" icon="fingerprint">
    EVM addresses are returned checksummed. TRON addresses are base58 starting with `T` and are **case-sensitive** — never normalise them.
  </Accordion>
</AccordionGroup>

## Typical flow

```mermaid theme={null}
sequenceDiagram
    participant Y as Your server
    participant A as API
    participant C as Customer

    Y->>A: create-quote
    A-->>Y: quoteId, paymentId, amount, expiresAt
    Y->>C: Show the amount
    C->>A: Pays (wallet or transfer)
    A-->>Y: Webhook: payment_confirmed
    Y->>Y: Fulfil
```

<Steps>
  <Step title="Create a quote" icon="calculator">
    Locks a price for a short window and produces a payment ID. [create-quote](/api/create-quote).
  </Step>

  <Step title="Create a payment" icon="credit-card">
    Produces either a pool address to sign against, or a one-time deposit address. [create-payment](/api/create-payment).
  </Step>

  <Step title="Wait for confirmation" icon="webhook">
    Use [webhooks](/webhooks/overview). Poll [payment-status](/api/payment-status) only as a backstop.
  </Step>
</Steps>

## Rate limits

Rate limited per merchant. Exceeding returns `429` with a `Retry-After` header — respect it and back off.

## Do not build these yourself

<Warning>
  Two things the embedded checkout does that a custom flow must also do:

  **On-chain verification.** The widget reads your payout address from the blockchain and refuses to proceed on a mismatch. A custom flow that skips this loses the protection entirely. [How it works](/concepts/verification).

  **Fulfilment from webhooks.** Never from a client-side response.
</Warning>

Unless you have a specific reason, embed the checkout instead.

<Card title="Errors" icon="triangle-exclamation" href="/api/errors" horizontal>
  Every error code and what to do about it.
</Card>
