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

# Environments and limits

> The base URL, why there is no sandbox, and how to test an integration safely against production.

## Base URL

```
https://api.vibepay.mn
```

One host, HTTPS only. All paths in this documentation are relative to it.

## There is no sandbox

Vibepay moves real employer money into real employees' wallets, and every charge produces a real
VAT receipt filed with the Mongolian tax authority. A simulated environment would not exercise the
parts most likely to break your integration — the tax pipeline, spend rules, and settlement — so
we do not offer one that would give you false confidence.

**Test against production with small amounts and reverse them.** Reversal is complete: the
customer's balance is restored, the VAT receipt is cancelled at the tax authority, and if the
charge had already been paid out to you it is netted off your next payout. Nothing is left behind.

<Steps>
  <Step title="Charge ₮100 against a real pass">
    A colleague with a Vibepay card is the easiest test subject.
  </Step>

  <Step title="Confirm it landed">
    `GET /v1/transactions?limit=1` should show it, and it should appear in your merchant dashboard.
  </Step>

  <Step title="Reverse it">
    `POST /v1/transactions/{txID}/reverse` → `204`. Check the balance is restored.
  </Step>

  <Step title="Come back later and check the receipt">
    Within a few minutes `vatStatus` should read `issued` and then `voided` once the reversal has
    propagated. That confirms the tax leg of your integration, which is the half most people
    forget to check.
  </Step>
</Steps>

## Rate limits

The API accepts roughly **100 requests per second sustained, with a burst allowance of 200**.

<Warning>
  This ceiling applies to the API as a whole, not to your terminal individually. You are sharing
  it with every other merchant, so treat `429` as a normal condition to handle rather than an
  emergency.
</Warning>

A `429` looks like this:

```json theme={null}
{ "message": "Too Many Requests" }
```

Back off exponentially with jitter and retry. **If you are retrying a charge, send the same
`Idempotency-Key`** — otherwise the retry is a second, separate payment. See
[Idempotency](/idempotency).

In practice a till makes a handful of requests per customer, so a normal POS never approaches this
limit. If you are hitting it, you are almost certainly polling `GET /v1/transactions` in a tight
loop — poll every 30 seconds or so instead.

## Timeouts and retries

| Situation                           | What to do                                                                                           |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Connection failed, nothing sent     | Retry. Same `Idempotency-Key` if it was a charge.                                                    |
| Request sent, no response (timeout) | **Do not assume it failed.** Retry with the same `Idempotency-Key`, or check `GET /v1/transactions`. |
| `5xx` response                      | Same as a timeout — the charge may have committed. Retry idempotently or verify.                     |
| `429`                               | Back off, then retry idempotently.                                                                   |
| `401`                               | Stop. The credentials are dead.                                                                      |
| `4xx` other than `401`/`429`        | Stop. Retrying will not change the answer.                                                           |

Set your HTTP client's timeout to around 30 seconds. A charge is a database write, not a
long-running job, and anything slower than that is a problem worth surfacing to the cashier.

## Service probes

Both are unauthenticated and neither tells you anything about your credentials.

<CodeGroup>
  ```bash Liveness theme={null}
  curl https://api.vibepay.mn/health
  # {"status":"ok"}
  ```

  ```bash Readiness theme={null}
  curl https://api.vibepay.mn/ready
  # {"status":"ok","deps":{"aurora":{"status":"ok"}}}
  ```
</CodeGroup>

Use these for a status board, not as a pre-flight check before every charge — that just doubles
your request count without making anything safer.
