Polyester validates the timestamp and signature of every API-key-authenticated request. State-changing endpoints may also reject a signed request that has already been seen.
These authentication checks are separate from operation idempotency. Replay protection determines whether a signed HTTP request is accepted. Idempotency determines whether multiple accepted requests represent one logical operation.
Request freshness
Every signed request includes X-API-TIMESTAMP as Unix time in milliseconds. The timestamp must be
within 10 seconds of Polyester server time.
Keep client clocks synchronized. For every request attempt, use a timestamp that is distinct from the previous attempt and sign the complete request again. Reusing the same timestamp, request data, and signature on a protected endpoint can be rejected as a replay.
See Ed25519 API keys for the required headers and canonical signing format.
Replay protection versus idempotency
| Mechanism | Purpose | Client value |
|---|---|---|
| Timestamp and signature | Authenticate a specific HTTP request and limit its lifetime | Fresh timestamp and signature for every attempt |
| Endpoint operation identity | Identify one logical operation under endpoint-specific rules | Follow that endpoint's retry contract |
Depending on the endpoint, an operation identity may be named clientOrderId, requestId, or idempotencyKey. Their guarantees differ. In particular, a retained clientOrderId on a
single-order create returns CONFLICT_DUPLICATE_CLIENT_ORDER_ID; it does not replay the earlier
result. Check the endpoint contract before retrying a state-changing request.
Safe retry pattern
For a state-changing request:
- Generate and persist the endpoint's operation identity before the first attempt.
- Keep the operation payload and identity unchanged while reconciling an uncertain result.
- Use a timestamp distinct from the previous attempt and sign each attempt.
- Retry only where the endpoint contract permits it, using bounded backoff with jitter.
- Do not create a new identity after a timeout or other uncertain result.
For order creation, see Client order IDs and idempotency.
Nonce behavior
X-API-NONCE is optional. It is not part of the canonical signing string, so changing only the
nonce does not produce a new signature and must not be used as a substitute for:
- a fresh
X-API-TIMESTAMPand signature - an endpoint idempotency field
Errors
A stale or malformed timestamp returns TIMESTAMP_SKEW. A repeated signed request may return SIGNATURE_INVALID, which is also used for other signature-verification failures.
Do not blindly retry authentication errors. Correct the timestamp or signing input first. If the operation may already have been accepted, keep its idempotency value and payload unchanged when signing the next attempt.