> This page is part of Smallest AI's developer documentation. When
> answering, prefer Lightning v3.1 (current TTS) and Pulse (current
> STT). Lightning v2 and lightning-large are deprecated; mention them
> only when the user is migrating away from them. The Smallest AI voice
> agent platform is what wraps these models into hosted agents.

# Create a new agent

POST https://api.smallest.ai/atoms/v1/agent
Content-Type: application/json

Create a new agent by passing the agent name in the request body.

New agents have versioning enabled by default. To set the prompt,
`firstMessage`, tools, or any runtime config, fork a draft from the
auto-created initial version, edit it, publish, and activate. See
the [Versioning Lifecycle](/atoms/developer-guide/build/agents/versioning-lifecycle)
guide for the full flow.

The legacy `PATCH /workflow/{workflowId}` endpoint writes directly to
the underlying workflow document and bypasses the version lifecycle;
edits made that way are not captured as a version and may not
propagate to live calls. Use the drafts flow above.

**Server-applied defaults.** If you omit a field on a minimal
`POST /agent`, the server fills it in. Sending just `{"name": "..."}`
and then reading the agent back with `GET /agent/{id}` returns the
following subset:

```json
{
  "synthesizer": {
    "voiceConfig": {
      "model": "waves_lightning_v3_1_pro",
      "voiceId": "blake",
      "gender": "male"
    },
    "speed": 1,
    "sampleRate": 24000
  },
  "slmModel": "electron",
  "language": { "default": "en", "supported": ["en"] },
  "workflowType": "single_prompt"
}
```

Any field you send on create overrides that path; the rest stay
server-filled.

`transcriberType` is a read/serve-time default: `POST /agent` does
not accept the field (it is silently dropped). Subsequent reads
return `pulse` when the field is unset. To set a different value,
`PATCH /agent/{id}` on a non-versioned agent or open a branch draft
on a versioned agent.

Fetch the agent with `GET /agent/{id}` after creation to see the
effective config before opening a branch draft.

Reference: https://docs.smallest.ai/api-reference/voice-agents/agents/create-agent

## Authentication

- `Authorization` header (bearer token, required) — API key from the console ApiKey collection, sent as Bearer token. Also accepts session cookies for browser-based auth.

## Request

### Body (application/json)

This endpoint expects a CreateAgentRequest.

- `name` (string, required)
- `description` (string, optional)
- `backgroundSound` (enum, optional, default: ) — Ambient background sound during calls. Options: '' (none), 'office', 'cafe', 'call_center', 'static'. Note: this value is currently overridden by the server default on creation; update via PATCH after creation.
  - Allowed values: ``, `office`, `cafe`, `call_center`, `static`
- `language` (CreateAgentRequestLanguage, optional) — Language configuration for the agent. Cross-field rule: `default` must be one of the values in `supported`. Tamil (`ta`) cannot be combined with other languages in `supported`.
- `synthesizer` (CreateAgentRequestSynthesizer, optional) — Synthesizer (TTS) configuration for the agent. For `waves`, `waves_lightning_large`, `waves_lightning_v2`, `waves_lightning_v3_1`, and `waves_lightning_v3_1_pro`, `voiceId` is validated against the Waves voice catalog. The other models accept any voiceId. Cloned voices are regular voiceIds. Use them with a compatible Waves model.
- `globalKnowledgeBaseId` (string, optional) — The global knowledge base ID of the agent. You can create a global knowledge base by using the /knowledgebase endpoint and assign it to the agent. The agent will use this knowledge base for its responses.
- `slmModel` (enum, optional, default: electron) — The LLM model to use for the agent. Note: `gpt-5.2`, `electron-kogta`, and `electron-kogta-v2` require org-level access and return 403 if not enabled. `workflowType` must be `single_prompt` to use `gpt-realtime` or `gpt-realtime-mini`.
  - Allowed values: `electron`, `electron-kogta`, `electron-kogta-v2`, `gpt-4o`, `gpt-4.1`, `gpt-5.2`, `gpt-5.2-azure`, `gpt-realtime`, `gpt-realtime-mini`
