A practical reference for every response from POST /api/agents:
authentication failures, request validation, rate limits, server errors,
webhook configuration, and valid responses whose verification found a mismatch.
Start with the full API reference or the
SDK quickstart if you need a working request.
A valid API key can return 200 even when verification fails. Treat
HTTP status as transport/authentication state, then inspect
verification.verified and its anomalies before deciding
whether the invoice is safe to pay. Do not retry a semantic verification failure
as though it were an HTTP failure.
| Stable field | Meaning | Corrective action |
|---|---|---|
authenticated |
true on a response produced with a recognized API key. |
Use this to distinguish a valid-key result from an HTTP 401; it does not mean the data verified. |
owner_label |
The label associated with the API key. | Use it for request tracing; do not use it as the verification decision. |
verification |
The receive/pay or three-way-match result, including verified, IDs, matched fields, anomalies, and checked_at. |
Gate downstream payment on verification.verified === true and investigate every error anomaly. |
verification.anomalies[] |
Each item has field and severity, plus optional expected, actual, and message. |
Fix the named request or source record, then make a new verification call when the data is corrected. |
// 200 OK — the key worked; the invoice data did not verify
{
"authenticated": true,
"owner_label": "your-key-label",
"verification": {
"verified": false,
"invoice_id": "inv_001",
"payment_id": "pay_001",
"matched_fields": [],
"anomalies": [
{
"field": "expected_amount",
"severity": "error",
"expected": 125,
"actual": 150,
"message": "amount mismatch (expected 125, actual 150)"
}
],
"checked_at": "2026-08-29T12:00:00.000Z"
}
}
These failures stop the request before a normal verification result is returned. The body shapes below are stable; use the action in the last column to recover.
| Status | Response body | When | What to do |
|---|---|---|---|
401 |
{ "error": "API key required" } |
No Authorization: Bearer ... or x-api-key header was supplied. |
Send the API key in one of those headers. Check that the header was not stripped by your HTTP client or proxy. |
401 |
{ "error": "Invalid or revoked API key" } |
The supplied key is not recognized or has been revoked. | Check for a truncated/copied key. Replace it with an active key from the Truss developer flow; do not keep retrying the revoked key. |
429 |
{ "error": "rate_limited", "plan_id": "beta", "rpm": 60, "retry_after_seconds": 12 } |
The API key reached its plan’s requests-per-minute limit. The same seconds value is sent in the Retry-After header. |
Back off for at least retry_after_seconds, then retry with jitter. Reduce concurrency or move to a plan with a higher rpm when the traffic is expected. |
500 |
{ "error": "Internal server error" } |
An unexpected server or authentication-dependency failure occurred. | Retry with bounded backoff. If it persists, record the time and request ID/context available to you and contact Truss support; do not infer a verification result. |
// 401 — no credential was received
{ "error": "API key required" }
// 429 — wait for the Retry-After duration
{
"error": "rate_limited",
"plan_id": "beta",
"rpm": 60,
"retry_after_seconds": 12
}
Receive/pay verification failures are normally semantic 200 responses.
Fix the request or the underlying invoice/payment data, inspect the next
verification.verified value, and only proceed when it is true.
| Field | Typical message or condition | Corrective action |
|---|---|---|
invoice_id |
invoice_id is required when the field is missing, null, or empty. |
Send the invoice identifier in the JSON body. |
invoice |
invoice not found when the identifier does not resolve. |
Check the ID and environment, then create or reference the correct invoice. |
payment |
no payment scheduled for invoice. |
Schedule the matching payment before expecting a verified receive/pay result. |
expected_* |
Comparison mismatch for amount, currency, vendor name, routing number, or account last four digits; the anomaly includes expected, actual, and often a message. |
Correct the request’s expected value or the stored invoice/payment data, then verify again. |
invoice.decision / payment.status |
A warning for a non-approved invoice decision, or an error for a failed payment. | Review the invoice decision or payment failure. An error means the result is not verified. |
With "mode": "three_way_match", Truss checks the supplied PO,
invoice, and receipt for amount, vendor_name, and
date. The PO also needs po_number. Missing or incomplete
documents produce verdict: "missing"; complete documents can produce
verified, partial, or mismatch depending on
how many comparisons match.
| Verdict | Meaning | Corrective action |
|---|---|---|
missing |
missing_documents lists a document missing one or more required fields. |
Supply PO po_number, and amount/vendor/date on all three documents. |
partial |
Some amount, vendor, or date comparisons match and others do not. | Use each anomaly’s values to correct the mismatching document fields. |
mismatch |
None of the three comparisons match. | Check that the documents belong to the same purchase and normalize their amount, vendor, and date data. |
// 200 OK — semantic result, not an HTTP failure
{
"authenticated": true,
"owner_label": "your-key-label",
"verification": {
"mode": "three_way_match",
"verdict": "missing",
"verified": false,
"missing_documents": ["receipt"],
"comparisons": [],
"matched_fields": [],
"anomalies": [
{
"field": "documents.receipt",
"severity": "error",
"message": "receipt missing required fields (amount, vendor_name, date)"
}
],
"checked_at": "2026-08-29T12:00:00.000Z"
}
}
A request with a revoked API key fails before verification with HTTP 401.
Its exact JSON response is { "error": "Invalid or revoked API key" }.
The response contains only the error field — never authenticated,
verification, invocation_id, or other invocation fields.
| Credential state | Status and response body | What it means |
|---|---|---|
| Missing header | 401{ "error": "API key required" } |
No Authorization: Bearer ... or x-api-key header was supplied. |
| Supplied key is revoked, malformed, truncated, or otherwise unrecognized | 401{ "error": "Invalid or revoked API key" } |
These supplied-key failures intentionally share one response, so the API does not disclose whether the token was revoked. Only the error field is returned. |
curl -i -X POST https://api.truss.polsia.app/api/agents \
-H "Authorization: Bearer truss_<revoked-or-invalid-key>" \
-H "Content-Type: application/json" \
-d '{"invoice_id":"inv_001"}'
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{ "error": "Invalid or revoked API key" }
To recover from a supplied invalid or revoked key:
Authorization: Bearer ... or x-api-key value and check the token copy for truncation or whitespace.Need to manage or replace a key? Return to the API key management section.
An invalid webhook_url is a request validation failure and returns
400 before verification runs. The URL must be non-empty, no longer
than 2048 characters, use http:// or https://, and contain
no URL username or password.
// 400 Bad Request
{
"error": "invalid_webhook_url",
"message": "webhook_url must use http:// or https://"
}
Fix it by sending a credential-free HTTP(S) URL. Omit webhook_url to
reuse the stored callback, or send null to clear the stored callback.
A malformed URL, credentials such as https://user:pass@example.com,
an unsupported protocol, and an overlong URL all use the same
invalid_webhook_url error with a specific message.
Callback delivery is asynchronous and separate from the inline response. Truss
retries non-2xx responses, timeouts, and network failures for three
total attempts (the initial delivery plus two retries), records the final failure,
and does not change the original valid
200 response. See the API reference’s
callback signature and retry guidance for the HMAC header and receiver example.
A server-side failure is not a verification verdict. Retry the generic
500 response with bounded backoff; if it continues, contact Truss with
the request timing and context. Once the request reaches verification, all data
correctness cases are represented by the stable 200 envelope described
above.
// 500 Internal Server Error
{ "error": "Internal server error" }