Submitting Feedback
When a bill or account connection looks right or wrong, surface a “is this correct?” affordance and submit the answer through POST /v1/feedback. You report on the resource, not on any internal run — BillerAPI attributes the feedback to the agent run that produced it and folds it into the self-improvement loop, so extraction quality compounds per biller.
Pick a signal
The valid signal depends on theresource_type. Each type has one positive signal plus the specific ways it can be wrong. The full list lives in the API reference; the common ones:
| resource_type | signal | Use when… |
|---|---|---|
| bill | bill_correct | The bill is accurate. Affirmative feedback is just as valuable — it auto-promotes winning prompt versions. |
| bill | wrong_amount | The amount due is wrong. Put specifics in notes. |
| bill | wrong_due_date | The due date is wrong. |
| bill | not_my_bill | The bill doesn’t belong to the account (also: duplicate_bill, wrong_status, missing_line_items, stale_data). |
| account_connection | accounts_correct | The discovered accounts are correct. |
| account_connection | missing_account | An account that should have been discovered is missing (also: wrong_account, wrong_biller_matched, duplicate_account). |
1. Hold onto the resource id
You already have it: the id of the bill you render, or the account-connection (account link) id. That’s theresource_id — no run id, no biller id to track. BillerAPI resolves the producing run on its side.
2. POST the feedback
On submission, POST with an idempotency_key so a network retry doesn’t double-count. Generate it once at the moment the user clicks submit and re-send it on retry. Recommended format: idem_<timestamp>_<resource_id>.
Minimal client-side submission
async function submitFeedback({ resourceType, resourceId, signal, notes }) {
// Generated ONCE here. If the network errors and you retry, reuse this same key.
const idempotencyKey = `idem_${Date.now()}_${resourceId}`;
const res = await fetch('https://sandbox.api.billerapi.com/v1/feedback', {
method: 'POST',
headers: {
'Authorization': 'Bearer $BILLERAPI_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
resource_type: resourceType, // 'bill' | 'account_connection'
resource_id: resourceId,
signal, // valid values depend on resource_type
idempotency_key: idempotencyKey,
notes, // optional, recommended when reporting a problem
}),
});
if (!res.ok) {
const error = await res.json();
throw new Error(`feedback failed: ${error.error_code} — ${error.error_message}`);
}
return await res.json(); // { resource_type, resource_id, agent_type, signal, attributable, run_id?, already_existed }
}3. Handle the response
Success is 202 Accepted. Two fields on the response are worth reading; the full error catalog is at Feedback errors.
attributable: false— recorded, but BillerAPI couldn’t locate the producing run (unknown or aged out). This is normal and not an error; the feedback is still stored.already_existed: true— idempotent replay; nothing new was written. Safe.400 FEEDBACK_INVALID_SIGNAL— the signal isn’t valid for the resource_type (or the key is missing). Fix client-side validation.404 FEEDBACK_RUN_NOT_FOUND— the resource doesn’t exist or isn’t owned by your client. Don’t expose to the user; log + investigate.409 FEEDBACK_ALREADY_SUBMITTED— a different key already submitted for this resource. Reuse the original key to replay, or treat as success.
What happens to your feedback
Attributed feedback enters the per-biller signal pipeline:
- Positive signals (
bill_correct,accounts_correct) — count toward auto-promote thresholds for the prompt version that ran. Affirmative feedback is what lets winning versions graduate. - Everything-wrong signals — count toward auto-rollback thresholds. A cluster on the same biller crosses the threshold and reverts the agent to its prior prompt version without human intervention.
This is why high-quality feedback matters. A noisy stream of mis-categorized signals or empty notes dilutes the pipeline. Gate on user confirmation, populate notes with the specifics, and the per-biller signal compounds.
Best practices
- Submit on success too. Most clients only file negative feedback. That biases the signal.
bill_correctsubmissions are what let us auto-promote new prompt versions safely. - Gate on user confirmation. Don’t auto-submit on every output you don’t recognize. False-positive feedback poisons the signal.
- One
idempotency_keyper submission — not per user session. Reuse it only to retry the same submission. - Use
notesfor specifics. “Amount is wrong” is noise; “$0 returned but statement shows $84.32” is actionable. Keep PII out. - Don’t block your UI on
attributable. Afalsevalue still means “recorded” — show the user their report landed.