# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.allscale.io/allscale-checkout/quickstart-with-postman.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
