Recipe: document collection

Show a user what is missing on their records, offer the documents already in their mailbox that could fill the gap, and prepare a message to ask the other party for the rest. This uses the chaser, bind.co's follow-up on records that are missing something; see Operations. The examples use expenses; the same routes exist for every operation type the chaser follows.

Why it matters: chasing missing documents is slow, manual work. Your users see what is missing, fill most gaps from files they already have, and send a ready-made request for the rest, so records get complete without a single "did you send it?" email written by hand.

Scopes: profile:read, operations:expenses:write (includes operations:expenses:read), and drafts:write (includes drafts:read): the prepared-message queue needs drafts:read together with the operation scope, and deciding needs drafts:write. Webhooks: expenses.first_completed, expenses.completed.

1. See where one record stands

curl https://api.bind.co/v1/operations/expenses/op_5b1f0c7e-8a2d-4c3b-9e61-2f7d4a9c0b13/chaser \
  -H "Authorization: Bearer $ACCESS_TOKEN"

The answer gives the record's phase, what is missing and the next step. To build a list instead, search with chaser_status, or read one of the three queues below.

2. Offer what is already in the mailbox

curl https://api.bind.co/v1/operations/expenses/chaser/self-help \
  -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "items": [
    {
      "operation_id": "op_5b1f0c7e-8a2d-4c3b-9e61-2f7d4a9c0b13",
      "chaser_status": "in_self_help",
      "gaps": [
        {
          "canonical_path": "expense_date",
          "reason": "absent",
          "candidates": [{"canonical_path": "expense_date", "source_operation_id": "op_3f6c2a9e-8b1d-4c57-9e0a-5d2f7b8c1e44",
                          "observed": {"value": "2026-10-14", "bind_inference_confidence": 0.94}}],
          "document_candidates": []
        }
      ]
    }
  ],
  "total_items": 1, "total_pages": 1, "page_number": 1, "page_size": 50
}

Each gap lists values found on the user's other records (candidates) and, for a missing document, files in their mailbox that could be it (document_candidates, each with file_name, doc_type and conforms). Let the user pick one:

curl https://api.bind.co/v1/operations/expenses/op_5b1f0c7e-8a2d-4c3b-9e61-2f7d4a9c0b13/chaser/self-help/confirm \
  -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \
  -d '{"canonical_path": "expense_date", "source_operation_id": "op_3f6c2a9e-8b1d-4c57-9e0a-5d2f7b8c1e44"}'

For a document, send file_id instead of source_operation_id. Accepting adds the evidence to the record and cannot be undone; .../chaser/self-help/reject with the same body removes a candidate for good.

3. Ask the other party

When the mailbox has nothing, bind.co prepares a message to the other party:

curl https://api.bind.co/v1/operations/expenses/chaser/outreach-approval \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Each item has counterpart_name, counterpart_email, missing_item, subject and body. Show it to the user; they approve it with POST /v1/operations/expenses/{operation_id}/chaser/outreach-approval/confirm or turn it down with .../outreach-approval/reject, optionally with a reason. Approving records the decision; it sends nothing from this call.

4. Hand the rest to the user

curl https://api.bind.co/v1/operations/expenses/chaser/owner-escalation \
  -H "Authorization: Bearer $ACCESS_TOKEN"

These records need the user: show their gaps and let them fill the values with PATCH /v1/operations/expenses/{operation_id}, or stop the follow-up with POST /v1/operations/expenses/{operation_id}/chaser/owner-escalation/dismiss, which leaves the record itself unchanged.

5. Stay current

On expenses.completed, read the queues again: new mail can fill gaps, and records move between phases. Files that arrive as evidence carry the same file_id wherever they appear; see Files.

Make it yours