# Admin Emails Source: https://docs.getomni.ai/ai-agent/admin-emails # Admin Emails Configure admin email addresses to enable additional communication workflows and notifications. ## Overview Once admin emails are set up, admins can: * Forward emails to the agent to create leads * CC the agent on email chains with borrowers * Receive notifications about agent activity ## Related Guides Set up agent email addresses Configure other agent settings # Autopilot Source: https://docs.getomni.ai/ai-agent/autopilot # Autopilot Mode Autopilot mode allows the AI agent to automatically send messages and take actions without requiring admin approval. This enables fully automated lead engagement and document collection. ## How Autopilot Works When Autopilot is enabled: * **Messages are sent immediately**: No admin review required * **Follow-ups are scheduled automatically**: Agent determines optimal timing * **Tools are executed automatically**: Agent can use tools without approval * **Responses are generated in real-time**: Fast turnaround for leads ## Autopilot vs Listen Mode ### Autopilot Mode * ✅ Messages sent automatically * ✅ Fully automated workflow * ✅ Faster response times * ⚠️ Less control over individual messages ### Listen Mode * ✅ Admin review before sending * ✅ Full control over messaging * ✅ Quality assurance * ⚠️ Requires admin attention ## When to Use Autopilot Autopilot is ideal for: * **High-volume workflows**: When you have many leads to manage * **Standardized processes**: When responses follow predictable patterns * **24/7 coverage**: When you need constant availability * **Initial engagement**: For first contact and follow-ups ## When to Use Listen Mode Listen mode is better for: * **Complex situations**: When human judgment is needed * **Policy-sensitive communications**: When compliance requires review * **New configurations**: When testing new agent behavior * **Low-volume, high-value leads**: When individual attention matters ## Configuring Autopilot Enable Autopilot in agent settings: 1. Go to [Agent Settings](https://platform.getomni.ai/agent#settings) 2. Find the "Agent Mode" section 3. Select "Autopilot" 4. Configure any additional settings ## Monitoring Autopilot Even in Autopilot mode, you can: * **View all messages**: See what the agent sent in the Timeline * **Review agent actions**: Check tool executions and results * **Monitor lead progress**: Track checklist completion * **Override when needed**: Switch to Listen mode for specific situations ## Best Practices * **Start with Listen mode**: Test agent behavior before enabling Autopilot * **Monitor regularly**: Review agent messages and actions * **Fine-tune prompts**: Adjust workflow prompts based on results * **Set escalation rules**: Configure when to escalate to humans ## Related Guides Configure Autopilot mode Customize agent behavior Monitor Autopilot activity # Checklist Source: https://docs.getomni.ai/ai-agent/checklist Checklist # Checklist The agent's main goal is to collect information from leads and help them complete the onboarding process. The checklist defines what information and documents are required from each applicant. ## Overview The checklist is a structured list of items that need to be collected from leads. Each item can be: * **Required or optional**: Mark which items are mandatory * **Different field types**: Text, file upload, date, address, EIN, etc. * **Validated**: Configure validation rules for each item * **Grouped**: Organize items into logical groups ## Setting Up Your Checklist ### 1. Create Checklist Groups Organize your checklist items into groups (e.g., "Business Information", "Financial Documents", "Ownership Information"). ### 2. Add Checklist Items For each item, configure: * **Label**: Display name for the item * **Field type**: What kind of data is expected (text, file, date, etc.) * **Required**: Whether this item is mandatory * **Validation rules**: Custom validation logic * **Help text**: Guidance for applicants * **Client instructions**: Instructions shown to applicants ### 3. Configure Validation Set up validation rules for each checklist item: * **Format validation**: Ensure data matches expected format * **Document validation**: Validate uploaded documents * **Custom rules**: Define custom validation logic When the agent receives a document, it will try to classify the document and see if it matches one of the checklist items. If yes, then it will apply the validation rules to the document. ## Field Types Supported field types include: * **TEXT**: Free-form text input * **FILE**: Document upload * **DATE**: Date picker * **ADDRESS**: Address input * **EIN**: Employer Identification Number * **Custom types**: Additional field types as needed ## Document Matching The agent automatically: 1. **Classifies documents** to identify their type 2. **Matches documents** to checklist items 3. **Validates documents** against configured rules 4. **Extracts data** from documents to populate checklist items ## Related Guides Learn how documents are collected Tools available to the agent Retrieve checklist via API # Conversation Source: https://docs.getomni.ai/ai-agent/conversation # Conversation The AI agent handles conversations with leads across multiple channels (email and SMS). Understanding how conversations work helps you configure and monitor agent behavior effectively. ## How Conversations Work ### Incoming Messages When a message is received: 1. **Agent identifies the lead**: Matches the message to an existing lead or creates a new one 2. **Processes the message**: Analyzes the content and any attachments 3. **Determines response**: Decides what action to take based on the message 4. **Executes tools if needed**: Uses tools to retrieve information or perform actions 5. **Generates response**: Creates an appropriate response based on context ### Outgoing Messages When the agent sends a message: * **Autopilot mode**: Message is sent immediately * **Listen mode**: Message is drafted for admin review before sending ### Documents in Conversations If documents are passed in: 1. **Documents are processed**: OCR, classification, and validation 2. **Checklist is updated**: Documents are matched to checklist items 3. **Data is extracted**: Information is pulled from documents 4. **Response is generated**: Agent acknowledges receipt and provides feedback ## Message Handling ### New Leads If the message is from a new lead: * A new lead is created automatically * The agent introduces itself and explains the process * The agent requests required information based on the checklist ### Existing Leads If the message is from an existing lead: * The agent retrieves the lead's current status * The agent continues from where the conversation left off * The agent updates checklist items based on new information ## Multi-channel Coordination The agent coordinates across channels: * **Email and SMS**: Messages can come from either channel * **Unified context**: Agent maintains context across all channels * **Channel selection**: Agent chooses the best channel for follow-ups ## Escalation If agent message could possibly violate lending policy, submit feedback to the agent. The system can be configured to escalate certain situations to human agents. ## Related Guides Enable automatic message sending Configure conversation settings View conversation history Retrieve conversations via API # Email Setup Source: https://docs.getomni.ai/ai-agent/email-setup # Email Setup Setting up an email address allows agents to send & receive emails. ## Steps 1. **Add a new email domain** in [workspace settings](https://platform.getomni.ai/settings/email-domains) 2. **Add all the DNS records** in your domain provider 3. **Wait for a few minutes** for domain verification 4. **Add a new email address** in [agent setting](https://platform.getomni.ai/agent#settings) * Choose the email domain that you added in the previous step * You can customize the email address and email display name 5. **Click `Send Test Email`** button to test sending a new email For detailed DNS configuration, see [Domain Configuration](/domain-configuration). ## Related Guides Set up email domain and DNS Configure other agent settings # Fine-tuning Source: https://docs.getomni.ai/ai-agent/fine-tuning # Fine-tuning Fine-tune your AI agent's behavior by customizing the workflow prompt and configuring agent settings. This allows you to tailor the agent's responses and actions to match your specific lending process and requirements. ## Workflow Prompt Workflow The workflow prompt is the main system prompt for the AI agent. You can: * **Define agent behavior**: Specify how the agent should interact with leads * **Set priorities**: Define what the agent should focus on first * **Customize tone**: Adjust the agent's communication style * **Add instructions**: Provide specific guidance for different scenarios ### Example Customizations **Prioritize document collection:** ``` Please focus on collecting all required documentation first before proceeding to other checklist items. ``` **Custom follow-up instructions:** ``` For drop-off leads, wait 2-3 days before following up, and schedule follow-ups for 9-11 AM in the lead's local timezone. ``` ## Knowledge Base Knowledge Base Enhance the agent's understanding by adding: * **Company information**: Your company background and values * **Product details**: Information about your loan products * **Process documentation**: Your lending process and requirements * **FAQ content**: Common questions and answers This helps the agent understand your company better and provide more accurate, automated responses to leads. ## Agent Behavior Settings Configure how the agent behaves: * **Communication preferences**: When to use email vs SMS * **Escalation rules**: When to escalate to human agents * **Follow-up frequency**: How often to follow up with leads ## Testing Your Configuration After making changes: 1. **Review the workflow prompt** to ensure it matches your requirements 2. **Test with sample leads** to verify behavior 3. **Monitor agent responses** in the Timeline 4. **Adjust as needed** based on results ## Best Practices * **Be specific**: Clear, specific instructions work better than vague guidance * **Set priorities**: Clearly define what the agent should focus on * **Update regularly**: Keep the knowledge base current with latest information * **Test changes**: Always test configuration changes before deploying widely ## Related Guides Configure agent communication settings Understand conversation handling Enable automatic agent responses # Agent Settings Source: https://docs.getomni.ai/ai-agent/settings Configure your AI agent's communication channels, behavior, and capabilities through the agent settings. ## Communication Channels Configure email addresses for your agent Set up SMS communication Configure admin email addresses ## Agent Behavior Configure agent automation mode Customize agent behavior and workflow prompt Configure agent tools and permissions # SMS Setup Source: https://docs.getomni.ai/ai-agent/sms-setup # SMS Setup Configure SMS communication for your AI agent to send and receive text messages with leads. ## Getting Started Reach out to the Monumint team and we will set up a Twilio number for your agent. ## Related Guides Set up email communication Configure other agent settings # Agent Tools Source: https://docs.getomni.ai/ai-agent/tools # Agent Tools AI agents can use tools to interact with the system, perform actions, and execute operations on behalf of leads. Tools allow agents to go beyond conversation and actually manipulate data, retrieve information, and perform tasks. ## Available Tools ### Document Processing Tools * **OCR Document**: Extract text from documents using OCR * **Document Classification**: Match documents to checklist requirements * **Data Extraction**: Extract structured data from documents ### Lead Management Tools * **Update Lead**: Update lead information including name, email, phone number, and website * **Create Lead**: Create new leads when needed * **Retrieve Lead Data**: Get current lead information and status ### Communication Tools * **Send Message**: Send emails or SMS messages * **Schedule Follow-up**: Schedule automated follow-up messages * **Retrieve Messages**: Access conversation history ## Tool Configuration Tools can be configured in the agent settings: * **Enable/Disable**: Choose which tools the agent can use * **Tool Permissions**: Set what actions each tool can perform ## Tool Execution When the agent uses a tool: 1. **Tool is called** with appropriate parameters 2. **Tool executes** the requested action 3. **Results are returned** to the agent 4. **Agent uses results** to continue the conversation or take next steps ## Tool Results in Timeline All tool executions are logged in the Timeline, showing: * **Tool name**: Which tool was used * **Input parameters**: What data was sent to the tool * **Output results**: What the tool returned * **Status**: Whether the tool execution succeeded or failed * **Timing**: When the tool was executed ## Related Guides View tool execution logs Configure available tools See how tools are used in conversations # Get Analytics Source: https://docs.getomni.ai/api-reference/analytics/get-analytics GET https://api-v2.getomni.ai/api/v0/analytics Fetch aggregate totals and per-lead analytics for your workspace Returns aggregate totals and a per-lead breakdown for leads in your workspace. Results are scoped to the API key's workspace and exclude deleted and test leads. ## Query Parameters ISO 8601 datetime (e.g. `2026-03-14T00:00:00Z`). Filters leads by `createdAt`. ISO 8601 datetime. Must be on or after `start` when both are provided. Response format. Either `json` or `csv`. When `csv`, the response is a JSON object with a signed `downloadUrl` pointing to a CSV file hosted on S3. Pagination token returned as `nextToken` on a prior request. Only used when `format=json`. Omit on the first request. If both `start` and `end` are omitted, all leads in the workspace are returned. JSON responses are capped at 500 leads per page. Use `nextToken` to fetch the next page. ## Response Echo of the start of the date range Echo of the end of the date range Pagination token for the next page. `null` when no more leads remain. Pass back as the `token` query param to fetch the next page. Workspace-wide aggregates over all leads matching the filter. Number of leads in the result set Leads with a submission timestamp Leads marked as not interested Leads who opted out Total messages across all leads Per-channel message counts, keyed by channel name (`sms`, `email`, `whatsapp`). Each value has `inbound` and `outbound` counts. Required-item completion aggregates. Sum of required + visible checklist items across all leads Sum of completed required items across all leads Completion count by source actor: `agent`, `imported`, `manual`, `portal` Human intervention counts across all leads. AI drafts edited by a human before sending AI drafts rejected or cancelled Human-initiated direct edits to lead or checklist fields Document validation overrides Escalations resolved by a human Array of per-lead analytics objects. Unique identifier for the lead ISO timestamp of lead creation ISO timestamp of lead submission, if completed ISO timestamp the lead was marked as not interested, if applicable ISO timestamp of opt-out, if applicable Most recent inbound message timestamp across all channels Most recent outbound message timestamp across all channels Per-channel stats for this lead. Keys are channel names (`sms`, `email`, `whatsapp`). Each value contains `inbound`, `outbound`, `lastInboundAt`, `lastOutboundAt`. Checklist completion for this lead. Same shape as `totals.completion`. Human intervention counts for this lead. Same shape as `totals.interventions`. One entry per checklist item associated with this lead. `{GROUP_KEY}.{ITEM_CODE}` — uppercase identifier for the checklist item. Group key is the group's internal name uppercased with spaces replaced by `_`. Just `{ITEM_CODE}` if the item has no group. `true` when the item is required AND visible to this lead (meets its conditions). One of `TODO`, `COMPLETED`, `INVALID`, `SKIPPED`, `NEEDS_REVIEW` Raw value entered for the item. Type varies by field. `null` if not filled. ISO timestamp of the last update to this item Source of the last update: `agent`, `imported`, `manual`, `portal`, or `null` if untouched ## Source values | Source | Origin | | ---------- | -------------------------------- | | `agent` | AI agent via tool calls | | `imported` | Public REST API calls | | `manual` | Human team member direct edits | | `portal` | Customer self-service via portal | ## CSV format When `format=csv`, the response is a JSON object with a signed URL to download the CSV file from S3. The URL expires after 1 hour. **Response fields:** Signed S3 URL to download the CSV file. Expires in 1 hour. ISO timestamp when the signed URL expires. **CSV file columns** (in the downloaded file): 1. Base fields: `leadId`, `firstName`, `lastName`, `email`, `phoneNumber`, `createdAt`, `completedAt`, `notInterestedAt`, `optedOutAt`, message counts, last-touch timestamps 2. Per-channel: `channels..inbound`, `channels..outbound`, `channels..lastInboundAt`, `channels..lastOutboundAt` 3. Completion: `completion.totalRequired`, `completion.totalCompleted`, `completion.bySource.*` 4. Interventions: `interventions.*` 5. Checklist items (index-based, sorted by group order then item order, padded to the maximum count across all leads): `checklist..code`, `checklist..required`, `checklist..status`, `checklist..value`, `checklist..updatedAt`, `checklist..source` Totals are not included in the CSV. Use `format=json` for aggregates. **Example CSV response:** ```json 200 theme={null} { "downloadUrl": "https://s3.amazonaws.com/your-bucket/analytics-exports/...?X-Amz-Signature=...", "expiresAt": "2026-04-14T18:00:00.000Z" } ``` ## Errors | Status | Cause | | ------ | ------------------------------------------------------------------------------------------------- | | 400 | Missing or invalid query parameters (e.g., non-ISO date, `start` after `end`, unrecognized param) | | 401 | Missing or invalid API key | ```javascript Node.js theme={null} const options = { method: 'GET', headers: { 'x-api-key': '', }, }; fetch( 'https://api-v2.getomni.ai/api/v0/analytics?start=2026-03-14T00:00:00Z&end=2026-04-14T00:00:00Z', options, ) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v0/analytics" params = { "start": "2026-03-14T00:00:00Z", "end": "2026-04-14T00:00:00Z" } headers = { "x-api-key": "" } response = requests.request("GET", url, headers=headers, params=params) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url 'https://api-v2.getomni.ai/api/v0/analytics?start=2026-03-14T00:00:00Z&end=2026-04-14T00:00:00Z' \ --header 'x-api-key: ' ``` ```bash cURL (CSV — get download URL) theme={null} curl --request GET \ --url 'https://api-v2.getomni.ai/api/v0/analytics?format=csv&start=2026-03-14T00:00:00Z&end=2026-04-14T00:00:00Z' \ --header 'x-api-key: ' ``` Then download the CSV from the returned `downloadUrl`: ```bash cURL (download CSV from signed URL) theme={null} curl -o analytics.csv '' ``` ```json 200 theme={null} { "start": "2026-03-14T00:00:00Z", "end": "2026-04-14T00:00:00Z", "totals": { "count": 950, "leadsCompleted": 320, "leadsNotInterested": 28, "leadsOptedOut": 45, "totalMessages": 12400, "inboundMessages": 4800, "outboundMessages": 7600, "channels": { "sms": { "inbound": 3200, "outbound": 4800 }, "email": { "inbound": 1400, "outbound": 2800 } }, "completion": { "totalRequired": 7600, "totalCompleted": 2060, "bySource": { "agent": 520, "imported": 80, "manual": 140, "portal": 1320 } }, "interventions": { "documentOverrides": 0, "escalations": 12, "manualUpdates": 51, "messageEdits": 109, "messageRejects": 14 } }, "breakdown": [ { "leadId": "4ef30123-90c2-4dc0-bd28-b43eee8664ea", "firstName": "Jane", "lastName": "Doe", "email": "jane@acme.com", "phoneNumber": "+15551234567", "createdAt": "2026-03-15T10:22:00Z", "completedAt": "2026-03-17T04:45:00Z", "notInterestedAt": null, "optedOutAt": null, "totalMessages": 18, "inboundMessages": 7, "outboundMessages": 11, "lastInboundAt": "2026-03-17T04:30:00Z", "lastOutboundAt": "2026-03-17T04:40:00Z", "channels": { "sms": { "inbound": 6, "outbound": 9, "lastInboundAt": "2026-03-17T04:30:00Z", "lastOutboundAt": "2026-03-17T04:40:00Z" }, "email": { "inbound": 1, "outbound": 2, "lastInboundAt": "2026-03-15T11:12:00Z", "lastOutboundAt": "2026-03-15T10:30:00Z" } }, "completion": { "totalRequired": 8, "totalCompleted": 8, "bySource": { "agent": 2, "imported": 0, "manual": 1, "portal": 5 } }, "interventions": { "documentOverrides": 0, "escalations": 0, "manualUpdates": 1, "messageEdits": 1, "messageRejects": 0 }, "checklistItems": [ { "code": "PERSONAL_DETAILS.FIRST_NAME", "required": true, "status": "COMPLETED", "value": "Jane", "updatedAt": "2026-03-15T10:22:00Z", "source": "portal" }, { "code": "DOCUMENTS.INCOME_VERIFICATION", "required": true, "status": "COMPLETED", "value": "s3://...", "updatedAt": "2026-03-15T11:02:00Z", "source": "portal" } ] } ] } ``` # Download Artifact Source: https://docs.getomni.ai/api-reference/artifacts/download-artifact GET https://api-v2.getomni.ai/api/v1/artifacts/:artifactId/content Download an artifact's bytes in its canonical format Download an artifact's bytes. A `REPORT` downloads as a PDF; a `SPREADSHEET` downloads as an `.xlsx` workbook. The response is the raw file with `Content-Disposition: attachment`, not JSON. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Path Parameters The artifact id, from a spread's `artifacts` array or the `spread.completed` webhook. ## Response The raw file bytes. The `Content-Type` header is `application/pdf` for a `REPORT` and `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` for a `SPREADSHEET`. A `404` is returned if the artifact isn't in your workspace. ```javascript Node.js theme={null} const fs = require("fs"); const response = await fetch( "https://api-v2.getomni.ai/api/v1/artifacts/art-report/content", { headers: { "x-api-key": "" } }, ); const buffer = Buffer.from(await response.arrayBuffer()); fs.writeFileSync("spread-report.pdf", buffer); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/artifacts/art-report/content" headers = {"x-api-key": ""} response = requests.request("GET", url, headers=headers) with open("spread-report.pdf", "wb") as file: file.write(response.content) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/artifacts/art-report/content \ --header 'x-api-key: ' \ --output spread-report.pdf ``` # Get Artifact Source: https://docs.getomni.ai/api-reference/artifacts/get-artifact GET https://api-v2.getomni.ai/api/v1/artifacts/:artifactId Retrieve metadata for an artifact Retrieve metadata for an artifact, such as a financial spread's report or spreadsheet. The response includes the download content type and a suggested filename; it does not include the file itself. Fetch the bytes with [Download Artifact](/api-reference/artifacts/download-artifact). ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Path Parameters The artifact id, from a spread's `artifacts` array or the `spread.completed` webhook. ## Response Whether the request succeeded. The artifact metadata. The artifact id. `REPORT` or `SPREADSHEET`. Human-readable title. Short description of the artifact. The lead the artifact belongs to, if any. When the artifact was created. The MIME type served by `/content`: `application/pdf` for a `REPORT`, `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` for a `SPREADSHEET`. A suggested download filename, including the extension. ## Errors No artifact with this id exists in your workspace. ```javascript Node.js theme={null} const options = { method: "GET", headers: { "x-api-key": "" }, }; fetch("https://api-v2.getomni.ai/api/v1/artifacts/art-report", options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/artifacts/art-report" headers = {"x-api-key": ""} response = requests.request("GET", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/artifacts/art-report \ --header 'x-api-key: ' ``` ```json 200 theme={null} { "success": true, "artifact": { "id": "art-report", "type": "REPORT", "title": "Financial Spread - Pacific Coast Container Haulers", "summary": "Consolidated financial spread from 2 document(s).", "leadId": "b1f0a790-201b-47e9-84ed-cc7eed1270c5", "createdAt": "2026-07-23T18:08:38.000Z", "contentType": "application/pdf", "filename": "Financial Spread - Pacific Coast Container Haulers.pdf" } } ``` # Get Document Source: https://docs.getomni.ai/api-reference/documents/get-document GET https://api-v2.getomni.ai/api/v1/documents/{documentId} Fetch a single document by ID This endpoint fetches a single document by ID, including metadata and a signed URL for accessing the document. ## Path Parameters The unique identifier of the document Optional. Whether to include the document’s base64-encoded content in the response ## Response Unique identifier for the document Original filename MIME type of the document (e.g., "application/pdf", "image/jpeg") File size in bytes ID of the lead this document belongs to ID of the workspace this document belongs to Pre-signed URL for accessing the document (expires after 1 hour) Base64-encoded document content ISO 8601 timestamp when the document was created ISO 8601 timestamp when the document was last updated Signed URLs expire after 1 hour. Use this API again to get a fresh signed URL. ```javascript Node.js theme={null} const documentId = 'd29176d4-25c6-4345-852d-0792e3812c70'; const options = { method: 'GET', headers: { 'x-api-key': '', }, }; fetch(`https://api-v2.getomni.ai/api/v1/documents/${documentId}`, options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests document_id = 'd29176d4-25c6-4345-852d-0792e3812c70' url = f"https://api-v2.getomni.ai/api/v1/documents/{document_id}" headers = { "x-api-key": "" } response = requests.request("GET", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/documents/d29176d4-25c6-4345-852d-0792e3812c70 \ --header 'x-api-key: ' ``` ```json 200 theme={null} { "id": "d29176d4-25c6-4345-852d-0792e3812c70", "filename": "monumint-technology-inc-8961-monthly-statement-2025-05.pdf", "mimeType": "application/pdf", "size": 131777, "leadId": "4cc8af99-b313-4c1f-b98b-009f38a4721a", "workspaceId": "6048d78a-584a-4f1e-9e39-e011ca4cc48c", "signedUrl": "https://omniai-server-v2-dev.s3.us-east-2.amazonaws.com/...", "createdAt": "2025-10-30T20:07:24.663Z", "updatedAt": "2025-10-30T20:08:20.033Z" } ``` # Upload Documents Source: https://docs.getomni.ai/api-reference/documents/upload-document POST https://api-v2.getomni.ai/api/v1/documents Upload one or more documents for a lead. Uses the same pipeline as the in-app Document Vault: S3 storage, action logs, Mastra memory, and document workflow. This endpoint uploads documents for a lead. Behavior matches the in-app Document Vault: files are stored in S3, a SYSTEM\_NOTE and DOCUMENT\_UPLOAD action log are created, documents are saved to Mastra memory, and the document workflow runs (validation, extraction, etc.). You can optionally associate uploads with a checklist item via `leadChecklistItemId`. Maximum 10 files per request; each file up to 100MB. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Request Body (multipart/form-data) The Monumint lead ID. The lead must exist and belong to your workspace. One or more files to upload. Use the form field name `files`. Up to 10 files; each file up to 100MB. Optional. Monumint lead checklist item ID to associate the uploaded documents with. The item must belong to the lead. Optional. Per-file metadata, index-aligned with `files`. When provided, its length must match the number of files. With `multipart/form-data`, send as a JSON-stringified form field. Each entry supports: * `externalId` (string, optional): your own identifier to persist on the document. Returned on the response. * `name` (string, optional): overrides the uploaded filename. ## Response Whether the request succeeded Array of uploaded document objects: id, externalId, filename, size, url (presigned), mimeType, uploadedAt, associatedChecklistItemId. The ID of the DOCUMENT\_UPLOAD action log entry for this upload ```javascript Node.js theme={null} const formData = new FormData(); formData.append("leadId", "a9d0a790-201b-47e9-84ed-cc7eed1270c5"); formData.append("files", file1); // File or Blob formData.append("files", file2); // Optional: formData.append('leadChecklistItemId', ''); // Optional: per-file metadata (must match the number of files) formData.append( "metadata", JSON.stringify([ { externalId: "doc-1", name: "document.pdf" }, { externalId: "doc-2", name: "statement.xlsx" }, ]), ); const response = await fetch("https://api-v2.getomni.ai/api/v1/documents", { method: "POST", headers: { "x-api-key": "", }, body: formData, }); const data = await response.json(); console.log(data); ``` ```python Python theme={null} import requests import json url = "https://api-v2.getomni.ai/api/v1/documents" headers = {"x-api-key": ""} data = { "leadId": "a9d0a790-201b-47e9-84ed-cc7eed1270c5", # Optional: per-file metadata (must match the number of files) "metadata": json.dumps([ {"externalId": "doc-1", "name": "document.pdf"}, {"externalId": "doc-2", "name": "statement.xlsx"}, ]), } # Optional: data["leadChecklistItemId"] = "" files = [ ("files", ("document.pdf", open("document.pdf", "rb"), "application/pdf")), ("files", ("statement.xlsx", open("statement.xlsx", "rb"), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")), ] response = requests.post(url, headers=headers, data=data, files=files) print(response.json()) ``` ```bash cURL theme={null} curl --request POST \ --url 'https://api-v2.getomni.ai/api/v1/documents' \ --header 'x-api-key: ' \ --form 'leadId=a9d0a790-201b-47e9-84ed-cc7eed1270c5' \ --form 'files=@/path/to/document.pdf' \ --form 'files=@/path/to/statement.xlsx' \ --form 'metadata=[{"externalId":"doc-1","name":"document.pdf"},{"externalId":"doc-2","name":"statement.xlsx"}]' # Optional: --form 'leadChecklistItemId=' ``` ```json 201 theme={null} { "success": true, "documents": [ { "id": "b1e2c3d4-5f6a-7890-bcde-f12345678901", "externalId": "doc-1", "filename": "document.pdf", "size": 102400, "url": "https://...", "mimeType": "application/pdf", "uploadedAt": "2026-01-30T02:00:00.000Z", "associatedChecklistItemId": null }, { "id": "c2d3e4f5-6a7b-8901-cdef-23456789012a", "externalId": "doc-2", "filename": "statement.xlsx", "size": 204800, "url": "https://...", "mimeType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "uploadedAt": "2026-01-30T02:00:00.000Z", "associatedChecklistItemId": null } ], "actionLogId": "7de43760-d12d-4bcc-931a-f728ef1a3e3b" } ``` # API Introduction Source: https://docs.getomni.ai/api-reference/introduction Introduction to the Monumint API # API Introduction Welcome to the Monumint API. This API allows you to programmatically manage leads, documents, and webhooks in your AI Lending workspace. ## Base URL ``` https://api-v2.getomni.ai ``` The `api-v2.getomni.ai` legacy API url will be depreciated in favor of `api.monumint.com`. ## Authentication All API requests require authentication using an API key. Include your API key in the request header: ``` x-api-key: YOUR_API_KEY ``` ## Getting Your API Key You can get your API Key in [workspace settings](https://platform.getomni.ai/settings/api). ## API Version The current API version is `v1`. All endpoints are prefixed with `/api/v1/`. ## Request Format All requests should use: * **Content-Type**: `application/json` * **Headers**: Include `x-api-key` for authentication ## Response Format All responses are returned in JSON format. Successful responses include a `200` status code. ## Rate Limits API rate limits apply to prevent abuse. Contact support if you need higher limits. ## Error Handling Errors are returned with appropriate HTTP status codes: * `400`: Bad Request - Invalid parameters * `401`: Unauthorized - Invalid or missing API key * `404`: Not Found - Resource doesn't exist * `500`: Internal Server Error - Server error ## Endpoints Overview Manage leads and retrieve lead data Retrieve and manage documents Configure webhooks for real-time events # Create Activity Source: https://docs.getomni.ai/api-reference/leads/create-activity POST https://api-v2.getomni.ai/api/v1/activity Push a structured activity event to the action log for a lead This endpoint creates an activity entry on a lead's timeline. Activities are visible in the timeline and available to the AI agent for context. Use it to log events such as sales calls, document errors, status changes, or any custom event from your system. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Request Body The Monumint lead ID. The lead must exist and belong to your workspace. Event type label (e.g. "sales\_call", "document\_error", "status\_change"). Shown as a badge on the timeline card. Short summary shown as the main title on the timeline card. Longer description or notes. Rendered as body text on the card; long text is clipped with a "Read more" expand. Freeform key-value object for additional context (e.g. durationMinutes, outcome, nextStep). Rendered in a "Details" section on the card. ## Response Whether the request succeeded The ID of the created action log entry ```javascript Node.js theme={null} const options = { method: "POST", headers: { "x-api-key": "", "Content-Type": "application/json", }, body: JSON.stringify({ leadId: "a9d0a790-201b-47e9-84ed-cc7eed1270c5", eventType: "sales_call", title: "Intro call – SBA loan interest", description: "Successful intro call. Borrower runs Pacific Coast Container Haulers (drayage at Port of Long Beach). In business 4 years, ~8 employees, ~$1.2M revenue. Interested in SBA 7(a) to refinance equipment and add a truck (~$180–220K). Next step: collect last two years of tax returns.", metadata: { durationMinutes: 25, outcome: "positive", loanType: "SBA", nextStep: "Request last 2 years of tax returns", followUpDays: 2, }, }), }; fetch("https://api-v2.getomni.ai/api/v1/activity", options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/activity" headers = { "x-api-key": "", "Content-Type": "application/json", } payload = { "leadId": "a9d0a790-201b-47e9-84ed-cc7eed1270c5", "eventType": "sales_call", "title": "Intro call – SBA loan interest", "description": "Successful intro call. Borrower runs Pacific Coast Container Haulers (drayage at Port of Long Beach). In business 4 years, ~8 employees, ~$1.2M revenue. Interested in SBA 7(a) to refinance equipment and add a truck (~$180–220K). Next step: collect last two years of tax returns.", "metadata": { "durationMinutes": 25, "outcome": "positive", "loanType": "SBA", "nextStep": "Request last 2 years of tax returns", "followUpDays": 2, }, } response = requests.request("POST", url, headers=headers, json=payload) print(response.json()) ``` ```bash cURL theme={null} curl --request POST \ --url https://api-v2.getomni.ai/api/v1/activity \ --header 'x-api-key: ' \ --header 'Content-Type: application/json' \ --data '{ "leadId": "a9d0a790-201b-47e9-84ed-cc7eed1270c5", "eventType": "sales_call", "title": "Intro call – SBA loan interest", "description": "Successful intro call. Borrower runs Pacific Coast Container Haulers (drayage at Port of Long Beach). In business 4 years, ~8 employees, ~$1.2M revenue. Interested in SBA 7(a) to refinance equipment and add a truck (~$180–220K). Next step: collect last two years of tax returns.", "metadata": { "durationMinutes": 25, "outcome": "positive", "loanType": "SBA", "nextStep": "Request last 2 years of tax returns", "followUpDays": 2 } }' ``` ```json 201 theme={null} { "success": true, "actionLogId": "7de43760-d12d-4bcc-931a-f728ef1a3e3b" } ``` # Create Lead Source: https://docs.getomni.ai/api-reference/leads/create-lead POST https://api-v2.getomni.ai/api/v1/leads Create a new lead with optional checklist item updates This endpoint creates a new lead. You can pass lead-level fields (firstName, lastName, email, etc.) and optional checklist item updates by code. A single API\_ACTIVITY action log is written for "Lead created" with all updates grouped in the timeline. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Request Body Lead first name Lead last name Lead email address Lead phone number (formatted or raw; stored in E.164 when possible) Lead middle name Business name Business or lead website URL External identifier for the lead (e.g. from a CRM system) URL of the lead's external portal, used instead of the default portal URL IANA timezone identifier (e.g. "America/New\_York"). If not provided and a phone number is given, the timezone is inferred from the area code. Who handles the lead: "agent" (AI) or "manual" (human) When true, marks the lead as opted out and sets optOutAt to the current time. When true, sets emailVerifiedAt to the current time (marks the lead's email as verified). Array of checklist updates. Each item: `{ "code": string, "value"?: any, "status"?: "TODO" | "COMPLETED" | "INVALID" | "SKIPPED" | "NEEDS_REVIEW" }`. Use the checklist item code from your workspace. Set lead tags. Matching is case-insensitive, so "VIP" and "vip" are treated as the same tag. Tags are created automatically the first time a name is used. Pass \[] to remove all tags. ## Response Whether the request succeeded The created lead record. Includes: id, activitySummary, assigneeType, businessName, createdAt, deletedAt, didOptOut, optOutAt, email, emailVerifiedAt, externalLeadId, externalPortalLink, firstName, lastName, phoneNumber, phoneVerifiedAt, source, tags, updatedAt, website. Full checklist for the lead, grouped by checklist group. Each group includes id, name, conditions, and an items array. Each item includes id, checklistItemId, value, status, itemOverride, and a nested checklistItem with code, label, fieldType, conditions, validationRules, etc. File-type items include a documents array with presigned URLs. Recent action logs for the lead (up to 100), enriched with tool info, messages, and document presigned URLs. Leads that share the same phone number or email (empty for test leads). The most recent completed outbound message or follow-up action log, including associated tool calls. The next pending follow-up message action log, if any. The next message awaiting approval, if any. ```javascript Node.js theme={null} const options = { method: "POST", headers: { "x-api-key": "", "Content-Type": "application/json", }, body: JSON.stringify({ firstName: "John", lastName: "Doe", email: "john@example.com", phoneNumber: "6782319992", businessName: "Pacific Coast Container Haulers", assigneeType: "manual", checklistItems: [ { code: "business_name", value: "Pacific Coast Container Haulers", status: "COMPLETED", }, { code: "tax_id", value: "12-3456789", status: "COMPLETED" }, ], }), }; fetch("https://api-v2.getomni.ai/api/v1/leads", options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/leads" headers = { "x-api-key": "", "Content-Type": "application/json", } payload = { "firstName": "John", "lastName": "Doe", "email": "john@example.com", "phoneNumber": "6782319992", "businessName": "Pacific Coast Container Haulers", "assigneeType": "manual", "emailVerified": True, "checklistItems": [ {"code": "business_name", "value": "Pacific Coast Container Haulers", "status": "COMPLETED"}, {"code": "tax_id", "value": "12-3456789", "status": "COMPLETED"}, ], } response = requests.request("POST", url, headers=headers, json=payload) print(response.json()) ``` ```bash cURL theme={null} curl --request POST \ --url https://api-v2.getomni.ai/api/v1/leads \ --header 'x-api-key: ' \ --header 'Content-Type: application/json' \ --data '{ "firstName": "John", "lastName": "Doe", "email": "john@example.com", "phoneNumber": "6782319992", "businessName": "Pacific Coast Container Haulers", "assigneeType": "manual", "emailVerified": true, "checklistItems": [ {"code": "business_name", "value": "Pacific Coast Container Haulers", "status": "COMPLETED"}, {"code": "tax_id", "value": "12-3456789", "status": "COMPLETED"} ] }' ``` ```json 201 theme={null} { "success": true, "lead": { "id": "a9d0a790-201b-47e9-84ed-cc7eed1270c5", "activitySummary": null, "assigneeType": "HUMAN_AGENT", "businessName": "Pacific Coast Container Haulers", "createdAt": "2026-01-30T02:00:00.000Z", "deletedAt": null, "didOptOut": false, "optOutAt": null, "email": "john@example.com", "emailVerifiedAt": "2026-01-30T02:00:00.000Z", "externalLeadId": null, "externalPortalLink": null, "firstName": "John", "lastName": "Doe", "phoneNumber": "+16782319992", "phoneVerifiedAt": null, "source": "api", "tags": ["VIP", "priority-1"], "updatedAt": "2026-01-30T02:00:00.000Z", "website": null }, "checklistItems": [ { "id": "group-id", "name": "Business Information", "conditions": null, "items": [ { "id": "lci-1", "checklistItemId": "ci-1", "value": "Pacific Coast Container Haulers", "status": "COMPLETED", "itemOverride": null, "checklistItem": { "id": "ci-1", "code": "business_name", "label": "Business Name", "fieldType": "TEXT", "isRequired": true, "conditions": null } }, { "id": "lci-2", "checklistItemId": "ci-2", "value": "12-3456789", "status": "COMPLETED", "itemOverride": null, "checklistItem": { "id": "ci-2", "code": "tax_id", "label": "Tax ID", "fieldType": "TEXT", "isRequired": true, "conditions": null } } ] } ], "actionLogs": [], "matchingLeads": [], "lastAction": null, "nextFollowUp": null, "nextDraft": null } ``` # Create Lead Checklist Item Source: https://docs.getomni.ai/api-reference/leads/create-lead-checklist-item POST https://api-v2.getomni.ai/api/v1/leads/{leadId}/checklist-items Add a one-off checklist requirement to a single lead This endpoint creates a custom checklist requirement on a specific lead. Use it when a lead needs a piece of information or document that isn't part of your agent's standard checklist (e.g. an extra utility bill, a one-off attestation, or a loan-specific tax document). The item appears on the lead's checklist immediately and can be completed via the portal, the dashboard, or the API. Items created this way are scoped to the lead — they do not affect your template checklists or any other lead. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Path Parameters Unique identifier of the lead to add the checklist item to. ## Request Body Label shown in the dashboard and portal. Example: `"Utility bill"`. Type of data being collected. Determines the expected `config` shape. * **Files**: `"BANK_STATEMENT"`, `"FILE"`, `"ID"`, `"TAX_RETURN"` * **Fields**: `"ADDRESS"`, `"DATE"`, `"EIN"`, `"EMAIL"`, `"MULTI_SELECT"`, `"NUMBER"`, `"PHONE"`, `"SELECT"`, `"SSN"`, `"TEXT"` Type-specific configuration. * `BANK_STATEMENT`: `{ months: number, gracePeriodDays?: number, isPersonal?: boolean }` * `ID`: `{ type: "DRIVERS_LICENSE" | "PASSPORT" }` * `MULTI_SELECT`: `{ options: string[] }` * `NUMBER`: `{ min?: number, max?: number }` * `SELECT`: `{ options: string[] }` * `TAX_RETURN`: `{ years: number, isPersonal?: boolean }` * `TEXT`: `{ pattern?: string }` Whether the lead must complete this item. Defaults to `true`. Instructions for the AI agent. Use this to guide how the agent should interpret, request, or evaluate this field. Instructions shown to the lead in the portal. Applies only to file-type fields. Natural-language rules the AI validator checks against uploaded documents. ```json theme={null} [ "Document is dated within the last 90 days", "Account holder name matches the lead's name on the application" ] ``` Stable identifier for the checklist item. If omitted, one is generated from the label. Provide your own if you need to reference this item from an external system. Must be unique. ## Response Whether the request succeeded The created lead checklist item. Unique identifier for this checklist item Lead this requirement belongs to Stable identifier (auto-generated if not supplied) Label Field type as provided in the request Whether the lead must complete this item Initial status — always `"TODO"` for new items Type-specific configuration as provided in the request Agent-facing instructions Client-facing instructions ISO 8601 timestamp ```javascript Node.js theme={null} const leadId = "4ef30123-90c2-4dc0-bd28-b43eee8664ea"; const options = { method: "POST", headers: { "x-api-key": "", "Content-Type": "application/json", }, body: JSON.stringify({ label: "Utility bill", fieldType: "FILE", isRequired: true, agentInstructions: "From the last 90 days", clientInstructions: "Please upload a PDF or photo of a recent utility bill", }), }; fetch( `https://api-v2.getomni.ai/api/v1/leads/${leadId}/checklist-items`, options, ) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests lead_id = "4ef30123-90c2-4dc0-bd28-b43eee8664ea" url = f"https://api-v2.getomni.ai/api/v1/leads/{lead_id}/checklist-items" headers = { "x-api-key": "", "Content-Type": "application/json", } payload = { "label": "Utility bill", "fieldType": "FILE", "isRequired": True, "agentInstructions": "From the last 90 days", "clientInstructions": "Please upload a PDF or photo of a recent utility bill", } response = requests.request("POST", url, headers=headers, json=payload) print(response.json()) ``` ```bash cURL theme={null} curl --request POST \ --url https://api-v2.getomni.ai/api/v1/leads/4ef30123-90c2-4dc0-bd28-b43eee8664ea/checklist-items \ --header 'x-api-key: ' \ --header 'Content-Type: application/json' \ --data '{ "label": "Utility bill", "fieldType": "FILE", "isRequired": true, "agentInstructions": "From the last 90 days", "clientInstructions": "Please upload a PDF or photo of a recent utility bill" }' ``` ```json 201 theme={null} { "success": true, "checklistItem": { "id": "9f1c4d80-4a2b-4f0e-8c2c-93a0a9c9b2a1", "leadId": "4ef30123-90c2-4dc0-bd28-b43eee8664ea", "code": "UTILITY_BILL", "label": "Utility bill", "fieldType": "FILE", "isRequired": true, "status": "TODO", "agentInstructions": "From the last 90 days", "clientInstructions": "Please upload a PDF or photo of a recent utility bill", "createdAt": "2026-05-04T18:21:30.123Z" } } ``` # Batch Create Lead Checklist Items Source: https://docs.getomni.ai/api-reference/leads/create-lead-checklist-items-batch POST https://api-v2.getomni.ai/api/v1/leads/{leadId}/checklist-items/batch Add multiple one-off checklist requirements to a single lead This endpoint adds several custom checklist requirements to a specific lead. It behaves like [Create Lead Checklist Item](/api-reference/leads/create-lead-checklist-item), but accepts an array of items. Each item is processed independently and the response reports a per-item result, so a problem with one item does not stop the others from being created. Items created this way are scoped to the lead — they do not affect your template checklists or any other lead. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Path Parameters Unique identifier of the lead to add the checklist items to. ## Request Body Array of checklist items to create. Must contain between 1 and 25 items. Each item has the same shape as the body of [Create Lead Checklist Item](/api-reference/leads/create-lead-checklist-item): Label shown in the dashboard and portal. Example: `"Utility bill"`. Type of data being collected. Determines the expected `config` shape. * **Files**: `"BANK_STATEMENT"`, `"FILE"`, `"ID"`, `"TAX_RETURN"` * **Fields**: `"ADDRESS"`, `"DATE"`, `"EIN"`, `"EMAIL"`, `"MULTI_SELECT"`, `"NUMBER"`, `"PHONE"`, `"SELECT"`, `"SSN"`, `"TEXT"` Type-specific configuration. * `BANK_STATEMENT`: `{ months: number, gracePeriodDays?: number, isPersonal?: boolean }` * `ID`: `{ type: "DRIVERS_LICENSE" | "PASSPORT" }` * `MULTI_SELECT`: `{ options: string[] }` * `NUMBER`: `{ min?: number, max?: number }` * `SELECT`: `{ options: string[] }` * `TAX_RETURN`: `{ years: number, isPersonal?: boolean }` * `TEXT`: `{ pattern?: string }` Whether the lead must complete this item. Defaults to `true`. Instructions for the AI agent. Use this to guide how the agent should interpret, request, or evaluate this field. Instructions shown to the lead in the portal. Applies only to file-type fields. Natural-language rules the AI validator checks against uploaded documents. Stable identifier for the checklist item. If omitted, one is generated from the label. Provide your own if you need to reference this item from an external system. Must be unique per lead. ## Response The endpoint returns `201` with a `results` array in the same order as the submitted `items`. Each entry reports whether that item was created — inspect each entry's `success` field to see which ones succeeded. Per-item outcomes, in the same order as the request `items`. Whether this item was created. The created lead checklist item. Present only when `success` is `true`. Same shape as the response of [Create Lead Checklist Item](/api-reference/leads/create-lead-checklist-item). Reason the item could not be created. Present only when `success` is `false` (for example, a duplicate `code`). ```javascript Node.js theme={null} const leadId = "4ef30123-90c2-4dc0-bd28-b43eee8664ea"; const options = { method: "POST", headers: { "x-api-key": "", "Content-Type": "application/json", }, body: JSON.stringify({ items: [ { label: "Utility bill", fieldType: "FILE", clientInstructions: "Please upload a recent utility bill", }, { label: "Annual revenue", fieldType: "NUMBER", config: { min: 0 }, }, ], }), }; fetch( `https://api-v2.getomni.ai/api/v1/leads/${leadId}/checklist-items/batch`, options, ) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests lead_id = "4ef30123-90c2-4dc0-bd28-b43eee8664ea" url = f"https://api-v2.getomni.ai/api/v1/leads/{lead_id}/checklist-items/batch" headers = { "x-api-key": "", "Content-Type": "application/json", } payload = { "items": [ { "label": "Utility bill", "fieldType": "FILE", "clientInstructions": "Please upload a recent utility bill", }, { "label": "Annual revenue", "fieldType": "NUMBER", "config": {"min": 0}, }, ] } response = requests.request("POST", url, headers=headers, json=payload) print(response.json()) ``` ```bash cURL theme={null} curl --request POST \ --url https://api-v2.getomni.ai/api/v1/leads/4ef30123-90c2-4dc0-bd28-b43eee8664ea/checklist-items/batch \ --header 'x-api-key: ' \ --header 'Content-Type: application/json' \ --data '{ "items": [ { "label": "Utility bill", "fieldType": "FILE", "clientInstructions": "Please upload a recent utility bill" }, { "label": "Annual revenue", "fieldType": "NUMBER", "config": { "min": 0 } } ] }' ``` ```json 201 theme={null} { "results": [ { "success": true, "checklistItem": { "id": "9f1c4d80-4a2b-4f0e-8c2c-93a0a9c9b2a1", "leadId": "4ef30123-90c2-4dc0-bd28-b43eee8664ea", "code": "UTILITY_BILL", "label": "Utility bill", "fieldType": "FILE", "isRequired": true, "status": "TODO", "agentInstructions": null, "clientInstructions": "Please upload a recent utility bill", "createdAt": "2026-05-04T18:21:30.123Z" } }, { "success": false, "error": "Checklist item with code \"ANNUAL_REVENUE\" already exists for this lead" } ] } ``` # Get Lead Source: https://docs.getomni.ai/api-reference/leads/get-lead GET https://api-v2.getomni.ai/api/v1/leads/:leadId Retrieve a single lead with all associated data This endpoint returns a single lead by ID along with its full checklist, documents, action logs, matching leads, and scheduling state. The response is the same standardized shape used by the create and update endpoints. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Path Parameters The Monumint lead ID to retrieve. ## Response The lead record. Includes: id, activitySummary, assigneeType, businessName, createdAt, deletedAt, didOptOut, email, emailVerifiedAt, externalLeadId, externalPortalLink, firstName, isTest, lastName, phoneNumber, phoneVerifiedAt, source, submittedAt, tags, updatedAt, website, workspaceId. Computed lead status. One of: IN\_PROGRESS, COMPLETED, REVIEW, NOT\_INTERESTED, OPTED\_OUT. Full checklist for the lead, grouped by checklist group. Each group includes id, name, conditions, and an items array. Each item includes id, checklistItemId, value, status, itemOverride, and a nested checklistItem with code, label, fieldType, conditions, validationRules, etc. File-type items include a documents array with presigned URLs. All documents uploaded for this lead, with presigned download URLs. Recent action logs for the lead (up to 100), enriched with tool info, messages, and document presigned URLs. Leads that share the same phone number or email (empty for test leads). The most recent completed outbound message or follow-up action log, including associated tool calls. The next pending follow-up message action log, if any. The next message awaiting approval, if any. ```javascript Node.js theme={null} const options = { method: "GET", headers: { "x-api-key": "", }, }; fetch( "https://api-v2.getomni.ai/api/v1/leads/a9d0a790-201b-47e9-84ed-cc7eed1270c5", options ) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/leads/a9d0a790-201b-47e9-84ed-cc7eed1270c5" headers = { "x-api-key": "", } response = requests.get(url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/leads/a9d0a790-201b-47e9-84ed-cc7eed1270c5 \ --header 'x-api-key: ' ``` ```json 200 theme={null} { "lead": { "id": "a9d0a790-201b-47e9-84ed-cc7eed1270c5", "activitySummary": null, "assigneeType": "HUMAN_AGENT", "businessName": "Pacific Coast Container Haulers", "createdAt": "2026-01-30T02:00:00.000Z", "deletedAt": null, "didOptOut": false, "email": "john@example.com", "emailVerifiedAt": "2026-01-30T02:00:00.000Z", "externalLeadId": null, "externalPortalLink": null, "firstName": "John", "isTest": false, "lastName": "Doe", "phoneNumber": "+16782319992", "phoneVerifiedAt": null, "source": "api", "submittedAt": null, "tags": ["VIP", "priority-1"], "updatedAt": "2026-01-30T02:00:00.000Z", "website": null, "workspaceId": "ws-123" }, "status": "IN_PROGRESS", "checklistItems": [ { "id": "group-id", "name": "Business Information", "conditions": null, "items": [ { "id": "lci-1", "checklistItemId": "ci-1", "value": "Pacific Coast Container Haulers", "status": "COMPLETED", "itemOverride": null, "checklistItem": { "id": "ci-1", "code": "business_name", "label": "Business Name", "fieldType": "TEXT", "isRequired": true, "conditions": null } } ] } ], "documents": [], "actionLogs": [ { "id": "log-1", "type": "API_ACTIVITY", "status": "COMPLETED", "summary": "Lead created", "createdAt": "2026-01-30T02:00:00.000Z" } ], "matchingLeads": [], "lastAction": null, "nextFollowUp": null, "nextDraft": null } ``` # Get Lead Action Logs Source: https://docs.getomni.ai/api-reference/leads/get-lead-action-logs GET https://api-v2.getomni.ai/api/v1/leads/{leadId}/action-logs Fetch all action logs (activity history) for a specific lead This endpoint fetches all action logs (activity history) for a specific lead. Action logs include messages, tool executions, follow-ups, and other agent actions. ## Path Parameters The unique identifier of the lead ## Response Array of action log objects Unique identifier for the action log Type of action (e.g., `MESSAGE`, `FOLLOW_UP_MESSAGE`, `TOOL_CALL`, `MANUAL_UPDATE`) Status of the action (e.g., `COMPLETED`, `PENDING`, `CANCELLED`, `AWAITING_APPROVAL`, `FAILED`) Brief summary of the action Input data for the action (structure varies by action type) Output data from the action (structure varies by action type) Error message if the action failed ID of the parent action that triggered this action ISO 8601 timestamp when the action is scheduled (for future actions) ISO 8601 timestamp when the action was created ISO 8601 timestamp when the action was completed Tool information if this is a tool call action Unique identifier for the tool Name of the tool Description of what the tool does Array of messages associated with this action Unique identifier for the message Channel of the message (e.g., "EMAIL", "SMS") Direction of the message (e.g., "INBOUND", "OUTBOUND") Subject of the message (for email messages) Body content of the message Array of documents attached to the message Unique identifier for the document Filename of the document MIME type of the document Size of the document in bytes ```javascript Node.js theme={null} const leadId = '4ef30123-90c2-4dc0-bd28-b43eee8664ea'; const options = { method: 'GET', headers: { 'x-api-key': '', }, }; fetch(`https://api-v2.getomni.ai/api/v1/leads/${leadId}/action-logs`, options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests lead_id = '4ef30123-90c2-4dc0-bd28-b43eee8664ea' url = f"https://api-v2.getomni.ai/api/v1/leads/{lead_id}/action-logs" headers = { "x-api-key": "" } response = requests.request("GET", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/leads/4ef30123-90c2-4dc0-bd28-b43eee8664ea/action-logs \ --header 'x-api-key: ' ``` ```json 200 theme={null} [ { "id": "25a6e7dc-2cdf-46b8-b0d5-9f1655ae154a", "type": "TOOL_CALL", "status": "COMPLETED", "summary": "Successfully executed deep research", "input": { "toolType": "deep_research", "companyInfo": "Vital Climbing Gym LLC", "instructions": "Conduct comprehensive company research" }, "output": { "success": true, "summary": "Completed deep research for VITAL Climbing Gym...", "researchResult": { "address": "29990 Technology Dr, Unit 22, Murrieta, CA 92563", "companyName": "VITAL Climbing Gym (Vital Climbing, LLC)", "website": "https://www.vitalclimbinggym.com" } }, "error": null, "parentActionId": null, "scheduledAt": "2025-09-07T23:51:06.209Z", "createdAt": "2025-09-07T23:51:06.210Z", "completedAt": "2025-09-07T23:54:29.052Z", "tool": { "id": "0a58309e-9657-4f35-a08d-4de9af03a5b7", "name": "update-checklist-item", "description": "Update a lead checklist item with a new value" }, "messages": [] }, { "id": "e8ff3def-d6fc-40f7-902c-264d18fda1c5", "type": "FOLLOW_UP_MESSAGE", "status": "COMPLETED", "summary": "Requested business details to start loan application process", "input": { "channel": "EMAIL", "attemptNumber": 1, "adminTriggered": true, "missingItemsCount": 11 }, "output": { "isReply": false, "messageMetadata": { "to": ["annapojawis@yahoo.com"], "from": "Mark Ding ", "subject": "Finishing up your application" } }, "error": null, "parentActionId": null, "scheduledAt": "2025-09-07T23:56:21.587Z", "createdAt": "2025-09-07T23:56:21.588Z", "completedAt": "2025-09-07T23:56:45.426Z", "tool": null, "messages": [ { "id": "a261a0ca-c77d-4226-a3f9-5cf63d0e8634", "channel": "EMAIL", "direction": "OUTBOUND", "subject": "Finishing up your application", "body": "Hi Anna,

