Docs
Dashboard
API reference / TasksBeta

Create a task

Needs the plan's agentRuns. The plan limits tasks (Free 1) and schedules switched on (Free 0, Hobby 5, Startup 50, Scale no limit): 402 plan_limit beyond. A secret variable has no default (its value is never stored), and a task with one cannot have a schedule. 60 changes per minute per project.

POST/v1/tasks

Request

Method and pathPOST/v1/tasks
Base URLhttps://api.boxline.dev
AuthenticationYour API key in the x-api-key header (or Authorization: Bearer). The examples read it from BOXLINE_API_KEY.
Safe retriesSend an Idempotency-Key header to retry without creating anything twice. See Idempotency keys.
Rate limitYes. See Rate limits for the numbers and headers.

Headers

NameTypeDefaultAllowed valuesDescription
Idempotency-Keystring––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. Required.

NameTypeDefaultAllowed valuesDescription
namerequiredstring––1 to 100 characters.
instructionrequiredstring––What the agent does, with %name% where a variable goes. Up to 20000 characters.
variablesobject[]––Up to 50 items.
variables[].namerequiredstring––Up to 64 characters. Pattern: ^[A-Za-z_][A-Za-z0-9_]*$.
variables[].secretbooleanfalse–The agent types it without seeing it (%name%). Its value is never stored: no default, it comes with every run, and the task cannot have a schedule.
variables[].defaultstring | null––Non-secret variables only. Up to 8000 characters.
variables[].descriptionstring | null––Up to 500 characters.
variables[].originsstring[] | null––Secret variables only (as agent variables' origins). 1 to 20 items.
variables[].shellbooleanfalse–Secret variables only: bash commands may use it.
credentialsstring[]––Credentials (by name) each run gets as placeholders, exactly like credentials on POST /v1/agent/runs: each must exist with scope "agent" or "all" (404 credential_not_found, 400 credential_not_for_ai), may not share a variable's name, and needs allowWithExtensions with extensions. Scheduled tasks may use them. Checked again at every run: a credential deleted since fails the run (credential_not_found). Uses are audited with usedBy task_run. Up to 50 items.
outputobject––Structured output: a JSON Schema (at most 32 KB, 2,000 parts, 32 levels; local $ref only) the answer must match. The model gets a finish tool taking it; an answer that does not match gets one repair try, then the run fails with errorCode output_invalid. Enforced: type, enum, const, properties, required, additionalProperties, items, prefixItems, min/maxItems, uniqueItems, min/maxLength, minimum, maximum, exclusiveMinimum/Maximum, multipleOf, min/maxProperties, allOf, anyOf, oneOf, not, $ref. Given to the model only: pattern, patternProperties, format.
sessionobject––The settings of each run's own session (a SessionSpec, so a task can be shell only: {browser: false, shell: true}). env is stored sealed and read back as names only. A custom proxy's password is never returned.
session.browserboolean | object––true or omitted: a browser with the defaults; false: none; an object: a browser with these settings.
session.browser.modestringstandardstandard, realisticrealistic puts the clock and language on the proxy's country. It never changes what the browser reports about itself.
session.browser.localestring––BCP 47, e.g. de-DE. Wins over the mode.
session.browser.timezonestring––IANA, e.g. Europe/Berlin. Wins over the mode.
session.shellbooleanfalse–A bash shell with Python, Node, ffmpeg and sudo, sharing /workspace.
session.timeoutinteger300–Seconds, up to the plan's maxTimeoutSeconds (402 plan_limit). At least 60.
session.idleTimeoutinteger | null––Opt-in (default off): the session stops (stopReason idle) after this many seconds without activity: 30 to its timeout. Activity: CDP commands through the gateway, live-view input, terminal keys, exec, files calls, actions and steps, scripts, agent steps and messages; an agent run working in the session (or one that can still be resumed) counts the whole time. Checked every few seconds. null switches it off (PATCH). At least 30.
session.keepAlivebooleanfalse–Keep a browser-only session after its last client disconnects.
session.viewportobject––
session.viewport.widthrequiredinteger––From 200 to 3840.
session.viewport.heightrequiredinteger––From 200 to 2160.
session.userMetadataobject––
session.profileobject––
session.profile.idrequiredstring––
session.profile.persistbooleanfalse–Save the browser's logins back into the profile at the end.
session.recordSessionbooleantrue–
session.setupstring[]––Shell commands run in order when the session starts, and again after a resume (needs shell). Up to 20 items.
session.proxyboolean | null | object | object[]––true = a residential US proxy; an object = one proxy; a list = rules by site (at most 10); null or false = none.
session.proxy.typerequiredstring–residential, datacenter, custom
session.proxy.countrystring––Two-letter country code (residential and datacenter).
session.proxy.statestring––Residential, US states, e.g. us_california (implies US).
session.proxy.citystring––Residential, e.g. los_angeles (needs country).
session.proxy.ipstring–sticky, rotatingDefault sticky for sessions and crawls, rotating for fetch, screenshot, pdf and extract.
session.proxy.scopestringbrowserbrowser, allall also routes the session's shell.
session.proxy.serverstring––custom: your proxy, http://host:port or https://host:port, on a public address.
session.proxy.usernamestring––
session.proxy.passwordstring––Stored encrypted; never returned.
session.proxy[].domainPatternstring––Up to 256 characters.
session.captchastring–ask, ignore, solveWhat happens when a CAPTCHA waits for a person. ask (default): agent runs and steps pause and hand over. ignore: they carry on. solve (opt-in, paid plans): the platform tries to solve it first.
session.blockAdsbooleanfalse–Refuse requests to ad and tracker sites inside the machine (its local proxy), with or without a session proxy. Blocked requests are counted in blockedRequests and reported in lifecycle events.
session.cookieBannersstringrejectreject, offreject: answer consent banners of the common platforms with "Reject all" or "Necessary only" (never accept), else hide them, in every tab and frame. Each answer is a lifecycle event.
session.extensionsstring[]––Uploaded extensions (POST /v1/extensions) to load into the browser; needs the plan feature extensions. Up to 10 items.
session.envobject––Variables for the session's shell (needs shell): new terminals, exec, scripts and setup commands get them, and they are set again on every new machine (resume, recovery). Names like the shell's ([A-Za-z_][A-Za-z0-9_]*, not PATH, HOME or BOXLINE_*), 64 KB together. Kept sealed; the session shows the names only.
session.credentialsstring[]––Credentials exported into the shell, one variable per field: a secret as $NAME, a password as $NAME_USERNAME and $NAME_PASSWORD (and boxline-otp NAME prints its 2FA code). Needs shell; the credential needs scope "shell" or "all", or shell true (else 400 credential_not_for_shell). Kept in the machine's memory only (never a file in /workspace), set again on every new machine, and hidden in exec, script and terminal output. Up to 50 items.
allowWithExtensionsbooleanfalse–Needed for a task with secret variables or credentials and a session with extensions (400 variables_with_extensions otherwise).
modelobject––
model.providerstring–anthropic, openai, xai, googleAnthropic Claude, OpenAI, Grok (xAI), Google Gemini. Grok and Gemini have no computer use (mode computer is 400).
model.modelstring––
maxStepsinteger | null30–null: no step limit for its runs. From 1 to 1000.
maxCostUsdnumber | null––Each run's money budget (as maxCostUsd on agent runs); default none. From 0.01 to 100.
notifyOnFailurestring | null–email, nullStored only; emails are not sent yet.
scheduleobject––
schedule.cronstring––Five fields (minute hour day-of-month month day-of-week), names JAN–DEC and SUN–SAT, or @hourly, @daily, @weekly, @monthly, @yearly. At most every 5 minutes.
schedule.timezonestringUTC–An IANA time zone; the cron is read on its clock.
schedule.variablesobject––Values for non-secret variables.
schedule.enabledbooleantrue–
curl -X POST "https://api.boxline.dev/v1/tasks" \  -H "x-api-key: $BOXLINE_API_KEY" \  -H "content-type: application/json" \  -H "Idempotency-Key: $(uuidgen)" \  -d '{    "name": "Books by category",    "instruction": "Open https://books.toscrape.com, open the category %category% and list the books on its first page with their prices",    "variables": [{"name": "category", "default": "Travel"}],    "output": {      "type": "object",      "properties": {        "books": {          "type": "array",          "items": {            "type": "object",            "properties": {"title": {"type": "string"}, "price": {"type": "number"}},            "required": ["title", "price"]          }        }      },      "required": ["books"]    },    "schedule": {"cron": "0 9 * * MON-FRI", "timezone": "Europe/London"}  }'

Responses

201 Created

The task.

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: true when this is the kept response of an earlier request with the same Idempotency-Key. (Idempotency keys)

Fields

NameTypeDefaultAllowed valuesDescription
idstring––
namestring––
instructionstring––
variablesobject[]––
variables[].namestring––Up to 64 characters. Pattern: ^[A-Za-z_][A-Za-z0-9_]*$.
variables[].secretbooleanfalse–The agent types it without seeing it (%name%). Its value is never stored: no default, it comes with every run, and the task cannot have a schedule.
variables[].defaultstring | null––Non-secret variables only. Up to 8000 characters.
variables[].descriptionstring | null––Up to 500 characters.
variables[].originsstring[] | null––Secret variables only (as agent variables' origins). 1 to 20 items.
variables[].shellbooleanfalse–Secret variables only: bash commands may use it.
credentialsstring[]––Names of the credentials its runs get (never values).
outputobject | null––
sessionobject | null––The settings of each run's own session (env as a list of names; the proxy without its password).
session.browserboolean | object––true or omitted: a browser with the defaults; false: none; an object: a browser with these settings.
session.browser.modestringstandardstandard, realisticrealistic puts the clock and language on the proxy's country. It never changes what the browser reports about itself.
session.browser.localestring––BCP 47, e.g. de-DE. Wins over the mode.
session.browser.timezonestring––IANA, e.g. Europe/Berlin. Wins over the mode.
session.shellbooleanfalse–A bash shell with Python, Node, ffmpeg and sudo, sharing /workspace.
session.timeoutinteger300–Seconds, up to the plan's maxTimeoutSeconds (402 plan_limit). At least 60.
session.idleTimeoutinteger | null––Opt-in (default off): the session stops (stopReason idle) after this many seconds without activity: 30 to its timeout. Activity: CDP commands through the gateway, live-view input, terminal keys, exec, files calls, actions and steps, scripts, agent steps and messages; an agent run working in the session (or one that can still be resumed) counts the whole time. Checked every few seconds. null switches it off (PATCH). At least 30.
session.keepAlivebooleanfalse–Keep a browser-only session after its last client disconnects.
session.viewportobject––
session.viewport.widthinteger––From 200 to 3840.
session.viewport.heightinteger––From 200 to 2160.
session.userMetadataobject––
session.profileobject––
session.profile.idstring––
session.profile.persistbooleanfalse–Save the browser's logins back into the profile at the end.
session.recordSessionbooleantrue–
session.setupstring[]––Shell commands run in order when the session starts, and again after a resume (needs shell). Up to 20 items.
session.proxyboolean | null | object | object[]––true = a residential US proxy; an object = one proxy; a list = rules by site (at most 10); null or false = none.
session.proxy.typestring–residential, datacenter, custom
session.proxy.countrystring––Two-letter country code (residential and datacenter).
session.proxy.statestring––Residential, US states, e.g. us_california (implies US).
session.proxy.citystring––Residential, e.g. los_angeles (needs country).
session.proxy.ipstring–sticky, rotatingDefault sticky for sessions and crawls, rotating for fetch, screenshot, pdf and extract.
session.proxy.scopestringbrowserbrowser, allall also routes the session's shell.
session.proxy.serverstring––custom: your proxy, http://host:port or https://host:port, on a public address.
session.proxy.usernamestring––
session.proxy[].domainPatternstring––Up to 256 characters.
session.captchastring–ask, ignore, solveWhat happens when a CAPTCHA waits for a person. ask (default): agent runs and steps pause and hand over. ignore: they carry on. solve (opt-in, paid plans): the platform tries to solve it first.
session.blockAdsbooleanfalse–Refuse requests to ad and tracker sites inside the machine (its local proxy), with or without a session proxy. Blocked requests are counted in blockedRequests and reported in lifecycle events.
session.cookieBannersstringrejectreject, offreject: answer consent banners of the common platforms with "Reject all" or "Necessary only" (never accept), else hide them, in every tab and frame. Each answer is a lifecycle event.
session.extensionsstring[]––Uploaded extensions (POST /v1/extensions) to load into the browser; needs the plan feature extensions. Up to 10 items.
session.envobject––Variables for the session's shell (needs shell): new terminals, exec, scripts and setup commands get them, and they are set again on every new machine (resume, recovery). Names like the shell's ([A-Za-z_][A-Za-z0-9_]*, not PATH, HOME or BOXLINE_*), 64 KB together. Kept sealed; the session shows the names only.
session.credentialsstring[]––Credentials exported into the shell, one variable per field: a secret as $NAME, a password as $NAME_USERNAME and $NAME_PASSWORD (and boxline-otp NAME prints its 2FA code). Needs shell; the credential needs scope "shell" or "all", or shell true (else 400 credential_not_for_shell). Kept in the machine's memory only (never a file in /workspace), set again on every new machine, and hidden in exec, script and terminal output. Up to 50 items.
allowWithExtensionsboolean––
modelobject | null––
model.providerstring–anthropic, openai, xai, googleAnthropic Claude, OpenAI, Grok (xAI), Google Gemini. Grok and Gemini have no computer use (mode computer is 400).
model.modelstring––
maxStepsinteger | null––null: no step limit (30 when the task never set one).
maxCostUsdnumber | null––
notifyOnFailurestring | null––
scheduleobject | null––
schedule.cronstring––
schedule.timezonestring––
schedule.variablesobject––
schedule.enabledboolean––
schedule.nextRunAtstring | null––Null while switched off. Format: date-time.
schedule.nextRunsstring[]––The next 3 times it fires, in UTC (the first is nextRunAt), read on the schedule's time zone and daylight-saving rules; empty while switched off. Up to 3 items.
lastRunAtstring | null––Format: date-time.
lastRunobject | null––
lastRun.idstring––
lastRun.statusstring–queued, running, paused, completed, failed, canceled
lastRun.errorCodestring | null––Why it stopped (max_steps, session_timeout, …), as on its agent run; null while working or when completed.
lastRun.createdAtstring––Format: date-time.
lastRun.finishedAtstring | null––Format: date-time.
createdAtstring––Format: date-time.
updatedAtstring––Format: date-time.
Response 201
{  "id": "task_Hk2Lq8Zx0Vb5Nm1C",  "name": "Work account",  "instruction": "…",  "variables": [    {      "name": "Work account",      "secret": false,      "default": "…",      "description": "…",      "origins": [        "https://*.example.com"      ],      "shell": false    }  ],  "credentials": [    "…"  ],  "output": {    "type": "object",    "properties": {      "title": {        "type": "string"      },      "price": {        "type": "number"      }    },    "required": [      "title",      "price"    ]  },  "session": {    "browser": {      "mode": "standard",      "locale": "…",      "timezone": "…"    },    "shell": false,    "timeout": 300,    "idleTimeout": 30,    "keepAlive": false,    "viewport": {      "width": 200,      "height": 200    },    "userMetadata": {},    "profile": {      "id": "…",      "persist": false    },    "recordSession": true,    "setup": [      "…"    ],    "proxy": {      "type": "residential",      "country": "US",      "state": "…",      "city": "…",      "ip": "sticky",      "scope": "browser",      "server": "…",      "username": "…"    },    "captcha": "ask",    "blockAds": false,    "cookieBanners": "reject",    "extensions": [      "…"    ],    "env": {},    "credentials": [      "…"    ]  },  "allowWithExtensions": false,  "model": {    "provider": "anthropic",    "model": "claude-sonnet-5-5"  },  "maxSteps": 0,  "maxCostUsd": 0,  "notifyOnFailure": "…",  "schedule": {    "cron": "…",    "timezone": "…",    "variables": {},    "enabled": false,    "nextRunAt": "2026-09-29T10:00:00.000Z",    "nextRuns": [      "2026-09-29T10:00:00.000Z"    ]  },  "lastRunAt": "2026-09-29T10:00:00.000Z",  "lastRun": {    "id": "trun_Q2x9L0aPz7NmK3Jb",    "status": "queued",    "errorCode": "…",    "createdAt": "2026-09-29T10:00:00.000Z",    "finishedAt": "2026-09-29T10:00:00.000Z"  },  "createdAt": "2026-09-29T10:00:00.000Z",  "updatedAt": "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.

StatusCodesWhen
400 Bad Requestinvalid_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_tokenThe request is not valid.
401 UnauthorizedunauthorizedMissing or invalid API key.
402 Payment Requiredfeature_not_in_plan, spend_limit, out_of_credit, plan_limit, spend_limit, out_of_credit, organization, project, plan, creditThe 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.
404 Not Foundnot_found, invite_not_found, provider_unavailableNo such thing in this project (or organization), or no such route.
409 Conflictsession_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_progressThe current state does not allow it, or a request with this Idempotency-Key is still being answered.
422 Unprocessable Contentidempotency_mismatchThis Idempotency-Key was already used for a different request.
429 Too Many Requestsrate_limited, concurrency_limitToo many requests, or the organization's concurrent sessions (its plan's) or the project's concurrencyCap are in use.
Error body
{  "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.