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

# Go-live checklist

> What a production integration needs before it trades real assets: safe order retries, deduplicated webhooks, a synced clock, fresh nonces, key rotation and tolerant parsing.

Check each item in the [sandbox](https://tetrafi.mintlify.site/overview.md#environments), then place your first production order at the [smallest amount a venue takes](https://tetrafi.mintlify.site/quickstart.md#find-the-smallest-amount-a-venue-takes). Open an item for how.

## Orders survive a crash

> [accordion] Store the idempotency key before you send
>
> Persist `{quoteId, idempotencyKey, exactBody}`, then send `POST /api/v1/orders`; a retry sends the same key and body bytes ([Retries and recovery](https://tetrafi.mintlify.site/trade/orders.md#retries-and-recovery)).

> [accordion] Recover, never reorder
>
> A timeout, `5xx` or `outcomeUnknown` does not mean the order failed: replay with the same key, or find the order by its quote.
>
> ```bash cURL theme={null}
> # When you cannot tell whether an order was placed, read it by its quote id before doing
> # anything else. ordered: read the order at statusUrl. notOrdered: nothing was placed.
> # unknown: wait, then read again.
> recovered=$(tetrafi GET "/api/v1/orders/by-quote/$order_quote")
> jq -c '{state, orderId, statusUrl}' <<<"$recovered" >&2
> unordered=$(tetrafi GET "/api/v1/orders/by-quote/$quote_id")
> jq -c '{state, expired}' <<<"$unordered" >&2
> ```

> [accordion] Order again only on a new quote
>
> Order again only on a new quote, and only when the order is shown not to exist or ended without filling.

> [accordion] Follow every order to the end
>
> Read its `statusUrl` until `terminal` is `true`, every 10 to 15 seconds or when a webhook arrives ([Order status](https://tetrafi.mintlify.site/trade/order-status.md)).

## Webhooks are handled once

> [accordion] Verify the signature
>
> Verify the signature over the raw body before parsing it.

> [accordion] Deduplicate on webhook-id
>
> Deduplicate on `webhook-id`: deliveries arrive at least once and out of order.

> [accordion] Answer 2xx within 10 seconds
>
> Answer `2xx` within 10 seconds, then work. Read `statusUrl` for the current state.

> [accordion] Watch for a paused endpoint
>
> Resume a paused endpoint and redeliver what it missed. The delivery log does not survive a TetraFi restart ([Webhooks](https://tetrafi.mintlify.site/trade/webhooks.md#retries-pauses-and-missed-events)).

## Signing holds up

> [accordion] Sync your clock with NTP
>
> `X-Timestamp` must be within 300 seconds of TetraFi's clock, and a write's at most 10 seconds ahead.

> [accordion] Use fresh nonces
>
> Generate every `X-Nonce` from a cryptographic random source, and sign each send, retries included, with a new nonce and timestamp ([Sign requests](https://tetrafi.mintlify.site/authentication.md#sign-requests)).

> [accordion] Keep secrets in a secret manager
>
> Keep secrets in a secret manager, never in code or a tracked file.

## Keys can be rotated

> [accordion] Pick up a rotated key within one hour
>
> After **Rotate key**, the old key works for one hour ([Rotate and revoke](https://tetrafi.mintlify.site/authentication.md#rotate-and-revoke)).

> [accordion] Grant only the permissions a key uses
>
> Grant only the permissions a key uses.

> [accordion] Use a service account for software
>
> Use a [service account](https://tetrafi.mintlify.site/authentication.md#service-account-tokens) for software that should outlive one person's access.

> [accordion] Know how to revoke a leaked key
>
> Know how to revoke a leaked key at once.

## Limits are respected

> [accordion] Watch markets with prices, never by polling quotes
>
> Each key may send one live quote request every 3 seconds ([Rate limits](https://tetrafi.mintlify.site/reference/rate-limits.md)).
>
> ```bash cURL theme={null}
> # Prices for the pair from memory: no venue is asked, so it costs no quote request.
> # Each row is one venue, location and variant pair. Rows are indicative, never orderable.
> path="/api/v1/prices?sell=$sell&buy=$buy&sellAmount=$amount"
> prices=$(tetrafi GET "$path")
> jq -c '{referenceMid: .referenceMid.buyPerSell, rows: [.rows[] | {venue: .venue.id,
>   location: .location.kind, status, buy: .sizes[0].buy}]}' <<<"$prices" >&2
> ```

> [accordion] On any 429, wait Retry-After and retry once
>
> On any `429`, wait `Retry-After` seconds and retry once.

> [accordion] Requote a held quote
>
> Requote a held quote instead of searching again ([Requotes and expiry](https://tetrafi.mintlify.site/search/firmness-and-lifetime.md#requote-a-quote)).

## Parsing tolerates change

> [accordion] Ignore response fields you do not recognise
>
> Ignore response fields you do not recognise.

> [accordion] Treat an unknown enum value as other
>
> Treat an unknown enum value as "other", such as a status, source reason or `next.kind`: keep following `terminal`, show `detail` or `message`, and carry on.

> [accordion] Match refusals on error, never message
>
> Match refusals on `error`, never `message`, and treat an unknown code by its status class ([Errors and refusals](https://tetrafi.mintlify.site/trade/errors.md#codes-you-do-not-know)).

> [accordion] Parse amounts as decimals
>
> Parse amounts as decimals, never floats ([Conventions](https://tetrafi.mintlify.site/reference/conventions.md)).

> [accordion] Read the Changelog before each release
>
> Read the [Changelog](https://tetrafi.mintlify.site/changelog.md) before each release of your integration.

## Next

> [card] [Retries and recovery](https://tetrafi.mintlify.site/trade/orders.md#retries-and-recovery)
>
> Retry an order safely and find out whether it was placed.

> [card] [Webhooks](https://tetrafi.mintlify.site/trade/webhooks.md)
>
> Receive order updates and recover missed deliveries.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.