Skip to main content

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.

1

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.

2

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).

3

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
StatusDescription
waitingAgent is queued and waiting to begin processing
runningAgent is actively processing
awaiting_toolAgent is waiting for an asynchronous tool call to resolve
finishedAgent completed successfully; artifacts are available
stoppedAgent was stopped by the user
failedAgent 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:

ParameterTypeDefaultDescription
limitnumber20Number of agents to return (max 100)
cursorstringPagination cursor from previous response
statusstringFilter by status
workflowIdstringFilter 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:

FieldTypeRequiredDescription
prompt.textstringConditionalText instruction. Required for simple agents and prompt-driven workflow agents. Must be omitted when a workflow declares file-input slots (use inputs instead).
prompt.imagesArray<{ media_type: string, data: string }>NoInline 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.
workflowIdstringNoWorkflow ID to run. Omit to launch a simple agent.
fileIdsstring[]NoFiles and folders the agent can read. Simple agents only; not allowed alongside workflowId.
inputsRecord<string, string[]>ConditionalNamed file inputs — keys are slot names, values are arrays of file IDs. Required for workflow agents whose workflow declares file-input slots. Requires workflowId.
projectIdstringNoProject 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:

FieldTypeRequiredDescription
prompt.textstringYesFollow-up instruction
prompt.imagesArray<{ media_type: string, data: string }>NoInline 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 statusCodeDescription
400bad_requestMalformed body, missing required fields
401unauthorizedMissing or invalid API key
403forbiddenValid key but not the agent's owner
404not_foundAgent not found
409invalid_stateOperation not allowed in the agent's current status
429rate_limitedToo many requests; retry after Retry-After header
500internal_server_errorUnexpected 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']})")