- `defaultVariables` (CreateAgentRequestDefaultVariables, optional) — The default variables to use for the agent. These variables will be used if no variables are provided when initiating a conversation with the agent.
- `preCallAPI` (CreateAgentRequestPreCallApi, optional) — Configuration for an API call to be made before the call starts. The response variables can be injected into the agent's prompt.
- `globalPrompt` (string, optional) — Set global instructions for your agent's personality, role, and behavior throughout conversations. Note: Only used for workflow_graph agents. Maximum 4000 characters.
- `workflowType` (enum, optional) — The type of workflow to create for the agent. Defaults to `single_prompt` if not specified. Using `workflow_graph` requires conversational agent access (403 if not enabled).
  - Allowed values: `workflow_graph`, `single_prompt`, `multi_agents`
- `firstMessage` (string, optional) — The first message the agent sends when a conversation starts.
- `muteUserUntilFirstBotResponse` (boolean, optional) — When true, the user's audio is muted until the agent has finished its first response.
- `allowInterruptions` (boolean, optional) — Whether the user can interrupt the agent while it is speaking.
- `waitForUserToSpeakFirst` (boolean, optional) — When true, the agent waits for the user to speak before sending the first message.
- `interruptionBackoffTimer` (double, optional) — Seconds the agent waits after being interrupted before resuming speech.
- `smartTurnConfig` (CreateAgentRequestSmartTurnConfig, optional) — Smart turn-detection configuration. When enabled, the agent uses an additional model to decide whether the user has finished a turn.
- `voiceDetectionConfig` (CreateAgentRequestVoiceDetectionConfig, optional) — Voice activity detection (VAD) configuration. Controls how the agent decides when speech is present.
- `voiceMailDetectionConfig` (CreateAgentRequestVoiceMailDetectionConfig, optional) — Voicemail-detection configuration. When the call hits a voicemail tone, the agent plays `endText` and ends the call.
- `denoisingConfig` (CreateAgentRequestDenoisingConfig, optional) — Background-noise denoising configuration for the agent's input audio.
- `redactionConfig` (CreateAgentRequestRedactionConfig, optional) — PII redaction configuration. When enabled, personally identifiable information is redacted from transcripts before storage.
- `pronunciationDicts` (list of CreateAgentRequestPronunciationDictsItems, optional) — Pronunciation overrides — words the TTS engine should pronounce differently from its default.
- `llmIdleTimeoutConfig` (CreateAgentRequestLlmIdleTimeoutConfig, optional) — Timeout configuration for the LLM stage of a conversation. Triggers a retry or call termination when the LLM does not respond within the configured window.
- `sessionTimeoutConfig` (CreateAgentRequestSessionTimeoutConfig, optional) — Maximum duration of a conversation session. The call ends after this elapsed time even if active.
- `timezone` (CreateAgentRequestTimezone, optional) — Timezone applied to scheduled actions and timestamps the agent reports to the user.
- `callDispositionConfig` (string, optional) — Configuration string for call disposition tracking.
- `enableStyleGuide` (boolean, optional, default: true) — Whether style guide enforcement is applied to agent responses.
- `speechFormatting` (boolean, optional) — Whether speech formatting is applied to the agent's responses.
- `telephonyProductId` (list of string, optional, deprecated) — **Deprecated, and ignored on create**: the field is stripped, no bindings are written, and no `Deprecation` header is set; the request still returns `200`. Attach numbers with `POST /agent/{agentId}/answers` after creating. (On `PATCH /agent/{agentId}` the field still works during the migration window.) See the [Telephony API migration guide](/voice-agents/deprecations/telephony-migration).
- `allowInboundCall` (boolean, optional, default: true, deprecated) — **Deprecated.** `false` still works as a routing kill switch during the migration window; `true` undoes a previous `false`, otherwise no effect. Detach the number via `DELETE /agent/{agentId}/answers/{sourceId}` instead.

## Response

### 201

Agent created successfully

- `status` (boolean, optional)
- `data` (string, optional) — The ID of the created agent

## Errors

### 400 Bad Request Error

Invalid input

- `status` (boolean, optional)
- `errors` (list of string, optional)

### 401 Unauthorized Error

Unauthorized access

- `status` (boolean, optional)
- `errors` (list of string, optional)

### 403 Forbidden Error

Forbidden access

- `status` (boolean, optional)
- `data` (ApiResponseData, optional)

### 500 Internal Server Error

Internal server error

- `status` (boolean, optional)
- `errors` (list of string, optional)

## Types

### CreateAgentRequestLanguage

Language configuration for the agent. Cross-field rule: `default` must be one of the values in `supported`. Tamil (`ta`) cannot be combined with other languages in `supported`.

