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. 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 verbatim only when you
supply it — 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, 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.
metadata is currently accepted only on POST /v3/fx/withdrawals — no other v3 write endpoint accepts it.
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 returned in data is:
Success response — metadata nested inside data.metadata, not a sibling of data
Encoding
All v3 requests and responses are UTF-8 encoded. Request and response bodies areapplication/json; charset=utf-8; send your request bodies as UTF-8.
Timestamp precision
Timestamp fields across v3 —X-Request-Timestamp and resource fields such as 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.