This is Mark with Monumint Capital...", "documents": [] } ] } ] ```
# Get Lead Checklist Source: https://docs.getomni.ai/api-reference/leads/get-lead-checklist GET https://api-v2.getomni.ai/api/v1/leads/{leadId}/checklist Fetch the checklist for a specific lead This endpoint fetches the checklist for a specific lead, including all checklist groups, items, and their current status. ## Path Parameters The unique identifier of the lead ## Response Array of checklist groups Checklist group ID Checklist group name Array of checklist items in this group Unique identifier for the checklist item entry ID of the checklist item definition Current value for this checklist item (can be string, number, or null) Array of alternate values for this checklist item (can be null) Validation error message if validation failed Status of the checklist item (e.g., "COMPLETED", "TODO") Details about the checklist item definition Unique identifier for the checklist item definition Code identifier for the checklist item Display label for the checklist item Field type (e.g., "TEXT", "NUMBER", "EMAIL", "PHONE", "ADDRESS", "EIN", "BANK\_STATEMENT", "TOOL") Whether this item is required Help text displayed to users for this checklist item Client-specific instructions for this checklist item Tool configuration for tool-type checklist items Type of tool (e.g., "deep\_research") Instructions for the tool Additional configuration for the tool Array of documents associated with this checklist item (only present for document-type items) Unique identifier for the document Original filename of the document MIME type of the document (e.g., "application/pdf", "image/jpeg") File size in bytes Pre-signed URL for accessing the document Document metadata including processing status Status of the extraction (e.g., "completed") Whether the document passed overall validation Detailed validation result for the document Additional notes about the validation Whether the document passed overall validation Array of individual validation rule results Whether this validation rule passed Name of the validation rule Reason explaining why the rule passed or failed ```javascript Node.js theme={null} const leadId = '4ef30123-90c2-4dc0-bd28-b43eee8664ea'; const options = { method: 'GET', headers: { 'x-api-key': '', }, }; fetch(`https://api-v2.getomni.ai/api/v1/leads/${leadId}/checklist`, options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests lead_id = '4ef30123-90c2-4dc0-bd28-b43eee8664ea' url = f"https://api-v2.getomni.ai/api/v1/leads/{lead_id}/checklist" headers = { "x-api-key": "" } response = requests.request("GET", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/leads/4ef30123-90c2-4dc0-bd28-b43eee8664ea/checklist \ --header 'x-api-key: ' ``` ```json 200 theme={null} [ { "id": "2490cb41-4e65-47bc-a662-54e05ac8133d", "name": "Business Information", "items": [ { "id": "a61b8be3-5f89-413b-b0eb-454a569bb06b", "checklistItemId": "5f71c15b-0022-4b72-b1bf-daf7a76486f5", "value": "Lexi", "status": "COMPLETED", "checklistItem": { "id": "5f71c15b-0022-4b72-b1bf-daf7a76486f5", "code": "BUSINESS_NAME", "label": "Business Name", "fieldType": "TEXT", "isRequired": true } }, { "id": "d78cbb58-5a6e-4fc3-8622-b783b3211b3f", "checklistItemId": "2f791c62-6a04-4d29-b7fa-477b777800f6", "value": null, "status": "TODO", "checklistItem": { "id": "2f791c62-6a04-4d29-b7fa-477b777800f6", "code": "EIN", "label": "EIN", "fieldType": "EIN", "isRequired": true } } ] } ] ``` # Get Lead Documents Source: https://docs.getomni.ai/api-reference/leads/get-lead-documents GET https://api-v2.getomni.ai/api/v1/leads/{leadId}/documents Fetch all documents associated with a specific lead This endpoint fetches all documents associated with a specific lead. ## Path Parameters The unique identifier of the lead ## Response Array of document objects Unique identifier for the document Original filename of the document MIME type of the document (e.g., "application/pdf", "image/jpeg") File size in bytes Pre-signed URL for accessing the document (expires after 1 hour) Document metadata including processing status Status of the extraction (e.g., "completed") Array of checklist items this document is matched to ID of the matched checklist item Label of the matched checklist item Array of checklist item document associations with validation results Unique identifier for the checklist item document association ID of the checklist item this document is associated with ID of the document Whether the document passed overall validation Detailed validation result for the document Additional notes about the validation Whether the document passed overall validation Array of individual validation rule results Whether this validation rule passed Name of the validation rule Reason explaining why the rule passed or failed Signed URLs expire after 1 hour. Use [Get Document API ](/api-reference/documents/get-document) to get a fresh signed URL. ```javascript Node.js theme={null} const leadId = '4ef30123-90c2-4dc0-bd28-b43eee8664ea'; const options = { method: 'GET', headers: { 'x-api-key': '', }, }; fetch(`https://api-v2.getomni.ai/api/v1/leads/${leadId}/documents`, options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests lead_id = '4ef30123-90c2-4dc0-bd28-b43eee8664ea' url = f"https://api-v2.getomni.ai/api/v1/leads/{lead_id}/documents" headers = { "x-api-key": "" } response = requests.request("GET", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/leads/4ef30123-90c2-4dc0-bd28-b43eee8664ea/documents \ --header 'x-api-key: ' ``` ```json 200 theme={null} [ { "id": "4fa0d0de-6958-4d1f-9468-ebb8629eae8c", "filename": "vital-checking-june-25.pdf", "mimeType": "application/pdf", "size": 153143, "metadata": { "extractionStatus": "completed", "Matched checklist items": [ { "leadChecklistItemId": "fb6c17f3-4d7e-4979-a262-9c287ae0e6dd", "label": "Bank Statements" } ] }, "signedUrl": "https://omniai-server-v2-prod.s3.us-east-2.amazonaws.com/...", "leadChecklistItemDocument": [ { "id": "0e66ab12-af87-4dbc-956a-2063b4ecb552", "leadChecklistItemId": "fb6c17f3-4d7e-4979-a262-9c287ae0e6dd", "documentId": "4fa0d0de-6958-4d1f-9468-ebb8629eae8c", "overallValid": true, "validationResult": { "otherNotes": "", "overallValid": true, "validationResults": [ { "isValid": true, "ruleName": "Files must be business bank statements", "isValidReason": "The document is a business bank statement..." } ] } } ] } ] ``` # Get Lead Portal URL Source: https://docs.getomni.ai/api-reference/leads/get-lead-portal-url GET https://api-v2.getomni.ai/api/v1/leads/{leadId}/portal-url Fetch a lead's portal URL This endpoint fetches a lead's portal URL by its `leadId`. ## Path Parameters The unique identifier of the lead ## Response Lead's portal URL ISO 8601 timestamp when the link expires, or `null` when the link does not expire (custom external link or portal URL template) ```javascript Node.js theme={null} const options = { method: "GET", headers: { "x-api-key": "", }, }; fetch( "https://api-v2.getomni.ai/api/v1/leads/b3f1c2d4-5e6a-7b8c-9d0e-1f2a3b4c5d6e/portal-url", options, ) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests lead_id = "b3f1c2d4-5e6a-7b8c-9d0e-1f2a3b4c5d6e" url = f"https://api-v2.getomni.ai/api/v1/leads/{lead_id}/portal-url" headers = { "x-api-key": "", } response = requests.get(url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url 'https://api-v2.getomni.ai/api/v1/leads/b3f1c2d4-5e6a-7b8c-9d0e-1f2a3b4c5d6e/portal-url' \ --header 'x-api-key: ' ``` ```json 200 theme={null} { "expiresAt": "2026-07-02T02:00:00.000Z", "portalUrl": "https://portal.acme.com/?token=eyJhbGciOi...", "success": true } ``` # List Leads Source: https://docs.getomni.ai/api-reference/leads/list-leads GET https://api-v2.getomni.ai/api/v1/leads Fetch all leads in your workspace This endpoint fetches all leads in your workspace. ## Query Parameters Filter leads by tag. Pass a comma-separated list (`?tags=vip,priority-1`) or repeat the parameter (`?tags=vip&tags=priority-1`). Matching is case-insensitive. Hide leads that carry any of the supplied tags. Pass a comma-separated list (`?excludeTags=archived,do-not-contact`) or repeat the parameter (`?excludeTags=archived&excludeTags=do-not-contact`). Matching is case-insensitive. ## Response Array of lead objects Unique identifier for the lead Lead name Lead email address Lead phone number Business name Lead status (e.g., "IN\_PROGRESS") Summary of recent activity Number of completed checklist items Total number of checklist items Tag names attached to the lead, sorted alphabetically. Empty array when none. Information about the next scheduled follow-up ```javascript Node.js theme={null} const options = { method: 'GET', headers: { 'x-api-key': '', }, }; fetch('https://api-v2.getomni.ai/api/v1/leads', options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/leads" headers = { "x-api-key": "" } response = requests.request("GET", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/leads \ --header 'x-api-key: ' ``` ```json 200 theme={null} [ { "id": "4ef30123-90c2-4dc0-bd28-b43eee8664ea", "name": "+14155099231", "email": null, "phoneNumber": "4155099231", "businessName": "Lexi", "status": "IN_PROGRESS", "activitySummary": "• Multiple documents submitted; some failed validation, checklist updated", "completedChecklistItems": 2, "totalChecklistItems": 6, "tags": ["VIP", "priority-1"], "nextFollowUp": { "id": "372de835-c8cd-4791-abf6-485c679d31e5", "type": "FOLLOW_UP_MESSAGE", "status": "PENDING", "scheduledAt": "2025-10-15T16:00:00.000Z", "summary": "Request missing documents" } } ] ``` # Trigger Follow-up Source: https://docs.getomni.ai/api-reference/leads/trigger-follow-up POST https://api-v2.getomni.ai/api/v1/leads/{leadId}/follow-up Evaluate and send a follow-up message to a lead This endpoint triggers the AI agent to evaluate a lead and send a follow-up message. Depending on agent configuration, the follow-up may be sent immediately, scheduled for later, or saved as a draft. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Path Parameters The unique identifier of the lead ## Response Whether the follow-up was successfully sent ID of the lead the follow-up was triggered for Follow-up message that was sent Channel used to send the follow-up (e.g. `SMS`, `EMAIL`, `WHATSAPP`) Status of the follow-up message (e.g. `DRAFT`, `SCHEDULED`, `SENT`) ```javascript Node.js theme={null} const options = { method: "POST", headers: { "x-api-key": "", }, }; fetch( "https://api-v2.getomni.ai/api/v1/leads/a9d0a790-201b-47e9-84ed-cc7eed1270c5/follow-up", options, ) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/leads/a9d0a790-201b-47e9-84ed-cc7eed1270c5/follow-up" headers = { "x-api-key": "", } response = requests.request("POST", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request POST \ --url https://api-v2.getomni.ai/api/v1/leads/a9d0a790-201b-47e9-84ed-cc7eed1270c5/follow-up \ --header 'x-api-key: ' ``` ```json 200 theme={null} { "success": true, "leadId": "a9d0a790-201b-47e9-84ed-cc7eed1270c5", "bodySegments": ["Hi Jordan, just following up on your application."], "channel": "SMS", "status": "SENT" } ``` # Update Lead Source: https://docs.getomni.ai/api-reference/leads/update-lead PUT https://api-v2.getomni.ai/api/v1/leads Update an existing lead with optional checklist item updates This endpoint updates an existing lead. Only the fields you include in the request body will be changed; omitted fields are left untouched. You can update lead-level fields (firstName, lastName, email, etc.) and/or checklist items by code. A single API\_ACTIVITY action log is written for "Lead updated" with all updates grouped in the timeline. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Request Body Monumint lead ID of the lead to update. Lead first name Lead last name Lead email address Lead phone number (formatted or raw; stored in E.164 when possible) Lead middle name Business name Business or lead website URL External identifier for the lead (e.g. from a CRM system) URL of the lead's external portal, used instead of the default portal URL IANA timezone identifier (e.g. "America/New\_York"). If not provided and a phone number is given, the timezone is inferred from the area code. Who handles the lead: "agent" (AI) or "manual" (human) When true, marks the lead as opted out and sets optOutAt to the current time. When false, clears the opt-out status. Set the lead's status. Allowed values are `"COMPLETED"`, `"IN_PROGRESS"`, `"NOT_INTERESTED"`, and `"OPTED_OUT"` (note that `"REVIEW"` is not settable via the API). If `didOptOut` is also provided, it must agree with `status`. When set to `"COMPLETED"`, any still-incomplete required checklist items are auto-skipped. When set to `"NOT_INTERESTED"`, the lead is marked as not interested and future follow-ups stop. When set to `"OPTED_OUT"`, the lead is opted out and in-flight outbound messages are cancelled. When set to `"IN_PROGRESS"`, auto-skips from a prior `"COMPLETED"` transition are cleared and the lead is re-opened. When true, sets emailVerifiedAt to the current time (marks the lead's email as verified). Array of checklist updates. Each item: `{ "code": string, "value"?: any, "status"?: "TODO" | "COMPLETED" | "INVALID" | "SKIPPED" | "NEEDS_REVIEW" }`. Use the checklist item code from your workspace. Only the items you include will be updated. Set lead tags. Matching is case-insensitive, so "VIP" and "vip" are treated as the same tag. Pass \[] to remove all tags. ## Response Whether the request succeeded The lead's current status after the update. One of `"COMPLETED"`, `"IN_PROGRESS"`, `"NOT_INTERESTED"`, `"OPTED_OUT"`, or `"REVIEW"`. `"REVIEW"` is not settable via this endpoint but may appear in the response when the lead has an unresolved escalation. The updated lead record. Includes: id, activitySummary, assigneeType, businessName, createdAt, deletedAt, didOptOut, optOutAt, notInterestedAt, email, emailVerifiedAt, externalLeadId, externalPortalLink, firstName, lastName, phoneNumber, phoneVerifiedAt, source, tags, updatedAt, website. Full checklist for the lead, grouped by checklist group. Each group includes id, name, conditions, and an items array. Each item includes id, checklistItemId, value, status, itemOverride, and a nested checklistItem with code, label, fieldType, conditions, validationRules, etc. File-type items include a documents array with presigned URLs. Recent action logs for the lead (up to 100), enriched with tool info, messages, and document presigned URLs. Leads that share the same phone number or email (empty for test leads). The most recent completed outbound message or follow-up action log, including associated tool calls. The next pending follow-up message action log, if any. The next message awaiting approval, if any. ```javascript Node.js theme={null} // Update lead fields and checklist items const options = { method: "PUT", headers: { "x-api-key": "", "Content-Type": "application/json", }, body: JSON.stringify({ leadId: "a9d0a790-201b-47e9-84ed-cc7eed1270c5", lastName: "Francisco", businessName: "Monumint Technology LLC", checklistItems: [ { code: "legal_name", value: "Monumint Technology LLC", status: "COMPLETED", }, ], }), }; fetch("https://api-v2.getomni.ai/api/v1/leads", options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/leads" headers = { "x-api-key": "", "Content-Type": "application/json", } payload = { "leadId": "a9d0a790-201b-47e9-84ed-cc7eed1270c5", "lastName": "Francisco", "businessName": "Monumint Technology LLC", "checklistItems": [ {"code": "legal_name", "value": "Monumint Technology LLC", "status": "COMPLETED"}, ], } response = requests.request("PUT", url, headers=headers, json=payload) print(response.json()) ``` ```bash cURL theme={null} curl --request PUT \ --url https://api-v2.getomni.ai/api/v1/leads \ --header 'x-api-key: ' \ --header 'Content-Type: application/json' \ --data '{ "leadId": "a9d0a790-201b-47e9-84ed-cc7eed1270c5", "lastName": "Francisco", "businessName": "Monumint Technology LLC", "checklistItems": [ {"code": "legal_name", "value": "Monumint Technology LLC", "status": "COMPLETED"} ] }' ``` ```json 200 theme={null} { "success": true, "lead": { "id": "a9d0a790-201b-47e9-84ed-cc7eed1270c5", "activitySummary": null, "assigneeType": "HUMAN_AGENT", "businessName": "Monumint Technology LLC", "createdAt": "2026-01-30T02:00:00.000Z", "deletedAt": null, "didOptOut": false, "optOutAt": null, "email": "john@example.com", "emailVerifiedAt": "2026-01-30T02:00:00.000Z", "externalLeadId": null, "externalPortalLink": null, "firstName": "John", "lastName": "Francisco", "phoneNumber": "+16782319992", "phoneVerifiedAt": null, "source": "api", "tags": ["VIP", "priority-1"], "updatedAt": "2026-01-30T02:05:00.000Z", "website": null }, "checklistItems": [ { "id": "group-id", "name": "Business Information", "conditions": null, "items": [ { "id": "lci-1", "checklistItemId": "ci-1", "value": "Pacific Coast Container Haulers", "status": "COMPLETED", "itemOverride": null, "checklistItem": { "id": "ci-1", "code": "business_name", "label": "Business Name", "fieldType": "TEXT", "isRequired": true, "conditions": null } }, { "id": "lci-3", "checklistItemId": "ci-3", "value": "Monumint Technology LLC", "status": "COMPLETED", "itemOverride": null, "checklistItem": { "id": "ci-3", "code": "legal_name", "label": "Legal Name", "fieldType": "TEXT", "isRequired": true, "conditions": null } } ] } ], "actionLogs": [ { "id": "log-1", "type": "API_ACTIVITY", "status": "COMPLETED", "summary": "Lead updated", "input": { "eventType": "lead_updated", "source": "api", "leadUpdates": { "lastName": "Francisco", "businessName": "Monumint Technology LLC" }, "checklistUpdates": [ { "code": "legal_name", "value": "Monumint Technology LLC", "status": "COMPLETED", "success": true } ] }, "createdAt": "2026-01-30T02:05:00.000Z" } ], "matchingLeads": [], "lastAction": null, "nextFollowUp": null, "nextDraft": null } ``` # Create Spread Source: https://docs.getomni.ai/api-reference/spreads/create-spread POST https://api-v2.getomni.ai/api/v1/spreads Start a financial spreading run for a lead Start a financial spreading run for a lead. Monumint classifies and extracts the lead's PDF financial documents (tax returns, income statements, balance sheets), consolidates them onto a standardized multi-period template, and produces a report and an Excel workbook. The run happens in the background and takes a few minutes; this endpoint returns immediately with the new run's id. Track it with [Get Spread](/api-reference/spreads/get-spread) or the [spread webhooks](/api-reference/webhooks/webhook-events). ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Request Body The lead whose documents to spread. Spread only these documents, a subset of the lead's documents. Every id must resolve to a document on the lead. Omit to spread all of the lead's PDF documents. ## Response Whether the request succeeded. The created run, in the same shape as [Get Spread](/api-reference/spreads/get-spread). `status` is always `IN_PROGRESS`, and `artifacts` is empty until the run completes. ## Errors No `leadId`; a `documentIds` value doesn't resolve to a document on the lead; or the resolved documents contain no PDFs. The `leadId` isn't a lead in your workspace. The lead already has a spread `IN_PROGRESS`. Wait for it to reach `COMPLETE` or `FAILED` before starting another. ```javascript Node.js theme={null} const options = { method: "POST", headers: { "x-api-key": "", "Content-Type": "application/json", }, body: JSON.stringify({ leadId: "b1f0a790-201b-47e9-84ed-cc7eed1270c5", }), }; fetch("https://api-v2.getomni.ai/api/v1/spreads", options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/spreads" headers = { "x-api-key": "", "Content-Type": "application/json", } payload = {"leadId": "b1f0a790-201b-47e9-84ed-cc7eed1270c5"} response = requests.request("POST", url, headers=headers, json=payload) print(response.json()) ``` ```bash cURL theme={null} curl --request POST \ --url https://api-v2.getomni.ai/api/v1/spreads \ --header 'x-api-key: ' \ --header 'Content-Type: application/json' \ --data '{ "leadId": "b1f0a790-201b-47e9-84ed-cc7eed1270c5" }' ``` ```json 201 theme={null} { "success": true, "spread": { "id": "9f1e2d3c-4b5a-6789-0abc-def012345678", "status": "IN_PROGRESS", "error": null, "leadId": "b1f0a790-201b-47e9-84ed-cc7eed1270c5", "documents": [ { "id": "doc-a", "filename": "2023-tax-return.pdf", "status": "PROCESSING", "error": null }, { "id": "doc-b", "filename": "2023-financials.pdf", "status": "PROCESSING", "error": null } ], "artifacts": [], "source": "API", "user": null, "createdAt": "2026-07-23T18:04:00.000Z", "updatedAt": "2026-07-23T18:04:00.000Z" } } ``` # Get Spread Source: https://docs.getomni.ai/api-reference/spreads/get-spread GET https://api-v2.getomni.ai/api/v1/spreads/:spreadId Poll a financial spreading run's status and artifacts Retrieve a spreading run: its lifecycle status, per-document progress, and — once complete — its report and spreadsheet artifacts. Poll this endpoint while a run is in flight, or subscribe to the [spread webhooks](/api-reference/webhooks/webhook-events) instead. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Path Parameters The run id returned by [Create Spread](/api-reference/spreads/create-spread). ## Response Whether the request succeeded. The run. The run id. The lifecycle status: `IN_PROGRESS`, `COMPLETE`, or `FAILED`. The failure message when `status` is `FAILED`, otherwise `null`. The lead the run belongs to. The input documents, each with `id`, `filename`, `status` (`PROCESSING`, `EXTRACTED`, `SKIPPED`, or `FAILED`), and `error`. `id` is the document's id in your workspace — the same id the [document endpoints](/api-reference/documents/get-document) use — or `null` if the document has since been deleted. The report and spreadsheet, each with `id`, `type` (`REPORT` or `SPREADSHEET`), and `title`. Populated whenever `status` is `COMPLETE`. A regenerating run keeps its previous artifacts until the new ones replace them on completion. How the run was started: `API` for a run started through this endpoint, or `USER` for one a member of your team started in the app. The person who started the run. `null` for runs started through this API, which authenticates a workspace rather than a person. Unique identifier for the user. Name of the user. Email address of the user. When the run was created. When the run last changed. ## Errors No spread with this id exists in your workspace. ```javascript Node.js theme={null} const options = { method: "GET", headers: { "x-api-key": "" }, }; fetch( "https://api-v2.getomni.ai/api/v1/spreads/9f1e2d3c-4b5a-6789-0abc-def012345678", options, ) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/spreads/9f1e2d3c-4b5a-6789-0abc-def012345678" headers = {"x-api-key": ""} response = requests.request("GET", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/spreads/9f1e2d3c-4b5a-6789-0abc-def012345678 \ --header 'x-api-key: ' ``` ```json 200 theme={null} { "success": true, "spread": { "id": "9f1e2d3c-4b5a-6789-0abc-def012345678", "status": "COMPLETE", "error": null, "leadId": "b1f0a790-201b-47e9-84ed-cc7eed1270c5", "documents": [ { "id": "doc-a", "filename": "2023-tax-return.pdf", "status": "EXTRACTED", "error": null }, { "id": "doc-b", "filename": "2023-financials.pdf", "status": "EXTRACTED", "error": null } ], "artifacts": [ { "id": "art-report", "type": "REPORT", "title": "Financial Spread - Pacific Coast Container Haulers" }, { "id": "art-sheet", "type": "SPREADSHEET", "title": "Financial Spread - Pacific Coast Container Haulers (Excel)" } ], "source": "API", "user": null, "createdAt": "2026-07-23T18:04:00.000Z", "updatedAt": "2026-07-23T18:08:40.000Z" } } ``` # Get Spread Results Source: https://docs.getomni.ai/api-reference/spreads/get-spread-results GET https://api-v2.getomni.ai/api/v1/spreads/:spreadId/results Read a completed spread's figures as JSON Read the numbers a spreading run produced: the consolidated income statement, balance sheet, and cash flow as line items by period. These are the same figures the report PDF presents. Every spread uses the same template — the possible rows and their keys are fixed. What varies is which rows have figures and what those figures are. ## Reading the figures Each statement is a list of `periods`. Every period has a `values` object with the rows that have figures for that period, keyed by row key. A row absent from `values` has no figure for that period. ```json theme={null} { "id": "48e65bef-2cea-5b97-b94d-86047b4c1b2e", "label": "FY2023", "start": "2023-01-01", "end": "2023-12-31", "basis": "accrual", "annualized": false, "derivedFrom": null, "values": { "netRevenues": { "label": "Net Revenues", "value": 4200000, "kind": "line", "computed": false, "memo": false }, "netIncome": { "label": "Net Income", "value": 565000, "kind": "total", "computed": true, "memo": false } } } ``` To match a period across statements, use `periods[].id` — the same period carries the same id in every block. `label` is display copy derived from the source documents and may differ between statements. The income statement adds an annualized column beside each interim period (shorter than 12 months), with figures scaled to a full year. `derivedFrom` points back to the period it was derived from. The cash flow starts one period later than the others, since it measures change between balance sheet dates. A period with no dates gets an id that doesn't match anything else in the response. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Path Parameters The run id returned by [Create Spread](/api-reference/spreads/create-spread). ## Response Whether the request succeeded. The spread's figures. The version of this response's structure. See [Compatibility](#compatibility). The run these figures came from, so a stored copy stays traceable. The lead the run belongs to. When the run last produced these figures, ISO 8601. Regenerating a spread moves this forward. The business name as read from the source documents. The currency the source reported in. `incomeStatement`, `balanceSheet`, and `cashFlow`, each an object with a `periods` array, or `null` if the run produced none. We compute the cash flow with the indirect method from the income statement and balance sheet rather than extracting it, so a single-period spread returns empty `periods` for it. ### Periods The block's columns in display order. Stable identifier for this period. The same period carries the same id in every statement and on subsequent fetches of the same run. Column heading, e.g. `FY2023`. Derived from the source documents and may differ between statements or across runs. Period start date, `YYYY-MM-DD`. On the cash flow this is the prior period's end date, since a cash flow column measures the movement between two balance sheet dates. Period end date, `YYYY-MM-DD`. The accounting basis, `accrual` or `cash`. Income statement only; `null` everywhere else. True when the figures have been scaled to a full year from a period shorter than 12 months. The unscaled period appears alongside it; `derivedFrom` points back to it. The `id` of the period this column was scaled from. `null` on all other columns. The rows with figures for this period, keyed by row key. A missing key means no figure. ### Values Each entry in a period's `values` object has the following fields. The figure for this row in this period. Display copy for the row. May be reworded over time. `line` for a line item, `subtotal` for a computed subtotal or derived metric, `total` for a statement total. True when we derived the row rather than reading it off a source document. Subtotals, totals, the variance rows, EBITDA/EBIDA, and every cash flow row are computed; template line items are not. True for display-only rows not included in computed totals — the balance sheet's equity rollforward rows, for instance. Including them in a total will double-count them. ## Row keys Row keys are stable camelCase identifiers from our spreading template. `label` is display copy and may be reworded; it's also not unique across statements ("Net Income" appears on all three). Line items: `netRevenues`, `cogsGoodsMaterials`, `cogsLabor`, `cogsOther`, `officerCompGuaranteedPayments`, `salariesWages`, `badDebts`, `rent`, `interest`, `depreciation`, `amortization`, `otherDiscretionary`, `otherSgna`, `otherIncome`, `otherExpense`. Subtotals and totals: `totalCostOfRevenues`, `grossProfit`, `totalOperatingExpenses`, `netIncome`. Also: `reportedNetIncome` (the net income the source printed, before our consolidation), `incomeStatementVariance` (our computed net income minus that reported figure), `ebitda`, and `ebida` (EBITDA without the income-tax add-back). Assets: `cash`, `accountsReceivable`, `inventory`, `otherCurrentAssets`, `totalCurrentAssets`, `grossFixedAssets`, `accumulatedDepreciation`, `netFixedAssets`, `loansToAffiliates`, `goodwill`, `otherIntangibles`, `otherNonCurrentAssets`, `totalNonCurrentAssets`, `totalAssets`. Liabilities: `accountsPayable`, `currentDebt`, `otherCurrentLiabilities`, `totalCurrentLiabilities`, `longTermDebt`, `dueToAffiliates`, `otherLiabilities`, `totalNonCurrentLiabilities`, `totalLiabilities`. Equity: `commonStock`, `additionalPaidInCapital`, `treasuryStock`, `endingRetainedEarnings`, `otherEquity`, `totalEquity`, `totalLiabilitiesAndEquity`. Equity rollforward, all `memo` rows excluded from `totalEquity`: `beginningRetainedEarnings`, `netIncomeEquity`, `distributionsDividends`. Also: `balanceSheetVariance`, total assets minus total liabilities and equity. A non-zero value means the spread is out of balance for that period. Operating: `netIncome`, `depreciation`, `amortization`, `changeInAccountsReceivable`, `changeInInventory`, `changeInOtherCurrentAssets`, `changeInAccountsPayable`, `changeInOtherCurrentLiabilities`, `netCashFromOperating`. Investing: `capitalExpenditures`, `changeInIntangibles`, `changeInLoansToAffiliates`, `changeInOtherNonCurrentAssets`, `netCashFromInvesting`. Financing: `changeInCurrentDebt`, `changeInLongTermDebt`, `changeInDueToAffiliates`, `changeInOtherLiabilities`, `distributionsDividends`, `netEquityContributions`, `netCashFromFinancing`. Totals: `netChangeInCash`, `beginningCash`, `endingCash`, and `cashFlowVariance` — net change in cash minus the actual movement in the cash balance. ## Compatibility `schemaVersion` is `2` today. We may make these changes without changing it, so parse defensively: * adding a statement or a row * adding a field to the response, a period, or a values entry * rewording any `label` * changing which rows a given spread carries We will change `schemaVersion` if we rename or remove a row `key`, or restructure `periods` or `values`. If you want to fail loudly rather than silently mis-read a future response, assert on it. ## Errors Every error body carries `success: false` and a human-readable `error`. Branch on the status code rather than on the message text, which we may reword. No spread with this id exists in your workspace. The run has not completed. Results are served only for a `COMPLETE` run: one still in flight has partly written statements, and regenerating a run rewrites them in place, so an earlier read could return a mix of the old spread and the new one. To know when to fetch, poll [Get Spread](/api-reference/spreads/get-spread) for the run's `status` or subscribe to the `spread.completed` [webhook](/api-reference/webhooks/webhook-events). A `FAILED` run will never produce results, so stop polling when you see one. ```json 409 theme={null} { "success": false, "error": "This spread is IN_PROGRESS. Results are available once it is COMPLETE." } ``` ```javascript Node.js theme={null} const options = { method: "GET", headers: { "x-api-key": "" }, }; fetch( "https://api-v2.getomni.ai/api/v1/spreads/9f1e2d3c-4b5a-6789-0abc-def012345678/results", options, ) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/spreads/9f1e2d3c-4b5a-6789-0abc-def012345678/results" headers = {"x-api-key": ""} response = requests.request("GET", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/spreads/9f1e2d3c-4b5a-6789-0abc-def012345678/results \ --header 'x-api-key: ' ``` ```json 200 theme={null} { "success": true, "results": { "schemaVersion": 2, "spreadId": "9f1e2d3c-4b5a-6789-0abc-def012345678", "leadId": "3a7c1b90-2e4d-4f61-8b0a-9c5d7e2f1a34", "generatedAt": "2026-03-04T17:42:11.000Z", "entityName": "Pacific Coast Container Haulers", "currency": "USD", "statements": { "incomeStatement": { "periods": [ { "id": "e05f7d35-d3fc-57c7-bb32-6dea39143f25", "label": "FY2022", "start": "2022-01-01", "end": "2022-12-31", "basis": "accrual", "annualized": false, "derivedFrom": null, "values": { "netRevenues": { "label": "Net Revenues", "value": 3730000, "kind": "line", "computed": false, "memo": false }, "cogsGoodsMaterials": { "label": "Cost of Revenues - Goods", "value": 2340000, "kind": "line", "computed": false, "memo": false }, "totalCostOfRevenues": { "label": "Total Cost of Revenues", "value": 2340000, "kind": "subtotal","computed": true, "memo": false }, "grossProfit": { "label": "Gross Profit", "value": 1390000, "kind": "subtotal","computed": true, "memo": false }, "salariesWages": { "label": "Salaries & Wages", "value": 710000, "kind": "line", "computed": false, "memo": false }, "rent": { "label": "Rent", "value": 180000, "kind": "line", "computed": false, "memo": false }, "depreciation": { "label": "Depreciation", "value": 88000, "kind": "line", "computed": false, "memo": false }, "totalOperatingExpenses": { "label": "Total Operating Expenses", "value": 978000, "kind": "subtotal","computed": true, "memo": false }, "netIncome": { "label": "Net Income", "value": 412000, "kind": "total", "computed": true, "memo": false }, "reportedNetIncome": { "label": "Net Income Per Books", "value": 412000, "kind": "subtotal","computed": false, "memo": false }, "incomeStatementVariance":{ "label": "Variance vs Reported", "value": 0, "kind": "subtotal","computed": true, "memo": false }, "ebitda": { "label": "EBITDA", "value": 541000, "kind": "subtotal","computed": true, "memo": false } } }, { "id": "48e65bef-2cea-5b97-b94d-86047b4c1b2e", "label": "FY2023", "start": "2023-01-01", "end": "2023-12-31", "basis": "accrual", "annualized": false, "derivedFrom": null, "values": { "netRevenues": { "label": "Net Revenues", "value": 4200000, "kind": "line", "computed": false, "memo": false }, "cogsGoodsMaterials": { "label": "Cost of Revenues - Goods", "value": 2600000, "kind": "line", "computed": false, "memo": false }, "totalCostOfRevenues": { "label": "Total Cost of Revenues", "value": 2600000, "kind": "subtotal","computed": true, "memo": false }, "grossProfit": { "label": "Gross Profit", "value": 1600000, "kind": "subtotal","computed": true, "memo": false }, "salariesWages": { "label": "Salaries & Wages", "value": 760000, "kind": "line", "computed": false, "memo": false }, "rent": { "label": "Rent", "value": 180000, "kind": "line", "computed": false, "memo": false }, "depreciation": { "label": "Depreciation", "value": 95000, "kind": "line", "computed": false, "memo": false }, "totalOperatingExpenses": { "label": "Total Operating Expenses", "value": 1035000, "kind": "subtotal","computed": true, "memo": false }, "netIncome": { "label": "Net Income", "value": 565000, "kind": "total", "computed": true, "memo": false }, "reportedNetIncome": { "label": "Net Income Per Books", "value": 565000, "kind": "subtotal","computed": false, "memo": false }, "incomeStatementVariance":{ "label": "Variance vs Reported", "value": 0, "kind": "subtotal","computed": true, "memo": false }, "ebitda": { "label": "EBITDA", "value": 701000, "kind": "subtotal","computed": true, "memo": false } } } ] }, "balanceSheet": { "periods": [ { "id": "e05f7d35-d3fc-57c7-bb32-6dea39143f25", "label": "FY2022", "start": "2022-01-01", "end": "2022-12-31", "basis": null, "annualized": false, "derivedFrom": null, "values": { "cash": { "label": "Cash", "value": 190000, "kind": "line", "computed": false, "memo": false }, "accountsReceivable": { "label": "Accounts Receivable", "value": 480000, "kind": "line", "computed": false, "memo": false }, "inventory": { "label": "Inventory", "value": 295000, "kind": "line", "computed": false, "memo": false }, "totalCurrentAssets": { "label": "Total Current Assets", "value": 965000, "kind": "subtotal","computed": true, "memo": false }, "totalAssets": { "label": "Total Assets", "value": 1885000, "kind": "total", "computed": true, "memo": false }, "accountsPayable": { "label": "Accounts Payable", "value": 195000, "kind": "line", "computed": false, "memo": false }, "totalLiabilities": { "label": "Total Liabilities", "value": 928000, "kind": "subtotal","computed": true, "memo": false }, "totalEquity": { "label": "Total Equity", "value": 957000, "kind": "subtotal","computed": true, "memo": false }, "totalLiabilitiesAndEquity": { "label": "Total Liabilities and Equity", "value": 1885000, "kind": "total", "computed": true, "memo": false } } }, { "id": "48e65bef-2cea-5b97-b94d-86047b4c1b2e", "label": "FY2023", "start": "2023-01-01", "end": "2023-12-31", "basis": null, "annualized": false, "derivedFrom": null, "values": { "cash": { "label": "Cash", "value": 250000, "kind": "line", "computed": false, "memo": false }, "accountsReceivable": { "label": "Accounts Receivable", "value": 540000, "kind": "line", "computed": false, "memo": false }, "inventory": { "label": "Inventory", "value": 320000, "kind": "line", "computed": false, "memo": false }, "totalCurrentAssets": { "label": "Total Current Assets", "value": 1110000, "kind": "subtotal","computed": true, "memo": false }, "totalAssets": { "label": "Total Assets", "value": 2090000, "kind": "total", "computed": true, "memo": false }, "accountsPayable": { "label": "Accounts Payable", "value": 210000, "kind": "line", "computed": false, "memo": false }, "totalLiabilities": { "label": "Total Liabilities", "value": 930000, "kind": "subtotal","computed": true, "memo": false }, "distributionsDividends": { "label": "Distributions / Dividends", "value": -180000, "kind": "line", "computed": false, "memo": true }, "totalEquity": { "label": "Total Equity", "value": 1160000, "kind": "subtotal","computed": true, "memo": false }, "totalLiabilitiesAndEquity": { "label": "Total Liabilities and Equity", "value": 2090000, "kind": "total", "computed": true, "memo": false } } } ] }, "cashFlow": { "periods": [ { "id": "48e65bef-2cea-5b97-b94d-86047b4c1b2e", "label": "FY2023", "start": "2022-12-31", "end": "2023-12-31", "basis": null, "annualized": false, "derivedFrom": null, "values": { "netIncome": { "label": "Net Income", "value": 565000, "kind": "line", "computed": true, "memo": false }, "depreciation": { "label": "Depreciation", "value": 95000, "kind": "line", "computed": true, "memo": false }, "changeInAccountsReceivable":{ "label": "Change in Accounts Receivable", "value": -60000, "kind": "line", "computed": true, "memo": false }, "netCashFromOperating": { "label": "Net Cash from Operating", "value": 560000, "kind": "subtotal","computed": true, "memo": false }, "netChangeInCash": { "label": "Net Change in Cash", "value": 60000, "kind": "total", "computed": true, "memo": false }, "cashFlowVariance": { "label": "Variance vs Change in Cash", "value": 0, "kind": "subtotal","computed": true, "memo": false } } } ] } } } } ``` # List Lead Spreads Source: https://docs.getomni.ai/api-reference/spreads/list-lead-spreads GET https://api-v2.getomni.ai/api/v1/leads/:leadId/spreads List a lead's financial spreading runs List every financial spreading run for a lead, newest first. Each entry is a complete spread in the same shape as [Get Spread](/api-reference/spreads/get-spread), including its `artifacts`, whose ids you pass to the [artifact endpoints](/api-reference/artifacts/download-artifact) to download. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Path Parameters The lead whose runs to list. ## Response Whether the request succeeded. The lead's runs, newest first. Each entry has the same fields as the `spread` object returned by [Get Spread](/api-reference/spreads/get-spread). ## Errors The `leadId` isn't a lead in your workspace. ```javascript Node.js theme={null} const options = { method: "GET", headers: { "x-api-key": "" }, }; fetch( "https://api-v2.getomni.ai/api/v1/leads/b1f0a790-201b-47e9-84ed-cc7eed1270c5/spreads", options, ) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/leads/b1f0a790-201b-47e9-84ed-cc7eed1270c5/spreads" headers = {"x-api-key": ""} response = requests.request("GET", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/leads/b1f0a790-201b-47e9-84ed-cc7eed1270c5/spreads \ --header 'x-api-key: ' ``` ```json 200 theme={null} { "success": true, "spreads": [ { "id": "9f1e2d3c-4b5a-6789-0abc-def012345678", "status": "COMPLETE", "error": null, "leadId": "b1f0a790-201b-47e9-84ed-cc7eed1270c5", "documents": [ { "id": "doc-a", "filename": "2023-tax-return.pdf", "status": "EXTRACTED", "error": null }, { "id": "doc-b", "filename": "2023-financials.pdf", "status": "EXTRACTED", "error": null } ], "artifacts": [ { "id": "art-report", "type": "REPORT", "title": "Financial Spread - Pacific Coast Container Haulers" }, { "id": "art-sheet", "type": "SPREADSHEET", "title": "Financial Spread - Pacific Coast Container Haulers (Excel)" } ], "createdAt": "2026-07-23T18:04:00.000Z", "updatedAt": "2026-07-23T18:08:40.000Z" } ] } ``` # Regenerate Spread Source: https://docs.getomni.ai/api-reference/spreads/regenerate-spread POST https://api-v2.getomni.ai/api/v1/spreads/:spreadId/regenerate Re-consolidate a spread from its already-extracted data Re-consolidate a finished run from its already-extracted data. The documents are not re-processed; only the consolidation and report run again. The run goes back to `IN_PROGRESS` and re-emits `spread.started`; on completion it emits `spread.completed` with new artifact ids. ## Authentication Requires the `x-api-key` header with a valid workspace API key. ## Path Parameters The run to regenerate. ## Request Body None. Send an empty body. ## Response Returns `202 Accepted` with the run's refreshed state, in the same shape as [Get Spread](/api-reference/spreads/get-spread). `artifacts` still lists the previous report and spreadsheet; when the regenerated run completes, new artifacts replace them. ## Errors The `spreadId` isn't a run in your workspace. The run is still in flight. Wait for it to reach `COMPLETE` or `FAILED` before regenerating. ```javascript Node.js theme={null} const options = { method: "POST", headers: { "x-api-key": "", "Content-Type": "application/json", }, }; fetch( "https://api-v2.getomni.ai/api/v1/spreads/9f1e2d3c-4b5a-6789-0abc-def012345678/regenerate", options, ) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/spreads/9f1e2d3c-4b5a-6789-0abc-def012345678/regenerate" headers = { "x-api-key": "", "Content-Type": "application/json", } response = requests.request("POST", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request POST \ --url https://api-v2.getomni.ai/api/v1/spreads/9f1e2d3c-4b5a-6789-0abc-def012345678/regenerate \ --header 'x-api-key: ' ``` ```json 202 theme={null} { "success": true, "spread": { "id": "9f1e2d3c-4b5a-6789-0abc-def012345678", "status": "IN_PROGRESS", "error": null, "leadId": "b1f0a790-201b-47e9-84ed-cc7eed1270c5", "documents": [ { "id": "doc-a", "filename": "2023-tax-return.pdf", "status": "EXTRACTED", "error": null }, { "id": "doc-b", "filename": "2023-financials.pdf", "status": "EXTRACTED", "error": null } ], "artifacts": [ { "id": "art-report", "type": "REPORT", "title": "Financial Spread - Pacific Coast Container Haulers" }, { "id": "art-sheet", "type": "SPREADSHEET", "title": "Financial Spread - Pacific Coast Container Haulers (Excel)" } ], "source": "API", "user": null, "createdAt": "2026-07-23T18:04:00.000Z", "updatedAt": "2026-07-23T18:12:05.000Z" } } ``` # Create Webhook Source: https://docs.getomni.ai/api-reference/webhooks/create-webhook POST https://api-v2.getomni.ai/api/v1/webhooks Create a new webhook for receiving real-time event notifications This endpoint creates a new webhook for receiving real-time event notifications. ## Body Parameters The webhook listener URL where events will be sent A list of event types to listen for. Supported events: `action_log.completed`, `action_log.failed`, `document.received`, `document.extracted`, `lead.created`, `lead.updated`, `lead.completed`, `spread.started`, `spread.completed`, `spread.failed` Custom headers to send with every delivery, as name-value pairs. Deliveries are not signed, so set a secret header here and check it on your endpoint to authenticate them — for example `{ "x-shared-secret": "" }`. Whether the webhook should be enabled immediately (default: `true`) Optional description for the webhook ## Response Unique identifier for the webhook The webhook URL where events will be sent Array of event types this webhook is subscribed to Whether the webhook is currently enabled Optional description for the webhook ISO 8601 timestamp when the webhook was created Your webhook endpoint should return a 200 status code within 5 seconds. If it doesn't, Monumint will retry the delivery. ```javascript Node.js theme={null} const options = { method: 'POST', headers: { 'x-api-key': '', 'Content-Type': 'application/json', }, body: JSON.stringify({ url: 'https://your-app.com/webhook/monumint', events: ['action_log.completed', 'action_log.failed'], isEnabled: true, description: 'Production webhook for CRM sync', }), }; fetch('https://api-v2.getomni.ai/api/v1/webhooks', options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/webhooks" headers = { "x-api-key": "", "Content-Type": "application/json" } payload = { "url": "https://your-app.com/webhook/monumint", "events": ["action_log.completed", "action_log.failed"], "isEnabled": True, "description": "Production webhook for CRM sync" } response = requests.request("POST", url, json=payload, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request POST \ --url https://api-v2.getomni.ai/api/v1/webhooks \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{ "url": "https://your-app.com/webhook/monumint", "events": ["action_log.completed", "action_log.failed"], "isEnabled": true, "description": "Production webhook for CRM sync" }' ``` ```json 200 theme={null} { "id": "06e4b90b-86dd-41c7-9a1e-73a592963682", "workspaceId": "6048d78a-584a-4f1e-9e39-e011ca4cc48c", "url": "https://c4b3632a95ef.ngrok-free.app/webhook/test-receiver", "secret": null, "events": ["action_log.completed", "action_log.failed"], "isEnabled": false, "description": null, "createdAt": "2025-10-30T19:49:46.581Z", "updatedAt": "2025-10-30T20:07:31.930Z" } ``` ```json 400 theme={null} { "error": "Invalid request" } ``` # action_log.completed Source: https://docs.getomni.ai/api-reference/webhooks/events/action-log-completed Triggered when an action log completes successfully. ## Event Type `action_log.completed` ## Description This event is fired whenever an action log (such as a message, tool call, or follow-up) completes successfully. Use this event to track agent activity and respond to completed actions in real-time. ## Payload Structure The event type: `action_log.completed` The completed action log object Unique identifier for the action log Type of action: `SYSTEM_NOTE`, `MESSAGE`, `FOLLOW_UP_MESSAGE`, `TOOL_CALL`, `DOCUMENT_UPLOAD`, `MANUAL_UPDATE`, `PORTAL_UPDATE`, `PORTAL_SUBMISSION` Status of the action: `COMPLETED` ID of the lead associated with this action Brief summary of the action Input data for the action (varies by action type) Output data from the action (if applicable) Array of messages if the action type is `MESSAGE` or `FOLLOW_UP_MESSAGE` Unique identifier for the message Channel of the message Direction of the message Subject of the message Body of the message Array of documents associated with the message Unique identifier for the document Filename of the document MIME type of the document Size of the document ISO 8601 timestamp when the action was completed Workspace user who triggered this action. Returns `null` for actions not initiated by a workspace user. Type of actor Unique identifier for the user Name of the user Email address of the user ID of the workspace this event belongs to ```json theme={null} { "event": "action_log.completed", "actionLog": { "id": "59ac65a5-33fe-43a6-924b-134c582a285e", "type": "MESSAGE", "status": "COMPLETED", "leadId": "4cc8af99-b313-4c1f-b98b-009f38a4721a", "summary": "Incoming email: docs", "input": { "channel": "EMAIL", "direction": "INBOUND", "metadata": { "agentMailData": { "to": ["Mark Ding "], "from": "Mark Ding ", "subject": "docs" } } }, "output": null, "messages": [ { "id": "2421bef7-95bc-4546-92a3-c7e5600fbb6a", "body": "

