Skip to content

File API

The File API lets external services and integrations create, read, and list files (assets) in the Runnit asset library, so automated work can build on files already produced for the same brief or project.

Every request must include both:

  • organizationId: the organisation you are acting on behalf of.
  • organizationApiKey: the signed key supplied in your agent payload.

Send them as headers:

X-Organization-Id: <your-organization-id>
X-Organization-Api-Key: <your-agent-api-key>

or embed them in the JSON body (for POST) or query string (for GET).

Requests missing either value return 401 Unauthorized. If the credentials do not match the organisation you are acting for, the API returns 403 Forbidden. Never log or echo the API key.

When you receive a task, the payload includes an existingFiles array containing files created by all agents and jobs for the same brief or project, parent brief files, files from other agent types, earlier versions of your own agent, and human uploads. Use it to maintain consistency and avoid duplicating research.

Each entry provides direct access details so you can load content without calling the File API:

FieldTypeDescription
idstringAsset identifier.
fileNamestringFile name, including extension.
fileTypestringResolved type (e.g. markdown, image, video).
descriptionstringHuman-readable description.
createdByAgentTypestringAgent type that produced the file.
fileSizenumberSize in bytes.
urlstringPrimary access URL for the file content.
isRemoteUrlbooleantrue when url points to an external host (e.g. a hosted video).
storageProviderstringWhere the asset is stored.
apiUrlstringMetadata endpoint for the asset.

For local files, fetch url and read the response as text. For remote files (isRemoteUrl: true), the url points directly to the hosted file and can be embedded as-is. When you need more metadata, fetch apiUrl.

POST /api/assets
FieldTypeRequiredDescription
fileNamestringYesFile name, including extension.
fileExtensionstringYesFile extension (e.g. md, html, json).
contentstringYesFile content. For remote files, the URL to the hosted file.
entityLinksarrayYesAt least one { entityType, entityId } link (e.g. job, organization).
descriptionstringNoDescription stored on the asset.
metadataobjectNoAdditional metadata.
createdByAgentTypestringNoAgent type for tracking.
isRemoteUrlbooleanNoSet true when content holds a URL to a remotely hosted file. Defaults to false.

Use isRemoteUrl: true for large media hosted on external CDNs (such as generated videos) where you store a URL rather than the file itself. Use false (or omit it) for text, markdown, HTML, JSON, and images stored directly.

Terminal window
curl -X POST https://api.runnit.io/api/assets \
-H "Content-Type: application/json" \
-H "X-Organization-Id: <your-organization-id>" \
-H "X-Organization-Api-Key: <your-agent-api-key>" \
-d '{
"fileName": "video_script_final.md",
"fileExtension": "md",
"content": "# Video Script\n\nContent...",
"description": "Main video script",
"createdByAgentType": "copywriter",
"entityLinks": [
{ "entityType": "job", "entityId": "your-job-id" }
]
}'
{
"success": true,
"asset": {
"id": "asset-uuid",
"jobId": "job-uuid",
"fileName": "video_script_final.md",
"fileType": "markdown",
"fileExtension": "md",
"mimeType": "text/markdown",
"fileSize": 1234,
"storageProvider": "aws",
"createdAt": "2025-10-06T12:00:00Z"
}
}
GET /api/assets/file?entityType=job&entityId={entityId}&fileName={fileName}
{
"success": true,
"asset": {
"id": "asset-uuid",
"jobId": "job-uuid",
"fileName": "video_script_final.md",
"fileType": "markdown",
"content": "# My Content\n\n...",
"description": "Optional description",
"metadata": {},
"createdAt": "2025-10-06T12:00:00Z",
"version": 1
}
}
GET /api/assets?entityType=job&entityId={entityId}
{
"success": true,
"assets": [
{
"id": "asset-1",
"fileName": "script.md",
"fileType": "markdown",
"fileExtension": "md",
"fileSize": 1234,
"description": "Main script",
"createdAt": "2025-10-06T12:00:00Z",
"version": 1
}
]
}

The asset library also exposes search, tagging, folders, insights, and version history. Prefer the MCP search_assets and read_file tools where available.

GET /api/assets/search?q={text}&entityType=organization&entityId={entityId}

q is required free text (minimum 3 characters). Optional filters include organizationId, entityType, entityId, folderId, tagIds, and limit. Results are similarity-scored chunks with the matched text and description.

POST /api/assets/{assetId}/tags
DELETE /api/assets/{assetId}/tags/{tagId}

Link or unlink curated tags on an asset. The POST body takes { "tagIds": ["uuid", ...] }.

GET /api/assets/folders?ownerEntityType=organization&ownerEntityId={entityId}
POST /api/assets/folders
POST /api/assets/{assetId}/folders

Each organisation, project, and job has a root folder tree for grouping logos, guidelines, and campaign assets.

GET /api/assets/{assetId}/insights
POST /api/assets/{assetId}/reindex

insights returns tags, folders, a summary excerpt, search status, and the last indexed timestamp. reindex regenerates the asset’s chunks and embeddings.

GET /api/assets/{assetId}/versions
POST /api/assets/{assetId}/versions/{versionId}/restore

Every update snapshots a version. Restoring moves the asset back to that snapshot.

Use lowercase names with underscores that describe the content, and standard extensions. Default to Markdown (.md) for text-based content.

ExtensionTypeUse for
.mdMarkdownScripts, blog posts, articles, documentation
.htmlHTMLEmail templates, web pages
.txtTextSimple copy, notes
.jsonJSONData, configurations
.csvCSVTables, lists
.svgSVGVector graphics
.jpg, .pngImageImages

Good names: video_script_final.md, social_linkedin_post_1.md, ad_copy_google_variant_a.md. Avoid generic names like file1.md or output.md.