Batches
Upload several files in one multipart request and inspect the result.
Use batches when you need to send several one-shot files together. A batch accepts 1–25 files and at most 104,857,600 bytes (100 MiB) in total. Each item uses the one-shot file rules, including path validation and the 100 MiB per-file limit.
Batch object
| Field | Type | Description |
|---|---|---|
type | string | Always batch. |
id | string | Batch ID. |
status | string | completed when every item stored, failed when any item failed. |
total | integer | Number of manifest entries. |
completed | integer | Number of files stored successfully. |
failed | integer | Number of files that failed. |
items | array | Result for each manifest entry. |
items[].part | string | Manifest part name. |
items[].path | string | Stored path without a leading slash. |
items[].file | object | File object when the item completed. |
items[].error | object | Failure details with code and detail when the item failed. |
items[].status | string | Item status when it is still processing. |
created_at | string | ISO 8601 creation time. |
The file, error, and status fields are alternatives for an item. A batch can return 200 with status: "failed"; inspect each item's error. Batch records are retained for 24 hours.
Upload a batch
POST /v1/batch
Upload the manifest and all named file parts in one multipart request. Send an API key with write permission for every target path. A path in a project the key cannot access fails authorization before the batch is created; a new project requires organization-level write permission.
Request body
Use multipart/form-data.
| Field | Type | Required | Description |
|---|---|---|---|
manifest | string | Yes | A JSON array with 1–25 entries. Each entry is { "part": string, "path": string }. part is 1–64 characters matching [A-Za-z0-9_-]; path is 1–2,048 characters and must include a project and filename. |
| Each named part | file | Yes | Include one file field whose name exactly matches every manifest part. Part names must be unique. |
The sum of file sizes and the request body are limited to 104,857,600 bytes. File content types are inferred from filenames; the batch endpoint does not accept per-file metadata fields.
Idempotency header
Idempotency-Key is required and must contain 1–200 characters. Reusing it with the same manifest and file bytes returns the existing batch. Reusing it with a different manifest or bytes returns idempotency_conflict. If a batch was cut short before it finished, the same request completes it: files that were already stored are not stored again.
Returns 200 OK. The batch runs to completion inside the request, so the response is the final result: read status, completed, failed, and items.
Response fields
Returns a batch object.
Request
curl -X POST https://agentfs.cloud/v1/batch \
-H "Authorization: Bearer $AGENTFS_KEY" \
-H "Idempotency-Key: import-2026-03" \
-F 'manifest=[{"part":"readme","path":"docs/readme.md"}]' \
-F "readme=@README.md;type=text/markdown"Response
{
"type": "batch",
"id": "b_5e21",
"status": "completed",
"total": 1,
"completed": 1,
"failed": 0,
"items": [
{
"part": "readme",
"path": "docs/readme.md",
"file": {
"type": "file",
"id": "f_8f2c",
"name": "readme.md",
"path": "docs/readme.md",
"label": null,
"content_type": "text/markdown",
"content_disposition": "inline",
"size_bytes": 48213,
"sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"etag": "etag-readme",
"revision": 1,
"visibility": "unlisted",
"expires_at": null,
"tags": [],
"metadata": {},
"agent_id": null,
"run_id": null,
"url": "https://f.agentfsusercontent.com/f/f_8f2c",
"markdown": "[readme.md](https://f.agentfsusercontent.com/f/f_8f2c)",
"created_at": "2026-03-02T12:00:00.000Z",
"updated_at": "2026-03-02T12:00:01.000Z"
}
}
],
"created_at": "2026-03-02T12:00:00.000Z"
}Errors
batch_too_large (413), unauthorized (401), invalid_agent_label (400), invalid_manifest (400), forbidden (403), idempotency_conflict (409), batch_create_failed (500), batch_item_create_failed (500), batch_update_failed (500), internal_error (500).
Individual item failures are returned inside items[].error; their codes can include the file upload errors documented for POST /v1/files.
Get a batch
GET /v1/batch/:id
Return a batch and check each item result. The API key must have read permission for every path in the manifest.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Batch ID. |
Expired batches are reported as not found.
Response fields
Returns a batch object.
Returns 200 OK.
Request
curl https://agentfs.cloud/v1/batch/b_5e21 \
-H "Authorization: Bearer $AGENTFS_KEY"Response
{
"type": "batch",
"id": "b_5e21",
"status": "completed",
"total": 1,
"completed": 1,
"failed": 0,
"items": [
{
"part": "readme",
"path": "docs/readme.md",
"file": {
"type": "file",
"id": "f_8f2c",
"name": "readme.md",
"path": "docs/readme.md",
"label": null,
"content_type": "text/markdown",
"content_disposition": "inline",
"size_bytes": 48213,
"sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"etag": "etag-readme",
"revision": 1,
"visibility": "unlisted",
"expires_at": null,
"tags": [],
"metadata": {},
"agent_id": null,
"run_id": null,
"url": "https://f.agentfsusercontent.com/f/f_8f2c",
"markdown": "[readme.md](https://f.agentfsusercontent.com/f/f_8f2c)",
"created_at": "2026-03-02T12:00:00.000Z",
"updated_at": "2026-03-02T12:00:01.000Z"
}
}
],
"created_at": "2026-03-02T12:00:00.000Z"
}Errors
unauthorized (401), invalid_agent_label (400), batch_not_found (404), forbidden (403), invalid_manifest (400), internal_error (500).
AgentFS