Capabilities
Files & Workflows
These endpoints let you discover the IDs you need to launch an agent: list projects you can access, find files by name, upload new ones, and list the workflows available on your instance. The workflow authoring endpoints let you create, edit, test, and release workflows of your own.
List projects
To discover the projectId you pass when
listing workflows or
launching an agent, list the projects available to
your API key:
GET /projects
curl "https://<your-domain>.nomic.ai/api/v0/projects?limit=10" \
-H "Authorization: Bearer $NOMIC_API_KEY"
For the full request and response shape — plus creating projects, updating their metadata, and managing members — see the Projects API.
Search files by name
GET /files/search
Search files readable by the authenticated user by file name. Use the returned
id as a file ID in other API calls.
Scope: developer:files · Rate limit: Standard (300 req / min)
Query parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | Yes | — | Case-insensitive substring to match file names. |
limit | number | No | 10 | Number of files to return. Minimum 1, maximum 50. |
cursor | string | No | — | Pagination cursor from a previous response. |
integrationId | string | No | — | Restrict results to files from a specific integration. |
Response
{
"data": [
{
"id": "019abc12-3456-7890-abcd-ef1234567890",
"name": "quarterly.pdf",
"mimeType": "application/pdf",
"parentId": null,
"path": "Project%20Alpha/reports/quarterly.pdf"
}
],
"nextCursor": null
}
| Field | Type | Description |
|---|---|---|
data | array | Page of matching files. |
id | string (uuid) | File ID. |
name | string | File name. |
mimeType | string | File MIME type. |
parentId | string (uuid) or null | Parent folder ID, or null if at root. |
path | string | Slash-delimited, URL-encoded display path including integration root and file. |
nextCursor | string (uuid) or null | Cursor for the next page, or null when there are no more results. |
Errors
| Status | Cause |
|---|---|
400 | Missing or invalid query parameters. |
401 | Missing or invalid API key. |
403 | API key lacks developer:files scope. |
429 | Standard rate limit exceeded. |
Example
curl "https://<your-domain>.nomic.ai/api/v0/files/search?query=quarterly&limit=10" \
-H "Authorization: Bearer $NOMIC_API_KEY"
Upload a file
POST /files/upload
Upload a file using multipart/form-data. The file is streamed directly to
storage without buffering. Auto-indexable types (PDF and legacy Office) are
queued for processing and return status: "processing". Other types are
immediately ready. Poll Get file status before launching
a workflow that needs the file.
Scope: developer:files · Rate limit: Heavy (30 req / min) · Max file size: 500 MB
Request
Send a multipart/form-data request with the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
file | binary | Yes | The file to upload. |
path | string | No | Slash-delimited path including filename, e.g. reports/2026/quarterly.pdf. Intermediate folders are created automatically. The last segment is used as the filename. |
parentId | string (uuid) | No | UUID of an existing folder to upload into. |
If neither path nor parentId is provided, the file is placed at the root of your file tree.
Response
{
"id": "019abc12-3456-7890-abcd-ef1234567890",
"name": "quarterly.pdf",
"mimeType": "application/pdf",
"size": 1048576,
"fileType": "DOCUMENT",
"parentId": null,
"fileVersionId": "019abc12-3456-7890-abcd-ef1234567891",
"createdAt": "2026-04-05T12:00:00.000Z",
"status": "processing"
}
| Field | Type | Description |
|---|---|---|
id | string (uuid) | File ID. |
name | string | File name. |
mimeType | string | MIME type of the uploaded file. |
size | number | File size in bytes. |
fileType | string | Always "DOCUMENT" for uploaded files. |
parentId | string (uuid) or null | Parent folder ID, or null if at root. |
fileVersionId | string (uuid) | ID of the created file version. Use this to submit a parse job. |
createdAt | string (ISO 8601) | Creation timestamp. |
status | processing | ready | failed | Initial processing status. Poll Get file status until ready or failed. |
Errors
| Status | Cause |
|---|---|
400 | Missing file field, empty file, or Content-Type is not multipart/form-data. |
401 | Missing or invalid API key. |
403 | API key lacks developer:files scope, or parentId is a folder you cannot write to. |
413 | File exceeds the 500 MB size limit. |
503 | Upload integration not configured on this instance. |
Example
curl -X POST "https://<your-domain>.nomic.ai/api/v0/files/upload" \
-H "Authorization: Bearer $NOMIC_API_KEY" \
-F "file=@drawings/floor-plan.pdf" \
-F "path=project-alpha/drawings/floor-plan.pdf"
Get file status
GET /files/{id}/status
Poll whether an uploaded file is ready to attach to an agent or workflow. Use this instead of sleeping for an arbitrary delay after upload.
Scope: developer:files · Rate limit: Standard (300 req / min, shared
with other standard-tier reads)
Suggested poll interval: 1–2 seconds. Stop when status is ready, failed,
or a client-defined deadline expires. A processing response does not promise
that processing will eventually complete.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string (uuid) | File ID returned by upload. |
Response
{
"id": "019abc12-3456-7890-abcd-ef1234567890",
"status": "ready"
}
| Field | Type | Description |
|---|---|---|
id | string (uuid) | File ID. |
status | processing | ready | failed | processing — keep polling. ready — safe to launch. failed — stop. |
Types that are never auto-indexed (CSV, XLSX, DOCX, images, and similar) are
ready as soon as upload returns. A file the caller cannot read is reported as
not found.
Errors
| Status | Cause |
|---|---|
401 | Missing or invalid API key. |
403 | API key lacks developer:files scope. |
404 | File not found or not readable. |
429 | Standard rate limit exceeded. |
Example
import os
import time
import requests
BASE_URL = "https://<your-domain>.nomic.ai/api/v0"
HEADERS = {"Authorization": f"Bearer {os.environ['NOMIC_API_KEY']}"}
upload = requests.post(
f"{BASE_URL}/files/upload",
headers=HEADERS,
files={"file": ("specs.pdf", open("specs.pdf", "rb"), "application/pdf")},
)
file_id = upload.json()["id"]
status = upload.json()["status"]
deadline = time.monotonic() + 300
while status == "processing":
if time.monotonic() >= deadline:
raise TimeoutError("File processing did not finish within 5 minutes")
time.sleep(1)
status = requests.get(
f"{BASE_URL}/files/{file_id}/status", headers=HEADERS
).json()["status"]
if status == "failed":
raise RuntimeError("File processing failed")
# status == "ready" — launch the workflow with file_id
List workflows
GET /api/v0/workflows
Scope: developer:agent · Rate limit: Standard (300 req / min)
List workflows available to the authenticated user. Use the returned id as
workflowId when launching an agent. Each workflow includes its input shape
(requestedFiles) so callers can build launch requests correctly.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | int | 20 | Max results per page (1–100). |
cursor | string | — | Opaque cursor from a previous page. |
projectId | uuid | — | Filter to workflows in a project. |
query | string | — | Case-insensitive substring match on workflow name or description (1–200 characters). |
Response
{
"data": [
{
"id": "019def34-...",
"name": "Submittal Review",
"description": "Reviews submittals against project specifications and codes",
"requestedFiles": [
{
"name": "submittals",
"description": "Submittal PDFs to review",
"optional": false,
"multiple": true
}
]
},
{
"id": "019def35-...",
"name": "Code Compliance Check",
"description": "Checks drawings against applicable building codes",
"requestedFiles": []
}
],
"nextCursor": null
}
| Field | Type | Description |
|---|---|---|
data[].id | uuid | Workflow ID — pass as workflowId when launching. |
data[].name | string | Display name. |
data[].description | string? | Optional description. |
data[].requestedFiles | array | File-input slots. Empty for prompt-only workflows. |
requestedFiles[].name | string | Slot name — use as the key in workflowInputs when launching. |
requestedFiles[].description | string | What this slot expects. |
requestedFiles[].optional | boolean | Whether the slot can be omitted. |
requestedFiles[].multiple | boolean | Whether the slot accepts more than one file. |
nextCursor | string? | Opaque cursor for the next page, or null if there are no more results. |
Errors
| Status | Cause |
|---|---|
401 | Missing or invalid API key. |
403 | API key lacks developer:agent scope. |
429 | Standard rate limit exceeded. |
Example
curl "https://<your-domain>.nomic.ai/api/v0/workflows?limit=10" \
-H "Authorization: Bearer $NOMIC_API_KEY"
Workflow authoring
These endpoints create and edit workflows the same way the workflow builder
does. Every save writes a version; agents launched from a workflow run its
released version unless you pass workflowVersionId. A typical loop:
- Create a workflow or update one.
Both return the
versionIdthey wrote, which is not released yet. - Launch an agent with
workflowIdand thatversionIdasworkflowVersionIdto test it. - Release the version once it works.
Writes require the developer:workflows scope; reads use developer:agent.
Reading a workflow's full definition or its versions, editing it, and releasing
it all require edit access to the workflow. A caller who can run a workflow but
not edit it gets 403.
Create a workflow
POST /api/v0/workflows
Scope: developer:workflows · Rate limit: Write (60 req / min)
Create a workflow owned by the caller, private to them, with an unreleased first version. Context files and tags are attached in the builder UI.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Workflow name shown in the workflow list (1–200 characters). |
instructionMarkdown | string | Yes | The Instructions field: the complete behavior of the workflow, in Markdown. Refer to input slots by name and to linked artifacts by path, e.g. /artifacts/Scoring Rubric.md. |
description | string | null | No | One-line description shown on the workflow card. |
metadata | object | No | Display metadata: greeting, placeholder, icon, workflowClass (a short category label such as Review), inputs, and outputs (human summaries). |
mode | low | medium | high | xhigh | No | Reasoning effort. Defaults to medium. |
model | string | No | Model the workflow runs with, e.g. claude-sonnet-5-5, or auto to let the platform choose. |
requestedFiles | array | No | Up to 20 file-input slots, each { name, description, optional?, multiple? }. Callers pass files under name in workflowInputs. Omit for a prompt-only workflow. |
capabilities | object | No | Extra tools, in the same shape as launch capabilities. Checked against what your organization has enabled. |
linkedArtifacts | Array<{ name: string, content: string }> | No | Up to 20 Markdown reference artifacts (rubrics, templates, examples) linked to the workflow. The agent reads each at /artifacts/<name>.md. |
projectId | uuid | No | Project to create the workflow in. Requires write access to the project. Omit for an organization-scoped workflow. |
Example:
curl -X POST "https://<your-domain>.nomic.ai/api/v0/workflows" \
-H "Authorization: Bearer $NOMIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Submittal Review",
"instructionMarkdown": "Review each file in Submittals against /artifacts/Checklist.md and list every deviation.",
"requestedFiles": [
{ "name": "Submittals", "description": "Submittal PDFs to review", "multiple": true }
],
"linkedArtifacts": [
{ "name": "Checklist", "content": "- Fire rating stated\n- Model numbers match the spec" }
]
}'
Response:
{
"data": {
"id": "019def34-...",
"versionId": "019def40-...",
"version": 1,
"createdNewVersion": true,
"linkedArtifacts": [{ "id": "019ccc10-...", "name": "Checklist" }],
"builderPath": "/workflows/019def34-.../edit"
}
}
| Field | Type | Description |
|---|---|---|
id | uuid | Workflow ID — pass as workflowId. |
versionId | uuid | The version just written. Pass it as workflowVersionId when launching to test it before releasing. |
version | integer | Version number. |
createdNewVersion | boolean | false when an unreleased, never-run draft was edited in place; true when a new version was created. |
linkedArtifacts | array | { id, name } of each artifact linked to the version. |
builderPath | string | Path of the workflow builder on this instance. |
Errors:
| Status | Cause |
|---|---|
400 | Validation error, or a capability is not available. |
401 | Missing or invalid API key. |
403 | API key lacks developer:workflows, or no write access to the project. |
404 | No project with that ID is visible to the caller. |
429 | Write rate limit exceeded. |
Get a workflow
GET /api/v0/workflows/{workflowId}
Scope: developer:agent · Rate limit: Standard (300 req / min)
Get one version of a workflow in full: instructions, input slots, model, effort, capabilities, and linked artifacts.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
versionId | uuid | — | Version to return. Omit for the latest version, which is the unreleased draft when one exists. |
Response: data holds the workflow — id, name, description,
metadata, projectId, isPublic, isShared, isArchived,
releasedVersionId, latestVersionId, and builderPath — plus version, the
requested version: id, version, isReleased, instructionMarkdown,
mode, model, requestedFiles, capabilities, and linkedArtifacts
(id, name, type, content). When latestVersionId differs from
releasedVersionId, the latest version is an unreleased draft. isShared is
true when anyone besides the owner can run the workflow.
Errors: 403 if you can run the workflow but not edit it; 404 if the
workflow or version is not found.
List workflow versions
GET /api/v0/workflows/{workflowId}/versions
Scope: developer:agent · Rate limit: Standard (300 req / min)
List every version of a workflow, newest first, with its run count and cost.
Read a version's content with Get a workflow and versionId.
Response:
{
"data": [
{
"id": "019def41-...",
"version": 2,
"isReleased": false,
"createdAt": "2026-04-09T10:30:00.000Z",
"updatedAt": "2026-04-09T11:05:00.000Z",
"changeNote": null,
"authorEmail": "alice@example.com",
"runCount": 3,
"averageCostUsd": 0.42,
"totalCostUsd": 1.26
}
]
}
runCount counts agents launched on the version by anyone. updatedAt changes
without a new version number when a draft is edited in place.
Errors: 403 if you can run the workflow but not edit it; 404 if no
workflow with that ID is visible to you.
Update a workflow
POST /api/v0/workflows/{workflowId}
Scope: developer:workflows · Rate limit: Write (60 req / min)
Write a new candidate version, as saving in the builder does. Takes the same
fields as Create a workflow except projectId, all
optional, plus baseVersionId. Fields you leave out are copied from
baseVersionId (default: the latest version). Nothing is released.
| Field | Type | Description |
|---|---|---|
baseVersionId | uuid | Version to start from. Omit to start from the latest version; pass an earlier one to branch from it, e.g. to abandon a candidate that did worse. |
metadata | object | Merged into the current metadata; null clears a field. |
capabilities | object | Merged into the current capabilities; pass false to turn one off. |
requestedFiles | array | Replaces the input slots. A slot keeps its identity while its name is unchanged. |
linkedArtifacts | array | Replaces the linked artifacts. Pass { "id": ... } to keep an artifact or { "name", "content" } to add one. To change one, drop its id and pass new content under the same name. |
The latest version is edited in place only when it is an unreleased draft that no agent has run and you start from it; otherwise a new version is created, so every run stays tied to the content it ran. The response has the same shape as Create a workflow.
Errors: 400 for a validation error, an artifact id not linked to the
base version, or an unavailable capability; 403 if you can run the workflow
but not edit it; 404 if the workflow or base version is not found; 409 if
the workflow is archived.
Release a workflow version
POST /api/v0/workflows/{workflowId}/versions/{versionId}/release
Scope: developer:workflows · Rate limit: Write (60 req / min)
Make a version the one everyone who can run the workflow gets by default —
forward to a new version or back to an earlier one. Sharing is unchanged, but on
a shared workflow (isShared: true) this changes what other people run.
Response:
{
"data": {
"id": "019def34-...",
"releasedVersionId": "019def41-...",
"version": 2,
"previousReleasedVersionId": "019def40-..."
}
}
To roll back, release previousReleasedVersionId again.
Errors: 403 if you can run the workflow but not edit it; 404 if the
workflow or version is not found; 409 if the workflow is archived.