# Applications

> Voice applications are reusable routing presets - a webhook, media stream, SIP, trunk, AI agent or IVR target plus caller ID, status callback and recording - shared by many numbers and outbound calls.

Source: https://edesy.in/docs/voice-api/calls/applications

An application is a saved routing preset. It holds where calls go (a webhook, media stream, SIP URI, SIP trunk, Edesy AI voice agent or IVR flow), plus an outbound caller ID, a status callback and a recording setting. Attach one application to many numbers so they all behave the same, and pass its ID as `application_id` on `POST /v1/calls` to reuse it for outbound calls.

## Endpoints

| Method | Path | Description |
|---|---|---|
| `GET` | `/v1/applications` | List applications |
| `POST` | `/v1/applications` | Create an application |
| `GET` | `/v1/applications/{id}` | Read one |
| `PATCH` | `/v1/applications/{id}` | Update (send only the fields to change) |
| `DELETE` | `/v1/applications/{id}` | Delete |
| `POST` | `/v1/applications/{id}/assign` | Attach numbers: `{"phone_number_ids": ["..."]}` |
| `GET` | `/v1/applications/{id}/numbers` | Numbers attached to it |
| `GET` | `/v1/applications/{id}/stats` | Call counts across its numbers, including answer rate, for a health view |

There is no `/v1/applications/{id}/calls` endpoint. To place a call with an application, send `application_id` in the body of `POST /v1/calls`.

## Create an application

```bash
curl -X POST https://voice-api.edesy.in/v1/applications \
  -H "Authorization: Bearer $EDESY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support bot",
    "inbound_target_type": "stream",
    "inbound_stream_url": "wss://bot.example.com/ws",
    "inbound_stream_sample_rate": 16000,
    "outbound_caller_id": "+9180XXXXXXXX",
    "status_callback_url": "https://example.com/edesy/status",
    "recording_enabled": true
  }'
```

| Field | Type | Required | Description |
|---|---|---|---|
| `name` | string | yes | Up to 255 characters |
| `friendly_name` | string | no | Display name |
| `inbound_target_type` | string | yes | `webhook`, `sip`, `stream`, `trunk`, `voiceagent` or `ivr` |
| `inbound_webhook_url`, `inbound_webhook_method` | string | for `webhook` | URL that returns VoiceML; `GET` or `POST` |
| `inbound_sip_uri` | string | for `sip` | `sip:` URI of your SIP endpoint |
| `inbound_stream_url`, `inbound_stream_sample_rate` | string, integer | for `stream` | `wss://` URL; `8000` or `16000` |
| `inbound_trunk_id` | UUID | for `trunk` | One of your SIP trunks |
| `ivr_flow_id` | UUID | for `ivr` | A published IVR Studio flow |
| `outbound_caller_id` | string | no | Default caller ID for outbound calls |
| `status_callback_url` | string | no | Receives status callbacks for calls on this application |
| `recording_enabled` | boolean | no | Record calls |

## Outbound calls with an application

```json
{ "from": "+9180XXXXXXXX", "to": "+9198XXXXXXXX", "application_id": "8d5c1e2a-0000-4000-8000-000000000000" }
```

Only applications whose target is `stream` or `webhook` can drive an outbound call. Any other target returns `400 VALIDATION_ERROR` with a message naming the application. `application_id` cannot be combined with `text`, `url`, `voiceml` or `stream_url`.

## Attaching to a number

Set a number's inbound target to `application` with its `application_id`, or call `POST /v1/applications/{id}/assign`. A target set directly on a number overrides its application. See [Inbound Routing](https://edesy.in/docs/voice-api/phone-numbers/inbound-routing).
