Docs / API and agents

References API

Add, correct and remind trade references (applicant and credit team), answer by private link (public), and the reference portal reads.

Four controllers in apps/services/src/references. Public routes are credentialed by an unguessable, expiring link token, not a session.

Routes#

Method and pathWhoWhat
POST /reference/:token/respond, POST /reference/saved/:token/respondpublic, link tokenanswer or decline
GET /reference/:token/view, GET /reference/saved/:token/viewpublic, link tokenwhat the reference page shows
POST /applications/:id/referencesthe applicant who owns the applicationadd a reference (max 10)
PATCH /applications/:id/references/:refIdownercorrect the email or phone; the old link stops working
DELETE /applications/:id/references/:refIdownerremove a reference that has no response, message or document
POST /applications/:id/remind-allowner (with references.remind), or supplier with references.remindremind every pending reference
POST /references/:id/remindowner (with references.remind), or supplier with references.remind (only suppliers may ask for an update)remind one reference
PATCH /references/:id/settingssupplier with references.settingsautomatic re-review interval: body { "autoRereviewDays": 1..3650 }, or null to turn it off
GET /references/:id/historysupplier with references.view, or staffresponse revisions
POST/PATCH/DELETE /saved-references[/:id], POST /saved-references/:id/remindsessionthe applicant's reusable reference contacts
GET /reference-portal/summary, inbox, history, messagessessionthe signed-in reference provider's portal

Answering#

A response needs certified: true, recommendation (highly, recommend, neutral, do-not) and a non-empty signedByName; payment timeliness, NSF, balances, terms and notes are optional. A drawn signature image must decode as PNG or JPEG. { "declined": true, "declineReason": "..." } declines. The response claims the current link and request version in one transaction and writes an immutable revision.

StatusWhen
200{ ok: true }
400invalid response or signature
404unknown link
409already answered or the request changed since the page loaded
410the link expired; ask the sender for a fresh one
413body too large
42910 attempts per IP per hour

Managing references#

Every reference request and update request email names the sender (company and postal address), and ends with a line telling the reference how to stop further requests (reply or write to support with "stop"; support handles it by hand today). Reminders rotate the private link. Limits: 50 reminders per user per hour, at least 24 hours between reminders to one reference (429), four hours between reminder batches. A declined reference cannot be reminded and a responded one only through an update request (409). Reference contacts with a response, message or document cannot be removed or edited (409). Non-owners get 403 or 404.

Lifecycle#

A reference is PENDING until it answers (RESPONDED) or declines (DECLINED). Each private link lives 90 days from the moment it was minted; an expired link answers 410 on view and on respond, and only a reminder mints a fresh one.

  • Reminders and update requests rotate the link: the old link stops working and the response must match the current link and request version (otherwise 409). A reminder to a reference that is RESPONDED is refused (409) unless it is an update request, which starts a new cycle; both answers stay in the history.
  • DECLINED is terminal for reminders (409).
  • Automatic chase (the rereview-references job, daily 08:30 UTC, see Scheduled jobs): a PENDING reference is re-sent a reminder every 3 days after the last send, at most 3 times, only when the supplier's published credit form has the reference auto-chase feature on and the application is not yet APPROVED or DECLINED. A recipient who muted reference email is skipped and the clock moves on; two simultaneous runs queue one reminder.
  • Automatic re-review: when a supplier sets autoRereviewDays on a RESPONDED reference, the same job sends an update request once that many days have passed since the last response or reminder. It does not depend on the auto-chase feature. Turning the interval off stops it.
  • The credit desk calls a pending reference late when it was neither sent nor reminded for 3 days.
  • At most 10 references per application (the 11th is 409, including when additions race). A slot is freed only by removing an unanswered reference. No reference can be added after a final decision.

The status NO_RESPONSE exists in the data model and the "closed" filter, but no code sets it today; an unanswered reference stays PENDING and shows as expired once its link lapses.