> For the complete documentation index, see [llms.txt](https://docs.allscale.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.allscale.io/allscale-checkout/quickstart-with-postman.md).

# Quickstart with Postman

Out-of-the-box Postman assets for QA and partner engineers. Import, fill in credentials, and you can hit every documented v1 endpoint with valid HMAC-signed requests.

### Files

| File                                                   | What it is                                                                             |
| ------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| `AllScale_OpenAPI.postman_collection.json`             | Collection — all v1 endpoints + collection-level request signer + response assertions. |
| `AllScale_OpenAPI_Production.postman_environment.json` | Production environment (`https://openapi.allscale.io`).                                |

### Import (Postman desktop or web)

1. **File → Import** → drop all three JSON files in at once.
2. Top-right environment dropdown → pick **AllScale OpenAPI**&#x20;
3. Open the environment, paste your `api_key` and `api_secret`, save.
   * `api_secret` is stored with Postman's `secret` type and is masked.
   * Both values are shown **once** in the merchant dashboard — keep them safe.

`base_url` and `checkout_intent_id` are already wired up; you should not need to edit them.

### Suggested run order

1. **Test / GET `/v1/test/ping`** — confirms keys + clock + signing.
2. **Test / POST `/v1/test/post`** — confirms body hashing.
3. **Checkout Intent / Create — fiat** *or* **Create — native stable-coin** — creates an intent and auto-saves `checkout_intent_id` into the environment.
   * Fiat: send `currency` (IntEnum). Server FX-converts to the resolved settlement coin (USDT or USDC); use `accepted_stable_coins` to pick which (first entry wins; defaults to USDT when omitted).
   * Native stable-coin: send `stable_coin` — `1` (USDT) or `2` (USDC) are both accepted. `amount_cents` is stable-coin cents, no FX, and `currency_rate` will be `null`.
   * Send exactly one — both or neither returns `10001`.
4. **Checkout Intent / GET `/v1/checkout_intents/{id}/status`** — polls the lifecycle state.
5. **Checkout Intent / GET `/v1/checkout_intents/{id}`** — full detail.
   * For a native-stable-coin intent, the fiat fields (`currency`, `currency_symbol`, `amount_cents`, `currency_rate`) will be `null`; the authoritative amount lives in `amount_coins`.

You can also run the whole collection with Postman's **Collection Runner** — every request has assertions attached, so the runner report is a usable QA smoke-test.

### How signing works (for the curious)

A pre-request script lives at the **collection root**, so it runs before every request without per-request setup. For each call it:

1. Reads `api_key` / `api_secret` from the active environment.
2. Builds the canonical string `METHOD\nPATH\nQUERY\nTIMESTAMP\nNONCE\nBODY_SHA256` (body hash = `sha256_hex(raw_body_bytes)`; empty body hashes the empty string).
3. Signs it with HMAC-SHA256, base64-encoded.
4. Upserts the required headers: `X-API-Key`, `X-Timestamp`, `X-Nonce`, `X-Signature: v1=<sig>`.

No need to touch the script for normal QA — but if a signature ever looks wrong, uncomment the two `console.log` lines at the bottom of the pre-request script to dump the canonical string and produced signature to the Postman console.

### Troubleshooting

| Symptom                                  | Likely cause                                                                                                                                                                                |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `20001 missing_headers`                  | `api_key` / `api_secret` not set in the active environment.                                                                                                                                 |
| `20002 timestamp_out_of_window`          | Your machine's clock is off; sync NTP (±5 min window).                                                                                                                                      |
| `20002 signature_mismatch` on POSTs only | Body was edited after the script ran, or Content-Type isn't `application/json`. Re-send; the script re-hashes on every send.                                                                |
| `20002 replay_nonce`                     | Sending two requests with the same nonce within the replay window. The script generates a new UUID every send, so this should not happen — double-check you don't have the script disabled. |
| `30001 ip_not_allowed`                   | Your egress IP isn't on the merchant IP allowlist.                                                                                                                                          |
| `40001`                                  | Rate limited. Back off per the `retry_after` in the error details.                                                                                                                          |
| `50001`                                  | `checkout_intent_id` is unset or belongs to another merchant. Re-run **Create** to capture a fresh id.                                                                                      |
| `50002`                                  | `Create` rejected the request (e.g. `amount must be greater than 0.1 <coin>` when the order is at or below the 0.1-coin floor). Read `error.details.reason` for the specifics.              |

### Updating the package

When endpoints change, edit `AllScale_OpenAPI.postman_collection.json` in this repo, then re-export the matching `.json` from Postman — or just keep editing JSON directly. Try to keep the canonical-string script in sync with `thirdparty_api/auth/__init__.py::_canonical_request`; they must produce byte-identical canonical strings.
