Skip to content
V2 (Legacy) API ReferenceGet started
Platform

Debugging

Using trace IDs for request tracing and troubleshooting.

Every API response and webhook payload includes a trace ID for end-to-end debugging. This guide covers how to use trace IDs and troubleshoot common issues. See Error Codes for the complete error reference.

Every API response includes a trace ID in the X-Trace-ID response header, following the W3C Trace Context standard. Error responses and webhook payloads also include trace_id in the response body.

Terminal window
# The response includes the trace ID header
< X-Trace-ID: 2eff5df5c6f688733c007523c4d61cd9
{
"success": false,
"error": {
"status": 400,
"code": 1001,
"message": "Missing required field"
},
"trace_id": "2eff5df5c6f688733c007523c4d61cd9"
}

The trace ID is the 32-character hex trace-id segment of the W3C traceparent header. Its structure is:

traceparent: 00-<trace-id>-<parent-id>-<flags>
│ │ │ └─ 2-hex flags (e.g. 01 for sampled)
│ │ └─ 16-hex span/parent ID
│ └─ 32-hex trace ID (returned as X-Trace-ID)
└─ version (currently 00)

The trace_id field in error bodies and webhook envelopes is the same 32-hex value. You can feed it straight into any OpenTelemetry-compatible tracing backend (Datadog, Honeycomb, Jaeger, Grafana Tempo, etc.) to join your spans with Linq’s internal spans — ask support to enable cross-account trace sharing if you need to inspect Linq-side spans.

Inbound headers are ignored. Per W3C security guidance for public APIs, the Linq API generates a fresh trace context for every request. Any client-supplied traceparent or tracestate headers are discarded and replaced. This prevents forged trace IDs and trace-ID collision across tenants.

To correlate an API request with your own records:

  • Store the returned X-Trace-ID and map it to your internal request/job ID
  • Log both together so you can cross-reference during support tickets
  • Capture it on webhook receipt too — the same trace ID flows through downstream message.sent / message.delivered events
const response = await client.chats.create({
from: '+12223334444',
to: ['+15556667777'],
message: { parts: [{ type: 'text', value: 'Hello!' }] },
});
// Log the trace ID with your internal ID for correlation
console.log(`Internal ID: ${internalId}, Trace ID: ${response._response.headers.get('x-trace-id')}`);
response = client.chats.with_raw_response.create(
from_="+12223334444",
to=["+15556667777"],
message={"parts": [{"type": "text", "value": "Hello!"}]},
)
print(f"Internal ID: {internal_id}, Trace ID: {response.headers['x-trace-id']}")

Many operations are processed asynchronously after the API responds. The initial HTTP response tells you the request was accepted; the final outcome arrives via webhooks.

The trace_id threads the full request lifecycle:

  1. You call POST /v3/chats/{id}/messages → response body and X-Trace-ID header carry trace_id: abc123...
  2. The message is queued and dispatched to Apple/carrier networks
  3. You receive a message.sent webhook whose envelope trace_id matches abc123...
  4. On delivery, a message.delivered webhook — same trace_id
  5. On read, message.read — same trace_id
  6. On failure, a message.failed webhook — same trace_id plus the final code / message

Recommended pattern: store the trace_id alongside the message in your database at step 1, then key webhook-handler updates off trace_id (or event_id for deduplication) so late-arriving events always land on the correct record.

Note: Webhook envelope trace_id is always present. The inner data object may also echo message_id, chat_id, and event_id for more granular joins. Use event_id for deduplication, trace_id for end-to-end correlation.

SymptomLikely causeSolution
401 UnauthorizedMissing or invalid bearer tokenCheck Authorization: Bearer header — see Authentication
400 E.164 formatPhone number format wrongUse + prefix with country code: +12223334444 — see error 1002
403 Phone number deniedPhone not assigned to your accountVerify phone assignment with your Linq representative
409 Chat still creatingDuplicate concurrent create requestsWait and retry, or use idempotency keys
429 Rate limitPer-pair cap, sandbox daily cap, or capability check limitWait the Retry-After interval, then check for retry loops or missing caching — see Rate Limits
5xx InfrastructureTransient server errorRetry with exponential backoff — see 3xxx server errors
Webhook not receivedEndpoint unreachable or returning non-2xxCheck endpoint URL, SSL cert, and firewall rules — see Webhooks
No message.delivered / message.read after sendMessage fell back to SMS/MMSSMS and MMS don’t support delivery or read receipts — see Protocol capabilities
Duplicate webhooksAt-least-once deliveryDeduplicate using event_id — see Webhook delivery

When contacting Linq support, always include:

  1. The trace ID from the API response
  2. The timestamp of the request
  3. The endpoint you called
  4. The response you received (status code and body)

This allows the support team to look up the exact request in their systems.