3. Request & Response Identification#
In production, the hardest bugs are the ones you can’t trace. JsonDispatch enforces consistent tracing identifiers on every response so developers can connect logs, monitor latency, and debug across distributed systems — automatically.
3.1 X-Request-Id – server-generated trace ID#
Every response must include a globally unique request identifier generated by the server. Clients do not send this header.
Rules
Generated once per inbound request (UUID v4, ULID, or equivalent unique token).
Must be a string.
Included in all responses, including errors.
Logged internally for correlation in monitoring and debugging.
Example
Client → Server:
GET /articles
Accept: application/vnd.infocyph.jd.v1+json
X-Api-Version: 1.4.0
Server → Client#
Response
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Api-Version-Selected: 1.4.0
X-Request-Id: 7e0e7b45-1e89-4a7f-bbd3-f7ac73fae951
Tip
When a user reports an issue, the X-Request-Id from the response can be searched in logs to reconstruct the full execution path.
3.3 Distributed tracing (traceparent, tracestate)#
For systems instrumented with distributed-tracing tools such as OpenTelemetry, Jaeger, or Zipkin, JsonDispatch is compatible with the W3C Trace Context.
These headers complement (not replace) JsonDispatch identifiers:
``traceparent`` — carries trace ID and span ID.
``tracestate`` — vendor-specific trace metadata.
Example
Request
GET /profile
Accept: application/vnd.infocyph.jd.v1+json
X-Api-Version: 1.4.0
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
tracestate: congo=t61rcWkgMzE
Response#
Response
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Api-Version-Selected: 1.4.0
X-Request-Id: 1b0c9d4b-eaa2-40d0-8715-fc93e6fefb99
X-Correlation-Id: session-998877
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
tracestate: congo=t61rcWkgMzE
Summary
Header |
Direction |
Purpose |
Required |
|---|---|---|---|
|
Response → |
Unique server-generated request trace ID |
✅ Yes |
|
Both ↔ |
Link related requests in a workflow |
⚪ Optional |
|
Request → |
Requested JsonDispatch API version |
✅ Yes |
|
Response → |
Server JsonDispatch version identifier |
✅ Yes |
|
Both ↔ |
Distributed tracing (W3C) |
⚪ Optional |
|
Both ↔ |
Vendor-specific tracing metadata |
⚪ Optional |
3.4 Rate limiting#
To protect API resources and ensure fair usage, JsonDispatch recommends standard rate limiting headers that inform clients about their current usage and limits.
Include these headers in all successful responses (and optionally in error responses).
Standard approach (X-prefixed headers)
Header |
Description |
Example |
|---|---|---|
|
Maximum requests allowed in the current window |
|
|
Requests remaining in the current window |
|
|
Unix timestamp when the rate limit resets |
|
|
Duration of the rate limit window |
|
Example response with rate limit headers
Response
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Api-Version-Selected: 1.4.0
X-Request-Id: 9b7f3c2a-4e1d-4f8c-a3b2-1e5d6c8f9a0b
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1698249600
IETF Draft Standard (optional alternative)
JsonDispatch also supports the IETF RateLimit Header Fields draft which uses non-prefixed headers:
Header |
Description |
Example |
|---|---|---|
|
Maximum requests allowed in the current window |
|
|
Requests remaining in the current window |
|
|
Seconds until the rate limit resets |
|
|
Rate limit policy definition |
|
Example response with IETF Draft headers
Response
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Api-Version-Selected: 1.4.0
X-Request-Id: 9b7f3c2a-4e1d-4f8c-a3b2-1e5d6c8f9a0b
RateLimit-Limit: 1000
RateLimit-Remaining: 987
RateLimit-Reset: 3600
RateLimit-Policy: 1000;w=3600
Note
The main difference is that RateLimit-Reset uses seconds (delta) while X-RateLimit-Reset uses a Unix timestamp.
Choose one approach consistently across your API.
Policy format
1000;w=3600= 1000 requests per 3600 seconds (1 hour)100;w=60= 100 requests per 60 seconds (1 minute)10000;w=86400= 10000 requests per 86400 seconds (24 hours)
Combined approach (maximum compatibility)
For maximum compatibility, you may send both header styles:
Response
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Api-Version-Selected: 1.4.0
X-Request-Id: 9b7f3c2a-4e1d-4f8c-a3b2-1e5d6c8f9a0b
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1698249600
RateLimit-Limit: 1000
RateLimit-Remaining: 987
RateLimit-Reset: 3600
RateLimit-Policy: 1000;w=3600
Tip
If you’re building a new API, prefer the IETF Draft headers as they are likely to become a standard. For existing APIs, continue with X-prefixed headers for backward compatibility.
When a client exceeds their rate limit, return ``429 Too Many Requests`` with a fail status:
Response
HTTP/1.1 429 Too Many Requests
Content-Type: application/json; charset=utf-8
X-Api-Version-Selected: 1.4.0
X-Request-Id: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1698249600
Retry-After: 3600
{
"status": "fail",
"message": "Rate limit exceeded",
"data": {
"errors": [
{
"code": "RATE_LIMIT_EXCEEDED",
"message": "You have exceeded the rate limit of 1000 requests per hour"
}
]
},
"_properties": {
"rate_limit": {
"limit": 1000,
"remaining": 0,
"reset_at": "2025-10-22T16:00:00Z",
"retry_after_seconds": 3600
}
},
"_links": {
"upgrade": "https://example.com/pricing",
"docs": "https://docs.example.com/rate-limits"
}
}
Note
Include the Retry-After header (in seconds) to tell clients when they can retry.
JsonDispatch supports various rate limiting strategies:
Per-user rate limiting
Rate limits tied to authenticated user accounts:
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4872
X-RateLimit-Reset: 1698253200
Per-API-key rate limiting
Different limits for different API keys or service tiers:
X-RateLimit-Limit: 100000
X-RateLimit-Remaining: 99234
X-RateLimit-Reset: 1698253200
Per-endpoint rate limiting
Some endpoints may have stricter limits than others. Use _properties to communicate this:
{
"status": "success",
"data": { "...": "..." },
"_properties": {
"rate_limit": {
"endpoint_limit": 100,
"endpoint_remaining": 87,
"endpoint_window": "60s"
}
}
}
Tip
Always log rate limit violations with X-Request-Id to identify abusive patterns and help legitimate users understand their usage.