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

# Inbound webhook

It's quite common to want to use different agents under the same number, and quite common to provide context based on caller for a call. For outbound calls / chats, you can do that simply by supplying the call specific information in the API when you send it. For inbound calls or SMS, however, you are not the one initiating it, so you need a way to notify you when that inbound call / SMS is received and you can then process it.

This inbound webhook is designed for this purpose. Once setup, you can override agent id, set dynamic variables and other fields specific to that call / SMS, and then you can process the call / SMS accordingly. It is part of your number configuration, and it works for numbers that you have purchased or imported.

This feature does not apply for [dial to sip calls](/deploy/custom-telephony#method-2-dial-to-sip-endpoint) calls, as you can provide call specific information when you register the phone call.

## Use cases

* Filter and reject unwanted inbound calls / SMS
* Add context (dynamic variables, metadata) to inbound calls / SMS
* Override agent id / version / specific agent settings for inbound calls / SMS
* Pause the call / SMS to pick it up with some delay
* Internal system records of the inbound call / SMS

## Webhook Spec

The webhook will `POST` the payload to your endpoint. The webhook has a timeout of 10 seconds. If within 10 seconds no success status (2xx) is received, the webhook will be retried, up to 3 times.

The webhook can be verified using your Retell API Key to make sure it comes from Retell AI. Read more at [Secure the webhook](/features/secure-webhook).

### Request payload

These fields might be provided in the payload depending on your configuration:

* `agent_id`: if the number has inbound agent id set, you will see it in payload
* `agent_version`: if the number has inbound agent version set, you will see it in payload
* `from_number`: this will always show up in payload, helps you identify the caller and process the call / SMS accordingly
* `to_number`: this will always show up in payload, helps you identify the receiver and process the call / SMS accordingly

Note that the call / SMS is not connected, and a call / SMS object is not yet created (and if you decided not to take the call for example, the call object will not be created). Therefore you will not have a call / SMS object and call / SMS id inside the payload.

Here's a sample payload for inbound call:

<CodeGroup>
  ```json Inbound Call  theme={null}
  {
    "event": "call_inbound",
    "call_inbound": {
      "agent_id": "agent_12345",
      "agent_version": 1,
      "from_number": "+12137771234",
      "to_number": "+12137771235"
    }
  }
  ```

  ```json Inbound SMS  theme={null}
  {
    "event": "chat_inbound",
    "chat_inbound": {
      "agent_id": "agent_12345",
      "agent_version": 1,
      "from_number": "+12137771234",
      "to_number": "+12137771235"
    }
  }
  ```
</CodeGroup>

### Response

We expect a JSON response with a successful status code (2xx) with fields grouped under `call_inbound` or `chat_inbound`. Here're the allowed fields (all of them are optional):

* `override_agent_id`: if you want to override the agent id, you can set it here
* `override_agent_version`: if you want to override the agent version, you can set it here
* `dynamic_variables`: if you want to set dynamic variables for this inbound call, you can set it here
* `metadata`: if you want to set metadata for this inbound call, you can set it here
* `agent_override`: if you want to override the agent settings.

#### Agent Override

You can also override per-call / per-chat agent behavior without modifying the saved agent by returning an `agent_override` object. The override is applied only for this session.

Supported groups:

* `agent`: Partial Agent settings (voice agents). Useful fields include `voice_id`, `voice_model`, `fallback_voice_ids`, `voice_temperature`, `voice_speed`, `volume`, `language`, `pronunciation_dictionary`, `boosted_keywords`, `stt_mode`, `vocab_specialization`, `denoising_mode`, `responsiveness`, `interruption_sensitivity`, `enable_backchannel`, `backchannel_frequency`, `backchannel_words`, `end_call_after_silence_ms`, `max_call_duration_ms`, `begin_message_delay_ms`, `ring_duration_ms`, `reminder_trigger_ms`, `reminder_max_count`, `ambient_sound`, `ambient_sound_volume`, `allow_user_dtmf`, `user_dtmf_options`, `voicemail_option`, `webhook_url`, `webhook_timeout_ms`, `data_storage_setting`, `opt_in_signed_url`, `pii_config`, `post_call_analysis_data`, `post_call_analysis_model`.
* `retell_llm`: Partial Retell LLM settings. Supported keys include `model`, `s2s_model`, `model_temperature`, `knowledge_base_ids`, `kb_config`, `start_speaker`, `begin_after_user_silence_ms`, `begin_message`.
* `conversation_flow`: Partial Conversation Flow settings. Supported keys include `model_choice`, `model_temperature`, `knowledge_base_ids`, `kb_config`, `start_speaker`, `begin_after_user_silence_ms`, `begin_message`.

Notes:

* If both `override_agent_id`/`override_agent_version` and `agent_override` are provided, we first resolve the target agent by id/version, then apply `agent_override` on top for this call.
* Overrides must satisfy the same validation rules as agent creation (e.g. voice/language compatibility, value ranges). Invalid overrides may cause the call to be rejected.
* Overrides do not persist back to the saved agent.

Here's a sample response for inbound call, for inbound SMS, simply replace `call_inbound` with `chat_inbound`:

```json theme={null}
{
  "call_inbound": {
    "override_agent_id": "agent_12345",
    "override_agent_version": 1,
    "agent_override": {
      "agent": {
        "voice_id": "11labs-Adrian",
        "voice_temperature": 0.6,
        "interruption_sensitivity": 0.8,
        "max_call_duration_ms": 1800000
      },
      "retell_llm": {
        "model": "gpt-4o-mini",
        "model_temperature": 0.2,
        "knowledge_base_ids": ["kb_abc123"],
        "start_speaker": "agent",
        "begin_message": "Hi {{customer_name}}, thanks for calling."
      }
    },
    "dynamic_variables": {
        "customer_name": "John Doe"
    },
    "metadata": {
        "random_id": "12345"
    }
  }
}
```

## FAQ

<AccordionGroup>
  <Accordion title="What would happen to the inbound call when the webhook response is not received yet?">
    The call would continue to stay in ringing state.
  </Accordion>

  <Accordion title="What would happen to the inbound SMS when the webhook response is not received yet?">
    The SMS will not get a reply.
  </Accordion>

  <Accordion title="What would happen if webhook was not successful?">
    It would get retried up to 3 times. If all of those attempts fail, it will check whether this number has an inbound agent id set. If it does, it will then try to connect the call to that agent. If not, it will then disconnect the call.
  </Accordion>

  <Accordion title="Can I use this webhook to decline inbound calls / SMS based on incoming number?">
    Yes, you can. To selectively reject some inbound calls:

    * Unset the `Inbound Call Agent` in the phone number setting
    * Enable the `Inbound Webhook`
    * Find `from_number` in the webhook request body to check if it matches the number you want to reject.
      * If you want to pick up / reply, respond with a 200 status code containing the "call\_inbound.override\_agent\_id" as a JSON object.
      * If you want to reject, respond with a 200 status code **without** containing the "call\_inbound.override\_agent\_id" as a JSON object.
  </Accordion>
</AccordionGroup>