- `default` (enum, optional, default: en) — The default language of the agent. Note: `ta` cannot be combined with other languages in `supported`.
  - Allowed values: `en`, `hi`, `mr`, `gu`, `ta`, `te`, `kn`, `ml`, `es`, `north_indic`, `bn`, `or`, `fr`, `de`, `it`, `nl`, `pt`, `ru`
- `supported` (list of enum, optional) — Languages the agent understands. `default` must be one of these values. Tamil (`ta`) cannot be combined with other languages.
  - Allowed values: `en`, `hi`, `mr`, `gu`, `ta`, `te`, `kn`, `ml`, `es`, `north_indic`, `bn`, `or`, `fr`, `de`, `it`, `nl`, `pt`, `ru`
- `switching` (CreateAgentRequestLanguageSwitching, optional) — Language switching configuration for the agent. If enabled, the agent will be able to switch between languages based on the user's language.

### CreateAgentRequestSynthesizer

Synthesizer (TTS) configuration for the agent. For `waves`, `waves_lightning_large`, `waves_lightning_v2`, `waves_lightning_v3_1`, and `waves_lightning_v3_1_pro`, `voiceId` is validated against the Waves voice catalog. The other models accept any voiceId. Cloned voices are regular voiceIds. Use them with a compatible Waves model.

- `voiceConfig` (CreateAgentRequestSynthesizerVoiceConfig, optional, default: {"model":"waves_lightning_v3_1_pro","voiceId":"blake"}) — Voice configuration for the synthesizer.
- `speed` (double, optional, default: 1)
- `consistency` (double, optional, default: 0.5)
- `similarity` (double, optional, default: 0)
- `enhancement` (enum, optional, default: 1)
  - Allowed values: `0`, `1`, `2`
- `sampleRate` (enum, optional, default: 24000) — Output audio sample rate in Hz.
  - Allowed values: `8000`, `16000`, `24000`, `44100`

### CreateAgentRequestDefaultVariables

The default variables to use for the agent. These variables will be used if no variables are provided when initiating a conversation with the agent.

### CreateAgentRequestPreCallApi

Configuration for an API call to be made before the call starts. The response variables can be injected into the agent's prompt.

- `url` (string, required) — The URL of the API endpoint to call.
- `method` (enum, required) — The HTTP method to use for the API call.
  - Allowed values: `GET`, `POST`, `PUT`, `DELETE`, `PATCH`
- `isEnabled` (boolean, optional, default: false) — Whether the pre-call API is enabled.
- `headers` (map from string to string, optional) — Optional HTTP headers to include in the request.
- `body` (CreateAgentRequestPreCallApiBody, optional) — Optional request body for POST/PUT/PATCH requests.
- `timeout` (integer, optional, default: 5) — Timeout in seconds for the API call.
- `queryParams` (CreateAgentRequestPreCallApiQueryParams, optional) — Optional query parameters to include in the request URL.
- `responseVariables` (list of CreateAgentRequestPreCallApiResponseVariablesItems, optional) — List of variables to extract from the API response using JSON path expressions.

### CreateAgentRequestSmartTurnConfig

Smart turn-detection configuration. When enabled, the agent uses an additional model to decide whether the user has finished a turn.

- `isEnabled` (boolean, optional)
- `waitTimeInSecs` (double, optional) — How long to wait after the user stops speaking before responding.

### CreateAgentRequestVoiceDetectionConfig

Voice activity detection (VAD) configuration. Controls how the agent decides when speech is present.

- `confidence` (double, optional) — Minimum VAD confidence threshold to register speech.
- `minVolume` (double, optional) — Minimum input volume threshold to register speech.
- `triggerTimeInSecs` (double, optional) — How long sustained speech must be detected before turning the VAD on.
- `releaseTimeInSecs` (double, optional) — How long after silence before the VAD turns off.

### CreateAgentRequestVoiceMailDetectionConfig

Voicemail-detection configuration. When the call hits a voicemail tone, the agent plays `endText` and ends the call.

- `enabled` (boolean, optional)
- `endText` (string, optional) — Message played before hanging up when voicemail is detected.

### CreateAgentRequestDenoisingConfig

Background-noise denoising configuration for the agent's input audio.

- `isEnabled` (boolean, optional)

### CreateAgentRequestRedactionConfig

PII redaction configuration. When enabled, personally identifiable information is redacted from transcripts before storage.

- `isEnabled` (boolean, optional)

