# Create an agent (full configuration)

> POST /agents. HeyRik API parameters and documented request and response examples.

Source: https://www.heyrik.com/docs/api-reference/agents/post-agents-create-an-agent-full-configuration

POST https://server.heyrik.com/api/v1/agents

## Headers

Authorization: Bearer $HEYRIK_API_KEY (required). Keep your key on your server.

## Parameters

- name (string, required): Shown in the dashboard and call logs.
- config.prompt_sections (object[], required): The agent's instructions as an ordered list of sections — edit these inside Assistant Details in the dashboard. Each: { title, content, order?, enabled? }. They're compiled in order into the agent's prompt (sections with enabled:false are skipped). Use these; this is how the builder defines an agent.
- — section.title (string): The section heading, e.g. "Identity & Purpose", "Language Restrictions", "Conversational Flow", "Guardrails", "Closing".
- — section.content (string): The instructions for that section (plain text; newlines and bullet dashes are fine).
- — section.order (number): 0-based position. Sections run top to bottom by order. Optional — array order is used if omitted.
- — section.enabled (boolean): false turns the section off without deleting it. Defaults to true.
- system_prompt (string): Alternative to prompt_sections: a single free-text instruction block. If BOTH are sent, prompt_sections wins. Use this only for a very simple agent.
- language (string): Primary BCP-47 code: en-IN, hi-IN, te-IN… Defaults to English.
- greeting (string): First line on an OUTBOUND call. Supports {{placeholders}} — any input variable you declare in config.input_variables (e.g. {{customer_name}}), plus {{lead_name}}, {{agency_name}}. Each is filled per call and falls back to its declared default when unset (an empty default drops it from the sentence, so a token never leaks).
- inbound_greeting (string): First line when someone calls IN. Falls back to greeting.
- voice_settings (object): { "voice_id": "<id from GET /voices>", "speed": 1.0 }. Works with any library voice OR one of your cloned voices. Omit and a default is picked.
- config (object): Everything else the dashboard builder configures — each key below is one builder section.
- config.languages (string[]): Every language the agent may speak. It mirrors the caller's language automatically.
- config.personality (string): Response Behavior → tone: Professional | Friendly | Empathetic | Energetic | Concise. (This is the persona/how-it-sounds steer — separate from the instruction sections.)
- config.fillers (object): Response Behavior → filler phrases: { "enabled": true }. Speaks a brief "let me check…" while a tool runs, so the caller isn't left in silence.
- config.call_behavior (object): Call Configuration + End Call Rules + Ambient Sound — see below.
- config.call_behavior.silence_ms (number): Silence timeout in ms before the agent re-engages (e.g. 3000 = 3s).
- config.call_behavior.max_call_duration_sec (number): End Call Rules → hard cap. The agent signs off and hangs up at this length. 0 = no cap.
- config.call_behavior.end_call_phrases (string[]): End Call Rules → phrases that end the call when the caller says them (e.g. "goodbye", "that's all").
- config.call_behavior.background_audio_name (string): Ambient Sound → the name of an available background clip from GET /background-audios, such as "Office"/"Café". Uploads are managed by the HeyRik team. null = silent.
- config.call_behavior.background_audio_id (string): Ambient Sound → the exact clip id (from GET /background-audios). Takes priority over the name. null = silent.
- config.no_response (object): Silence Handling: { "enabled": true, "max_retries": 2, "prompts": [{ "after_sec": 3, "text": "Are you still there?" }] }. Re-engages a quiet caller, then gives up after max_retries.
- config.transfer (object): Transfer & Routing: { "enabled": true, "mode": "static", "static_number": "+91…", "condition": "when the caller asks for a human" }. Escalates to a phone number.
- config.input_variables (object[]): Variables tab → INPUT: the {{placeholders}} your greeting and prompt_sections use, each DECLARED with a fallback: [{ "name": "customer_name", "default": "there", "description": "who is being called" }]. A per-call value (the originate `variables` object, or a lead's custom field) fills it; if none is supplied the `default` is used, so a token never leaks to the caller as literal "{{customer_name}}". Identity slots — {{agent_name}}, {{company_name}} — left with an empty default drop gracefully from the sentence when unknown. This is what POST /agents/generate returns for any placeholder it writes.
- config.extracted_variables (object[]): Post-Call → OUTPUT: data to collect: [{ "name": "customer_name", "description": "the caller's full name" }]. The agent fills these DURING the call and they appear on each call afterwards. (Input variables go IN via {{placeholders}}; extracted variables come OUT.)
- config.post_call_webhook (string): Post-Call → a URL we POST the finished call to (transcript, recording URL, extracted fields, summary).

## Notes

config.prompt_sections IS the Conversation Flow — the agent's instructions, in order. It's compiled into the agent's prompt and takes priority over a flat system_prompt. Add the KB after creating: POST /agents/{id}/knowledge. New config applies to the NEXT call.

## Request example

```sh
curl -X POST https://server.heyrik.com/api/v1/agents \
  -H "Authorization: Bearer $HEYRIK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Real Estate Qualifier",
    "language": "te-IN",
    "greeting": "Namaskaram {{customer_name}}, calling from the property team about your enquiry.",
    "voice_settings": { "voice_id": "vx_9f2a1c30", "speed": 1.0 },
    "config": {
      "languages": ["te-IN", "en-IN"],
      "personality": "Professional",

      "prompt_sections": [
        {
          "order": 0, "enabled": true, "title": "Identity & Purpose",
          "content": "- You are a professional, warm real-estate lead-qualification agent.\n- The goal of this call is to understand the prospect's requirements (type, budget, location, timeline) and qualify them for a site visit."
        },
        {
          "order": 1, "enabled": true, "title": "Language Restrictions",
          "content": "- Speak ONLY in Telugu and English.\n- Code-switch to English for property terms (BHK, flats, villas, plots), money (lakhs, crores), digits, dates and locations."
        },
        {
          "order": 2, "enabled": true, "title": "Conversational Flow",
          "content": "- Confirm you are speaking to the right person, then ask — one at a time — property type, budget, preferred location, and timeline."
        },
        {
          "order": 3, "enabled": true, "title": "Guardrails",
          "content": "- Never quote a price you are unsure of. If you do not know something, offer to have a senior expert follow up. Never invent facts."
        },
        {
          "order": 4, "enabled": true, "title": "Closing",
          "content": "- Once the requirements are captured, secure the prospect's agreement to speak with a senior sales expert, then thank them and end the call."
        }
      ],

      "call_behavior": {
        "silence_ms": 3000,
        "max_call_duration_sec": 900,
        "end_call_phrases": ["goodbye", "thanks bye"],
        "background_audio_name": "Office"
      },
      "no_response": {
        "enabled": true,
        "max_retries": 2,
        "prompts": [{ "after_sec": 3, "text": "Are you still there?" }]
      },
      "transfer": { "enabled": true, "mode": "static", "static_number": "+91 98765 43210", "condition": "caller asks to speak to a human" },
      "input_variables": [
        { "name": "customer_name", "default": "there", "description": "who is being called — fills {{customer_name}} in the greeting" },
        { "name": "company_name", "default": "", "description": "the brand; empty default drops it from the sentence when unknown" }
      ],
      "extracted_variables": [
        { "name": "property_type", "description": "flat / villa / plot" },
        { "name": "budget", "description": "the prospect's budget" },
        { "name": "location", "description": "preferred area" },
        { "name": "timeline", "description": "when they plan to buy" }
      ]
    }
  }'
```

## Response example

```json
{
  "data": {
    "id": "agc_9f2a1c30",
    "name": "Real Estate Qualifier",
    "language": "te-IN",
    "greeting": "Namaskaram {{customer_name}}, calling from the property team about your enquiry.",
    "voice_settings": { "voice_id": "vx_9f2a1c30", "speed": 1.0 },
    "config": {
      "personality": "Professional",
      "languages": ["te-IN", "en-IN"],
      "prompt_sections": [ { "order": 0, "title": "Identity & Purpose", "content": "…" }, "…" ],
      "input_variables": [ { "name": "customer_name", "default": "there", "description": "…" }, "…" ],
      "extracted_variables": [ { "name": "property_type", "description": "…" }, "…" ],
      "call_behavior": { "max_call_duration_sec": 900 }
    },
    "created_at": "2026-07-24T06:11:44.201Z"
  }
}
```