\n", "channel": "EMAIL", "subject": "docs", "direction": "INBOUND", "documents": [ { "id": "2421bef7-95bc-4546-92a3-c7e5600fbb6a", "filename": "docs.pdf", "mimeType": "application/pdf", "size": 1000 } ] } ], "completedAt": "2025-10-30T20:07:17.553Z" }, "actor": { "type": "USER", "id": "8a1f6c2e-4b7d-4e2a-9c3f-1d5e6f7a8b9c", "name": "Jane Doe", "email": "jane@acme.com" }, "workspaceId": "6048d78a-584a-4f1e-9e39-e011ca4cc48c" } ```
# action_log.failed Source: https://docs.getomni.ai/api-reference/webhooks/events/action-log-failed Triggered when an action log fails. ## Event Type `action_log.failed` ## Description This event is fired whenever an action log fails to complete successfully. Use this event to monitor errors, implement retry logic, or alert your team about failed actions. ## Payload Structure The event type: `action_log.failed` The failed action log object Unique identifier for the action log Type of action that failed: `SYSTEM_NOTE`, `MESSAGE`, `FOLLOW_UP_MESSAGE`, `TOOL_CALL`, `DOCUMENT_UPLOAD`, `MANUAL_UPDATE` Status of the action: `FAILED` Brief summary of the failed action Input data for the action Output data from the action (usually null for failed actions) Error message describing why the action failed ID of the lead associated with this action ID of the agent that attempted the action Tool information if this was a tool call failure ISO 8601 timestamp when the action failed Workspace user who triggered this action. Returns `null` for actions not initiated by a workspace user. Type of actor Unique identifier for the user Name of the user Email address of the user ID of the workspace this event belongs to ```json theme={null} { "event": "action_log.failed", "workspaceId": "6048d78a-584a-4f1e-9e39-e011ca4cc48c", "actionLog": { "id": "8f2b3f2a-9a3e-4f02-9f0d-1a2b3c4d5e6f", "type": "TOOL_CALL", "status": "FAILED", "summary": "Deep research failed", "input": { "toolType": "deep_research", "query": "market analysis for ACME" }, "output": null, "error": "Upstream provider timeout after 5s", "completedAt": "2025-10-30T21:12:44.987Z", "leadId": "4cc8af99-b313-4c1f-b98b-009f38a4721a", "agentId": "c12d3456-7890-4abc-def1-234567890abc", "tool": { "id": "tool_123", "name": "deep_research" }, "messages": [] }, "actor": null } ``` # document.extracted Source: https://docs.getomni.ai/api-reference/webhooks/events/document-extracted Triggered when the document processing pipeline finishes, whether or not extraction actually ran. ## Event Type `document.extracted` ## Description This event fires once per document outcome: `completed` when the pipeline finished (extraction may have been skipped because validation flagged the document), and `failed` when extraction itself errored. The payload always includes a `classification` object describing which checklist item(s) the document matched, with per-item validation results on each matched item. ## Payload Structure The event type, always `document.extracted` ID of the workspace this event belongs to ID of the lead this document belongs to External ID of the lead this document belongs to, if one was provided at creation ID of the document that was processed External identifier for the document, if one was provided at creation `completed` when the pipeline finished or `failed` when extraction errored ID of the parent action that triggered the pipeline One- to two-sentence document summary from OCR, when available (same as stored on the document) Inferred document type from OCR (same as the `type` column on `documents`, e.g. `Bank Statement`, `Tax Return`). `null` when not set. How the document was classified before extraction (or an empty match list with a no-match reason) When the document was not matched to a checklist item, a short human-readable reason; otherwise `null` Checklist item rows the model linked this document to The checklist item code from configuration, if present Field type for the checklist item Checklist item label ID of the lead checklist item row Validation result for this checklist item. `null` when no validation ran (no rules, not a period-checked field type). For invalid items, one message per failed rule; empty when `status` is `valid` `valid` when the item passed every rule, `invalid` when any rule failed Returns any checklist items extracted from documents. Array of extracted data items The checklist item code from configuration, when the extracted value maps to a configured checklist item; `null` otherwise Label/field name for the extracted value ID of the lead checklist item this value was extracted for (if applicable) Extracted value Number of items with a non-empty extracted value ## Examples ### Successful extraction ```json theme={null} { "event": "document.extracted", "workspaceId": "6048d78a-584a-4f1e-9e39-e011ca4cc48c", "leadId": "910bb19a-2e9d-400f-8d15-9c461bb0f4aa", "externalLeadId": "SF-00142", "documentId": "ac52376a-fe68-4024-8b16-6acdcb9b3530", "externalId": "DOC-2025-001", "status": "completed", "parentActionId": "9d7fe2f3-ec1a-481c-b814-a0d1c8017e1f", "summary": "Business bank statement for Q1 2025 with ending balance and transactions.", "type": "Bank Statement", "classification": { "noMatchedItemReason": null, "matchedChecklistItems": [ { "checklistItemCode": "company-legal-name", "fieldType": "TEXT", "label": "Company Name", "leadChecklistItemId": "adc887d0-7238-4ce0-998d-523a22c282f4", "validation": null } ] }, "extractionResult": { "items": [ { "checklistItemCode": "company-legal-name", "label": "Company Name", "leadChecklistItemId": "adc887d0-7238-4ce0-998d-523a22c282f4", "value": "Monumint Technology Inc." } ], "extractedCount": 1 } } ``` ### Completed with validation failure When at least one matched checklist item has `validation.status: "invalid"`, extraction is not run, but the pipeline still reports `status: completed`. `extractionResult` is still present with an empty `items` array and `extractedCount: 0`; the per-item `validation` block on each matched item carries the failure reasons (`null` when no rules ran). ```json theme={null} { "event": "document.extracted", "workspaceId": "6048d78a-584a-4f1e-9e39-e011ca4cc48c", "leadId": "910bb19a-2e9d-400f-8d15-9c461bb0f4aa", "externalLeadId": "SF-00142", "documentId": "8f0c3d1b-2a00-4f0d-8c1e-0e5f1a2b3c4d", "externalId": "DOC-2025-002", "status": "completed", "parentActionId": "9d7fe2f3-ec1a-481c-b814-a0d1c8017e1f", "summary": "Monthly business checking statement.", "type": "Bank Statement", "classification": { "noMatchedItemReason": null, "matchedChecklistItems": [ { "checklistItemCode": "bank-statement", "fieldType": "BANK_STATEMENT", "label": "Recent bank statement", "leadChecklistItemId": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9", "validation": { "reasons": [ "The statement end date is earlier than the requested coverage period." ], "status": "invalid" } } ] }, "extractionResult": { "items": [], "extractedCount": 0 } } ``` # document.received Source: https://docs.getomni.ai/api-reference/webhooks/events/document-received Triggered when a document is received. ## Event Type `document.received` ## Description This event is fired whenever a document is received by the agent, whether via email, SMS, portal upload, or API. Use this event to track document collection and trigger downstream processing. ## Payload Structure The event type: `document.received` The received document object Unique identifier for the document External identifier for the document, if one was provided at creation Original filename of the document ID of the lead this document belongs to External ID of the lead this document belongs to, if one was provided at creation Pre-signed URL for accessing the document (expires after 1 hour) File size in bytes MIME type of the document (e.g., `application/pdf`, `image/jpeg`) ID of the message that contained this document (if applicable) Additional metadata about the document ISO 8601 timestamp when the document was created Workspace user who uploaded this document. Returns `null` for documents not uploaded by a workspace user. Type of actor Unique identifier for the user Name of the user Email address of the user ID of the workspace this event belongs to ## Signed URLs The `signedUrl` field provides temporary access to the document. Note that: * URLs expire after 1 hour * Request a new document via the API to get a fresh signed URL * URLs are pre-signed for secure access ## Next Steps After receiving this event, you may want to: * Download and process the document * Wait for the `document.extracted` event for extraction results * Update your system with the new document information ```json theme={null} { "event": "document.received", "document": { "id": "a80e6241-327f-419d-bae1-a4806d1a7641", "externalId": "DOC-2025-001", "filename": "vital-checking-june-25.pdf", "leadId": "50713355-df73-4077-9d84-dcda6da5729c", "externalLeadId": "SF-00142", "signedUrl": "https://omniai-server-v2-dev.s3.us-east-2.amazonaws.com/...", "size": 153143, "mimeType": "application/pdf", "messageId": "1ae4c028-ae4d-4e6d-aebd-cde96fdd8b3f", "metadata": null, "createdAt": "2025-10-31T19:00:01.675Z" }, "actor": { "type": "USER", "id": "8a1f6c2e-4b7d-4e2a-9c3f-1d5e6f7a8b9c", "name": "Jane Doe", "email": "jane@acme.com" }, "workspaceId": "6048d78a-584a-4f1e-9e39-e011ca4cc48c" } ``` # lead.completed Source: https://docs.getomni.ai/api-reference/webhooks/events/lead-completed Triggered when a lead application is completed. ## Event Type `lead.completed` ## Description This event is fired when all required checklist items for a lead have been completed or marked as needs review. Use this event to trigger downstream processing, notify your team, or sync the completed application to your systems. This event fires only once per lead. ## Payload Structure The event type: `lead.completed` The completed lead data Unique identifier for the lead External identifier for the lead (if set) Lead's first name Lead's middle name Lead's last name Lead's phone number (E.164 format, e.g., `+15551234567`) Lead's email address Lead's business name Lead's website URL How the lead was created: `inbound-email`, `inbound-sms`, `inbound-whatsapp`, `admin-email`, `portal`, `api`, `http`, `salesforce` Tags attached to the lead at completion, or an empty array when none All checklist items for the lead ID of the checklist item definition Code identifier for the checklist item Current value of the checklist item. Type depends on the field type: `string` for text fields, `number` for numeric fields, or an address object with the following structure: `{ "street": "...", "city": "...", "state": "...", "postalCode": "...", "country": "..." }`. Alternative extracted values The alternate extracted value ID of the action that produced this value Status: `TODO`, `COMPLETED`, `INVALID`, `SKIPPED`, `NEEDS_REVIEW` ISO 8601 timestamp of the last update Array of documents associated with the checklist item (only for file-type fields) Unique identifier for the document External identifier for the document Original filename MIME type of the document File size in bytes S3 bucket name (only included if external S3 integration is configured) S3 object key (only included if external S3 integration is configured) Document validation results (if validation rules are configured) ID of the validated document Whether the document passed all validation rules Additional notes from validation Individual rule results Whether this rule passed Name of the validation rule Index of the rule Explanation of why the rule passed or failed ID of the associated checklist item Whether the document passed all validation rules ```json theme={null} { "event": "lead.completed", "data": { "leadId": "50713355-df73-4077-9d84-dcda6da5729c", "externalId": "ext-lead-001", "firstName": "John", "middleName": null, "lastName": "Doe", "phoneNumber": "+15551234567", "email": "john@example.com", "businessName": "Acme Inc", "website": "https://acme.com", "source": "inbound-email", "tags": ["VIP", "priority-1"], "checklistItems": [ { "checklistItemId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "checklistItemCode": "company_name", "value": "Acme Inc", "alternateValues": [], "status": "COMPLETED", "updatedAt": "2025-10-31T18:30:00.000Z" }, { "checklistItemId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "checklistItemCode": "bank_statement", "value": "bank-statement-oct.pdf", "alternateValues": [], "status": "COMPLETED", "updatedAt": "2025-10-31T19:00:01.675Z", "documents": [ { "documentId": "8349efe7-3c68-49c3-9411-f9affda0d03a", "externalId": null, "filename": "bank-statement-oct.pdf", "mimeType": "application/pdf", "size": 153143, "validationResult": { "documentId": "8349efe7-3c68-49c3-9411-f9affda0d03a", "overallValid": true, "otherNotes": null, "validationResults": [ { "isValid": true, "ruleName": "First name should match", "ruleIndex": 0, "isValidReason": "Lead first name 'John' matches document name 'JOHN'." }, { "isValid": true, "ruleName": "Statement must be dated within the last 3 months", "ruleIndex": 1, "isValidReason": "October 2025 is within the required period." } ], "leadChecklistItemId": "f830cc29-16ad-4c64-9fa8-f90f318f8dce" }, "overallValid": true } ] } ] } } ``` # lead.created Source: https://docs.getomni.ai/api-reference/webhooks/events/lead-created Triggered when a lead is created. ## Event Type `lead.created` ## Description This event is fired whenever a new lead is created in your workspace, whether via API, email, SMS, WhatsApp, or portal. Use this event to sync new leads to your CRM or trigger onboarding workflows. ## Payload Structure The event type: `lead.created` The lead data Unique identifier for the lead External identifier for the lead (if set) Lead's first name Lead's middle name Lead's last name Lead's phone number (E.164 format, e.g., `+15551234567`) Lead's email address Lead's business name Lead's website URL How the lead was created: `inbound-email`, `inbound-sms`, `inbound-whatsapp`, `admin-email`, `portal`, `api`, `http`, `salesforce` Tags attached to the lead at creation, or an empty array when no tags were provided Workspace user who created this lead. Returns `null` for leads not created by a workspace user. Type of actor Unique identifier for the user Name of the user Email address of the user ```json theme={null} { "event": "lead.created", "actor": { "type": "USER", "id": "8a1f6c2e-4b7d-4e2a-9c3f-1d5e6f7a8b9c", "name": "Jane Doe", "email": "jane@acme.com" }, "data": { "leadId": "50713355-df73-4077-9d84-dcda6da5729c", "externalId": "ext-lead-001", "firstName": "John", "middleName": null, "lastName": "Doe", "phoneNumber": "+15551234567", "email": "john@example.com", "businessName": "Acme Inc", "website": "https://acme.com", "source": "inbound-email", "tags": ["VIP", "priority-1"] } } ``` # lead.updated Source: https://docs.getomni.ai/api-reference/webhooks/events/lead-updated Triggered when a lead is updated. ## Event Type `lead.updated` ## Description This event is fired when lead fields or checklist items are updated. The payload is sparse — it only includes fields that changed, along with `leadId` and `externalId` which are always present. ## Payload Structure The event type: `lead.updated` The updated lead data (sparse — only changed fields included) Unique identifier for the lead External identifier for the lead (if set) Lead's first name (only included if changed) Lead's middle name (only included if changed) Lead's last name (only included if changed) Lead's phone number (only included if changed) Lead's email address (only included if changed) Lead's business name (only included if changed) Lead's website URL (only included if changed) List of tags attached to the lead Array of updated checklist items (only included if checklist items changed) ID of the checklist item definition Code identifier for the checklist item Current value of the checklist item. Type depends on the field type: `string` for text fields, `number` for numeric fields, or an address object with the following structure: `{ "street": "...", "city": "...", "state": "...", "postalCode": "...", "country": "..." }`. Alternative extracted values The alternate extracted value ID of the action that produced this value Status of the checklist item: `TODO`, `COMPLETED`, `INVALID`, `SKIPPED`, `NEEDS_REVIEW` ISO 8601 timestamp of the last update Array of documents associated with the checklist item (only for file-type fields) Unique identifier for the document External identifier for the document Original filename MIME type of the document File size in bytes S3 bucket name (only included if external S3 integration is configured) S3 object key (only included if external S3 integration is configured) Document validation results (if validation rules are configured) ID of the validated document Whether the document passed all validation rules Additional notes from validation Individual rule results Whether this rule passed Name of the validation rule Index of the rule Explanation of why the rule passed or failed ID of the associated checklist item Whether the document passed all validation rules Workspace user who made this change. Returns `null` for actions not initiated by a workspace user. Type of actor Unique identifier for the user Name of the user Email address of the user ```json theme={null} { "event": "lead.updated", "actor": { "type": "USER", "id": "8a1f6c2e-4b7d-4e2a-9c3f-1d5e6f7a8b9c", "name": "Jane Doe", "email": "jane@acme.com" }, "data": { "leadId": "50713355-df73-4077-9d84-dcda6da5729c", "externalId": "ext-lead-001", "email": "newemail@example.com", "tags": ["VIP", "priority-1"], "checklistItems": [ { "checklistItemId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "checklistItemCode": "bank_statement", "value": "bank-statement-june.pdf", "alternateValues": [], "status": "NEEDS_REVIEW", "updatedAt": "2025-10-31T19:00:01.675Z", "documents": [ { "documentId": "8349efe7-3c68-49c3-9411-f9affda0d03a", "externalId": null, "filename": "bank-statement-june.pdf", "mimeType": "application/pdf", "size": 153143, "validationResult": { "documentId": "8349efe7-3c68-49c3-9411-f9affda0d03a", "overallValid": false, "otherNotes": "Document shows account holder name as 'JOHN DOE'.", "validationResults": [ { "isValid": true, "ruleName": "First name should match", "ruleIndex": 0, "isValidReason": "Lead first name 'John' matches document name 'JOHN'." }, { "isValid": false, "ruleName": "Statement must be dated within the last 3 months", "ruleIndex": 1, "isValidReason": "June 2025 is outside the required period. Valid months are October 2025, September 2025, August 2025." } ], "leadChecklistItemId": "f830cc29-16ad-4c64-9fa8-f90f318f8dce" }, "overallValid": false } ] } ] } } ``` # spread.completed Source: https://docs.getomni.ai/api-reference/webhooks/events/spread-completed Triggered when a financial spreading run completes. ## Event Type `spread.completed` ## Description This event fires when a spreading run finishes and its report and spreadsheet artifacts are ready; `data.artifacts` is always populated. Download each with the [artifact endpoints](/api-reference/artifacts/download-artifact). A regenerated run re-emits this event with new artifact ids for the same `spreadId`. Spreads not tied to a lead and spreads on a test lead do not emit webhooks. ## Payload Structure The event type: `spread.completed` Always `null` for spread events. ISO 8601 timestamp of when the event was emitted. The run data. The spreading run id. The lead the run belongs to. The lead's external identifier, if set. The workspace the run belongs to. Always `COMPLETE` for this event. The input documents, each with `id`, `filename`, and `status`. `id` is the document's id in your workspace, or `null` if the document has since been deleted. The outputs, each with `id`, `type` (`REPORT` or `SPREADSHEET`), and `title`. ```json theme={null} { "event": "spread.completed", "actor": null, "occurredAt": "2026-07-23T18:08:40.000Z", "data": { "spreadId": "9f1e2d3c-4b5a-6789-0abc-def012345678", "leadId": "b1f0a790-201b-47e9-84ed-cc7eed1270c5", "externalLeadId": "crm-4471", "workspaceId": "ws-1", "status": "COMPLETE", "documents": [ { "id": "doc-a", "filename": "2023-tax-return.pdf", "status": "EXTRACTED" }, { "id": "doc-b", "filename": "2023-financials.pdf", "status": "EXTRACTED" } ], "artifacts": [ { "id": "art-report", "type": "REPORT", "title": "Financial Spread - Pacific Coast Container Haulers" }, { "id": "art-sheet", "type": "SPREADSHEET", "title": "Financial Spread - Pacific Coast Container Haulers (Excel)" } ] } } ``` # spread.failed Source: https://docs.getomni.ai/api-reference/webhooks/events/spread-failed Triggered when a financial spreading run fails. ## Event Type `spread.failed` ## Description This event fires when a spreading run fails. `data.error` carries a short, human-readable reason for the failure. There are no artifacts. Spreads not tied to a lead and spreads on a test lead do not emit webhooks. ## Payload Structure The event type: `spread.failed` Always `null` for spread events. ISO 8601 timestamp of when the event was emitted. The run data. The spreading run id. The lead the run belongs to. The lead's external identifier, if set. The workspace the run belongs to. Always `FAILED` for this event. The input documents, each with `id`, `filename`, and `status`. `id` is the document's id in your workspace, or `null` if the document has since been deleted. The failure message. ```json theme={null} { "event": "spread.failed", "actor": null, "occurredAt": "2026-07-23T18:06:20.000Z", "data": { "spreadId": "9f1e2d3c-4b5a-6789-0abc-def012345678", "leadId": "b1f0a790-201b-47e9-84ed-cc7eed1270c5", "externalLeadId": "crm-4471", "workspaceId": "ws-1", "status": "FAILED", "documents": [ { "id": "doc-a", "filename": "2023-tax-return.pdf", "status": "FAILED" } ], "error": "Unable to extract financial data from the uploaded documents." } } ``` # spread.started Source: https://docs.getomni.ai/api-reference/webhooks/events/spread-started Triggered when a financial spreading run starts. ## Event Type `spread.started` ## Description This event fires whenever a spreading run is created and queued, whether it was started through the API or from the Monumint app. A regenerated run re-emits it. The run is `IN_PROGRESS`; a first run has no artifacts yet, while a regenerating run keeps its previous artifacts until the new ones replace them on completion. Spreads not tied to a lead and spreads on a test lead do not emit webhooks. ## Payload Structure The event type: `spread.started` Always `null` for spread events. ISO 8601 timestamp of when the event was emitted. The run data. The spreading run id. The lead the run belongs to. The lead's external identifier, if set. The workspace the run belongs to. Always `IN_PROGRESS` for this event. The input documents, each with `id`, `filename`, and `status`. `id` is the document's id in your workspace, or `null` if the document has since been deleted. ```json theme={null} { "event": "spread.started", "actor": null, "occurredAt": "2026-07-23T18:04:00.000Z", "data": { "spreadId": "9f1e2d3c-4b5a-6789-0abc-def012345678", "leadId": "b1f0a790-201b-47e9-84ed-cc7eed1270c5", "externalLeadId": "crm-4471", "workspaceId": "ws-1", "status": "IN_PROGRESS", "documents": [ { "id": "doc-a", "filename": "2023-tax-return.pdf", "status": "PROCESSING" }, { "id": "doc-b", "filename": "2023-financials.pdf", "status": "PROCESSING" } ] } } ``` # List Webhooks Source: https://docs.getomni.ai/api-reference/webhooks/list-webhooks GET https://api-v2.getomni.ai/api/v1/webhooks Fetch all webhooks configured for your workspace This endpoint fetches all webhooks configured for your workspace. ## Response Array of webhook objects Unique identifier for the webhook The webhook URL where events will be sent Array of event types this webhook is subscribed to Whether the webhook is currently enabled Optional description for the webhook ISO 8601 timestamp when the webhook was created ISO 8601 timestamp when the webhook was last updated ```javascript Node.js theme={null} const options = { method: 'GET', headers: { 'x-api-key': '', }, }; fetch('https://api-v2.getomni.ai/api/v1/webhooks', options) .then((response) => response.json()) .then((response) => console.log(response)) .catch((err) => console.error(err)); ``` ```python Python theme={null} import requests url = "https://api-v2.getomni.ai/api/v1/webhooks" headers = { "x-api-key": "" } response = requests.request("GET", url, headers=headers) print(response.json()) ``` ```bash cURL theme={null} curl --request GET \ --url https://api-v2.getomni.ai/api/v1/webhooks \ --header 'x-api-key: ' ``` ```json 200 theme={null} [ { "id": "06e4b90b-86dd-41c7-9a1e-73a592963682", "workspaceId": "6048d78a-584a-4f1e-9e39-e011ca4cc48c", "url": "https://c4b3632a95ef.ngrok-free.app/webhook/test-receiver", "secret": null, "events": [ "action_log.completed", "action_log.failed" ], "isEnabled": false, "description": null, "createdAt": "2025-10-30T19:49:46.581Z", "updatedAt": "2025-10-30T20:07:31.930Z" } ] ``` # Webhook Events Source: https://docs.getomni.ai/api-reference/webhooks/webhook-events # Webhook Events This page provides an overview of all available webhook events. Each event type has its own detailed documentation page. ## Event Types ### Action Log Events Track agent activity and action completion: Fired when an action completes successfully Fired when an action fails ### Document Events Track document collection and processing: Fired when a document is received Fired when document extraction completes ### Lead Events Track lead lifecycle: Fired when a lead is created Fired when a lead is updated Fired when a lead application is completed ### Spread Events Track financial spreading runs: Fired when a spreading run starts, from the API or the Monumint app Fired when a spreading run completes and its artifacts are ready Fired when a spreading run fails ## Webhook Delivery ### Request Format Webhooks are sent as HTTP POST requests with: * **Content-Type**: `application/json` * **Method**: POST * **Body**: JSON payload containing the event data ### Response Requirements Your webhook endpoint should: * Return a `200 OK` status code within 5 seconds * Handle requests asynchronously if processing takes longer * Return appropriate error codes for invalid requests ### Retry Logic If your endpoint doesn't respond with a 2xx status code within 5 seconds, Monumint will retry: * **Initial retry**: After 1 minute * **Subsequent retries**: Backoff of roughly 2, 5, 10, then 20 minutes * **Maximum**: 6 total attempts ## Security ### Authenticating Deliveries Deliveries are not signed. To authenticate them, set custom `headers` on the subscription — for example a shared-secret header — and reject requests to your endpoint that don't carry it. See [Create Webhook](/api-reference/webhooks/create-webhook). ### Best Practices * Use HTTPS endpoints only * Reject deliveries that don't carry your secret header * Implement idempotency to handle duplicate events * Set up retry logic for failed webhook deliveries * Monitor webhook delivery status ## Related Guides Learn how to set up webhooks Create webhooks via API List your webhooks # Week of April 14, 2026 Source: https://docs.getomni.ai/changelog/2026-04-14 # Smarter Templates, a New Launcher, and Document Intelligence This week was all about making the assistant more powerful and discoverable — from a new launcher UI that surfaces what the agent can do, to Handlebars-powered templates that support real logic, to layout-aware document understanding. ## Features ### Improved Template Rendering The Monumint Assistant is currently in beta. Contact your rep to activate it for your workspace. Create dynamic templates with conditionals, loops, and computed fields — not just simple placeholders. Templates now support full [Handlebars](https://handlebarsjs.com/) syntax. This means you can use `{{#each}}` loops for line items, `{{#if}}` conditionals for optional sections, and more. You can also upload images (like a company logo) directly in the assistant chat and have them embedded in generated reports and templates. The template sidebar and report artifact views have been updated to display these control flows clearly. ### Assistant Launcher Help users discover what the AI assistant can do and quickly attach context to their messages. A new command palette-style launcher is now available in the assistant chat. Action chips below the input suggest common tasks, and the launcher modal lets you search for actions and attach leads, documents, or templates directly to your message. ### Document Layout Analysis Upload a document and have the AI recreate its formatting as a reusable template. A new document layout analysis tool lets the agent understand not just the text content of an uploaded file, but its visual structure — headings, tables, spacing, and more. Upload a PDF, DOCX, or image, and the agent can generate a matching template that preserves the original layout. ## Improvements ### Document Upload API Metadata The `/api/v1/documents` upload endpoint now accepts an optional `metadata` parameter, letting you pass `externalId` and `name` for each uploaded file. This makes it easier to link uploaded documents back to records in your system. See the [Upload Documents API reference](/api-reference/documents/upload-document) for request and response details. ### Twilio API Key Authentication You can now authenticate your Twilio integration using an [API key and secret](https://www.twilio.com/docs/iam/api-keys) as an alternative to an auth token. A dropdown in the integration settings lets you choose between the two methods, and credentials are validated against Twilio before saving. ### Configurable Agent Response Timing Agent response delay now supports seconds-level granularity. Previously limited to whole minutes, you can now set delays as short as 30 seconds for faster follow-ups. ## Fixes * Fixed checklist items not updating correctly in the portal * Fixed an issue with Twilio SMS webhook responses * Fixed Twilio credential handling when using workspace-level integration tokens # Week of April 27, 2026 Source: https://docs.getomni.ai/changelog/2026-04-27 # A New Analytics Page, WhatsApp Sequences, and Manual Status Overrides A big week for visibility and outbound — the analytics page has been rebuilt from the ground up, WhatsApp joins email and SMS in automated sequences, and you can now set a lead's status by hand from the dashboard. ## Features ### Redesigned Analytics Page *Use case:* Get a faster read on conversion, agent activity, and lead pipeline health without exporting data. The analytics page has been rebuilt with new charts, cleaner filters, and a layout that puts the metrics that matter first. The underlying [Analytics API](/api-reference/analytics/get-analytics) is unchanged — this is a pure frontend refresh. ### WhatsApp in Sequences *Use case:* Reach leads on the channel they actually answer — extend automated follow-ups beyond email and SMS into WhatsApp. Sequence steps now support WhatsApp alongside email and SMS. Pick a Twilio Content Template from the new template dropdown, map your variables, and the step will send through your connected WhatsApp number on schedule. Templates are pulled live from Twilio so approved content shows up automatically. ### Manually Update Lead Status *Use case:* Override the agent when you already know the outcome — close a lead, opt them out, or send them to review without waiting on the checklist. A new status picker on the leads dashboard and lead detail page lets you set a lead to **Completed**, **Opt Out**, or **Needs Review**. The change goes through the same logic the agent uses — opting out stamps `optedOutAt`, completing skips remaining required checklist items, and review creates an escalation — and a confirmation modal summarizes the impact before applying. The action is attributed to the user who triggered it, and completing a lead this way fires the [`lead.completed` webhook](/api-reference/webhooks/events/lead-completed) just like an agent-driven completion. ## Improvements ### Email Threading in Sequences Sequence emails can now reply to the previous thread instead of starting a new one, keeping the conversation in a single thread in the recipient's inbox. A new "Reply to previous thread" checkbox controls the behavior per step, and it defaults on for new email steps. ### Document Validation in Webhooks The [`document.extracted` webhook](/api-reference/webhooks/events/document-extracted) now includes a `classification` block with per-checklist-item `validation` results. When validation fails, the webhook fires with `status: completed`, an empty `extractionResult`, and human-readable failure reasons on each matched item — making it much easier to react to document rejections downstream. ### Document Period Returned for All Types When a document type has a configured grace period, the webhook and document responses now return both the **preferred** and **fallback** period, and a period is returned for every document type rather than only those tied to a specific checklist item. This makes it possible to surface "valid but outside preferred range" documents in your own systems. ### Clearer Status Attribution When a user manually changes a lead's status, the timeline summary and `actionLog` row now record which user made the change, so it's easy to trace status updates back to the operator who made them. ## Fixes * Fixed an email rendering error that prevented quoted content from being collapsed for messages from certain email clients * Fixed the "publish changes" banner appearing on sequence steps when no changes had actually been made * Fixed an editor issue where empty paragraphs in email bodies could cause downstream errors * Fixed inconsistent display of the completed/in-progress badge between the leads dashboard and the lead detail page * Fixed a rare error reading properties of an undefined message body # Week of May 4, 2026 Source: https://docs.getomni.ai/changelog/2026-05-04 # Improved knowledge base search A focused week on the agent's knowledge base — answers are now grounded in verbatim quotes from your KB, and items pulled from your website source can be edited inline like any other entry. ## Improvements ### Knowledge Base Lookups Return Verbatim Citations We've made improvements to the agent's `search-knowledge-base` tool. As well as adding visibility to the timeline view for any answers pulled directly from the Knowledge Base. Each lookup returns a concise answer plus the matching group and item titles and verbatim quotes from the underlying entries, so the agent can cite exactly where its answer came from rather than paraphrasing. Tool calls show up in the lead timeline alongside other agent actions. See [Knowledge Base setup](/ai-agent/fine-tuning#knowledge-base) for how to populate it. ### Edit Website-Sourced Knowledge Base Items in the UI Knowledge base items pulled from a website source were previously read-only. You can now edit both the title and the extracted content inline from the dashboard, the same way you would for manually authored answer items — useful for trimming boilerplate from a scrape or correcting a mis-extracted heading. The original source URL still renders below the content. See the [Knowledge Base guide](/ai-agent/fine-tuning#knowledge-base) for managing entries. ## Fixes * Fixed a case where a WhatsApp follow-up scheduled to send outside the 24-hour conversation window would attempt to deliver a free-form message instead of falling back to a Twilio template. * Fixed conditional [checklist item](/ai-agent/checklist) status badges on the leads dashboard not refreshing after their conditions were edited. * Fixed the most recent inbound WhatsApp message occasionally not being picked up when building lead context for an AI-generated reply. # Week of May 18, 2026 Source: https://docs.getomni.ai/changelog/2026-05-18 # Date-filtered Leads, Programmatic Status, and a More Conversational Agent This week brings From/To date filters to the Leads page and assistant chat, a new way to mark leads complete through the API, and tweaks to how the agent handles opt-out and follow-up conversations. ## Features ### Date Filters on the Leads Page and in Assistant Chat *Use case:* Answer "how many leads came in today?" or "show me everything from last week" without scrolling or exporting. The Leads page now has **From** and **To** date filters at the top of the filter bar. The same filters are available to the assistant, so questions like *"how many leads came in this week?"* return exact counts and lists scoped to that window. ### Set Lead Status via the Update Lead API *Use case:* Sync lead status from an external CRM into Monumint in a single call. `PUT /api/v1/leads` now accepts a `status` field with values `"COMPLETED"`, `"IN_PROGRESS"`, and `"OPTED_OUT"`. Marking a lead `COMPLETED` cancels any scheduled follow-ups for that lead. See the [Update Lead API](/api-reference/leads/update-lead) for the full parameter list. ## Improvements ### More Conversational Opt-out and Follow-up Drafts The agent now handles ambiguous opt-out signals more carefully: when a lead's reply is unclear, it asks a clarifying question instead of promising to stop messaging and then continuing the conversation a day later. Follow-up drafts also read more naturally when a lead is disengaging, rather than always pushing the application forward. See the [Conversation guide](/ai-agent/conversation) for more on how the agent handles replies and follow-ups. ## Fixes * Pending follow-ups and replies are now refreshed when a lead uploads a document, so scheduled messages reflect the new upload. See [Document Vault](/leads/document-vault). * Test leads no longer trigger outbound [webhooks](/webhooks). Real-lead webhooks are unaffected. * The Last Action card on the lead details page now shows the time of the most recent outbound message, matching the [timeline](/leads/timeline). * Sorting the timeline "Newest first" now also reverses the messages inside a batched timeline entry, instead of leaving them oldest-first. # Week of June 1, 2026 Source: https://docs.getomni.ai/changelog/2026-06-01 # Lead Tags, Activity based Follow-ups, and Improved Webhook Deliveries page This week ships two net-new capabilities — manual lead tagging across the dashboard and API, and an activity based followup triggers to the agent (document uploaded, portal updates, API activity) — alongside a richer webhook deliveries view and additional dashboard filters. ## Features ### Lead Tags *Use case:* Group leads by anything that matters to your team — product line, source campaigns, regions — and filter or sort the dashboard around it. You can now add free-form tags to a lead from the leads dashboard or the lead detail page, sort the dashboard by tag, and set tags on lead creation or update through the API. Tag matching is case-insensitive, and tags are returned on every lead payload, including the [`lead.created`](/api-reference/webhooks/events/lead-created) and [`lead.updated`](/api-reference/webhooks/events/lead-updated) webhooks. See the [Create Lead API](/api-reference/leads/create-lead), [Update Lead API](/api-reference/leads/update-lead), and the [List Leads API](/api-reference/leads/list-leads) for the `tags` parameter. ### Activity based Agent Follow-ups *Use case:* Keep momentum going after a lead does something on their own — uploads a document, fills in a value in the portal, or completes a checklist item — without waiting for the next scheduled follow-up. When a lead makes progress on their checklist, the agent now sends a context-aware follow-up message instead of staying silent until the next scheduled touchpoint. The trigger respects the same debounce window as other outbound messages, so leads don't get a burst of replies for back-to-back updates, and it only fires once the agent has already started a conversation with the lead. See the [Autopilot guide](/ai-agent/autopilot) for how the agent handles automated outreach. ## Improvements ### Pagination, Filters, and Copy-Payload on Webhook Deliveries The webhook deliveries page now supports pagination and filtering, so you can scope to a specific webhook, event type, or status when something looks off. Each delivery row also exposes a copy-payload action that grabs the exact JSON we sent, which is the fastest way to replay a request locally when debugging an integration. See the [Webhooks guide](/webhooks) for the surrounding setup. ## Fixes * The status filter on the leads dashboard now includes **Not Interested** and **Opt Out**, so it's possible to scope the list to leads who explicitly disengaged. The unused **Pending** option has been removed. * Document-extracted values no longer overwrite checklist answers a lead provided directly in conversation. The agent keeps the original answer and tracks the document value as an alternative to surface during review. # Week of July 13, 2026 Source: https://docs.getomni.ai/changelog/2026-07-13 # A Refreshed Look, a Knowledge-Base-Savvy Assistant, and Tighter Lead Controls This week rolls out a full brand refresh across the app, teaches the assistant to save and update knowledge base entries straight from chat, and adds a new agent setting to keep unknown senders from starting conversations you never asked for. ## Features ### A refreshed brand and color system *Use case:* Make the app feel cohesive with the rest of the Monumint brand and easier to skim, without changing where anything lives. The web app has been recolored end to end around a new brand palette and a shared color system. Colors now split into clear roles — brand, semantic (info / success / warn / error), neutral, and a small set of intentional exceptions like the purple used for agent-authored surfaces — so status badges, buttons, and highlights read more consistently across every page. Nothing has moved; the app should feel more cohesive without changing where anything lives. ### Save to your knowledge base from the assistant chat *Use case:* Capture a new fact — or correct an existing one — the moment it comes up in an assistant conversation, without leaving the chat. When you share something worth remembering with the assistant, it now proposes saving it as a knowledge base entry. You get an editable card in the chat showing the title and content it wants to save; you can tweak either field and approve, or reject the suggestion. If the fact already exists, the assistant proposes an update to the exact entry it found so you don't end up with duplicates. New assistant-created entries land under a dedicated "Assistant-added" group so it's always clear what originated in chat versus what your team wrote by hand. ### Block leads from unknown senders *Use case:* Prevent the agent from engaging cold, unsolicited inbound leads while still keeping a record that the contact came in. A new agent setting lets you stop the agent from replying to inbound SMS, WhatsApp, email, or calls from a contact you've never seen before. When the setting is on, the message still creates a lead — so you have visibility into who reached out — but the lead is marked blocked, assigned to a human, and the agent will not send anything. Existing leads writing in from a new address are unaffected as long as they land on an already-linked conversation thread. You can find the toggle on the [Agent Settings](/ai-agent/settings) page. ## Improvements ### Email signatures per agent Email signatures now live on the individual agent instead of on the workspace, so agents with different names, phone numbers, or disclaimers can each sign off correctly. Existing workspace signatures were copied onto every agent on rollout, so drafts and scheduled sends resolve to the same text as before. Edit each signature from the agent's overview page. ### Include and exclude tag filters on the leads dashboard The tag filter in the leads dashboard now has explicit "contains" and "does not contain" rows, so you can build a view like *contains `VIP`, does not contain `archived`* in one place. "Contains" now matches leads that carry every selected tag rather than any of them, which makes multi-tag filtering more precise. The same conditions save and restore with your saved views, and `excludeTags` is available on the [List Leads API](/api-reference/leads/list-leads) too. ### Share saved views with your workspace Admins can now mark a saved view as shared, and it will appear under a new "Workspace views" section for everyone in the workspace. Personal views still belong to their creator; shared views can only be edited or deleted by workspace admins. Non-admins who tweak the filters on a shared view are offered "Save as new view" so they can fork it into a personal view without stepping on the shared one. ### Web search for the assistant The assistant can now pull in results from the open web when a question needs context that isn't in your workspace, using a new web-search tool. This is useful for looking up companies, checking public information about a lead, or grounding a reply against something happening outside your CRM. ### Faster Salesforce sync and nested field support The Salesforce importer runs meaningfully faster on large workspaces. Field mappings and lead-filter conditions now accept nested paths (for example `Accounts.Contact.FirstName`), so you can pull related-object fields into an agent's checklist or use them to decide when the agent should be active on a lead. ### Multi-agent workspaces (early access) Workspaces can now host more than one agent, with each agent optionally acting as either a checklist collector or a support-only agent. The lead detail page picks up an agent selector when a lead is linked to multiple agents, so you can send or draft as any of them. This is behind an opt-in feature flag while we iron out the workflow — reach out if you'd like it turned on for your workspace. ## Fixes * Fixed a case where a lead update through the API could cancel an agent's in-flight reply and replace it with a next-business-day follow-up instead of answering the lead. * Sequence emails that require approval now include the agent's email signature before you review them. * Removed a false "unpublished changes" banner that appeared on the agent settings page when the email signature editor loaded, along with a few cases where the editor was silently rewriting link colors, paragraph styling, or underline markup on save. * Fixed a layout overflow in the conversation view where long draft or reply content could push past the panel edge. # Domain Configuration Source: https://docs.getomni.ai/domain-configuration Configure your email domain to enable your AI agent to send and receive emails. This allows your agent to communicate with leads using a custom email address from your domain. ## Overview The agent email domain configuration allows you to: * **Use your own domain** for agent email addresses (e.g., `agent@yourcompany.com`) * **Maintain brand consistency** with custom email addresses * **Enable email communication** between your AI agent and leads * **Receive and process** documents sent via email ## Email Domain Setup Setting up an email domain allows your AI agent to send & receive emails using addresses from your domain. ### Steps 1. **Add a new email domain** in [workspace settings](https://platform.getomni.ai/settings/email-domains) * Enter your domain (e.g., `yourcompany.com`) * The system will generate the required DNS records 2. **Add all the DNS records** in your domain provider * Copy the DNS records shown in workspace settings * Add them to your domain's DNS configuration 3. **Wait for domain verification** (usually a few minutes, can take up to 48 hours) * The system will verify that DNS records are correctly configured 4. **Add a new email address** in [agent settings](https://platform.getomni.ai/agent#settings) * Choose the email domain that you added in the previous step * You can customize the email address (e.g., `loans@yourcompany.com` or `agent@yourcompany.com`) * Set the email display name (e.g., "Your Company Loan Agent") 5. **Click `Send Test Email`** button to test sending a new email ## DNS Records for Agent Email Domain When you add an email domain for your agent, you'll need to configure DNS records in your domain provider. The specific records will be shown in the workspace settings after you add the domain. ### Required DNS Records The DNS records are used for: * **Domain Verification**: TXT records to verify domain ownership * **Email Authentication**: SPF and DKIM records to ensure emails are delivered and not marked as spam * **Email Routing**: MX records (if required) to route emails to Monumint's servers ### Common DNS Record Types * **TXT Records**: For domain verification and email authentication (SPF, DKIM) * **MX Records**: For email routing (if required by your setup) * **CNAME Records**: For subdomain configuration (if using subdomains) DNS changes can take up to 48 hours to propagate, though they're usually faster. Wait for domain verification to complete before proceeding with email setup. ## Subdomain Configuration (Optional) If you're setting up a subdomain for your white-label applicant portal or other features, you'll need to configure CNAME records pointing to Monumint's servers. Subdomain configuration is separate from email domain configuration. The email domain is used for agent email addresses, while subdomains are used for white-label portals and other features. The specific subdomain configuration will be provided in your workspace settings. ## SMS Setup For SMS configuration, see [SMS Setup](/ai-agent/sms-setup). ## Admin Emails For admin email configuration, see [Admin Emails](/ai-agent/admin-emails). ## Troubleshooting ### Domain Verification Failed * Check that all DNS records are correctly configured * Ensure DNS records have propagated (can take up to 48 hours) * Verify there are no typos in the DNS record values ### Agent Email Not Sending * Verify the email domain is verified and active in workspace settings * Check that an email address is configured in agent settings * Ensure the email address is using the verified domain * Test with the "Send Test Email" button in agent settings ### Agent Email Not Receiving * Verify MX records are correctly configured (if required) * Check that the email address is active in agent settings * Verify the domain is still verified in workspace settings * Check spam/junk folders (emails may be filtered initially) * Ensure the email address matches the configured domain ## Related Guides Configure agent email and communication settings Learn how email collection works # Introduction Source: https://docs.getomni.ai/introduction # Conversational AI for financial institutions Monumint is the conversational AI platform for modern financial institutions — agents that handle the full borrower lifecycle across voice, email, SMS, and chat. ## What we do Meet customers where they are. One agent carries the conversation from first touch to resolution across every channel. Agents read and write to the systems that matter — CRMs, loan platforms, and cores — so every conversation drives real work. TCPA-safe windows, fair-lending language scoring, and audit-ready trails for every message, decision, and system update. Collect, classify, and extract data from loan documents so applications keep moving without manual review bottlenecks. ## Built for every stage of the customer journey Pre-qualify, nurture, and collect documents end-to-end with automated validation. Re-engage applicants who stall mid-application with policy-bounded, personalized outreach. # Document Vault Source: https://docs.getomni.ai/leads/document-vault Document Vault # Document Vault The Document Vault is where all documents submitted by leads are stored and organized. Each lead has their own document vault containing all uploaded documents, extracted data, and processing results. ## Overview The Document Vault provides: * **Centralized storage** for all lead documents * **Document organization** by checklist item * **Extracted data** from processed documents * **Document metadata** including classification and validation status * **Secure access** via signed URLs ## Accessing Documents Documents can be accessed through: * **Lead detail page**: View all documents for a specific lead * **API**: Retrieve documents programmatically via the [Documents API](/api-reference/documents/get-document) * **Webhooks**: Receive notifications when documents are received or processed ## Document Processing When a document is uploaded, the system automatically: 1. **Stores the document** securely in S3 2. **Runs OCR** to extract text 3. **Classifies the document** to match checklist items 4. **Validates the document** against configured rules 5. **Extracts data** to populate checklist items ## Document Metadata Each document includes: * **Filename**: Original filename * **Document type**: Classified document type * **Size**: File size in bytes * **MIME type**: File type (PDF, image, etc.) * **Processing status**: Extraction and validation status * **Extracted text**: OCR results * **Checklist matches**: Which checklist items the document matches ## Related Guides Learn how documents are collected Retrieve documents via API View document activity in timeline # Lead Imports Source: https://docs.getomni.ai/leads/imports # Lead Imports Learn how to use imports in Monumint to bulk add leads via CSV upload, API, or webhooks. This article explains the import overview and available import methods. ## Import Methods ### 1️⃣ Create leads from dashboard Click "New lead", fill out the required information, and a new lead will be created. In order to start the AI agent, you'll have to go to the new lead and click "Trigger followup". ### 2️⃣ Create a lead via Email If a client directly emails the agent for the first time, it will create a new lead automatically. ### 3️⃣ Create a lead via admin email If an admin user emails the agent with lead information, or CC's the agent on an email chain with a borrower, it will create a new lead. ### 4️⃣ CSV upload In the app dashboard: 1. Click "New lead" 2. Click "Import from CSV" 3. Upload a lead CSV with lead information 4. Map CSV columns to lead properties and their checklist items if any CSV uploads support bulk imports of multiple leads at once. Make sure your CSV includes required fields like email or phone number. ### 5️⃣ Webhooks Monumint supports **webhook-based imports** as a powerful way to send lead data directly into your workspace in real time. This is particularly useful for integrating external systems such as: * CRMs * Marketing platforms * Signup forms * Internal tools Webhooks allow you to push data into Monumint automatically whenever a new contact is created or updated externally. See [Webhooks](/webhooks) for detailed setup instructions. ### 6️⃣ API You can create leads programmatically using our API. See the [API Reference](/api-reference/leads/list-leads) for details. ## Best Practices * **Include contact information**: Always include email or phone number for each lead * **Map checklist items**: When importing via CSV, map columns to checklist items for automatic population * **Verify data**: Review imported leads to ensure data accuracy * **Use webhooks for real-time sync**: For CRM integrations, use webhooks for automatic lead creation ## Related Guides View documents for imported leads Track activity for imported leads Set up webhook-based imports Create leads via API # Timeline Source: https://docs.getomni.ai/leads/timeline Timeline # Timeline The Timeline view shows all activity logs among leads, admins, and the AI agent. It provides a comprehensive history of all interactions and actions taken during the loan application process. ## What's Logged The Timeline logs: * **Email and SMS messages**: All inbound and outbound communications * **Agent tools results**: Results from tools the agent uses (see [Tools](/ai-agent/tools)) * **Follow-up messages**: Scheduled and sent follow-up communications * **System messages**: System-generated notifications and updates * **Document uploads**: When documents are received and processed * **Checklist updates**: When checklist items are completed or updated * **Action logs**: All agent actions and their outcomes ## Viewing Timeline Access the Timeline from: * **Lead detail page**: View timeline for a specific lead * **Dashboard**: See recent activity across all leads ## Timeline Features * **Chronological view**: All activities shown in order of occurrence * **Filtering**: Filter by activity type, date range, or participant * **Search**: Search for specific activities or keywords * **Export**: Export timeline data for reporting ## Action Logs Action logs provide detailed information about: * **Action type**: What action was performed (message, tool call, etc.) * **Status**: Whether the action completed successfully or failed * **Input/Output**: What data was sent and received * **Timing**: When the action was scheduled and completed * **Agent information**: Which agent performed the action ## Related Guides Retrieve action logs via API Learn about agent tools Understand conversation handling # Portal Domain Source: https://docs.getomni.ai/portals/domain-configuration Portal Domain Configure a custom subdomain for your white-label applicant portal to provide a branded experience for your leads. This allows your portal to be accessed via a custom URL like `portal.yourcompany.com` instead of the default Monumint domain. ## Overview The application portal domain configuration allows you to: * **Use your own subdomain** for the applicant portal (e.g., `portal.yourcompany.com` or `apply.yourcompany.com`) * **Maintain brand consistency** with a custom domain for your portal * **Improve trust and credibility** with leads by using your own domain * **Customize the portal URL** to match your brand identity ## Portal Domain Setup Setting up a custom subdomain for your applicant portal requires configuring DNS records to point your subdomain to Monumint's servers. ### Steps 1. **Choose a subdomain** for your portal * Common choices: `portal.yourcompany.com`, `apply.yourcompany.com`, `app.yourcompany.com` * Ensure the subdomain is available and not used for other services 2. **Add the portal domain** in [workspace settings](https://platform.getomni.ai/settings/portal-domains) * Enter your subdomain (e.g., `portal.yourcompany.com`) * The system will generate the required DNS records 3. **Configure DNS CNAME record** in your domain provider * Copy the CNAME record shown in workspace settings * Add it to your domain's DNS configuration * The CNAME should point your subdomain to Monumint's portal servers 4. **Wait for domain verification** (usually a few minutes, can take up to 48 hours) * The system will verify that the DNS record is correctly configured * You'll receive a notification when verification is complete 5. **Activate the custom domain** in portal settings * Once verified, enable the custom domain for your portal * Portal links will now use your custom subdomain ## DNS Configuration When you add a portal domain, you'll need to configure a CNAME record in your domain provider's DNS settings. ### CNAME Record Setup The CNAME record is used to point your subdomain to Monumint's portal servers. The specific CNAME target will be provided in your workspace settings. **Example CNAME Record:** ``` Type: CNAME Name: portal (or your chosen subdomain) Value: [provided by Monumint] TTL: 3600 (or your provider's default) ``` ## SSL Certificate Once your domain is verified, Monumint automatically provisions an SSL certificate for your custom subdomain. This ensures secure HTTPS connections to your portal. SSL certificate provisioning may take a few minutes after domain verification. Your portal will be accessible via HTTPS once the certificate is active. ## Portal Links After configuring your custom domain, all portal links will use your subdomain: * **Before**: `https://portal.getomni.ai/lead/abc123` * **After**: `https://portal.yourcompany.com/lead/abc123` Portal links sent via email, SMS, or shared directly will automatically use your custom domain. ## Troubleshooting ### Domain Verification Failed * Check that the CNAME record is correctly configured in your DNS provider * Ensure DNS records have propagated (can take up to 48 hours) * Verify there are no typos in the CNAME record value * Make sure the subdomain is not already in use for another service * Check that the CNAME record name matches exactly (e.g., `portal` not `portal.yourcompany.com`) ### Portal Not Accessible via Custom Domain * Verify the domain is verified and active in workspace settings * Check that the custom domain is enabled in portal settings * Ensure SSL certificate has been provisioned (may take a few minutes) * Try accessing the portal after waiting a few minutes for DNS/SSL propagation * Verify the CNAME record is still correctly configured ### SSL Certificate Issues * Wait a few minutes after domain verification for SSL provisioning * Clear your browser cache and try again * Check that the CNAME record is correctly pointing to Monumint's servers * Verify the domain is still verified in workspace settings ## Related Guides Learn about portal features and customization Configure email domain for AI agent # White-Label Applicant Portal Source: https://docs.getomni.ai/portals/white-label-portal Portal If you need a white-label application form for your application process, the white-label applicant portal is here for you. ## Overview Each lead will have a client portal where they can: * Fill out their basic information * Upload documents * View their application status * Complete checklist items ## Features * **Customizable branding**: Match your company's look and feel * **Secure access**: Each lead has a unique portal link * **Real-time updates**: Portal reflects current checklist status * **Document upload**: Easy file upload interface * **Progress tracking**: Leads can see what's completed and what's remaining ## Accessing the Portal Leads can access their portal via: * **Email link**: Portal link sent via email * **SMS link**: Portal link sent via SMS * **Direct link**: Share portal link directly with leads ## Portal Customization Configure the portal to match your brand: * **Company logo**: Add your logo * **Colors**: Customize color scheme * **Welcome message**: Personalized greeting * **Instructions**: Custom guidance for applicants ## Integration The portal integrates seamlessly with: * **Agent communication**: Agent can reference portal in messages * **Document collection**: Documents uploaded via portal are processed automatically * **Checklist updates**: Portal reflects real-time checklist status * **Timeline**: Portal activity is logged in the Timeline ## Related Guides Learn about document collection Configure checklist items Set up custom subdomain for portal # Document Collection Source: https://docs.getomni.ai/use-cases/document-collection-email **🧗‍♂️ The Challenge**: Processing loan documents manually is time-consuming and error-prone. Staff spend hours reviewing bank statements, pay stubs, and tax documents, often going back and forth with applicants about missing information or document quality issues. **💡 Our Solution**: Monumint's AI agent automatically receives documents via email, reads and validates them against your specific checklist requirements, and instantly sends detailed feedback about any issues - reducing processing time from hours to minutes. ## How It Works ### 1️⃣ Set up email for agent Follow the **Email Setup** guide in [Settings](/ai-agent/settings). After setting up, the agent can start sending & receiving emails. ### 2️⃣ Set up checklist * Set up document checklist in [Agent Checklist](https://platform.getomni.ai/agent#checklist) * Define required document types (bank statements, tax returns, or a custom document type) * Agent will help streamline document collection via email or SMS Checklist Setup You can also add custom validation rules to each checklist item. When the agent receives a document, it will try to classify the document and see if it matches one of the checklist items. If yes, then it will apply the validation rules to the document. ### 3️⃣ Send emails to agent Monumint's agent monitors its email inbox for incoming emails. For each email received, the agent will: 1. **Find or create a lead**: * If new email, it will create a new lead * If existing email from the lead list, retrieve the existing lead 2. **Extract & update checklist items** from email message 3. **Process attachments** using document intelligence (step 4) 4. **Auto-generate a response** to the message * If agent is on `Autopilot` mode, it will directly send the response without permission * If agent is on `Listen` mode, it will draft a response and admin can review and edit it ### 4️⃣ Document intelligence For each attachment in the email message, our agent will perform the following action in order: 1. **Use OCR** to convert document to markdown 2. **Classify the document** into one of the document requirements (bank statements, etc.) 3. **Apply validation rules** to the document if any 4. **Extract lead's checklist values** from documents Document Intelligence ### 5️⃣ Automated follow-up If agent is on `Autopilot` mode, after agent sends the response, it will generate a follow up message and schedule a follow-up email if it doesn't hear back from the leads. ## Benefits * **Automated Processing**: Documents are processed automatically without manual intervention * **Real-time Validation**: Instant feedback on document quality and completeness * **Intelligent Classification**: Documents are automatically matched to checklist requirements * **Data Extraction**: Key information is extracted from documents automatically * **Multi-channel Support**: Works with both email and SMS ## Related Guides Learn how to configure your checklist Fine-tune agent behavior View and manage collected documents Track all document collection activity # Dropoff Follow-up Source: https://docs.getomni.ai/use-cases/dropoff-follow-up **🧗 The Challenge**: When loan applicants start the application process but don't complete it, they often need gentle reminders and guidance to continue. Manual follow-ups are time-consuming and inconsistent. **💡 Our Solution**: Monumint automatically detects when applicants drop off and schedules intelligent, personalized follow-ups based on their specific onboarding status and needs. ## How It Works ### 1. Set Up Your Checklist * Define required documents and information for your loan process * Configure validation rules for each checklist item * Set field types (text, file upload, date, etc.) * Mark which items are required vs optional * Add help text and guidance for applicants Checklist Setup ### 2. Import Drop-off Leads There are a few ways you can import your drop-off leads: * **CSV upload** * **Email imports** * **Webhook imports** * **Manual imports** For more details, please see [Imports](/leads/imports). ### 3. Intelligent Follow-up Scheduling & Personalized Messages AI determines optimal timing and creates contextual messages: * **Smart Timing**: Analyzes applicant's timezone and engagement patterns * **Personalized Content**: References specific missing checklist items and application progress * **Multi-channel Delivery**: Automatically chooses SMS or email based on available contact info You can write custom follow up instructions in the agent workflow prompt. For example, if you want to prioritize collecting all the documents first from the applicants, you could write *"Please focus on collecting all required documentation first before proceeding to other checklist items."* ## Example Scenarios ### Scenario 1: Incomplete Documents * **Trigger**: Applicant uploaded bank statements but missing income verification * **AI Action**: Schedules follow-up for next business day at 10 AM local time * **Message**: "Hi \[Name], thanks for submitting your bank statements! To complete your application, we just need your income verification. You can upload it here: \[link]" ### Scenario 2: Document Review Issues * **Trigger**: Uploaded document failed validation * **AI Action**: Immediate follow-up with specific guidance * **Message**: "Hi \[Name], we received your document but need a clearer photo. Please retake ensuring all corners are visible: \[link]" ## Benefits * **Automated Detection**: System automatically identifies when applicants need follow-up * **Intelligent Timing**: Follow-ups are scheduled at optimal times based on timezone and engagement patterns * **Personalized Messages**: Each follow-up references specific missing items and progress * **Multi-channel**: Works across email and SMS channels ## Related Guides Configure your checklist requirements Learn how to import drop-off leads Customize follow-up behavior Enable automatic follow-ups # Financial Spreading API Source: https://docs.getomni.ai/use-cases/financial-spreading-api Upload a business's financial documents, run a spread, track it to completion, and download the report and Excel workbook Run financial spreads programmatically: upload a business's financial documents, start a spread, track it to completion, and download the finished report and Excel workbook. This guide walks the full loop end to end. Every step is a copy-pasteable `curl`. All requests go to `https://api-v2.getomni.ai` and authenticate with your workspace API key in the `x-api-key` header. Export both once so the examples run as-is: ```bash theme={null} export MONUMINT_API_KEY="sk-..." export MONUMINT_API_URL="https://api-v2.getomni.ai" ``` ## Before you start Three things to have in place before writing integration code: 1. **An API key.** Generate one in [workspace settings](https://platform.getomni.ai/settings/api). Keys are scoped to your workspace: every lead, document, spread, and artifact in this guide is only visible to keys from the same workspace. Requests without a valid `x-api-key` header return `401`. 2. **Leads and documents flowing into Monumint.** A spread always runs against a lead's documents, so decide where those come from first. If you already create leads via the API or a CRM sync and collect documents through Monumint, you're set — skip straight to step 4. If not, steps 2 and 3 show the minimal API calls to create a lead and attach files. 3. **A webhook endpoint (recommended).** To be notified when spreads finish rather than polling, you'll need a public HTTPS endpoint that accepts POST requests and responds `2xx` within 5 seconds. Step 6 covers registering it and authenticating deliveries. ## 1. Overview Financial spreading takes a set of financial documents for one business — tax returns, income statements, balance sheets — and turns them into a standardized, multi-period spread. Monumint classifies each document, extracts the line items, consolidates everything onto a fixed underwriting template, and computes the derived statements (income statement, balance sheet, cash flow) plus summary ratios. A completed spread produces two downloadable artifacts: | Artifact type | Download format | What it is | | ------------- | --------------- | ------------------------------------------------------------------------------------------------- | | `REPORT` | PDF | The paginated analyst report (statements, ratios, per-document detail). | | `SPREADSHEET` | xlsx | The same consolidated data as an Excel workbook, one sheet per statement and per source document. | The consolidated statements are also available as JSON, for integrations that want the numbers rather than a document — see step 8. A spread runs in the background and typically takes a few minutes, driven mostly by document count and page count. You start a run, then either poll its status or wait for a webhook. Spreads are always scoped to a lead — the business you are underwriting — so the flow is: create a lead, upload its documents, start the spread. ## 2. Create a lead A lead represents the business you are spreading. If you already create leads through the API or a CRM sync, reuse the existing lead's id and skip to step 3. ```bash theme={null} curl -sS -X POST "$MONUMINT_API_URL/api/v1/leads" \ -H "x-api-key: $MONUMINT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "firstName": "Jordan", "lastName": "Rivera", "businessName": "Pacific Coast Container Haulers", "email": "jordan@pacificcoast.example" }' ``` The `201` response wraps the created lead under `lead`; keep `lead.id`: ```json theme={null} { "success": true, "lead": { "id": "b1f0…", "businessName": "Pacific Coast Container Haulers" } } ``` ```bash theme={null} export LEAD_ID="b1f0…" ``` ## 3. Upload financial documents Attach the business's financial documents to the lead. You can either upload the files directly (multipart) or pass a list of URLs Monumint will fetch. Only PDF documents are spreadable — other file types are stored on the lead but ignored by the spread. Upload local files (multipart form-data): ```bash theme={null} curl -sS -X POST "$MONUMINT_API_URL/api/v1/documents" \ -H "x-api-key: $MONUMINT_API_KEY" \ -F "leadId=$LEAD_ID" \ -F "files=@/path/to/2023-tax-return.pdf" \ -F "files=@/path/to/2023-financials.pdf" ``` Or reference files by URL (JSON): ```bash theme={null} curl -sS -X POST "$MONUMINT_API_URL/api/v1/documents" \ -H "x-api-key: $MONUMINT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "leadId": "'"$LEAD_ID"'", "fileUrls": [ "https://files.example/2023-tax-return.pdf", "https://files.example/2023-financials.pdf" ] }' ``` The `201` response lists the created documents with their ids: ```json theme={null} { "success": true, "documents": [ { "id": "doc-a…", "filename": "2023-tax-return.pdf" }, { "id": "doc-b…", "filename": "2023-financials.pdf" } ] } ``` These document ids are the ids you'll see everywhere else in this guide: in the spread's `documents` array, in webhook payloads, and as the `documentIds` filter when starting a spread. ## 4. Start the spread Start a run for the lead with [Create Spread](/api-reference/spreads/create-spread). By default it spreads every PDF document on the lead; pass `documentIds` to restrict it to a subset. ```bash theme={null} curl -sS -X POST "$MONUMINT_API_URL/api/v1/spreads" \ -H "x-api-key: $MONUMINT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "leadId": "'"$LEAD_ID"'" }' ``` ### Request body | Field | Type | Required | Description | | ------------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------ | | `leadId` | string | yes | The lead whose documents to spread. | | `documentIds` | string\[] | no | Spread only these documents. Every id must be a document on the lead. Omit to spread all of the lead's PDFs. | ### Response — `201 Created` The run is created and queued immediately; the response returns before any processing happens. ```json theme={null} { "success": true, "spread": { "id": "9f1e…", "status": "IN_PROGRESS", "error": null, "leadId": "b1f0…", "documents": [ { "id": "doc-a…", "filename": "2023-tax-return.pdf", "status": "PROCESSING", "error": null }, { "id": "doc-b…", "filename": "2023-financials.pdf", "status": "PROCESSING", "error": null } ], "artifacts": [], "createdAt": "2026-07-23T18:04:00.000Z", "updatedAt": "2026-07-23T18:04:00.000Z" } } ``` ```bash theme={null} export SPREAD_ID="9f1e…" ``` ### Errors | Status | When | | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | `400` | No `leadId`; a `documentIds` value doesn't resolve to a document on the lead; or the resolved documents contain no PDFs. | | `404` | The `leadId` isn't a lead in your workspace. | | `409` | The lead already has a spread `IN_PROGRESS`. Only one spread per lead runs at a time; wait for it to reach `COMPLETE` or `FAILED` before starting another. | ## 5. Track progress Poll the run with [Get Spread](/api-reference/spreads/get-spread) for its status, per-document progress, and (once finished) its artifacts. ```bash theme={null} curl -sS "$MONUMINT_API_URL/api/v1/spreads/$SPREAD_ID" \ -H "x-api-key: $MONUMINT_API_KEY" ``` ```json theme={null} { "success": true, "spread": { "id": "9f1e…", "status": "IN_PROGRESS", "error": null, "leadId": "b1f0…", "documents": [ { "id": "doc-a…", "filename": "2023-tax-return.pdf", "status": "EXTRACTED", "error": null }, { "id": "doc-b…", "filename": "2023-financials.pdf", "status": "EXTRACTED", "error": null } ], "artifacts": [], "createdAt": "2026-07-23T18:04:00.000Z", "updatedAt": "2026-07-23T18:06:12.000Z" } } ``` ### Run lifecycle A run's `status` is `IN_PROGRESS` from the moment it's created, then resolves to `COMPLETE` or `FAILED`. Each input document also has its own status: `PROCESSING` while the run works on it, ending at `EXTRACTED` (financial data captured), `SKIPPED` (nothing spreadable found), or `FAILED` (that document couldn't be processed). A single failed document doesn't necessarily fail the whole run — the other documents still spread. The run resolves to `FAILED` when it can't produce a spread — most often because every document failed to process or none of them contains a recognizable financial statement, though a processing stage can also fail outright. In every case `error` carries a short, human-readable reason (for example, "No financial statements were found in the uploaded documents…"). Poll until `status` is `COMPLETE` or `FAILED`. A `COMPLETE` status always includes the `artifacts` array with the report and spreadsheet. ## 6. Webhooks (recommended) Polling works, but webhooks let you react the moment a spread finishes without a poll loop. Subscribe once, then receive an HTTP POST for each event. Register a subscription for the three spread events with [Create Webhook](/api-reference/webhooks/create-webhook) (or do the same in the Monumint app under [Settings → Webhooks](https://platform.getomni.ai/settings/webhook)): ```bash theme={null} curl -sS -X POST "$MONUMINT_API_URL/api/v1/webhooks" \ -H "x-api-key: $MONUMINT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.example/webhooks/monumint", "events": ["spread.started", "spread.completed", "spread.failed"], "headers": { "x-shared-secret": "choose-a-random-value" } }' ``` Deliveries are not signed, so `headers` is how you authenticate them: any headers you set on the subscription are sent with every delivery. Set a secret header here and reject requests to your endpoint that don't carry it. ### Events | Event | Fires when | | --------------------------------------------------------------------- | -------------------------------------------------------------------------- | | [`spread.started`](/api-reference/webhooks/events/spread-started) | A run is created and queued, including runs started from the Monumint app. | | [`spread.completed`](/api-reference/webhooks/events/spread-completed) | A run finishes and its report + spreadsheet artifacts are ready. | | [`spread.failed`](/api-reference/webhooks/events/spread-failed) | A run fails. | Every delivery has the same envelope. `actor` is always `null` for spread events; `data` carries the run, with documents keyed by the same document ids as the rest of the API: ```json theme={null} { "event": "spread.completed", "actor": null, "occurredAt": "2026-07-23T18:08:40.000Z", "data": { "spreadId": "9f1e…", "leadId": "b1f0…", "externalLeadId": "crm-4471", "workspaceId": "ws-1…", "status": "COMPLETE", "documents": [ { "id": "doc-a…", "filename": "2023-tax-return.pdf", "status": "EXTRACTED" }, { "id": "doc-b…", "filename": "2023-financials.pdf", "status": "EXTRACTED" } ], "artifacts": [ { "id": "art-report…", "type": "REPORT", "title": "Financial Spread - Pacific Coast Container Haulers" }, { "id": "art-sheet…", "type": "SPREADSHEET", "title": "Financial Spread - Pacific Coast Container Haulers (Excel)" } ] } } ``` `spread.started` carries the same shape at `status: "IN_PROGRESS"` with no `artifacts`. `spread.failed` omits `artifacts` and adds `error`, a short, human-readable reason for the failure. ### Things to know * **`spread.started` fires for every run, not just yours.** If a teammate starts a spread from the Monumint app, your endpoint still receives `spread.started` with the new `spreadId` — record the id, then poll or await the terminal event. * **Respond within 5 seconds.** A delivery that doesn't get a `2xx` within 5 seconds counts as failed and is retried with backoff (roughly 1, 2, 5, 10, then 20 minutes between attempts) for up to 6 total attempts, after which it's marked failed. Acknowledge fast and do heavy work (like downloading artifacts) asynchronously. * **Handle repeat deliveries.** The same event can arrive more than once for a spread: a retry repeats an identical payload, and a regeneration (step 9) legitimately re-emits `spread.completed` with new artifact ids. Don't drop repeats by event name alone — treat each delivery as the run's latest state, keyed by `data.spreadId`, and process it idempotently. * **Test leads don't fire.** Spreads on a test lead emit no webhooks. ## 7. Download the artifacts When a run is `COMPLETE`, its `artifacts` array (from the status poll or the `spread.completed` webhook) holds the ids you download. A `REPORT` downloads as a PDF and a `SPREADSHEET` as an xlsx workbook. Fetch metadata with [Get Artifact](/api-reference/artifacts/get-artifact) (optional — gives you the content type and a suggested filename): ```bash theme={null} curl -sS "$MONUMINT_API_URL/api/v1/artifacts/$ARTIFACT_ID" \ -H "x-api-key: $MONUMINT_API_KEY" ``` ```json theme={null} { "success": true, "artifact": { "id": "art-report…", "type": "REPORT", "title": "Financial Spread - Pacific Coast Container Haulers", "summary": "Consolidated financial spread from 2 document(s).", "leadId": "b1f0…", "createdAt": "2026-07-23T18:08:38.000Z", "contentType": "application/pdf", "filename": "Financial Spread - Pacific Coast Container Haulers.pdf" } } ``` Download the bytes with [Download Artifact](/api-reference/artifacts/download-artifact). Use `-o` to save the file: ```bash theme={null} # Report -> PDF curl -sS "$MONUMINT_API_URL/api/v1/artifacts/$REPORT_ARTIFACT_ID/content" \ -H "x-api-key: $MONUMINT_API_KEY" \ -o spread-report.pdf # Spreadsheet -> xlsx curl -sS "$MONUMINT_API_URL/api/v1/artifacts/$SPREADSHEET_ARTIFACT_ID/content" \ -H "x-api-key: $MONUMINT_API_KEY" \ -o spread.xlsx ``` To list every spread on a lead (for example to find a past run's artifacts), use [List Lead Spreads](/api-reference/spreads/list-lead-spreads). Each entry is the same shape as the single-spread response, including its `artifacts` array: ```bash theme={null} curl -sS "$MONUMINT_API_URL/api/v1/leads/$LEAD_ID/spreads" \ -H "x-api-key: $MONUMINT_API_KEY" ``` The same report and spreadsheet also appear in the Monumint app on the lead's detail page — useful for eyeballing output while you build, without wiring up downloads first. ## 8. Read the figures as JSON When you want to load the numbers into your own system — to store them, run your own credit model, or populate a screen — use [Get Spread Results](/api-reference/spreads/get-spread-results). ```bash theme={null} curl -sS "$MONUMINT_API_URL/api/v1/spreads/$SPREAD_ID/results" \ -H "x-api-key: $MONUMINT_API_KEY" ``` ```json theme={null} { "success": true, "results": { "schemaVersion": 2, "spreadId": "9f1e2d3c-4b5a-6789-0abc-def012345678", "generatedAt": "2026-03-04T17:42:11.000Z", "entityName": "Pacific Coast Container Haulers", "currency": "USD", "statements": { "incomeStatement": { "periods": [ { "id": "e05f7d35-d3fc-57c7-bb32-6dea39143f25", "label": "FY2022", "start": "2022-01-01", "end": "2022-12-31", "basis": "accrual", "annualized": false, "derivedFrom": null, "values": { "netRevenues": { "label": "Net Revenues", "value": 3730000, "kind": "line", "computed": false, "memo": false }, "netIncome": { "label": "Net Income", "value": 612000, "kind": "total", "computed": true, "memo": false } } }, { "id": "48e65bef-2cea-5b97-b94d-86047b4c1b2e", "label": "FY2023", "start": "2023-01-01", "end": "2023-12-31", "basis": "accrual", "annualized": false, "derivedFrom": null, "values": { "netRevenues": { "label": "Net Revenues", "value": 4200000, "kind": "line", "computed": false, "memo": false }, "netIncome": { "label": "Net Income", "value": 714000, "kind": "total", "computed": true, "memo": false } } } ] } } } } ``` Each statement is a list of periods. Every period has a `values` object containing the rows that have figures for it, keyed by row key — a row with no figure for a period simply isn't there. The full key list is in the [endpoint reference](/api-reference/spreads/get-spread-results). To match a period across statements, use `periods[].id`. The same period carries the same id in every block. The income statement may have more periods than the others — it adds an annualized column beside each interim period. Results are only available once a run is `COMPLETE`; before that the endpoint returns `409`. Don't wait on this endpoint — poll the run's status or subscribe to the `spread.completed` webhook (steps 5 and 6), then fetch results when the run completes. A `FAILED` run will never produce results. This endpoint returns the three consolidated statements. For per-document detail, download the workbook. ## 9. Regenerate a spread [Regenerate Spread](/api-reference/spreads/regenerate-spread) rebuilds a finished run from its already-extracted data: the documents are not re-processed; only the consolidation and report run again. Any analyst adjustments recorded on the run inside Monumint are applied, so regenerating is how an integration picks up corrections made in the app. ```bash theme={null} curl -sS -X POST "$MONUMINT_API_URL/api/v1/spreads/$SPREAD_ID/regenerate" \ -H "x-api-key: $MONUMINT_API_KEY" ``` The `202` response returns the run back at `IN_PROGRESS`; on completion the run has new artifact ids. A regenerated run re-emits `spread.started` and `spread.completed` — the second completion carries the new artifact ids, which is why deliveries are processed as state updates rather than dropped as duplicates. Regenerating a run that is still in flight returns `409`, and an unknown spread id returns `404`. ## 10. End-to-end script This bash script chains the whole loop: create a lead, upload a PDF, start the spread, poll until it finishes, then download both artifacts. It needs `curl` and [`jq`](https://jqlang.github.io/jq/). ```bash theme={null} #!/usr/bin/env bash set -euo pipefail API="${MONUMINT_API_URL:-https://api-v2.getomni.ai}" KEY="$MONUMINT_API_KEY" PDF_PATH="${1:?usage: spread.sh }" auth=(-H "x-api-key: $KEY") echo "Creating lead..." lead_id=$(curl -sS -X POST "$API/api/v1/leads" "${auth[@]}" \ -H "Content-Type: application/json" \ -d '{"firstName":"Jordan","lastName":"Rivera","businessName":"Pacific Coast Container Haulers"}' \ | jq -r '.lead.id') echo " lead: $lead_id" echo "Uploading document..." curl -sS -X POST "$API/api/v1/documents" "${auth[@]}" \ -F "leadId=$lead_id" -F "files=@$PDF_PATH" > /dev/null echo "Starting spread..." spread_id=$(curl -sS -X POST "$API/api/v1/spreads" "${auth[@]}" \ -H "Content-Type: application/json" \ -d "{\"leadId\":\"$lead_id\"}" \ | jq -r '.spread.id') echo " spread: $spread_id" echo "Polling..." while true; do spread=$(curl -sS "$API/api/v1/spreads/$spread_id" "${auth[@]}") status=$(echo "$spread" | jq -r '.spread.status') echo " status: $status" case "$status" in COMPLETE) break ;; FAILED) echo "Spread failed: $(echo "$spread" | jq -r '.spread.error')"; exit 1 ;; esac sleep 8 done report_id=$(echo "$spread" | jq -r '.spread.artifacts[] | select(.type=="REPORT") | .id') sheet_id=$(echo "$spread" | jq -r '.spread.artifacts[] | select(.type=="SPREADSHEET") | .id') echo "Downloading artifacts..." curl -sS "$API/api/v1/artifacts/$report_id/content" "${auth[@]}" -o spread-report.pdf curl -sS "$API/api/v1/artifacts/$sheet_id/content" "${auth[@]}" -o spread.xlsx echo "Done: spread-report.pdf, spread.xlsx" ``` # Webhooks Source: https://docs.getomni.ai/webhooks # Webhooks Webhooks allow you to receive real-time notifications about events in your AI Lending workspace. This enables you to integrate Monumint with your existing systems, CRMs, or custom applications. ## Overview Webhooks are HTTP callbacks that send event data to a URL you specify whenever certain events occur in your workspace. This allows you to: * **Sync data** with your CRM or other systems * **Trigger workflows** in external applications * **Monitor activity** in real-time * **Create custom integrations** with your existing tools ## Setting Up Webhooks ### 1. Create a Webhook Endpoint First, set up an endpoint in your application that can receive HTTP POST requests. This endpoint should: * Accept POST requests * Return a 200 status code on success * Handle webhook payloads securely ### 2. Configure Webhook in Monumint 1. Go to your [webhook settings](https://platform.getomni.ai/settings/webhook) 2. Click "Create Webhook" 3. Enter your webhook URL 4. Select the events you want to subscribe to ### 3. Test Your Webhook Use the test functionality to verify your webhook is receiving events correctly. ## Webhook Events Monumint supports the following webhook events: ### Action Log Events * **`action_log.completed`**: Triggered when an action log completes successfully * **`action_log.failed`**: Triggered when an action log fails ### Document Events * **`document.received`**: Triggered when a document is received * **`document.extracted`**: Triggered when document extraction completes ### Lead Events * **`lead.created`**: Triggered when a lead is created * **`lead.updated`**: Triggered when a lead is updated * **`lead.completed`**: Triggered when a lead application is completed ### Spread Events * **`spread.started`**: Triggered when a financial spreading run starts, from the API or the Monumint app * **`spread.completed`**: Triggered when a spreading run completes and its report and spreadsheet artifacts are ready * **`spread.failed`**: Triggered when a spreading run fails See the [Webhook Events API Reference](/api-reference/webhooks/webhook-events) for detailed payload structures. ## Webhook Security Deliveries are not signed. To authenticate them, set custom `headers` on the subscription — for example a shared-secret header — and reject requests to your endpoint that don't carry it. ### Best Practices * Use HTTPS endpoints only * Reject deliveries that don't carry your secret header * Implement idempotency to handle duplicate events * Set up retry logic for failed webhook deliveries * Monitor webhook delivery status ## Webhook Payloads Each webhook event includes: * **Event type**: The type of event that occurred * **Event data**: The relevant data for the event * **Timestamp**: When the event occurred * **Workspace ID**: The workspace where the event occurred ## Handling Webhooks ### Response Requirements Your webhook endpoint should: * Return a `200 OK` status code within 5 seconds * Handle the request asynchronously if processing takes longer * Return appropriate error codes if the request is invalid ### Retry Logic If your endpoint doesn't respond with a 2xx status code within 5 seconds, Monumint will retry the webhook delivery: * Initial retry: After 1 minute * Subsequent retries: Backoff of roughly 2, 5, 10, then 20 minutes * Maximum: 6 total attempts ## Related Guides Manage webhooks via API View all available events and payloads Use webhooks to import leads