> ## Documentation Index
> Fetch the complete documentation index at: https://docs.60db.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Agent

> Create a phone voice agent. The webhook signing secret is returned once.

Create an agent. The response includes `webhook_secret`, which is shown **only in this response** and again only if you rotate it. Store it now. For field rules, see [Agents](https://docs.60db.ai/features/agents.md#limits) and [Tools and webhooks](https://docs.60db.ai/features/agents-tools-and-webhooks.md#define-tools).

## Request

### Headers

**Authorization** `string` *required*

Bearer token with your API key (scope `agents`)

**Content-Type** `string` *required*

application/json

### Body

**name** `string` *required*

1–64 characters. Unique in the workspace, case-insensitive

**script** `string` *required*

1–8,000 characters. Who the agent is and how it handles calls

**voice\_id** `string` *required*

A 60db voice ID. See [Voices](https://docs.60db.ai/api-reference/voices/get-voices.md)

**greeting** `string | null`

Up to 500 characters. The opening line when the call connects

**gender** `string | null`

`female`, `male` or `null`

**listen\_languages** `string[]`

Up to 20 lowercase codes, for example `["hi", "en"]`. No dialect tags

**speak\_languages** `string[]`

Up to 20 lowercase codes the agent may reply in

**emotion** `boolean` (default: true)

Expressive speech

**tools** `object[]`

Up to 16 tools, each with `name`, `description` (1–500 characters) and `parameters` (JSON Schema with `"type": "object"`, up to 4 KB). Requires `tool_webhook_url`

**transfer\_targets** `object[]`

Call transfer. Up to 10 groups, each `{ "name": "Sales", "numbers": ["+919876543210"] }`. `name` is up to 40 characters, starts with a letter, and uses letters, digits, spaces, `_` or `-`; two names that become the same function (`Sales` and `sales`) are refused. `numbers` holds 1–10 unique E.164 numbers, tried in turn. Each group becomes a `transfer_to_<name>` function the agent can use. See [Call transfer](https://docs.60db.ai/features/agents-tools-and-webhooks.md#call-transfer)

**tool\_webhook\_url** `string | null`

Public HTTPS URL on port 443 that receives tool calls. Up to 2,048 characters

**event\_webhook\_url** `string | null`

Public HTTPS URL on port 443 that receives `call.completed`, `call.failed` and `recording.ready`

**knowledge\_collection\_id** `string | null`

UUID of a workspace Smart Memory collection. Personal collections are not supported yet

**call\_defaults** `object`

Default call settings: `speaks_first`, `start_delay_ms`, `idle_ms`, `idle_checkins`, `max_duration_secs` (10–900), `record`, `voice_speed`, `voice_stability`, `voice_similarity`, `speech_terms`. Overridable per call

## Response

**201 Created**. The agent, plus `webhook_secret`.

```json theme={null}
{
  "success": true,
  "data": {
    "id": "9c2e1d7a-0b3f-4e6a-8f1d-5a7b9c0e2d44",
    "name": "Front desk",
    "script": "You are the receptionist for Juniper Kitchen. Keep replies short.",
    "greeting": "Hello, Juniper Kitchen. How can I help?",
    "voice_id": "YOUR_VOICE_ID",
    "gender": null,
    "listen_languages": ["hi", "en"],
    "speak_languages": [],
    "emotion": true,
    "tools": [],
    "transfer_targets": [],
    "tool_webhook_url": null,
    "event_webhook_url": null,
    "knowledge_collection_id": null,
    "call_defaults": { "max_duration_secs": 300, "record": true },
    "created_at": "2026-11-03T10:00:00.000Z",
    "updated_at": "2026-11-03T10:00:00.000Z",
    "webhook_secret": "whsec_…"
  }
}
```

## Errors

| Status | Code | Meaning |
| - | - | - |
| 400 | `VALIDATION_ERROR` | A field is invalid, or `tools` is set without `tool_webhook_url`. `field` names it |
| 404 | `KNOWLEDGE_COLLECTION_NOT_FOUND` | `knowledge_collection_id` is not a collection in your workspace |
| 409 | `AGENT_NAME_TAKEN` | An agent with this name already exists |
| 422 | `KNOWLEDGE_COLLECTION_UNSUPPORTED` | The collection is a personal one. Use a workspace collection |
| 422 | `UNSAFE_WEBHOOK_URL` | A webhook URL is not public HTTPS on port 443 |

## Example

```bash cURL theme={null}
curl -X POST https://api.60db.ai/agents \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Front desk",
    "script": "You are the receptionist for Juniper Kitchen. Keep replies short.",
    "voice_id": "YOUR_VOICE_ID",
    "greeting": "Hello, Juniper Kitchen. How can I help?",
    "listen_languages": ["hi", "en"],
    "call_defaults": { "max_duration_secs": 300, "record": true }
  }'
```

```javascript JavaScript theme={null}
const agent = await client.agents.create({
  name: 'Front desk',
  script: 'You are the receptionist for Juniper Kitchen. Keep replies short.',
  voice_id: 'YOUR_VOICE_ID',
  greeting: 'Hello, Juniper Kitchen. How can I help?',
  listen_languages: ['hi', 'en'],
  call_defaults: { max_duration_secs: 300, record: true },
});
console.log(agent.webhook_secret); // shown once
```

```python Python theme={null}
agent = client.agents.create(
    name="Front desk",
    script="You are the receptionist for Juniper Kitchen. Keep replies short.",
    voice_id="YOUR_VOICE_ID",
    greeting="Hello, Juniper Kitchen. How can I help?",
    listen_languages=["hi", "en"],
    call_defaults={"max_duration_secs": 300, "record": True},
)
print(agent["webhook_secret"])  # shown once
```


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