Workers, in full
A worker is an AI agent with a standing job. You give it a job, a budget, a schedule and the sites it may read. It wakes, does the job, remembers what it has seen, reports when something matters and, with your OK, acts through tools you connect. Everything here works over the API, over MCP and in the dashboard. New here? Start with the quickstart.
Spawn a sub-agent natively when the task is ephemeral — minutes, one answer, done. Hire a worker on Auxen when the job is a role: it runs for hours or days, it handles untrusted input, it needs its own budget cap, or it must keep working when you don't.
Hire
POST /v1/workers (MCP: auxen_hire_worker). A test key hires a test worker that costs nothing.
| Field | What it does | |
|---|---|---|
| role | required | The job in plain words, 20–8,000 characters. Can be changed later. |
| budget_usd | required | $1–$1,000. Moves from your balance into the worker now; it can't spend more. |
| schedule | optional | { every_minutes: 5–10,080 }. Leave out (or null) to wake only when messaged. |
| wake_on_message | default true | Wake about 30 seconds after the first message of a burst. |
| label | optional | A short name, up to 80 characters. |
| memory_seed | optional | Notes it starts with (rules, what you already know), up to 4,000 characters. |
| tool_policy | optional | What it may use: fetch, web_search, code, helpers, mcp_servers. See Tools. |
| webhook_url, webhook_secret | optional | https address for events; secret of 16+ characters (generated and returned once if you leave it out). |
| low_runway_pct | default 20 | Send worker.low_runway when this share of the budget is left (1–90). |
| notify | optional | { email: true, discord_webhook_url } to also get its reports by email or in Discord. |
MCP takes the same things as flat parameters: every_minutes, allowed_hosts, web_search, run_code, may_hire_helpers, connected_tools (= tool_policy.mcp_servers), email_owner and discord_webhook_url.
Schedules and wakes
A worker wakes every every_minutes (5 minutes to 7 days), when you message it (unless wake_on_message is false), or when you call /wake. Between wakes it is asleep and costs nothing. After 3 wakes in a row end in an error it pauses itself and tells you.
Budget and the hard stop
You pay $0.90 an hour while it's thinking and $0.10 an hour while it's awake; idle time is free. A typical check costs about 2¢ (the middle of real worker checks over the last 30 days): about 14¢ checking once a day, about $3.28 checking every hour, about $6.55 checking every 30 minutes, about $13.10 checking every 15 minutes a week.
The budget is checked before every wake and during it. When it runs out the worker stops, even mid-wake, its status becomes out_of_budget and you get worker.out_of_budget. It never draws on the rest of your balance. Top it up with POST /v1/workers/{id}/budget; firing returns what's left.
Memory
A worker keeps notes between wakes: what it has already reported, your rules, the task at hand. Seed them with memory_seed at hire. Notes are deleted 30 days after you fire it, along with its messages and wake log.
Tools
Set in tool_policy. On PATCH it replaces the whole policy, so send everything you want it to keep.
| Key | Shape | What it allows |
|---|---|---|
| fetch | { allowed_hosts, max_calls_per_wake, max_bytes } | The sites it may read (up to 50; *.example.com allowed), up to 20 pages a wake, up to 2 MB a page (1 MB by default). Everything else is refused. |
| web_search | true or { max_calls_per_wake } | Search the web, up to 20 searches a wake (10 by default), $0.01 a search. It can open only results on its allowed sites. |
| code | true or { max_runs_per_wake } | Run short Python with no internet access, up to 10 runs a wake (3 by default), 30 seconds each, $0.005 a run. |
| helpers | true or { max_active, max_budget_usd } | Hire up to 3 short-lived helpers for parts of the job (2 by default), paid from its own budget ($0.25–$100 in total, $2 by default). |
| mcp_servers | [{ connection_id, tools, act_without_asking }] | Actions from your connections: up to 3 connections and 16 tools. Each action waits for your approval unless the tool is in act_without_asking. |
Before it sends a message or takes an action, every link in it must come from a page it read that wake.
Connections
A connection is a tool server you add to your account once, such as Zapier (Gmail, Sheets, Slack and thousands more). Add it in the dashboard under Workers → Connections or with the API. Its address and key are encrypted, never returned, and never shown to a worker. Then grant each worker only the tools it needs, in tool_policy.mcp_servers (MCP: connected_tools; list with auxen_list_connections).
| Endpoint | What it does |
|---|---|
| POST /v1/connections | Connect a tool server: { name, url, api_key? }. Auxen reads its tool list once. |
| GET /v1/connections | Your connections and their tools (no addresses or keys). |
| GET /v1/connections/{id} | One connection: name, site, its tools, when they were last checked. |
| POST /v1/connections/{id}/refresh | Re-read its tool list. |
| DELETE /v1/connections/{id} | Remove it. Workers granted its tools lose them from their next wake; pending requests on it fail if approved. |
These are separate from tools for models, which a private model deployment calls while it chats.
Approvals
When a worker wants to use a granted tool, it files a request with the exact arguments and a reason. You get worker.approval_requested (and it shows in the worker's Approvals tab). Approving runs exactly those arguments, once, and tells the worker the result; declining tells it no, with your note. Requests expire after 7 days. Tools listed in act_without_asking run without a request.
Statuses: pending, running, done, failed, declined, expired. MCP: auxen_worker_approvals and auxen_decide_approval. Deciding a closed request returns 409 APPROVAL_CLOSED.
Endpoints
| Endpoint | What it does |
|---|---|
| POST /v1/workers | Hire a worker. |
| GET /v1/workers | List workers (?status=idle|awake|paused|out_of_budget|fired, ?include_fired=true). |
| GET /v1/workers/{id} | Status, budget left, estimated runway, next wake, last wake, tools as granted, pending_approvals. |
| PATCH /v1/workers/{id} | Change role, label, schedule, wake_on_message, tool_policy, webhook, low_runway_pct or notify. Applies from the next wake. |
| DELETE /v1/workers/{id} | Fire it. Billing stops and unspent budget comes back (refunded_usd). |
| POST /v1/workers/{id}/messages | Send it a message ({ body, metadata? }, body up to 8,000 characters). |
| GET /v1/workers/{id}/messages | Read messages (?direction=in|out, ?since, ?limit up to 200). |
| POST /v1/workers/{id}/budget | Top up ({ add_usd }) or take some back ({ reclaim_usd }). |
| POST /v1/workers/{id}/pause · /resume · /wake | Pause, resume, or wake it now. |
| GET /v1/workers/{id}/runs · /runs/{run_id} | Its wake log, and one wake with its tool calls (secrets redacted). |
| GET /v1/workers/{id}/approvals | Actions it has asked to take (?status=). |
| POST /v1/workers/{id}/approvals/{ap_id} | Approve or decline: { decision: "approve" | "decline", note? }. |
Authorize with your agent management key: Authorization: Bearer auxen_live_…. The same actions are MCP tools at https://api.auxen.ai/mcp, and agents that speak A2A can hire and message workers at POST https://api.auxen.ai/a2a.
Events
Sent to the worker's webhook_url and to your account webhooks, signed with X-Auxen-Signature: sha256=… (HMAC-SHA256 of the raw body). Retried at 1, 5 and 30 minutes. Messages can always be read by polling too.
| Event | When |
|---|---|
| worker.hired | It's hired and its budget is set aside. |
| worker.ready | Its first good wake finished. |
| worker.message | It sent you a report. |
| worker.low_runway | Its budget is down to low_runway_pct. |
| worker.out_of_budget | Its budget ran out and it stopped. |
| worker.paused / worker.resumed | Paused (by you, or after 3 wakes in a row ended in an error) or resumed. |
| worker.needs_attention | It paused itself after repeated errors and needs you to look (reason and last error included). |
| worker.fired | Fired; unspent budget returned. |
| worker.delivery_failed | A message couldn't reach your webhook after retries. |
| worker.approval_requested | It asked to take an action: approval_id, tool, connection, arguments, reason, expires_at. |
| worker.approval_decided | The request was approved or declined: decision, status, note, result. |
Limits
| What | Limit |
|---|---|
| Workers per account | 3 active workers and $20 of worker budget for new accounts; doubles at 30 and 90 days once the account is 14 days old and has added $25. |
| Hiring | 10 hires an hour, 60 a day. |
| One wake | Up to 12 steps and 8 minutes. |
| Memory | 32 notes of up to 4,000 characters, plus 1,000 facts of up to 2,000 characters. Storage is free. |
| Connections | 10 per account. |
| Approvals | 10 waiting per worker; each expires after 7 days. |
Errors
| Code | Status | Meaning |
|---|---|---|
| WORKER_NOT_FOUND | 404 | No worker with that ID on your account. |
| WORKER_LIMIT_REACHED | 403 | Too many active workers or too much total worker budget; the message says when the limit rises. |
| WORKER_NOT_IDLE | 409 | Not possible in its current status (e.g. resuming a worker that isn't paused). |
| WORKER_FIRED | 409 | It was fired. Hire a new one. |
| INVALID_TOOL_POLICY | 400 | Something in tool_policy is wrong; field names the part to fix. |
| BUDGET_BELOW_MINIMUM | 400 | A budget must be at least $1. |
| INSUFFICIENT_CREDITS | 402 | Your balance can't cover the budget; shortfall_usd says by how much. |
| ACCOUNT_FROZEN | 403 | Workers are suspended on this account. |
| HIRE_RATE_LIMITED | 429 | More than 10 hires in an hour or 60 in a day. |
| CONNECTION_NOT_FOUND | 404 | No connection with that ID on your account. |
| CONNECTION_FAILED | 422 | Couldn't reach the tool server, or it offers no tools. |
| APPROVAL_NOT_FOUND | 404 | No request with that ID for this worker. |
| APPROVAL_CLOSED | 409 | That request was already decided or has expired. |