FINANCE API IMPLEMENTATION GUIDE

Building an accounts-payable exception API for human and agent review

How stable codes, severity, evidence, precedence, and next actions turn AP exceptions into a dependable workflow contract.

Define exceptions as product contracts

Free-form error messages are difficult to route and impossible to version safely. Give each business exception a stable code, severity, human-readable message, structured evidence, retryability, and recommended next action. Preserve the same code across REST, webhooks, dashboards, and MCP.

  • Code for branching.
  • Severity for prioritization, not automatic authority.
  • Evidence for review and audit.
  • Next action for an agent or operator.

Separate operational failures from business exceptions

A missing required request field is an API validation error. An invoice with no invoice number after successful extraction is a business exception. A Textract outage is a processing failure. Mixing these states leads callers to retry records that require review or send malformed requests to humans.

  • 4xx: caller must correct authentication or input.
  • FAILED job: retry only when the code says the failure is retryable.
  • COMPLETED with exceptions: route the evidence packet according to policy.

Document precedence

When multiple rules fire, the top-level decision must be predictable. An exact duplicate can be BLOCKED even when OCR confidence is low. A missing invoice number may require review when no blocking duplicate exists. Publish precedence and keep all relevant exceptions so the reviewer sees the full record.

  • BLOCKED outranks REVIEW_REQUIRED.
  • REVIEW_REQUIRED outranks CLEAR.
  • Review acknowledgements record a decision but do not rewrite the original control evidence.

Make review append-only

Record acknowledgement or dismissal as a separate audit event. Do not mutate a historical exception into CLEAR and do not write the reviewer decision to an accounting system. This preserves what the control found and what the human decided.

REPRESENTATIVE CONTRACT

Auditable exception result

The values below are synthetic. Use a tenant-scoped key stored as a secret, and evaluate the documented status, decision, evidence, and next action before continuing a workflow.

Representative request
POST /v1/invoices
Authorization: Bearer apc_...
Idempotency-Key: inv-demo-1042
Content-Type: application/json

{
  "invoice": {
    "vendor_name": "Northstar Supply",
    "invoice_number": "INV-1042",
    "invoice_date": "2026-08-09",
    "currency": "USD",
    "total": "1250.00"
  }
}
Representative response
{
  "id": "inv_01...",
  "status": "QUEUED",
  "decision": null,
  "source_type": "STRUCTURED",
  "exceptions": []
}

IMPLEMENTATION CHECKLIST

Ship the control with its safety boundary intact.

  • Version a stable code catalog.
  • Return structured evidence with every exception.
  • Publish decision precedence.
  • Distinguish retryable failures from review work.
  • Record review separately from analysis.
  • Use the same contract across REST, MCP, webhooks, and UI.

FREQUENTLY ASKED QUESTIONS

Questions workflow builders ask

Should dismissing an exception change the original API decision?

No. Store the review decision separately so the original control result remains auditable.

Can severity determine payment approval?

No. Severity helps prioritize review. Approval remains in the customer's authorized process.

What makes an exception agent-readable?

A stable code, bounded evidence, retryability, and one safe recommended next action let an agent branch without interpreting vague prose.

Test the control with your own authorized workflow.

Start with synthetic or non-sensitive data, inspect the structured evidence, and keep every ERP, vendor, approval, and payment write in your own authorized system.