Documentation

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_typesignalUse when…
billbill_correctThe bill is accurate. Affirmative feedback is just as valuable — it auto-promotes winning prompt versions.
billwrong_amountThe amount due is wrong. Put specifics in notes.
billwrong_due_dateThe due date is wrong.
billnot_my_billThe bill doesn’t belong to the account (also: duplicate_bill, wrong_status, missing_line_items, stale_data).
account_connectionaccounts_correctThe discovered accounts are correct.
account_connectionmissing_accountAn 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
Node
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_correct submissions 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_key per submission — not per user session. Reuse it only to retry the same submission.
  • Use notes for 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. A false value still means “recorded” — show the user their report landed.
Was this page helpful?