Feedback
A structured way for an integrating agent to report an unexpected failure back to Tyxter.
POST /v1/feedback is accepted with any valid live or sandbox API key, requires no scope, and is accepted even when production credit is exhausted. Reporting a failure must never be gated on balance.How it fits
When a public /v1/* call fails with an unhandled internal_error, the error envelope carries a feedback pointer (see /errors). That pointer tells an integrating agent where to report what it saw. POST /v1/feedback is that endpoint: it records a short free-text report plus optional, submitter-asserted correlation so the issue can be triaged. The receipt never echoes the report back; use the API-origin status reads below when you need to follow its latest customer-safe resolution.
Request
The body is strict — unknown fields are rejected. Only these fields are accepted:
message(required) - the report text, trimmed, 1–2000 characters.related_error(optional) -{ code?, request_id?, trace_id? }. Copy these from the failing response envelope so the report correlates to the failure. Submitter-asserted and stored as untrusted data.context(optional) - a flat string-to-string map (Record<string, string>), not a nested object. Bounds: at most 32 entries, keys ≤ 64 characters, values ≤ 1024 characters, 16 KiB serialized, 32 KiB total body.
Tenant provenance (organization, project, environment, and the API key id) is derived from your key on the server — never read from the body. The body cannot set provenance, status, or redaction fields; they are unknown keys and rejected. Idempotency-Key is mandatory: a missing or blank header is rejected before the report is recorded.
POST /v1/feedback
authorization: Bearer $TYXTER_API_KEY
idempotency-key: 8f1c0e9a-...
{
"message": "Send failed with internal_error on a valid template send.",
"related_error": {
"code": "internal_error",
"request_id": "req_...",
"trace_id": "trc_..."
},
"context": {
"sdk_version": "1.4.0",
"route": "POST /v1/messages"
}
}Receipt
A successful submit returns 201 with a minimal receipt. It confirms the report was recorded and whether any redaction occurred — it never echoes the message, context, or correlation back.
{
"id": "fbk_...",
"object": "feedback_receipt",
"received_at": "2026-06-22T12:00:00Z",
"redacted": true
}Replaying the same Idempotency-Key with the same body returns the same receipt and records no new report.
Read status
GET /v1/feedbacklists only API-origin reports in the authenticated key's organization, project, and environment. It is newest-first with a strict after cursor over created_at and id (default 20, maximum 50). A replacement key in the same tuple can read prior reports. Dashboard-origin reports are never returned.
Detail and list items contain only the report ID, status, a 160-character message excerpt, creation timestamp, and latest customer-safe resolution. The raw message, diagnostics, identities, API-key provenance, and resolution history are never returned. A missing, foreign, dashboard-origin, or purged ID returns the same 404 feedback_report_not_found response.
GET /v1/feedback?limit=20
authorization: Bearer $TYXTER_API_KEY
{
"object": "list",
"data": [{
"id": "fbk_...",
"object": "feedback_report",
"status": "resolved",
"message_excerpt": "Send failed with internal_error...",
"created_at": "2026-08-26T12:00:00Z",
"latest_resolution": {
"disposition": "resolved",
"public_summary": "We fixed the delivery issue.",
"published_at": "2026-08-26T13:00:00Z"
}
}],
"has_more": false,
"next_cursor": null
}Pass a non-null next_cursor as after to continue. A malformedafter returns 400 invalid_cursor; an invalid limit or query shape returns 400 invalid_query. Both fail before data is read.
JavaScript SDK
const page = await client.feedback.list({ limit: 20 });
const report = await client.feedback.get(page.data[0].id);These SDK methods use the same routes, tuple fence, pagination, response fields, and not-found behavior as the REST API.
Product MCP
Connect an agent to the product MCP endpoint and discover list_feedback and get_feedback through the normal tool list. Both are read-only tools requiringmessages:read; they return the same minimized result as REST. Use list_feedback with optional after and limit, then pass a report ID to get_feedback.
list_feedback({ limit: 20 })
get_feedback({ feedback_report_id: "fbk_..." })Endpoints
Agent guidance
Do not paste credentials or raw request bodies into message or context. Supported credential patterns — Tyxter tx_live_ / tx_sandbox_ keys, Bearer tokens, and the values of sensitive context keys — are redacted before storage, and redactedreports whether that happened. The redactor is a data-at-rest control, not a guarantee: keep secrets out of the report. Send the failure's trace_id in related_error rather than copying response payloads.
Feedback is rate-limited per API key and per organization, with a stricter policy for sandbox keys. Idempotent replays do not count as new accepted writes.