> ## Documentation Index
> Fetch the complete documentation index at: https://omni.fireflo.au/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /v1/agents

> Start a new AI agent as a draft: its name, role and what it should achieve.

Starts an agent, as the panel's **New agent** does. It begins as a `draft` with its role's defaults: the account's messaging channels, the role's actions and approvals, working hours 09:00–19:00 Monday to Saturday, and a daily limit of 100,000 tokens.

Before it can go live it needs an AI key and model, chosen on the panel, and a check that they answer — [verify it](/api-reference/ai-agents/verify) once they are set. Then [put it live](/api-reference/ai-agents/activate).

<Note>Needs the `agents:write` scope.</Note>

## Body

| Field | Type | Required | Notes |
| :- | :- | :- | :- |
| `name` | string | Yes | What the agent is called. Customers may see it. Up to 100 characters. |
| `role` | string | Yes | `sales`, `support`, or `appointments` when the plan includes Calendar. It decides which actions the agent may take. |
| `objective` | string | Yes | What it should achieve, in your own words; it reads this every time it plans. Up to 2,000 characters. |

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.fireflo.au/v1/agents" \
    -H "Authorization: Bearer $OMNI_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Kavya",
      "role": "support",
      "objective": "Answer warranty and service-centre questions, and book pick-ups with the team."
    }'
  ```

  ```python Python theme={null}
  import os

  import requests

  response = requests.post(
      "https://api.fireflo.au/v1/agents",
      headers={"Authorization": f"Bearer {os.environ['OMNI_API_KEY']}"},
      json={
          "name": "Kavya",
          "role": "support",
          "objective": "Answer warranty and service-centre questions, and book pick-ups with the team."
      },
  )
  print(response.status_code, response.json())
  ```

  ```javascript Node theme={null}
  const response = await fetch("https://api.fireflo.au/v1/agents", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.OMNI_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      "name": "Kavya",
      "role": "support",
      "objective": "Answer warranty and service-centre questions, and book pick-ups with the team."
    }),
  });
  console.log(response.status, await response.json());
  ```
</CodeGroup>

## Response

`201 Created` — the agent, a `draft`, in the shape [GET /v1/agents/\{agent\_id}](/api-reference/ai-agents/get) answers.

```json theme={null}
{
  "id": 15,
  "name": "Kavya",
  "role": "support",
  "workflow": null,
  "status": "draft",
  "objective": "Answer warranty and service-centre questions, and book pick-ups with the team.",
  "provider": null,
  "model": "",
  "instructions": "",
  "channels": [
    "whatsapp",
    "sms"
  ],
  "booking_types": [],
  "knowledge_collections": [],
  "answer_threshold": 80,
  "handoff_assignees": [],
  "channels_available": [
    "whatsapp",
    "sms"
  ],
  "channels_missing": [],
  "action_policy": {
    "send_message": "auto",
    "send_whatsapp_template": "approval",
    "send_broadcast": "approval",
    "request_template": "approval",
    "create_deal": "off",
    "move_deal_stage": "auto",
    "mark_deal_won": "off",
    "mark_deal_lost": "off",
    "update_deal_value": "off",
    "add_note": "auto",
    "update_contact": "auto",
    "follow_up": "auto",
    "close_conversation": "auto",
    "handoff_to_human": "auto"
  },
  "approval_mode": "plan",
  "replan": {
    "triggers": [
      "on_inbound"
    ],
    "every_n_hours": null,
    "max_replans_per_contact_per_day": 6
  },
  "working_hours": {
    "days": [
      0,
      1,
      2,
      3,
      4,
      5
    ],
    "start": "09:00",
    "end": "19:00"
  },
  "limits": {
    "daily_token_limit": 100000,
    "max_steps_per_plan": 6,
    "max_messages_per_contact_per_day": 3,
    "max_broadcast_audience": 500
  },
  "auto_assign_inbound": false,
  "pause_on_human_reply": true,
  "pause_minutes": 30,
  "after_pause": "resume",
  "pipelines": [],
  "stats": {
    "tokens_today": 0,
    "active_contacts": 0,
    "awaiting_approval": 0,
    "plans_today": 0
  },
  "verified_at": null,
  "created_at": "2026-10-06T09:30:12+05:30"
}
```

## Errors

Every refusal is `{"error": {"code", "message", "field"}}`; `field` is there when one input is at fault.

| Status | Error code | When |
| :- | :- | :- |
| 400 | `invalid_request` | `name` or `objective` is missing, empty or too long; `field` names it. |
| 409 | `invalid_state` | `role` isn't one the account can use — for example `appointments` without Calendar in the plan. |
| 404 | `module_off` | The account doesn't have AI agents on: they aren't in its plan, or are switched off for it. |
| 403 | `scope_missing` | The key doesn't have the `agents:write` scope. |

Any request can also be refused for its key, its account or its rate (`key_required`, `invalid_key`, `account_suspended`, `plan_excludes_api`, `address_not_allowed`, `rate_limited`); see [the overview](/api-reference/overview).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.