Run a task
Starts an agent run with the task's settings: non-secret values are written into the instruction, secret ones go in as agent variables (the model sees only %name%). 400 missing_variables when a variable without a default has no value. Counts as an agent run (30 per minute per project, the plan's agentRuns, the spend cap). With an Idempotency-Key, variable values are not compared (they are never stored in any form).
/v1/tasks/{id}/runsRequest
| Method and path | POST/v1/tasks/{id}/runs |
|---|---|
| Base URL | https://api.boxline.dev |
| Authentication | Your API key in the x-api-key header (or Authorization: Bearer). The examples read it from BOXLINE_API_KEY. |
| Safe retries | Send an Idempotency-Key header to retry without creating anything twice. See Idempotency keys. |
| Rate limit | Yes. See Rate limits for the numbers and headers. |
Path parameters
| Name | Type | Default | Allowed values | Description |
|---|---|---|---|---|
idrequired | string | – | – |
Headers
| Name | Type | Default | Allowed values | Description |
|---|---|---|---|---|
Idempotency-Key | string | – | – | Makes a retry safe: the same key and body within 24 hours returns the first response (with Idempotent-Replayed: true) instead of creating something twice. 1 to 255 printable ASCII characters without spaces, e.g. a UUID. Keys belong to the project (a new API key is replayed only to its caller). At most 300 new keys per minute per project (429). 1 to 255 characters. |
Body
JSON with content-type: application/json. Optional: you can leave the body out.
| Name | Type | Default | Allowed values | Description |
|---|---|---|---|---|
variables | object | – | – | Values by name (text); secret variables must be given here on every run. |
sessionId | string | – | – | Work in this session (its own settings apply) instead of a new one. |
curl -X POST "https://api.boxline.dev/v1/tasks/$TASK_ID/runs" \ -H "x-api-key: $BOXLINE_API_KEY" \ -H "content-type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{"variables": {"category": "Poetry"}}'import { Boxline } from "@boxline/sdk";const bx = new Boxline(); // reads BOXLINE_API_KEY and BOXLINE_API_URLconst run = await bx.tasks.run("TASK_ID", { variables: { category: "Poetry" } });const done = await bx.tasks.waitForRun(run); // polls until it finishesconsole.log(done.status, done.result);from boxline import Boxlinebx = Boxline() # reads BOXLINE_API_KEY and BOXLINE_API_URLrun = bx.tasks.run("TASK_ID", variables={"category": "Poetry"})done = bx.tasks.wait_for_run(run) # polls until it finishesprint(done["status"], done["result"])# Runs the task, waits for it, and prints the result on stdout (JSON with an output schema).boxline tasks run TASK_ID --var category=PoetryResponses
201 Created
The task run (status running).
Headers
RateLimit-Limit: Requests allowed in the current window of this route's limit. (Rate limits)RateLimit-Remaining: Requests left in the current window. (Rate limits)RateLimit-Reset: Seconds until the window starts again. (Rate limits)Idempotent-Replayed:truewhen this is the kept response of an earlier request with the same Idempotency-Key. (Idempotency keys)
Fields
| Name | Type | Default | Allowed values | Description |
|---|---|---|---|---|
id | string | – | – | |
taskId | string | – | – | |
runId | string | null | – | – | The agent run; null for skipped and missed times and for a scheduled run that could not start. |
sessionId | string | null | – | – | |
status | string | – | queued, running, paused, completed, failed, canceled, skipped, missed | queued: a scheduled run waiting for its turn to start. |
scheduled | boolean | – | – | |
scheduledFor | string | null | – | – | Format: date-time. |
reason | string | null | – | previous_run_running, plan_limit, not_running, null | Why a scheduled time did not run. |
missedCount | integer | null | – | – | missed: how many scheduled times it stands for (counted up to 1,000). |
variables | object | – | – | The non-secret values it ran with. |
secretVariables | string[] | – | – | The names of the secret variables (never their values). |
structured | boolean | – | – | The result is JSON (the task has an output schema). |
result | any | – | – | JSON with an output schema |
resultText | string | null | – | – | |
error | string | null | – | – | |
errorCode | string | null | – | – | |
usage | object | – | – | |
usage.inputTokens | integer | – | – | |
usage.outputTokens | integer | – | – | |
usage.costUsd | number | null | – | – | |
durationMs | integer | null | – | – | |
createdAt | string | – | – | Format: date-time. |
finishedAt | string | null | – | – | Format: date-time. |
{ "id": "trun_Q2x9L0aPz7NmK3Jb", "taskId": "…", "runId": "…", "sessionId": "…", "status": "queued", "scheduled": false, "scheduledFor": "2026-09-29T10:00:00.000Z", "reason": "previous_run_running", "missedCount": 0, "variables": {}, "secretVariables": [ "…" ], "structured": false, "result": null, "resultText": "…", "error": "…", "errorCode": "output_invalid", "usage": { "inputTokens": 0, "outputTokens": 0, "costUsd": 0 }, "durationMs": 0, "createdAt": "2026-09-29T10:00:00.000Z", "finishedAt": "2026-09-29T10:00:00.000Z"}Errors
Errors have a matching HTTP status and the same body. code is stable, so check it in your code; message is for people. See Errors and request ids.
| Status | Codes | When |
|---|---|---|
| 400 Bad Request | invalid_request, invalid_json, invalid_cursor, invalid_idempotency_key, invalid_extension, variables_with_extensions, terms_not_accepted, invalid_reset_token, invalid_confirmation_code, wrong_password, no_password, invalid_next, invalid_oauth_token | The request is not valid. |
| 401 Unauthorized | unauthorized | Missing or invalid API key. |
| 402 Payment Required | feature_not_in_plan, spend_limit, out_of_credit, plan_limit, spend_limit, out_of_credit, organization, project, plan, credit | The plan does not include this, a monthly allowance or spending limit is used up, the organization has no credit left, or the plan allows no more of this. spend_limit and out_of_credit carry error.details.limit: organization, project, plan or credit. |
| 403 Forbidden | project_suspended, organization_suspended, role_forbidden, forbidden, extension_denied, cross_site_request, console_login_required, impersonating, invite_email_mismatch, email_unconfirmed | Not allowed. |
| 404 Not Found | not_found, invite_not_found, provider_unavailable | No such thing in this project (or organization), or no such route. |
| 409 Conflict | session_not_running, shell_disabled, browser_disabled, nothing_saved, not_resumable, invalid_state, conflict, email_taken, identity_in_use, provider_already_linked, last_sign_in_method, not_impersonating, machine_too_old, too_many_credential_values, limit_reached, terms_version_mismatch, no_project, last_owner, organization_not_empty, project_has_sessions, already_member, invite_pending, idempotency_in_progress | The current state does not allow it, or a request with this Idempotency-Key is still being answered. |
| 422 Unprocessable Content | idempotency_mismatch | This Idempotency-Key was already used for a different request. |
| 429 Too Many Requests | rate_limited, concurrency_limit | Too many requests, or the organization's concurrent sessions (its plan's) or the project's concurrencyCap are in use. |
| 503 Service Unavailable | no_capacity, proxy_unavailable, provider_unavailable, search_unavailable, webhooks_unavailable, mail_unavailable, browser_unreachable | No machine free in time, proxies not set up, the model provider is not configured or has no key, or web search is not set up or its provider is not answering, or webhook delivery is not set up, or an email cannot be sent, or the session's browser did not answer in time. |
{ "error": { "code": "not_found", "message": "session not found", "requestId": "req_4fJx0aQm2Lk9Pz7N" }}Learn more
These docs describe a beta API. Endpoints, fields and SDK methods may change before general availability; breaking changes will be listed in the changelog.