X-Trace-Id and an X-Request-Timestamp. X-Trace-Id is OpenFX’s correlation handle for the request. Log it on every call so you can stitch together your own logs across retries and services, and give OpenFX support the trace they need. For your own per-call correlation, send an optional X-Request-Id header. See Client request correlation. FX withdrawals additionally accept a persistent metadata object in the body that outlives the single request. See Withdrawal metadata.
Response headers
Server-side and client-side correlation are separate headers.
X-Trace-Id
is the server-generated request identifier, present on every response; there
is no server requestId field in the response body. X-Request-Id is the
client-side equivalent: optional, and echoed back only when it matches the
required format. See Client request correlation. If
you need a body-portable copy of the server handle (for queued retries or
webhook envelopes that lose HTTP headers), capture X-Trace-Id into your own
log record at call time.Client request correlation
X-Trace-Id is the server’s correlation handle. For your own per-call correlation, send an optional X-Request-Id header on any request:
X-Request-Id is independent of X-Trace-Id: it’s client-generated and lives in headers on both the request and the response when valid, for the lifetime of that one HTTP round-trip. There is no server-generated requestId field in any response body.
X-Request-Id vs X-Trace-Id. X-Request-Id is your correlation
value, chosen by your client and echoed back only when you send it.
X-Trace-Id is OpenFX’s debug/trace handle, present on every response
(success and error) whether or not you sent an X-Request-Id. Include both
when you log, and quote X-Trace-Id when filing a support ticket.Withdrawal metadata
For bookkeeping that should persist with the resource (not just the one request/response round-trip),POST /v3/fx/withdrawals accepts an optional metadata object in the request body. This is a separate mechanism from X-Request-Id: X-Request-Id is per-call and lives in headers; metadata is per-resource, persists with the withdrawal, and travels in the body.
Within the FX API (/v3/fx/...), metadata is accepted only on POST /v3/fx/withdrawals. The Payments API accepts its own metadata object on create account, create payout address, create payout quote, and create payout, with the same key-count, key-length, value-length, and total-size limits as below. Payments metadata keys are also limited to letters, digits, and underscores.
It is a general-purpose, client-owned bag: keys are client-defined strings (for example metadata.customerId, metadata.reconId). All values must be strings.
The server treats metadata as opaque pass-through: it enforces only size and structure limits, never interprets the contents, persists it with the withdrawal, and returns it nested inside the resource at data.metadata on the success response, not as a top-level sibling of data.
Limits: at most 50 keys, each key ≤ 40 characters, each value ≤ 500 characters, and the serialized object under 8 KB. A request that exceeds any of these limits is rejected with 400 VALIDATION_BODY_FAILED.
Request: POST /v3/fx/withdrawals
Withdrawal resource inside data, with metadata nested inside it, not as a sibling of data:
Success response: metadata nested inside data.metadata, not a sibling of data
Encoding
Requests use UTF-8 encodedapplication/json. Responses use Content-Type: application/json without a charset parameter. A request body with duplicate JSON keys returns 400 VALIDATION_BODY_FAILED.
Timestamp precision
Across v3, timestamp fields such asX-Request-Timestamp, createdAt, expiresAt, and completedAt are RFC 3339 / ISO 8601 in UTC with millisecond precision and a trailing Z. RateLimit-Reset and Retry-After are not timestamps at all: both are plain integers counting seconds until you should retry, per the IETF RateLimit-* convention. See Rate limiting.
Logging pattern
A two-line capture on every request is enough to make support and incident response fast:Filing a support ticket
When something goes wrong, include theX-Trace-Id from the failing response.
Common mistakes
- Reading trace info from the body: the trace handle is the
X-Trace-Idheader; there is no body trace field - Logging only on errors (you lose context for prior successful calls)
- Truncating the trace ID in logs
- Comparing
X-Request-Timestampagainst a local clock without allowing for skew
What’s next
Errors
When something goes wrong, start with headers and code-based triage.
Rate limiting
Headers for back-pressure.