Agent API
The Agent API lets you programmatically launch, monitor, and manage background AI agents that work on your documents. Agents run asynchronously, optionally using a workflow template, and produce structured artifacts (markdown documents or tables) as output.
The API operates on background agents only — interactive chat sessions are not included in list or detail responses.
Typical use-cases:
- Trigger document analysis from an external application or script
- Orchestrate workflows programmatically (e.g. "run submittal review on every new upload")
- Retrieve structured extraction results for downstream processing
Quickstart
Use the steps below, then continue on this page for authentication, lifecycle, and endpoints.
API key
In the Developer Console on your Nomic instance, create a Platform API key that includes the developer scope (covers agents, files, parse, and codes). See API keys.
Skill for your coding agent
Open SKILL.md (plain text, new tab). Select all and copy, then save as SKILL.md in your coding agent's skills folder (for example .cursor/skills/nomic-agent-api/SKILL.md).
Call the API
Use your instance base URL and Authorization: Bearer <key> as described in API overview. Launch, poll, and follow-ups are covered below and in your copied skill.
Authentication
All requests require a Nomic Platform API key with the developer:agent scope.
Pass it as a Bearer token:
curl -H "Authorization: Bearer npk_YOUR_API_KEY" \
https://<your-domain>.nomic.ai/api/v0/agents
Create API keys from the Developer Console in your Platform instance settings.
Agent lifecycle
┌─────────┐
│ waiting │
└────┬────┘
▼
┌─────── running ───────┐
│ │ │
│ ▼ │
│ awaiting_tool │
│ │ │
▼ ▼ ▼
finished stopped failed
└──────────┬───────────┘
│ follow-up
▼
running
| Status | Description |
|---|---|
waiting | Agent is queued and waiting to begin processing |
running | Agent is actively processing |
awaiting_tool | Agent is waiting for an asynchronous tool call to resolve |
finished | Agent completed successfully; artifacts are available |
stopped | Agent was stopped by the user |
failed | Agent encountered an error |
Any agent in a terminal state (finished, stopped, or failed) can be
resumed with a follow-up, which transitions it back to
running.
Endpoints
List agents
GET /api/v0/agents
Scope: developer:agent · Rate limit: Standard (300 req / min)
Returns a paginated list of background agents for the authenticated user.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 20 | Number of agents to return (max 100) |
cursor | string | — | Pagination cursor from previous response |
status | string | — | Filter by status |
workflowId | string | — | Filter by workflow ID. Pass null to exclude agents launched from a workflow. |
Response:
{
"data": [
{
"id": "019abc12-...",
"status": "finished",
"workflowId": "019def34-...",
"projectId": null,
"artifacts": [
{
"id": "019ccc00-...",
"name": "Results",
"type": "MARKDOWN_DOCUMENT",
"createdAt": "2026-04-09T10:35:00.000Z"
}
],
"createdAt": "2026-04-09T10:30:00.000Z",
"updatedAt": "2026-04-09T10:45:00.000Z"
}
],
"nextCursor": null
}
Launch agent
POST /api/v0/agents
Scope: developer:agent · Rate limit: Heavy (30 req / min)
Start a new background agent. The agent runs asynchronously and can be monitored via Get agent.
A simple agent runs from prompt.text, with optional prompt.images
for visual context and optional fileIds scoping the files the agent can read:
curl -X POST https://<your-domain>.nomic.ai/api/v0/agents \
-H "Authorization: Bearer npk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": {
"text": "Summarize the attached drawings and flag anything unusual."
},
"fileIds": ["019aaa00-...", "019aaa01-..."]
}'
Pass workflowId to instead launch a workflow agent — a run of a
pre-built workflow template. Workflows come in two flavors: ones whose
work is driven by a text prompt (same prompt.text shape as a simple
agent), and ones that take files through named input slots. For the
latter, pass inputs in place of prompt. The workflow's own attached
files, tags, and reference artifacts are included automatically; you do
not need to pass them.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
prompt.text | string | Conditional | Text instruction. Required for simple agents and prompt-driven workflow agents. Must be omitted when a workflow declares file-input slots (use inputs instead). |
prompt.images | Array<{ media_type: string, data: string }> | No | Inline images for simple agents and prompt-driven workflow agents. Up to 4 images. Each data value is raw base64 image bytes, not a data URL. |
workflowId | string | No | Workflow ID to run. Omit to launch a simple agent. |
fileIds | string[] | No | Files and folders the agent can read. Simple agents only; not allowed alongside workflowId. |
inputs | Record<string, string[]> | Conditional | Named file inputs — keys are slot names, values are arrays of file IDs. Required for workflow agents whose workflow declares file-input slots. Requires workflowId. |
projectId | string | No | Project to scope the agent to. |
A body that provides neither prompt.text nor workflowId is rejected
with 400. The server also rejects combinations that mix simple-agent
fields with workflow fields — see the field table above.
Supported image media types are image/jpeg, image/png, image/webp, and
image/gif. Each image can be up to 20 MB after base64 decoding. Image prompts
are part of prompt, so they cannot be used with workflows that declare
file-input slots and therefore require inputs instead of prompt.
Example — simple agent with an image prompt:
curl -X POST https://<your-domain>.nomic.ai/api/v0/agents \
-H "Authorization: Bearer npk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": {
"text": "Review this site photo and list visible safety issues.",
"images": [
{
"media_type": "image/jpeg",
"data": "<base64-encoded-image-bytes>"
}
]
}
}'
Example — workflow agent, file-input slots:
curl -X POST https://<your-domain>.nomic.ai/api/v0/agents \
-H "Authorization: Bearer npk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"workflowId": "019def34-...",
"inputs": {
"Drawing Set": ["019aaa00-...", "019aaa01-..."],
"Standards": ["019aaa02-..."]
}
}'
Example — workflow agent, prompt-driven:
curl -X POST https://<your-domain>.nomic.ai/api/v0/agents \
-H "Authorization: Bearer npk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"workflowId": "019abc12-...",
"prompt": {
"text": "Analyze the compliance status of our current project"
}
}'
Response (201 Created):
{
"data": {
"id": "019abc12-...",
"status": "waiting",
"workflowId": "019def34-...",
"projectId": null,
"activeFileIds": ["019aaa00-...", "019aaa01-...", "019aaa02-..."],
"artifacts": [],
"createdAt": "2026-04-09T10:30:00.000Z",
"updatedAt": "2026-04-09T10:30:00.000Z"
}
}
For simple agents the response workflowId is null, and
activeFileIds reflects the files passed in fileIds (plus any added
during the run).
Get agent
GET /api/v0/agents/{id}
Scope: developer:agent · Rate limit: Standard (300 req / min)
Retrieve details of a specific agent. When the agent is finished, the response
includes artifacts.
Response:
{
"data": {
"id": "019abc12-...",
"status": "finished",
"workflowId": "019def34-...",
"projectId": null,
"activeFileIds": ["019aaa00-..."],
"artifacts": [
{
"id": "019ccc00-...",
"name": "Review Results",
"type": "MARKDOWN_DOCUMENT",
"createdAt": "2026-04-09T10:35:00.000Z"
},
{
"id": "019ccc01-...",
"name": "Issues",
"type": "TABLE",
"createdAt": "2026-04-09T10:36:00.000Z"
}
],
"createdAt": "2026-04-09T10:30:00.000Z",
"updatedAt": "2026-04-09T10:45:00.000Z"
}
}
Add follow-up
POST /api/v0/agents/{id}/followup
Scope: developer:agent · Rate limit: Heavy (30 req / min)
Send a follow-up message to an agent in a terminal state (finished,
stopped, or failed). The agent resumes processing with the new
instruction.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
prompt.text | string | Yes | Follow-up instruction |
prompt.images | Array<{ media_type: string, data: string }> | No | Inline images for the follow-up prompt, using the same shape and limits as launch |
Example:
curl -X POST https://<your-domain>.nomic.ai/api/v0/agents/019abc12-.../followup \
-H "Authorization: Bearer npk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": {
"text": "Also check against ADA accessibility requirements"
}
}'
Response (202 Accepted):
Returns the full agent detail. The new turn is kicked off asynchronously —
the pipeline's transition to running races this response, so the
returned status reflects the current DB state and may still be the
prior terminal state for a brief window. Poll Get agent to
observe the next active-to-terminal transition.
Stop agent
POST /api/v0/agents/{id}/stop
Scope: developer:agent · Rate limit: Standard (300 req / min)
Request cancellation of an agent. A stopped agent can be resumed with a follow-up.
Idempotent — stopping an already-terminal (finished, stopped, or
failed) agent returns the agent in its current state without error.
Response (200 OK):
Returns the agent summary. For a waiting agent the transition to
stopped is immediate. For a running agent the transition is
asynchronous (the pipeline writes the final status on cleanup), so the
returned status may still be running — poll Get agent
to observe the final status.
Delete agent
DELETE /api/v0/agents/{id}
Scope: developer:agent · Rate limit: Standard (300 req / min)
Permanently delete an agent session and its messages and attachments. If the agent is currently running, an abort is broadcast first and the server waits briefly for the pipeline to release its internal lock before tearing down the row.
Artifacts produced by the agent are not deleted — their
creatingSessionId is set to null and they remain retrievable via their
own endpoints.
Response: 204 No Content on success, with an empty body.
Error responses
Errors use a standard envelope:
{
"error": "Human-readable description of the problem",
"code": "machine_readable_code"
}
| HTTP status | Code | Description |
|---|---|---|
| 400 | bad_request | Malformed body, missing required fields |
| 401 | unauthorized | Missing or invalid API key |
| 403 | forbidden | Valid key but not the agent's owner |
| 404 | not_found | Agent not found |
| 409 | invalid_state | Operation not allowed in the agent's current status |
| 429 | rate_limited | Too many requests; retry after Retry-After header |
| 500 | internal_server_error | Unexpected server error |
Full example
Upload a file, launch an agent against a workflow, and poll until
completion. Before running this you need a WORKFLOW_ID — obtain one
from the workflow's page in the Platform UI. The example assumes the
workflow has a single file-input slot named "Documents"; for a workflow
without slots, replace the inputs field with
{"prompt": {"text": "..."}}.
import time
import requests
BASE_URL = "https://<your-domain>.nomic.ai/api/v0"
HEADERS = {"Authorization": "Bearer npk_YOUR_API_KEY"}
WORKFLOW_ID = "019def34-..." # ID of the workflow to run
# 1. Upload a file
with open("specs.pdf", "rb") as f:
upload = requests.post(
f"{BASE_URL}/files/upload",
headers=HEADERS,
files={"file": ("specs.pdf", f, "application/pdf")},
)
file_id = upload.json()["id"]
# 2. Launch an agent against the workflow
agent = requests.post(
f"{BASE_URL}/agents",
headers=HEADERS,
json={
"workflowId": WORKFLOW_ID,
"inputs": {"Documents": [file_id]},
},
).json()["data"]
# 3. Poll until the agent reaches a terminal state
while agent["status"] not in ("finished", "failed", "stopped"):
time.sleep(5)
agent = requests.get(
f"{BASE_URL}/agents/{agent['id']}", headers=HEADERS
).json()["data"]
print(f"Status: {agent['status']}")
# 4. Inspect results
if agent["status"] == "finished":
print(f"Agent completed with {len(agent['artifacts'])} artifact(s)")
for ref in agent["artifacts"]:
print(f" - {ref['name']} ({ref['type']})")