API documentation
Everything your developers need to connect Aurora’s AI agents to your CRM, ERP or TMS: authentication, tasks, conversations, tools, webhooks, token limits and billing.
The Aurora API lets your CRM, ERP, TMS or any backend hand work to Aurora’s AI agents and receive structured results. Every agent has a fixed set of task types with documented inputs and JSON outputs, so your system can rely on the shape of what comes back.
BASEhttps://api.auroraaisystems.com/v1
Content-Type: application/json with every request body.2026-10-09T08:14:03Z. Billing months start at 00:00 UTC on the 1st.task_, thr_, msg_, tool_, doc_, whk_, evt_, inv_. Agents use readable ids such as carla.699.00.Aurora-Request-Id header. Quote it when you contact support.| Agent id | Agent | Main task types |
|---|---|---|
| carla | Carla — Transport Request Coordinator | transport_request.extract, transport_request.qualify |
| rio | Rio — Dispatch & Carrier Coordinator | carrier.match, carrier.request_offers |
| quinn | Quinn — Quote & Pricing Specialist | quote.create, quote.compare_offers |
| victor | Victor — Sales Development Rep | lead.qualify, lead.research |
| mara | Mara — Marketing Manager | content.plan, content.draft |
| sofia | Sofia — Customer Support Lead | ticket.triage, ticket.reply |
| ada | Ada — Accounting Assistant | invoice.extract, invoice.match |
| paul | Paul — Procurement Specialist | rfq.create, offers.compare |
| hugo | Hugo — HR & Recruitment Partner | job_ad.draft, applications.organize |
| lex | Lex — Legal & Compliance Assistant | contract.review, contract.draft |
| iris | Iris — Data & Reporting Analyst | data.ask, report.generate |
| atlas | Atlas — Chief of Staff | task.route, brief.generate |
Your account, agents and integrations are configured with you during onboarding. Test keys are issued after the kickoff and live keys at go-live. Until then, everything on this page can be tried in the sandbox.
Four steps from an email in your inbox to a structured record in your CRM.
Keep keys on your server, as an environment variable. Never put them in a browser, a mobile app or a public repository.
export AURORA_API_KEY="aur_test_…"Ask Carla to turn a client email into a transport request. The metadata comes back unchanged, so you can match the result to your CRM record.
curl https://api.auroraaisystems.com/v1/agents/carla/tasks \
-H "Authorization: Bearer $AURORA_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"type": "transport_request.extract",
"input": {
"channel": "email",
"from": "mihai@agrodelta.example",
"subject": "Truck Pitesti - Lyon",
"body": "Hi, we need a truck from Pitești to Lyon next week, 14 europallets ~9t, not stackable. Can you send a price?"
},
"metadata": {
"crm_record_id": "REQ-2041"
}
}'{
"id": "task_01J9Z3K8R4",
"object": "task",
"agent_id": "carla",
"type": "transport_request.extract",
"status": "queued",
"metadata": {
"crm_record_id": "REQ-2041"
},
"created_at": "2026-10-09T08:14:03Z"
}Register a webhook and receive task.completed, or poll the task until its status is final.
curl https://api.auroraaisystems.com/v1/tasks/task_01J9Z3K8R4 \
-H "Authorization: Bearer $AURORA_API_KEY"{
"id": "task_01J9Z3K8R4",
"object": "task",
"agent_id": "carla",
"type": "transport_request.extract",
"status": "completed",
"output": {
"transport_request": {
"pickup": {
"city": "Pitești",
"country": "RO",
"postcode": null,
"date": null
},
"delivery": {
"city": "Lyon",
"country": "FR",
"postcode": null
},
"cargo": {
"pallet_type": "EUR",
"pallets": 14,
"stackable": false,
"weight_kg": 9000,
"loading_meters": 5.6,
"adr": false
},
"missing_fields": [
"pickup.date",
"delivery.postcode"
],
"language": "en",
"confidence": 0.93
}
},
"handoffs": [
{
"agent_id": "quinn",
"task_id": "task_01J9Z3M2QP",
"type": "quote.create",
"mode": "auto"
}
],
"parent_task_id": null,
"escalation": null,
"error": null,
"usage": {
"input_tokens": 3120,
"output_tokens": 640,
"total_tokens": 3760
},
"metadata": {
"crm_record_id": "REQ-2041"
},
"created_at": "2026-10-09T08:14:03Z",
"completed_at": "2026-10-09T08:14:09Z"
}Write output.transport_request into your CRM record. Carla also handed the request to Quinn automatically — her quote arrives as another task.completed event once the client has sent the missing details.
Authenticate every request with a secret key in the Authorization header.
Authorization: Bearer aur_live_4f9c…| Key prefix | Environment | Behaviour |
|---|---|---|
aur_test_ | Sandbox | Same agents and API. 500,000 free tokens per month. Tool calls and webhooks go to your test endpoints. Never invoiced. |
aur_live_ | Production | Real work, metered and invoiced. Issued at go-live. |
Each key can be limited to specific scopes and agents, and can have its own monthly token limit. Available scopes: agents:read, agents:write, tasks:read, tasks:write, threads:write, tools:write, knowledge:write, webhooks:write, usage:read, limits:write, billing:read.
401 authentication_error; a key without the right scope returns 403 permission_denied.| Object | What it is |
|---|---|
| Agent | A configured AI worker with one job. Its manifest combines persona, skills, tools, knowledge, guardrails and limits. |
| Task | One unit of work for one agent: a type, an input and, when finished, a JSON output. Tasks run asynchronously. |
| Thread & message | A conversation — a support chat, a WhatsApp exchange. The thread keeps the history; each message gets the agent’s reply. |
| Tool | An action in your systems that an agent may call, such as finding a customer or creating an order. |
| Knowledge document | A file or text the agent can draw on: tariffs, terms, policies, templates. |
| Handoff | Passing a finished result to the next agent, automatically or after your confirmation. |
| Usage & limits | Tokens metered per model call; they drive alerts, limits and the extra-token line on your invoice. |
| Event | A webhook notification that something happened — a task completed, a limit was reached, an invoice was paid. |
The agent object is the agent’s manifest: how it sounds, what it can do, what it may touch and where it stops. You read all of it; you can change the persona, status and limits.
{
"id": "carla",
"object": "agent",
"name": "Carla",
"title": "Transport Request Coordinator",
"status": "active",
"persona": {
"traits": [
"meticulous",
"calm under volume",
"politely persistent"
],
"tone": {
"formality": 3,
"description": "Warm and precise"
},
"languages": [
"en",
"ro",
"de"
],
"reply_in_sender_language": true,
"signature": "Carla, dispatch desk"
},
"skills": [
"transport_request.extract",
"transport_request.qualify",
"transport_request.follow_up"
],
"tools": [
"crm.find_customer",
"crm.create_request"
],
"knowledge": [
"kb_lanes",
"kb_general_terms"
],
"guardrails": {
"never": [
"quote_prices",
"invent_missing_data"
],
"handover_when": [
"adr_goods",
"oversized_cargo",
"estimated_value_eur > 20000"
]
},
"handoffs": [
{
"on": "transport_request.qualified",
"to": "quinn",
"task_type": "quote.create",
"mode": "auto"
}
],
"limits": {
"monthly_token_limit": null,
"max_output_tokens": 4000
},
"created_at": "2026-10-01T09:00:00Z",
"updated_at": "2026-10-06T15:20:11Z"
}| Parameter | Description |
|---|---|
| id string | Readable agent id, e.g. carla. Never changes, even if you rename the agent. |
| status enum | active, paused or configuring. Paused agents reject new tasks with 409. |
| persona object | Display name, traits, tone (formality 1–5), languages, whether to reply in the sender’s language, and signature. |
| skills array | Task types this agent runs. See the agent reference. |
| tools array | Names of tools this agent may call. |
| knowledge array | Knowledge collections the agent may use. |
| guardrails object | What the agent never does and when it hands over to a person. Read-only. |
| handoffs array | Which result goes to which agent, and how. Read-only. |
| limits object | Monthly token limit for this agent (or null for the shared pool) and maximum output tokens per model call. |
GET/v1/agents
curl https://api.auroraaisystems.com/v1/agents \
-H "Authorization: Bearer $AURORA_API_KEY"GET/v1/agents/{agent_id}
PATCH/v1/agents/{agent_id}
Only the fields below can be changed through the API. Skills, tools, guardrails and handoffs change together with our team, so every change is tested in the sandbox before it reaches your clients.
| Parameter | Description |
|---|---|
| persona.display_name string | The name clients see, e.g. if you rename Carla to fit your brand. |
| persona.tone.formality integer 1–5 | 1 is very formal, 5 is very casual. |
| persona.languages array | ISO 639-1 codes the agent writes in, e.g. ["en","ro","de"]. |
| persona.reply_in_sender_language boolean | Reply in the language of the incoming message when it is in the list. |
| persona.signature string | Sign-off used in outgoing messages, up to 60 characters. |
| status enum | active or paused. |
| limits.monthly_token_limit integer or null | Monthly cap for this agent within your pool. |
| limits.max_output_tokens integer | Up to 4,000 unless agreed otherwise. |
curl -X PATCH https://api.auroraaisystems.com/v1/agents/carla \
-H "Authorization: Bearer $AURORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"persona": {
"tone": {
"formality": 2
},
"signature": "Carla, dispatch desk — Northline Logistics"
}
}'A task is one unit of work for one agent. Tasks run asynchronously: create one, then receive the result by webhook or by polling.
POST/v1/agents/{agent_id}/tasks
| Parameter | Description |
|---|---|
| type string required | A task type the agent supports, e.g. transport_request.extract. |
| input object required | Input for the task type. Fields per type are listed in the agent reference; invalid input returns 422. |
| metadata object | Up to 20 key–value pairs returned unchanged, e.g. your CRM record id. |
| callback_url string | Send this task’s events to this URL instead of your registered webhooks. |
| thread_id string | Attach the task to a conversation so the agent sees its history. |
| priority enum | normal (default) or high. |
| handoff enum | auto, suggest or none. Defaults to the agent’s manifest. |
| max_output_tokens integer | Lower the output limit for this task. |
Send an Idempotency-Key header so a retried request never creates a duplicate task. The response is 202 Accepted with the task in status queued.
{
"id": "task_01J9Z3K8R4",
"object": "task",
"agent_id": "carla",
"type": "transport_request.extract",
"status": "completed",
"output": {
"transport_request": {
"pickup": {
"city": "Pitești",
"country": "RO",
"postcode": null,
"date": null
},
"delivery": {
"city": "Lyon",
"country": "FR",
"postcode": null
},
"cargo": {
"pallet_type": "EUR",
"pallets": 14,
"stackable": false,
"weight_kg": 9000,
"loading_meters": 5.6,
"adr": false
},
"missing_fields": [
"pickup.date",
"delivery.postcode"
],
"language": "en",
"confidence": 0.93
}
},
"handoffs": [
{
"agent_id": "quinn",
"task_id": "task_01J9Z3M2QP",
"type": "quote.create",
"mode": "auto"
}
],
"parent_task_id": null,
"escalation": null,
"error": null,
"usage": {
"input_tokens": 3120,
"output_tokens": 640,
"total_tokens": 3760
},
"metadata": {
"crm_record_id": "REQ-2041"
},
"created_at": "2026-10-09T08:14:03Z",
"completed_at": "2026-10-09T08:14:09Z"
}| Status | Meaning |
|---|---|
queued | Accepted and waiting to run. |
running | The agent is working on it. |
requires_action | The agent called a tool in client mode and is waiting for your result. See submit tool outputs. |
completed | Finished; output holds the result. |
escalated | A guardrail handed the work to a person. escalation holds the reason and a summary for your team. |
failed | Could not finish; error explains why. Failures caused by our side aren’t billed. |
cancelled | Cancelled by you. Tokens already used are billed. |
GET/v1/tasks/{task_id}
GET/v1/tasks
| Parameter | Description |
|---|---|
| agent_id string | Only tasks of this agent. |
| status enum | Only tasks in this status. |
| type string | Only this task type. |
| created_after / created_before timestamp | Time window. |
| limit / cursor integer / string | See pagination. |
POST/v1/tasks/{task_id}/tool_outputs
When an agent calls a tool registered in client mode, the task pauses in requires_action and you receive task.requires_action:
{
"id": "task_01J9Z3K8R4",
"object": "task",
"agent_id": "carla",
"status": "requires_action",
"required_action": {
"type": "submit_tool_outputs",
"tool_calls": [
{
"id": "call_7Hk2",
"tool": "crm.find_customer",
"arguments": {
"email": "mihai@agrodelta.example"
}
}
]
}
}curl https://api.auroraaisystems.com/v1/tasks/task_01J9Z3K8R4/tool_outputs \
-H "Authorization: Bearer $AURORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tool_outputs": [
{
"tool_call_id": "call_7Hk2",
"output": {
"customer_id": "C-1042",
"name": "Agro Delta SRL",
"payment_terms_days": 30
}
}
]
}'POST/v1/tasks/{task_id}/cancel
Tasks in queued, running or requires_action can be cancelled. Tokens already used are billed.
Use threads for conversations — a support chat, a WhatsApp exchange, an internal assistant. The thread keeps the history; each message you send returns the agent’s reply.
POST/v1/threads
| Parameter | Description |
|---|---|
| agent_id string required | The agent that owns the conversation, e.g. sofia. |
| channel enum | chat, email, whatsapp or internal. Shapes formatting and length. |
| contact object | Name, email and phone of the person writing. Used to look up data the agent may share with them. |
| metadata object | Returned unchanged. |
curl https://api.auroraaisystems.com/v1/threads \
-H "Authorization: Bearer $AURORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "sofia",
"channel": "whatsapp",
"contact": {
"name": "Mihai Popa",
"phone": "+40700000000"
},
"metadata": {
"crm_contact_id": "C-1042-01"
}
}'POST/v1/threads/{thread_id}/messages
curl https://api.auroraaisystems.com/v1/threads/thr_01J9ZC6Y2B/messages \
-H "Authorization: Bearer $AURORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"role": "user",
"content": "Hello, where is our shipment to Lyon?",
"stream": false
}'{
"id": "msg_01J9ZC7T1D",
"object": "message",
"thread_id": "thr_01J9ZC6Y2B",
"role": "agent",
"agent_id": "sofia",
"content": "Hi Mihai! Your shipment SHP-5530 left Pitești on 14 October and is now near Dijon. The driver’s ETA in Lyon is today at 16:30.",
"handover": false,
"sources": [
"tms:shipment:SHP-5530"
],
"usage": {
"input_tokens": 2210,
"output_tokens": 96,
"total_tokens": 2306
},
"created_at": "2026-10-16T13:02:44Z"
}If handover is true, the agent has stopped and a person should continue; the message content tells the client so, and task.escalated carries the summary for your team.
Set "stream": true to receive the reply as server-sent events (text/event-stream) while it’s written. Events: message.delta, message.completed and error.
event: message.delta
data: {"delta":"Hi Mihai! Your shipment SHP-5530 "}
event: message.delta
data: {"delta":"left Pitești on 14 October and is now near Dijon…"}
event: message.completed
data: {"id":"msg_01J9ZC7T1D","handover":false,"usage":{"input_tokens":2210,"output_tokens":96,"total_tokens":2306}}GET/v1/threads/{thread_id}/messages
DELETE/v1/threads/{thread_id}
Deleting a thread permanently removes it and all its messages.
Tools let agents act in your systems. You describe an action with a JSON Schema; the agent decides when to call it and with which arguments. Nothing runs in your systems unless you register a tool for it.
POST/v1/tools
| Parameter | Description |
|---|---|
| name string required | Unique name, e.g. crm.find_customer. Letters, digits, dots and underscores. |
| description string required | What the tool does and when to use it. Agents read this, so be specific. |
| input_schema object required | JSON Schema for the arguments. |
| mode enum required | webhook: we call your URL. client: the task pauses and you run the tool. |
| url string | Required in webhook mode. HTTPS only. |
| agents array required | Agent ids allowed to call the tool. |
| timeout_ms integer | How long we wait for your response in webhook mode. Default 10,000, maximum 30,000. |
curl https://api.auroraaisystems.com/v1/tools \
-H "Authorization: Bearer $AURORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "crm.find_customer",
"description": "Find a customer in our CRM by email address or VAT number.",
"mode": "webhook",
"url": "https://crm.yourcompany.example/aurora/tools",
"agents": [
"carla",
"sofia",
"ada"
],
"timeout_ms": 10000,
"input_schema": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email"
},
"vat_id": {
"type": "string"
}
},
"additionalProperties": false
}
}'We send a signed POST to your URL — same signature scheme as webhooks — and wait for your JSON response.
{
"tool": "crm.find_customer",
"tool_call_id": "call_7Hk2",
"task_id": "task_01J9Z3K8R4",
"agent_id": "carla",
"arguments": {
"email": "mihai@agrodelta.example"
}
}{
"output": {
"customer_id": "C-1042",
"name": "Agro Delta SRL",
"payment_terms_days": 30
}
}If your endpoint returns an error or times out, the agent is told the tool failed. It retries once, continues without the result if it safely can, or escalates the task.
The task pauses with status requires_action. Run the action yourself and send the result with submit tool outputs. Use client mode when your system can’t receive inbound calls.
GET/v1/tools
DELETE/v1/tools/{tool_id}
Upload the documents agents should rely on — price lists, terms, policies, templates, past cases. When an agent works on a task, it retrieves the relevant passages and uses your facts instead of general knowledge.
POST/v1/knowledge/documents
| Parameter | Description |
|---|---|
| file file | PDF, DOCX, XLSX, CSV, TXT, MD or HTML, up to 50 MB. Send as multipart/form-data. |
| url / text string | Instead of a file, a public URL to fetch or plain text, as JSON. |
| title string required | Shown in the console and in the agent’s sources. |
| agents array required | Agent ids that may use the document. |
| collection string | Group documents, e.g. kb_lanes. |
curl https://api.auroraaisystems.com/v1/knowledge/documents \
-H "Authorization: Bearer $AURORA_API_KEY" \
-F file=@road-tariffs-2026.xlsx \
-F title="Road tariffs 2026" \
-F "agents[]=quinn" \
-F "agents[]=carla"{
"id": "doc_8KQ2M1",
"object": "knowledge_document",
"title": "Road tariffs 2026",
"status": "processing",
"agents": [
"quinn",
"carla"
],
"bytes": 184320,
"created_at": "2026-10-06T10:41:00Z"
}Status moves from processing to ready or failed, and you receive knowledge.document.ready or knowledge.document.failed. Uploading and indexing is free; passages used in a task count as input tokens.
GET/v1/knowledge/documents
GET/v1/knowledge/documents/{document_id}
DELETE/v1/knowledge/documents/{document_id}
Deleting a document removes the file and its index; agents stop using it.
Agents pass work to each other the way your team does: Carla completes a transport request, Quinn prices it, Rio books the carrier. Handoffs are defined in each agent’s manifest and agreed with you during setup.
| Mode | What happens |
|---|---|
auto | The next task is created automatically, with the finished output as its input. |
suggest | The output includes suggested_handoffs; nothing happens until you confirm. |
none | No handoff; your system decides what comes next. |
POST/v1/tasks/{task_id}/handoff
curl https://api.auroraaisystems.com/v1/tasks/task_01J9Z3K8R4/handoff \
-H "Authorization: Bearer $AURORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "quinn",
"type": "quote.create",
"input_overrides": {
"pricing_rules": "key_accounts"
}
}'Every handoff is recorded in the parent task’s handoffs array and the child task’s parent_task_id, and fires handoff.created. Atlas can coordinate longer chains for you.
Webhooks push events to your system as they happen, so you don’t have to poll.
POST/v1/webhooks
curl https://api.auroraaisystems.com/v1/webhooks \
-H "Authorization: Bearer $AURORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://crm.yourcompany.example/hooks/aurora",
"events": [
"task.completed",
"task.escalated",
"limit.reached",
"invoice.created"
],
"description": "CRM production"
}'{
"id": "whk_3MZ81Q",
"object": "webhook",
"url": "https://crm.yourcompany.example/hooks/aurora",
"events": [
"task.completed",
"task.escalated",
"limit.reached",
"invoice.created"
],
"secret": "whsec_…",
"created_at": "2026-10-06T10:02:00Z"
}| Event | Sent when |
|---|---|
task.completed | A task finished with an output. |
task.failed | A task could not finish. |
task.requires_action | A task waits for your tool result. |
task.escalated | A guardrail handed a task to a person. |
handoff.created | An agent passed work to another agent. |
message.completed | An agent finished a reply in a thread. |
knowledge.document.ready | A document is indexed and in use. |
knowledge.document.failed | A document could not be processed. |
usage.threshold_reached | Usage crossed one of your alert thresholds. |
limit.reached | A token limit or spending cap was reached. |
invoice.created | A new invoice was issued. |
invoice.paid | An invoice was paid. |
invoice.payment_failed | An automatic payment failed. |
agent.updated | An agent’s persona, status or limits changed. |
{
"id": "evt_01J9Z4D2WQ",
"object": "event",
"type": "task.completed",
"created_at": "2026-10-09T08:14:09Z",
"data": {
"object": {
"id": "task_01J9Z3K8R4",
"object": "task",
"agent_id": "carla",
"status": "completed",
"output": {
"transport_request": {
"…": "…"
}
},
"metadata": {
"crm_record_id": "REQ-2041"
}
}
}
}Every webhook and webhook-mode tool call carries an Aurora-Signature header, e.g. t=1760000043,v1=6c1f…. Compute an HMAC-SHA256 with your endpoint secret over {t}.{raw body}, compare it in constant time with v1, and reject requests older than 5 minutes.
import crypto from "node:crypto";
// rawBody: the request body exactly as received, before JSON parsing
export function verifyAuroraSignature(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const t = Number(parts.t);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
const given = Buffer.from(parts.v1 || "", "hex");
const exp = Buffer.from(expected, "hex");
return given.length === exp.length && crypto.timingSafeEqual(given, exp);
}Respond with a 2xx status within 10 seconds, then do the heavy work in the background. Otherwise we retry with exponential backoff for up to 24 hours. Events can arrive more than once or out of order — store the event id and ignore duplicates.
Every model call made for your tasks is metered in tokens. Usage drives your alerts, your limits and the extra-token line on your invoice.
Every task and message returns a usage object, and every response carries these headers:
| Header | Value |
|---|---|
Aurora-Tokens-Used | Tokens used by this request. |
Aurora-Tokens-Remaining | Included tokens left in the current billing month, across your account. |
Aurora-Spend-Remaining | EUR left before your spending cap, when the policy is cap. |
GET/v1/usage
| Parameter | Description |
|---|---|
| period YYYY-MM | Billing month. Defaults to the current one. |
| group_by enum | agent (default), api_key or day. |
curl https://api.auroraaisystems.com/v1/usage?period=2026-10&group_by=agent \
-H "Authorization: Bearer $AURORA_API_KEY"{
"object": "usage",
"period": "2026-10",
"included_tokens": 30000000,
"used_tokens": 18412360,
"remaining_included_tokens": 11587640,
"overage_tokens": 0,
"overage_amount_eur": 0.00,
"by_agent": [
{
"agent_id": "carla",
"input_tokens": 6904112,
"output_tokens": 1301228,
"total_tokens": 8205340,
"tasks": 1874
},
{
"agent_id": "quinn",
"input_tokens": 5140215,
"output_tokens": 964665,
"total_tokens": 6104880,
"tasks": 932
},
{
"agent_id": "rio",
"input_tokens": 3512018,
"output_tokens": 590122,
"total_tokens": 4102140,
"tasks": 611
}
],
"updated_at": "2026-10-19T08:00:00Z"
}Limits decide what happens when your included tokens run out, and keep any single agent or integration from using the whole pool. You set the policy at checkout and can change it at any time; changes take effect immediately.
GET/v1/limits
{
"object": "limits",
"overage_policy": "cap",
"monthly_spend_cap_eur": 500.00,
"alert_thresholds_pct": [
50,
80,
100
],
"alert_emails": [
"finance@yourcompany.example"
],
"agents": {
"carla": {
"monthly_token_limit": 12000000
},
"quinn": {
"monthly_token_limit": null
}
},
"api_keys": {
"key_crm_prod": {
"monthly_token_limit": null
}
},
"rate_limits": {
"requests_per_minute_per_agent": 60,
"tokens_per_minute_per_agent": 200000
},
"max_output_tokens": 4000
}PATCH/v1/limits
| Parameter | Description |
|---|---|
| overage_policy enum | hard_stop: stop at the included tokens. cap: allow extra tokens up to monthly_spend_cap_eur. unlimited: allow extra tokens without a cap. |
| monthly_spend_cap_eur number | Maximum spend on extra tokens per month, excl. VAT. Used with cap. |
| alert_thresholds_pct array | Percentages of included tokens that trigger usage.threshold_reached. |
| alert_emails array | Who receives alert emails. |
| agents.{agent_id}.monthly_token_limit integer or null | Monthly limit for one agent. |
| api_keys.{key_id}.monthly_token_limit integer or null | Monthly limit for one API key. |
curl -X PATCH https://api.auroraaisystems.com/v1/limits \
-H "Authorization: Bearer $AURORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"overage_policy": "cap",
"monthly_spend_cap_eur": 800,
"agents": {
"quinn": {
"monthly_token_limit": 8000000
}
}
}'Rate limits are read-only; contact us to raise them.
| Situation | Response |
|---|---|
Included tokens used up and policy is hard_stop | 402 with code quota_exceeded |
Spending cap reached (policy cap) | 402 with code spend_cap_reached |
| An agent’s monthly limit reached | 402 with code agent_limit_reached, for that agent only |
| An API key’s monthly limit reached | 402 with code key_limit_reached, for that key only |
Tasks already running finish normally. New tasks and messages are rejected until the next billing month or until you raise the limit. A limit.reached event is sent once per limit per month.
{
"error": {
"type": "limit_error",
"code": "spend_cap_reached",
"message": "Monthly spend cap of €500.00 reached. Raise monthly_spend_cap_eur or wait until 1 November 2026.",
"request_id": "req_01J9ZB4N7F"
}
}Read your subscription, preview the next invoice and fetch invoices — for example to book them automatically in your ERP.
GET/v1/billing/subscription
{
"object": "subscription",
"status": "active",
"currency": "EUR",
"agents": [
{
"agent_id": "carla",
"status": "active",
"unit_price": 699.00,
"active_since": "2026-10-06"
},
{
"agent_id": "quinn",
"status": "active",
"unit_price": 699.00,
"active_since": "2026-10-06"
},
{
"agent_id": "rio",
"status": "active",
"unit_price": 699.00,
"active_since": "2026-10-06"
}
],
"current_period": {
"start": "2026-10-01",
"end": "2026-10-31"
},
"overage_price_per_million": 15.00,
"payment_method": {
"type": "sepa_debit",
"last4": "3000"
}
}POST/v1/billing/subscription/agents
curl https://api.auroraaisystems.com/v1/billing/subscription/agents \
-H "Authorization: Bearer $AURORA_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "sofia"
}'The agent is added in status configuring and becomes active once it’s set up for you; billing starts on activation, prorated. If it needs a new integration, we confirm the scope with you first.
DELETE/v1/billing/subscription/agents/{agent_id}
Removes the agent at the end of the current billing month.
GET/v1/billing/upcoming
{
"object": "invoice_preview",
"issue_date": "2026-11-01",
"currency": "EUR",
"lines": [
{
"description": "Agent subscription — November 2026",
"quantity": 3,
"unit_price": 699.00,
"amount": 2097.00
},
{
"description": "Extra tokens — October 2026",
"quantity": 0,
"unit": "1M tokens",
"unit_price": 15.00,
"amount": 0.00
}
],
"subtotal": 2097.00,
"vat": {
"treatment": "domestic",
"rate": 21,
"amount": 440.37
},
"total": 2537.37
}GET/v1/billing/invoices
GET/v1/billing/invoices/{invoice_id}
GET/v1/billing/invoices/{invoice_id}/pdf
{
"id": "inv_2026_11_0042",
"object": "invoice",
"number": "AUR 0142",
"status": "paid",
"issue_date": "2026-11-01",
"due_date": "2026-11-01",
"currency": "EUR",
"subtotal": 2097.00,
"vat_amount": 440.37,
"total": 2537.37,
"payment": {
"method": "sepa_debit",
"status": "succeeded",
"paid_at": "2026-11-04T06:12:00Z"
},
"e_invoice": {
"system": "RO e-Factura",
"status": "accepted"
},
"pdf_url": "https://api.auroraaisystems.com/v1/billing/invoices/inv_2026_11_0042/pdf"
}| Parameter | Description |
|---|---|
| number string | Series and number as issued by our invoicing system. |
| status enum | open, paid, overdue or void. |
| payment object | Method and status of the automatic payment, if any. |
| e_invoice object or null | For Romanian companies: pending, sent, accepted or rejected in e-Factura. |
Errors use standard HTTP status codes and a consistent JSON body.
{
"error": {
"type": "validation_error",
"code": "missing_field",
"message": "input.body is required when input.channel is \"email\".",
"param": "input.body",
"request_id": "req_01J9ZA2K5C"
}
}| Status | Type | When |
|---|---|---|
| 400 | invalid_request_error | Malformed JSON, unknown parameter or wrong type. |
| 401 | authentication_error | Missing, invalid or revoked API key. |
| 402 | limit_error | A token limit or spending cap was reached. code says which. |
| 403 | permission_denied | The key lacks the scope or agent access for this request. |
| 404 | not_found | The object doesn’t exist or isn’t visible to this key. |
| 409 | conflict | Idempotency key reused with a different body, or the object’s state doesn’t allow the action. |
| 413 | payload_too_large | Request body or file over the size limit. |
| 422 | validation_error | Input doesn’t match the task type’s schema; param names the field. |
| 429 | rate_limit_error | Too many requests or tokens per minute. |
| 500 | api_error | Something went wrong on our side. Safe to retry with the same Idempotency-Key. |
| 503 | overloaded | Temporary capacity issue. Retry with backoff. |
Every error includes a request_id. Send it to support@auroraaisystems.com if you need help.
By default each agent accepts 60 requests and 200,000 tokens per minute on your account. Higher limits are available on request.
| Header | Meaning |
|---|---|
RateLimit-Limit | Requests allowed in the current window. |
RateLimit-Remaining | Requests left in the window. |
RateLimit-Reset | Seconds until the window resets. |
Retry-After | Sent with 429: seconds to wait before retrying. |
Retry 429 and 503 with exponential backoff and jitter. Don’t retry other 4xx errors without changing the request.
Send an Idempotency-Key header — any unique string, such as a UUID — with POST requests. If the same key arrives again within 24 hours with the same body, you get the original response instead of a duplicate task. The same key with a different body returns 409 conflict.
List endpoints return pages of up to 100 objects (default 20). Pass limit and, for the next page, cursor.
{
"object": "list",
"data": [
{
"id": "task_01J9Z3K8R4",
"object": "task",
"status": "completed"
}
],
"has_more": true,
"next_cursor": "c_9f3a1e"
}Pin a version with the Aurora-Version header, e.g. Aurora-Version: 2026-10-01. Without the header, your account’s version — set at go-live — is used. Breaking changes only ship in new dated versions, announced in the changelog. New fields, event types and task types can appear at any time, so ignore fields you don’t recognise.
Task types and example payloads for each agent. Exact input fields and output schemas for your account — including fields added for your systems during setup — are available in the console and through GET /v1/agents/{agent_id}.
Agent id carla, Operations. Agent page
| Task type | What it does |
|---|---|
transport_request.extract | Turn an email, message or document into a structured transport request |
transport_request.qualify | Check completeness and fit against your lanes and rules |
transport_request.follow_up | Draft or send the message that asks the client for missing details |
{
"type": "transport_request.extract",
"input": {
"channel": "email",
"from": "mihai@agrodelta.example",
"subject": "Truck Pitesti - Lyon",
"body": "Hi, we need a truck from Pitești to Lyon next week, 14 europallets ~9t, not stackable. Can you send a price?"
},
"callback_url": "https://crm.yourcompany.example/hooks/aurora"
}{
"transport_request": {
"pickup": {
"city": "Pitești",
"country": "RO",
"postcode": null,
"date": null
},
"delivery": {
"city": "Lyon",
"country": "FR",
"postcode": null
},
"cargo": {
"pallet_type": "EUR",
"pallets": 14,
"stackable": false,
"weight_kg": 9000,
"loading_meters": 5.6,
"adr": false
},
"missing_fields": [
"pickup.date",
"delivery.postcode"
],
"language": "en",
"confidence": 0.93
}
}Agent id rio, Operations. Agent page
| Task type | What it does |
|---|---|
carrier.match | Shortlist carriers for a load from your own data |
carrier.request_offers | Send price requests to carriers and collect the replies |
shipment.update | Process a status, ETA or delay event and notify the right people |
documents.check | Check CMR, POD and photos for completeness |
{
"type": "carrier.match",
"input": {
"shipment_id": "SHP-5530",
"lane": {
"from": "RO-110",
"to": "FR-69"
},
"vehicle": "tautliner",
"max_buy_price": 1260
}
}{
"candidates": [
{
"carrier_id": "car_118",
"name": "Carpat Trans SRL",
"lane_loads_90d": 4,
"last_price": 1190,
"score": 0.91
},
{
"carrier_id": "car_052",
"name": "Dunav Freight EOOD",
"lane_loads_90d": 2,
"last_price": 1240,
"score": 0.78
}
],
"recommended": "car_118"
}Agent id quinn, Sales & marketing. Agent page
| Task type | What it does |
|---|---|
quote.create | Price a request and produce the offer |
quote.compare_offers | Rank carrier or supplier offers against your rules |
quote.follow_up | Chase open offers and record win or loss reasons |
{
"type": "quote.create",
"input": {
"transport_request_id": "REQ-2041",
"pricing_rules": "default",
"currency": "EUR",
"formats": [
"email",
"pdf"
]
}
}{
"quote": {
"id": "Q-7781",
"sell_price": 1560,
"currency": "EUR",
"breakdown": {
"estimated_buy_price": 1240,
"margin": 320
},
"margin_pct": 20.5,
"valid_until": "2026-10-12T14:00:00Z",
"approval_required": false,
"files": [
{
"type": "pdf",
"file_id": "file_q7781"
}
]
}
}Agent id victor, Sales & marketing. Agent page
| Task type | What it does |
|---|---|
lead.qualify | Score a lead against your ideal customer profile |
lead.research | Summarise what a company does and why it may need you |
outreach.draft | Write a first message or a follow-up sequence |
deal.next_step | Suggest and schedule the next action on a deal |
{
"type": "lead.qualify",
"input": {
"lead": {
"name": "Elena Radu",
"company": "Nordic Pack SRL",
"website": "https://nordicpack.example",
"message": "We’re looking for a partner for weekly groupage to Germany."
},
"criteria": "default"
}
}{
"qualification": {
"score": 82,
"fit": "high",
"segment": "manufacturing",
"reasons": [
"recurring weekly volume",
"lane matches RO to DE groupage"
],
"next_step": {
"type": "call_proposal",
"draft_id": "drf_441"
}
}
}Agent id mara, Sales & marketing. Agent page
| Task type | What it does |
|---|---|
content.plan | Build a content calendar for a period and a goal |
content.draft | Write posts, newsletters, articles or ad copy |
seo.brief | Prepare an SEO brief with search intent and outline |
review.reply | Draft a reply to a review or comment |
{
"type": "content.draft",
"input": {
"format": "social_post",
"channel": "linkedin",
"topic": "Weekly groupage Romania to Germany",
"audience": "operations managers in manufacturing",
"language": "en",
"variants": 2
}
}{
"drafts": [
{
"id": "drf_901",
"text": "Every Thursday a truck leaves Romania for Germany with room for your pallets…",
"status": "waiting_for_approval"
},
{
"id": "drf_902",
"text": "Groupage to Germany shouldn’t mean waiting for a full truck…",
"status": "waiting_for_approval"
}
]
}Agent id sofia, Customer service. Agent page
| Task type | What it does |
|---|---|
ticket.triage | Classify a message by topic and urgency and route it |
ticket.reply | Answer a client message with data from your systems |
claim.intake | Open a claim and collect the required documents |
{
"type": "ticket.reply",
"input": {
"channel": "whatsapp",
"contact": {
"phone": "+40700000000"
},
"message": "Hello, where is our shipment to Lyon?",
"context_lookup": true
}
}{
"reply": {
"text": "Hi Mihai! Your shipment SHP-5530 left Pitești on 14 October and is now near Dijon…",
"language": "en",
"sources": [
"tms:shipment:SHP-5530"
]
},
"ticket": {
"id": "T-9120",
"status": "answered",
"handover": false
}
}Agent id ada, Finance & procurement. Agent page
| Task type | What it does |
|---|---|
invoice.extract | Read a supplier invoice into structured data |
invoice.match | Match an invoice to orders, shipments or POs |
payments.reconcile | Reconcile a bank statement against open items |
collections.remind | Prepare or send a payment reminder |
{
"type": "invoice.extract",
"input": {
"file_id": "file_inv_4471",
"match_against": [
"orders",
"shipments"
]
}
}{
"invoice": {
"supplier": {
"name": "Carpat Trans SRL",
"vat_id": "RO00000000"
},
"number": "4471",
"issue_date": "2026-10-17",
"currency": "EUR",
"total": 1250.00,
"lines": [
{
"description": "Transport Pitești–Lyon",
"amount": 1210.00
},
{
"description": "Waiting time",
"amount": 40.00
}
]
},
"match": {
"shipment_id": "SHP-5530",
"expected_total": 1210.00,
"difference": 40.00,
"status": "needs_review"
}
}Agent id paul, Finance & procurement. Agent page
| Task type | What it does |
|---|---|
rfq.create | Write and send a request for quotation |
offers.compare | Compare supplier offers against weighted criteria |
po.draft | Draft a purchase order for approval |
spend.analyze | Break down spend by category and supplier |
{
"type": "offers.compare",
"input": {
"rfq_id": "rfq_311",
"criteria": {
"price": 0.5,
"delivery": 0.3,
"terms": 0.2
}
}
}{
"ranking": [
{
"supplier": "Supplier C",
"unit_price": 326,
"delivery_days": 2,
"includes_fitting": true,
"score": 0.86
},
{
"supplier": "Supplier A",
"unit_price": 318,
"delivery_days": 1,
"includes_fitting": false,
"score": 0.82
},
{
"supplier": "Supplier B",
"unit_price": 299,
"delivery_days": 21,
"includes_fitting": false,
"score": 0.64
}
],
"recommendation": "Supplier C if fitting is needed; otherwise Supplier A."
}Agent id hugo, People & legal. Agent page
| Task type | What it does |
|---|---|
job_ad.draft | Write a job ad from a short brief |
applications.organize | Turn CVs into one structured table — no scoring |
interview.schedule | Propose and book interview slots |
documents.expiry | List licences, certificates and contracts that expire soon |
{
"type": "documents.expiry",
"input": {
"within_days": 60,
"document_types": [
"driving_licence",
"adr_certificate",
"tachograph_card",
"contract"
]
}
}{
"expiring": [
{
"employee_id": "emp_204",
"document": "tachograph_card",
"expires_on": "2026-11-28"
},
{
"employee_id": "emp_118",
"document": "tachograph_card",
"expires_on": "2026-12-03"
},
{
"employee_id": "emp_311",
"document": "tachograph_card",
"expires_on": "2026-12-09"
}
],
"notified": [
"employees",
"fleet_manager"
]
}Agent id lex, People & legal. Agent page
| Task type | What it does |
|---|---|
contract.review | Check a contract against your playbook |
contract.draft | Draft a document from your template |
contract.compare | Explain the differences between two versions |
claim.prepare | Assemble a damage or delay claim file |
gdpr.request | Log and track a data-subject request |
{
"type": "contract.review",
"input": {
"file_id": "file_nordic_fta",
"playbook": "transport_client_v3"
}
}{
"review": {
"issues": [
{
"clause": "7.2",
"topic": "payment_term",
"found": "90 days",
"playbook": "max 45 days",
"severity": "high",
"suggested_text": "Payment within 45 days of the invoice date."
},
{
"clause": "9.3",
"topic": "liability_cap",
"found": "EUR 500 per shipment",
"playbook": "CMR limits",
"severity": "high"
},
{
"clause": "15.1",
"topic": "auto_renewal",
"found": "3 years",
"playbook": "max 1 year",
"severity": "medium"
}
],
"escalate": [
{
"clause": "12",
"reason": "exclusive foreign jurisdiction"
}
]
}
}Agent id iris, Management. Agent page
| Task type | What it does |
|---|---|
data.ask | Answer a question about your data, with sources |
report.generate | Build a scheduled KPI report |
anomaly.scan | Look for unusual movements in your metrics |
{
"type": "data.ask",
"input": {
"question": "Why is our margin lower this month?",
"sources": [
"erp",
"tms"
],
"period": "2026-10"
}
}{
"answer": {
"text": "Gross margin is 14.2% against 17.9% last month…",
"figures": [
{
"metric": "gross_margin_pct",
"value": 14.2,
"previous": 17.9
}
],
"sources": [
"erp:invoices",
"tms:shipments"
],
"suggested_actions": [
{
"agent_id": "ada",
"type": "collections.remind",
"note": "invoice unbilled waiting time"
}
]
}
}Agent id atlas, Management. Agent page
| Task type | What it does |
|---|---|
task.route | Understand a request and send it to the right agent |
brief.generate | Prepare a management brief for a period |
meeting.summarize | Turn notes or a transcript into decisions and tasks |
followups.track | List open items and chase their owners |
{
"type": "brief.generate",
"input": {
"period": "yesterday",
"audience": "management",
"agents": [
"carla",
"quinn",
"rio",
"ada",
"paul",
"lex"
]
}
}{
"brief": {
"summary": "Yesterday: 38 transport requests, 21 quotes sent, 14 accepted.",
"needs_decision": [
{
"ref": "PO-1204",
"agent_id": "paul",
"action": "approve purchase order"
},
{
"ref": "contract_nordic_fta",
"agent_id": "lex",
"action": "sign off contract check"
},
{
"ref": "client_agro_delta",
"agent_id": "quinn",
"action": "framework price"
}
]
}
}First public version of the API: agents, tasks, threads and messages with streaming, tools, knowledge, handoffs, webhooks, usage and limits, billing and invoices.