Tasks & Output
Dispatch tasks, track progress, and retrieve the files your agents produce.
Tasks and Output
A task is the core unit of work in AgentContainer. You dispatch a task to an agent, the platform runs it inside a sandboxed container, and you retrieve the result through the API. Tasks can run autonomously to completion or stay conversational so you can send follow-up messages on the same task.
Before continuing, make sure you have an API key ready. See the Authentication docs if you need to generate one.
Dispatching a Task
To create a task, send a POST request to the agent's tasks endpoint:
POST https://agentcontainer.co/api/v1/agents/{agentId}/tasksThe request body accepts the following fields:
instructions(required) — The primary instructions the agent should follow. These are written to/workspace/task/TASK.md.versionId— Pin the task to a specific agent version. If omitted, the agent's current active version is used.inputFileIds— An array of file IDs to make available inside the container. See Uploading Input Files below.metadata— An arbitrary JSON object stored alongside the task. Useful for tracking external references or tags.overrides— Per-task overrides for the agent's default configuration. See Per-Task Overrides.
Here is a minimal example that dispatches a task:
curl -X POST https://agentcontainer.co/api/v1/agents/agt_abc123/tasks \
-H "Authorization: Bearer ac_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"instructions": "Analyze the CSV file and produce a summary report in Markdown."
}'A successful response returns the new task object:
{
"id": "tsk_xyz789",
"agentId": "agt_abc123",
"status": "pending",
"instructions": "Analyze the CSV file and produce a summary report in Markdown.",
"createdAt": "2026-03-26T14:00:00.000Z"
}Balance requirement: AgentContainer reserves $0.50 from your balance when a task starts. If your balance is below $0.50, the task will not start and the request will return an error. Visit the Billing docs for details on how credits and usage charges work.
Uploading Input Files
If your task needs input files (datasets, images, configuration files, etc.), you upload them through a two-step process before dispatching the task.
Step 1: Prepare the upload
Call the prepare endpoint with the file name and MIME type. This returns an uploadId, a pre-signed uploadUrl, and the HTTP method and headers to use.
curl -X POST https://agentcontainer.co/api/v1/uploads/prepare \
-H "Authorization: Bearer ac_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"filename": "sales_data.csv",
"contentType": "text/csv"
}'Response:
{
"uploadId": "upl_abc123",
"uploadUrl": "https://uploads.example.com/...",
"method": "PUT",
"headers": {
"content-type": "text/csv"
},
"expiresAt": "2026-04-24T12:00:00.000Z"
}Step 2: Upload the file bytes
Send the raw file contents to the uploadUrl returned in the previous step using the returned method and headers.
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: text/csv" \
--data-binary @sales_data.csvStep 3: Complete the upload
Finalize the upload by sending the uploadId back to AgentContainer. This registers the file and returns a file ID you can reference in tasks. If the prepare response used method POST, include the storageId returned by the upload request. For PUT uploads, omit storageId.
curl -X POST https://agentcontainer.co/api/v1/uploads/complete \
-H "Authorization: Bearer ac_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"uploadId": "upl_abc123"
}'For POST upload URLs, complete with both values:
curl -X POST https://agentcontainer.co/api/v1/uploads/complete \
-H "Authorization: Bearer ac_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"uploadId": "upl_abc123",
"storageId": "kg2..."
}'The response includes a fileId. Pass this ID (or multiple IDs) in the inputFileIds array when you dispatch the task:
curl -X POST https://agentcontainer.co/api/v1/agents/agt_abc123/tasks \
-H "Authorization: Bearer ac_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"instructions": "Analyze the CSV and produce a summary report.",
"inputFileIds": ["file_ghi789"]
}'Task Lifecycle
Every task moves through a well-defined set of statuses:
Autonomous: pending --> running --> finished
| |--> hibernating --> pending
| |--> failed
| |--> cancelled
Conversation: pending --> running --> awaiting_input --> running --> ...
|--> finished
|--> failed
|--> cancelled
|--> expiredpending— The task has been created and is waiting for a container to become available.running— The container is active and the agent is executing the task.awaiting_input— A conversational task has completed its current turn and is waiting for the next user message.hibernating— An autonomous task paused itself, checkpointed its workspace, and stopped container billing until a wake message or timeout resumes it. See Hibernating Tasks.finished— The agent completed the task successfully (calledfinish).failed— The task encountered an unrecoverable error (crash, timeout, or infrastructure failure).cancelled— The task was cancelled by the user before completion.expired— A conversational task timed out while waiting for more input.
Polling for status
Use the task detail endpoint to check on a running task. Poll until the status reaches the state you care about. For autonomous tasks that is usually a terminal state. For conversational tasks you will often poll until awaiting_input before sending the next message.
Conversation follow-up
Conversational tasks keep the same task ID across turns. Send follow-up messages to /api/v1/conversations/:taskId/messages, read the full paginated transcript from that same resource, and use /api/v1/conversations/:taskId/events?stream=true if you want a live streaming view of task and message updates. Streaming still requires authentication using either an Authorization: Bearer ... header or the apiKey query parameter (for browser EventSource clients that cannot send headers).
curl https://agentcontainer.co/api/v1/tasks/tsk_xyz789 \
-H "Authorization: Bearer ac_live_xxxxxxxxxxxx"Cancelling a task
If you need to stop a running task, send a cancel request. The container will be shut down and the task status will move to cancelled.
curl -X POST https://agentcontainer.co/api/v1/tasks/tsk_xyz789/cancel \
-H "Authorization: Bearer ac_live_xxxxxxxxxxxx"See the API Reference for the full response schema of both endpoints.
What Happens Inside the Container
When a task moves to running, AgentContainer provisions a sandboxed Linux container and sets up the workspace. Here is what the agent sees:
~/TASK.md— The task instructions you provided are written to this file. These are the primary instructions the agent reads.~/task_files/— Any input files you attached viainputFileIdsare placed in this directory, using their original file names.~/reference_files/— Reference files configured on the agent (documentation, templates, style guides, etc.) are placed here. These persist across tasks and help the agent understand your project context.
Once the workspace is ready, the task's configured runtime starts running. AgentContainer uses Pi. In autonomous mode the runtime works toward completion. In conversation mode it completes one turn, returns a reply, and can later resume from the same task state when you send another message.
When the agent is done, it calls the finish helper to signal completion and declare output files. This is the only way a task reaches the finished status. See the next section for details on the finish convention.
For more on how agents and runtimes are structured, see the Concepts page.
The finish Convention
The finish command is a helper available inside every AgentContainer container. It is the mechanism the agent uses to signal that work is done and to declare output files. The daemon process running alongside the agent validates the finish request against the task's output policy before accepting it.
Successful completion
When the agent completes the task successfully, it calls finish with the --complete-task flag, a message, and any output files:
finish --complete-task --message "Analysis complete. Report generated." report.md charts.pngIncomplete completion
Sometimes the agent cannot fully satisfy the task — perhaps the input data was malformed, or a required external service was unreachable. In these cases, the agent calls finish with --incomplete-task:
finish --incomplete-task --message "CSV had missing columns; partial analysis attached." partial_report.mdAn incomplete finish is still a controlled completion, not a failure. The task status will be finished in both cases. The difference is recorded in the task metadata so you can distinguish between fully complete and partially complete work. A failed status, by contrast, indicates an uncontrolled exit — a crash, timeout, or infrastructure error.
Output Policies
An output policy defines the rules for what files a task must (or must not) produce. The policy is set on the agent and can be overridden per task. When the agent calls finish, the daemon validates the declared output files against the policy. If the validation fails, the finish request is rejected and the agent must try again.
There are four output policies:
any— Zero or more files, no constraints. This is the default policy. The agent can finish with or without output files.none— The task produces no output files. The agent must callfinishwithout listing any files. This is useful for tasks that perform side effects (sending emails, updating databases) rather than producing artifacts.at_least_one— The agent must declare at least one output file when callingfinish. Use this when you always expect a deliverable from the task.named— The agent must produce specific named outputs. With this policy, the agent uses the--output name=pathsyntax to map logical output names to file paths:
finish --complete-task --message "Done" \
--output report=analysis_report.md \
--output dataset=cleaned_data.csvThe named policy is especially useful when you are building automations that depend on specific output artifacts. The list output files endpoint returns each logical name as outputName, so you can match artifacts without guessing file paths.
Retrieving Output Files
Once a task reaches the finished status, you can list and download its output files.
List output files
Retrieve the list of files the agent declared when it called finish. This endpoint returns output files only, supports limit and cursor for pagination, and includes outputName when the task used the named output policy:
curl https://agentcontainer.co/api/v1/tasks/tsk_xyz789/files \
-H "Authorization: Bearer ac_live_xxxxxxxxxxxx"Response:
{
"data": [
{
"id": "file_out001",
"filename": "analysis_report.md",
"contentType": "text/markdown",
"sizeBytes": 4096,
"createdAt": "2026-03-26T14:03:17.000Z",
"outputName": "report"
},
{
"id": "file_out002",
"filename": "charts.png",
"contentType": "image/png",
"sizeBytes": 102400,
"createdAt": "2026-03-26T14:03:18.000Z",
"outputName": null
}
],
"pageInfo": {
"hasMore": false,
"nextCursor": null
}
}Download a file
Use the file ID to download a specific output file. The response body is the raw file content.
curl https://agentcontainer.co/api/v1/tasks/tsk_xyz789/files/file_out001 \
-H "Authorization: Bearer ac_live_xxxxxxxxxxxx" \
-o report.mdFor the complete file endpoints, including error codes and optional query parameters, see the API Reference.
Per-Task Overrides
Every agent has default settings for provider selection, model choice, agent runtime, internet access, runtime limits, output policy, and runtime region. You can override any of these on a per-task basis by including an overrides object in the task creation request. This is useful when a specific task needs a different provider, model mix, runtime, longer timeout, or a stricter output policy than the agent's defaults.
Runtime compatibility is validated strictly. Task overrides can set runtime: "pi"; Anthropic, OpenRouter, and OpenAI models all run through Pi.
{
"instructions": "Generate a detailed financial model from the uploaded spreadsheet.",
"inputFileIds": ["file_ghi789"],
"overrides": {
"provider": "anthropic",
"providerApiKey": "sk-ant-...",
"runtime": "pi",
"model": "claude-sonnet-4.6",
"weakModel": "claude-3-5-haiku-latest",
"internetAccess": false,
"maxRuntimeSeconds": 1800,
"softFinishAfterSeconds": 1500,
"runtimeRegion": "eu",
"outputPolicy": {
"mode": "at_least_one"
}
}
}The available override fields are:
provider— LLM provider override for this task. Current values areanthropic,openrouter, andopenai.providerApiKey— Provider API key to use for this task. This is write-only and is never returned in API responses.runtime— Agent runtime override for this task. Current value ispi.model— The primary model to use for this task. Overrides the agent's default model.weakModel— Optional lighter-weight model for auxiliary work during the task.internetAccess— Whether the container has outbound internet access. Set tofalsefor tasks that should run in a fully isolated environment.maxRuntimeSeconds— Maximum wall-clock time the task is allowed to run before being terminated. If the task exceeds this limit, it will be marked asfailed.softFinishAfterSeconds— Optional earlier deadline that asks the agent to wrap up and callfinishbefore the hard runtime limit.outputPolicy— The output policy for this specific task. Pass an object such as{ "mode": "at_least_one" }or{ "mode": "named", "files": [{ "name": "report" }] }. See Output Policies above.runtimeRegion— Runtime placement preference. Useeuto keep execution in Europe, oranyto let the platform choose.
Overrides only apply to the individual task — they do not change the agent's default configuration.