Docs / API and agents
AI assist API
Pipeline and reference summaries, application assist drafts, and public scan-to-fill, all through the configured model gateway.
Model calls go through OpenRouter. The key comes from the environment; the model for each flow is chosen by staff (below) and otherwise comes from the environment, which defaults to free models. Vendor context is checked for role, permission and tenant before any data reaches the provider.
| Method and path | Who | What |
|---|---|---|
POST /ai-assist | supplier role with applications.ai_assist | body action: summarize_pipeline, flag_priority, summarize_references, flag_concerns; plain-text answer about the caller's organization |
POST /ai-chip | session | short help or draft chip; vendor context needs applications.ai_assist |
POST /applications/:id/ai-assist | supplier of that application | action: summarize, draft_message, draft_decline |
POST /extract | public | multipart file (PDF or image, 4 MB max) to prefill an application |
| Status | When |
|---|---|
| 400 | invalid input; file contents do not match the declared type |
| 403 | not vendor-scoped, or the application belongs to another organization |
| 404 | application not found |
| 413 | scan file above 4 MB |
| 429 | 30 AI calls per user per hour; 5 scans per IP per 15 minutes |
| 503 | scan-to-fill is disabled, the AI runtime is not configured, or the daily AI spending cap was reached (ai_spend_cap; resumes at 00:00 UTC) |
Choosing the model per flow#
Staff pick the OpenRouter model for each flow on the platform Settings screen (tab "AI models"). A flow with no choice runs the environment chain (AI_MODEL, AI_MODEL_VISION, AI_MODEL_FALLBACKS), which is a list of free models when nothing is set. A chosen model goes first and the environment chain stays behind it, so a model that is busy or withdrawn still falls through.
| Flow | Used by | Model must |
|---|---|---|
| Applicant writing help | ai-assist, ai-chip, application assist | answer in text |
| Scan to fill | extract | accept images |
| Supplier discovery | the supplier finder | answer in text |
| Credit terms drafting | credit terms drafts | answer in text |
| Form builder assistant | POST /forms/:id/assistant | answer in text |
| Method and path | Permission | What |
|---|---|---|
GET /platform/ai/models | staff.ai.models.view | every flow with its choice, the environment defaults, and the OpenRouter model list (price per million tokens, context, image support) |
PUT /platform/ai/models/:flow | staff.ai.models.manage | body model; refused when the id is not in the live list (400), the flow needs images and the model has none (400), the list cannot be read (503), or the model costs money and AI_DAILY_USD_CAP is not set (409 spend_cap_not_set) |
DELETE /platform/ai/models/:flow | staff.ai.models.manage | back to the environment chain |
Every change records ai.model_changed or ai.model_reset with the model ids (no prompts or keys). A change reaches every instance within 15 seconds.
Free models rate-limit, disappear and may log prompts, so the default is meant for testing. A paid model spends the OpenRouter balance from the first request; set
AI_DAILY_USD_CAPto a small amount first.
The model is told that application and reference text is untrusted evidence and that it may only draft, never approve, decline or set terms.
With
AI_ALLOW_PII=false(default in production) names, emails, phone numbers and tax or account numbers are replaced by placeholders before the request leaves the service and restored in the answer, andPOST /extractanswers 503 (document_extraction_pii_blocked). Each call that reads application or reference data records anai.readaudit event with who, organization, route and target id, never values.
AI output is a draft for a person. Nothing here records a decision or sends a message by itself.