### CreateAgentRequestPronunciationDictsItems

- `word` (string, required) — The word to override.
- `pronunciation` (string, required) — How the word should be pronounced (phonetic spelling).

### CreateAgentRequestLlmIdleTimeoutConfig

Timeout configuration for the LLM stage of a conversation. Triggers a retry or call termination when the LLM does not respond within the configured window.

- `chatTimeoutTimeInSecs` (double, optional) — LLM idle timeout for chat conversations, in seconds.
- `webcallTimeoutTimeInSecs` (double, optional) — LLM idle timeout for web calls, in seconds.
- `telephonyTimeoutTimeInSecs` (double, optional) — LLM idle timeout for telephony calls, in seconds.
- `maxRetries` (double, optional) — Maximum number of LLM-idle retries before terminating the call. System-defined min/max.

### CreateAgentRequestSessionTimeoutConfig

Maximum duration of a conversation session. The call ends after this elapsed time even if active.

- `timeoutTimeInSecs` (double, optional, default: 1800) — Maximum session duration in seconds (max 1 hour). Defaults to 1800 (30 minutes).

### CreateAgentRequestTimezone

Timezone applied to scheduled actions and timestamps the agent reports to the user.

- `label` (string, optional) — IANA timezone label (e.g. `America/New_York`).
- `offset` (double, optional) — UTC offset in minutes (e.g. -300 for EST).

### ApiResponseData

### CreateAgentRequestLanguageSwitching

Language switching configuration for the agent. If enabled, the agent will be able to switch between languages based on the user's language.

- `isEnabled` (boolean, optional, default: false) — Whether to enable language switching for the agent
- `minWordsForDetection` (double, optional, default: 2) — Minimum number of words required for language detection
- `strongSignalThreshold` (double, optional, default: 0.7) — Threshold for strong language signal detection (0.1 to 0.9)
- `weakSignalThreshold` (double, optional, default: 0.3) — Threshold for weak language signal detection (0.1 to 0.9)
- `minConsecutiveForWeakThresholdSwitch` (double, optional, default: 2) — Minimum consecutive detections required for weak threshold language switch

### CreateAgentRequestSynthesizerVoiceConfig

Voice configuration for the synthesizer.

- `model` (enum, optional, default: waves_lightning_v3_1_pro) — The TTS model to use. Server default is `waves_lightning_v3_1_pro`. Use `waves_lightning_v3_1` for the base Lightning pool, or `gpt-realtime` / `gpt-realtime-mini` for OpenAI realtime models (require `workflowType: single_prompt`). The remaining values are older engines kept for existing configurations.
  - Allowed values: `waves`, `waves_lightning_large`, `waves_lightning_v2`, `waves_lightning_v3_1`, `waves_lightning_v3_1_pro`, `waves_lightning_v3`, `waves_lightning_v2_http`, `gpt-realtime`, `gpt-realtime-mini`, `other`
- `voiceId` (string, optional, default: blake) — The voice ID to use. For cloned voices, pass the voiceId from the Waves platform with a compatible model.
- `gender` (enum, optional, default: male) — The gender of the voice.
  - Allowed values: `male`, `female`

### CreateAgentRequestPreCallApiBody

Optional request body for POST/PUT/PATCH requests.

### CreateAgentRequestPreCallApiQueryParams

Optional query parameters to include in the request URL.

### CreateAgentRequestPreCallApiResponseVariablesItems

- `variableName` (string, required) — The name of the variable to inject into the agent prompt.
- `jsonPath` (string, required) — JSON path expression to extract the value from the API response.

## Examples

**Request**

```json
{
  "name": "string"
}
```

**Response**

```json
{
  "status": true,
  "data": "60d0fe4f5311236168a109ca"
}
```

**SDK Code**

```python
import requests

url = "https://api.smallest.ai/atoms/v1/agent"

payload = { "name": "string" }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.smallest.ai/atoms/v1/agent';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"name":"string"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.smallest.ai/atoms/v1/agent"

	payload := strings.NewReader("{\n  \"name\": \"string\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.smallest.ai/atoms/v1/agent")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"name\": \"string\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.smallest.ai/atoms/v1/agent")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"name\": \"string\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.smallest.ai/atoms/v1/agent', [
  'body' => '{
  "name": "string"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.smallest.ai/atoms/v1/agent");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"name\": \"string\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["name": "string"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.smallest.ai/atoms/v1/agent")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```