> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.jambonz.org/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.jambonz.org/_mcp/server.

# New Call

POST https://{yourserver}/webhooks/call
Content-Type: application/json

This webhook is sent when a new call is created on the platform, it is configured at the appplication level

Reference: https://docs.jambonz.org/reference/webhooks/call-hook-get

## Authentication

- `Authorization` header (basic auth, required) — Basic authentication of the form `Basic <base64(username:password)>`.

## Request

### Body (application/json)

This endpoint expects a CallHook.

- `call_sid` (string, required) — a unique identifier for the call.
- `call_id` (string, required) — the call id in our server.
- `application_sid` (string, required) — a unique identifier for the jambonz application controlling this call
- `account_sid` (string, required) — a unique identifier for the jambonz account associated with the application
- `direction` (enum, required) — the direction of the call: * `inbound` - The call was originated outside jambonz * `outbound` - The call was originated by jambonz
  - Allowed values: `inbound`, `outbound`
- `from` (string, required) — the calling party number
- `to` (string, required) — the called party number
- `caller_name` (string, required) — the caller name, if known
- `sip_status` (double, required) — the most recent sip status code received or generated for the call
- `sip_reason` (string, required) — the reason phrase from the SIP status LINE of the last response (e.g. `Trying`, `OK`, `Busy Here`). This is not the RFC 3326 `Reason` header - see `sip_reason_header`.
- `call_status` (enum, required) — current status of the call: * `trying` - a new incoming call has arrived or an outbound call has just been sent * `ringing` - a 180 Ringing response has been sent or received * `early-media` - an early media connection has been established prior to answering the call (183 Session Progress) * `in-progress` - call has been answered * `completed` - an answered call has ended * `failed` - a call attempt failed * `busy` - a call attempt failed because the called party returned a busy status * `no-answer` - a call attempt failed because it was not answered in time
  - Allowed values: `trying`, `ringing`, `early-media`, `in-progress`, `completed`, `failed`, `busy`, `no-answer`
- `sip_reason_header` (string, optional) — the RFC 3326 `Reason` header of the SIP message that caused this status change, if it carried one; omitted otherwise. Carriers fronting ISDN/E1 PRI trunks put the authoritative disconnect cause here rather than in the status line, and the same SIP status can carry different causes - a `503` may be `cause=38` (network out of order) or `cause=41` (temporary failure) - so the status code alone cannot classify the outcome of a call. A `408` with `Q.850;cause=18` ("no user responding") is a call nobody answered, not a platform fault. Present on whichever event observed it: a final failure response, a `BYE` on an answered call, or a `CANCEL` from a caller who gave up. The `CANCEL` case matters most, because the `487` and its `Request Terminated` phrase are generated by jambonz itself - so without this header every abandoned inbound call looks identical, and `SIP;cause=200;text="Call completed elsewhere"` is what distinguishes a forked branch losing the race from a caller who hung up. Two parsing caveats: the header is re-serialized in transit, which normalizes the optional whitespace RFC 3326 allows around `;`, so a carrier's `Q.850 ;cause=18` arrives as `Q.850;cause=18` - parse tolerantly rather than string-matching. And a message may carry more than one `Reason` header, in which case they arrive comma-separated; split on commas outside quotes, since a `text="..."` value may contain one.
- `sbc_callid` (string, optional) — the orignal call ID of the call when it arrived at jambonz
- `originating_sip_ip` (string, optional) — The IP address that send the call to jambonz
- `originating_sip_trunk_name` (string, optional) — The name of the carrier in Jambonz that recieved the call
- `local_sip_address` (string, optional) — Internal Address of the Feature Server handling the call
- `service_provider_sid` (string, optional) — The ID of the service provider the account handling the call belongs to
- `sip` (sipRequest, optional) — The SIP request for the call
- `env_vars` (CallHookEnvVars, optional) — Application Environment Variables configured for the applicaiton

## Response

### 200

Return a 200 containing a JSON payload consisting of an array of verbs

## Types

### sipRequest

- `raw` (string, required) — the complete SIP request as a single string.
- `headers` (SipRequestHeaders, required) — each of the SIP headers as a key/value object
- `body` (string, required) — the body of the request, containing SDP
- `method` (string, required) — The SIP method
- `version` (string, required) — the SIP version
- `uri` (string, required) — The SIP URI of the request
- `payload` (SipRequestPayload, required) — the body of the request

### CallHookEnvVars

Application Environment Variables configured for the applicaiton

### SipRequestHeaders

each of the SIP headers as a key/value object

### SipRequestPayload

the body of the request

## Examples

**Request**

```json
{
  "call_sid": "d2515c3b-b79a-41a2-971a-445e769c823c",
  "call_id": "d2515c3b-b79a-41a2-971a-445e769c823c",
  "application_sid": "72c5c38f-9bba-40ce-aa83-aaa6be55e1b5",
  "account_sid": "bad98250-b34d-459d-9e90-f97dfb9bc519",
  "direction": "inbound",
  "from": "+12125551212",
  "to": "+14155551234",
  "caller_name": "John Doe",
  "sip_status": 100,
  "sip_reason": "Trying",
  "call_status": "trying"
}
```

**Response**

```json
{}
```

**SDK Code**

```python
import requests

url = "https://{yourserver}/webhooks/call"

payload = {
    "call_sid": "d2515c3b-b79a-41a2-971a-445e769c823c",
    "call_id": "d2515c3b-b79a-41a2-971a-445e769c823c",
    "application_sid": "72c5c38f-9bba-40ce-aa83-aaa6be55e1b5",
    "account_sid": "bad98250-b34d-459d-9e90-f97dfb9bc519",
    "direction": "inbound",
    "from": "+12125551212",
    "to": "+14155551234",
    "caller_name": "John Doe",
    "sip_status": 100,
    "sip_reason": "Trying",
    "call_status": "trying"
}
headers = {
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers, auth=("<username>", "<password>"))

print(response.json())
```

```javascript
const url = 'https://{yourserver}/webhooks/call';
const credentials = btoa("<username>:<password>");

const options = {
  method: 'POST',
  headers: {
    Authorization: `Basic ${credentials}`,
    'Content-Type': 'application/json'
  },
  body: '{"call_sid":"d2515c3b-b79a-41a2-971a-445e769c823c","call_id":"d2515c3b-b79a-41a2-971a-445e769c823c","application_sid":"72c5c38f-9bba-40ce-aa83-aaa6be55e1b5","account_sid":"bad98250-b34d-459d-9e90-f97dfb9bc519","direction":"inbound","from":"+12125551212","to":"+14155551234","caller_name":"John Doe","sip_status":100,"sip_reason":"Trying","call_status":"trying"}'
};

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://{yourserver}/webhooks/call"

	payload := strings.NewReader("{\n  \"call_sid\": \"d2515c3b-b79a-41a2-971a-445e769c823c\",\n  \"call_id\": \"d2515c3b-b79a-41a2-971a-445e769c823c\",\n  \"application_sid\": \"72c5c38f-9bba-40ce-aa83-aaa6be55e1b5\",\n  \"account_sid\": \"bad98250-b34d-459d-9e90-f97dfb9bc519\",\n  \"direction\": \"inbound\",\n  \"from\": \"+12125551212\",\n  \"to\": \"+14155551234\",\n  \"caller_name\": \"John Doe\",\n  \"sip_status\": 100,\n  \"sip_reason\": \"Trying\",\n  \"call_status\": \"trying\"\n}")

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

	req.SetBasicAuth("<username>", "<password>")
	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://{yourserver}/webhooks/call")

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

request = Net::HTTP::Post.new(url)
request.basic_auth("<username>", "<password>")
request["Content-Type"] = 'application/json'
request.body = "{\n  \"call_sid\": \"d2515c3b-b79a-41a2-971a-445e769c823c\",\n  \"call_id\": \"d2515c3b-b79a-41a2-971a-445e769c823c\",\n  \"application_sid\": \"72c5c38f-9bba-40ce-aa83-aaa6be55e1b5\",\n  \"account_sid\": \"bad98250-b34d-459d-9e90-f97dfb9bc519\",\n  \"direction\": \"inbound\",\n  \"from\": \"+12125551212\",\n  \"to\": \"+14155551234\",\n  \"caller_name\": \"John Doe\",\n  \"sip_status\": 100,\n  \"sip_reason\": \"Trying\",\n  \"call_status\": \"trying\"\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://{yourserver}/webhooks/call")
  .basicAuth("<username>", "<password>")
  .header("Content-Type", "application/json")
  .body("{\n  \"call_sid\": \"d2515c3b-b79a-41a2-971a-445e769c823c\",\n  \"call_id\": \"d2515c3b-b79a-41a2-971a-445e769c823c\",\n  \"application_sid\": \"72c5c38f-9bba-40ce-aa83-aaa6be55e1b5\",\n  \"account_sid\": \"bad98250-b34d-459d-9e90-f97dfb9bc519\",\n  \"direction\": \"inbound\",\n  \"from\": \"+12125551212\",\n  \"to\": \"+14155551234\",\n  \"caller_name\": \"John Doe\",\n  \"sip_status\": 100,\n  \"sip_reason\": \"Trying\",\n  \"call_status\": \"trying\"\n}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://{yourserver}/webhooks/call', [
  'body' => '{
  "call_sid": "d2515c3b-b79a-41a2-971a-445e769c823c",
  "call_id": "d2515c3b-b79a-41a2-971a-445e769c823c",
  "application_sid": "72c5c38f-9bba-40ce-aa83-aaa6be55e1b5",
  "account_sid": "bad98250-b34d-459d-9e90-f97dfb9bc519",
  "direction": "inbound",
  "from": "+12125551212",
  "to": "+14155551234",
  "caller_name": "John Doe",
  "sip_status": 100,
  "sip_reason": "Trying",
  "call_status": "trying"
}',
  'headers' => [
    'Content-Type' => 'application/json',
  ],
    'auth' => ['<username>', '<password>'],
]);

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

```csharp
using RestSharp;
using RestSharp.Authenticators;

var client = new RestClient("https://{yourserver}/webhooks/call");
client.Authenticator = new HttpBasicAuthenticator("<username>", "<password>");
var request = new RestRequest(Method.POST);

request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"call_sid\": \"d2515c3b-b79a-41a2-971a-445e769c823c\",\n  \"call_id\": \"d2515c3b-b79a-41a2-971a-445e769c823c\",\n  \"application_sid\": \"72c5c38f-9bba-40ce-aa83-aaa6be55e1b5\",\n  \"account_sid\": \"bad98250-b34d-459d-9e90-f97dfb9bc519\",\n  \"direction\": \"inbound\",\n  \"from\": \"+12125551212\",\n  \"to\": \"+14155551234\",\n  \"caller_name\": \"John Doe\",\n  \"sip_status\": 100,\n  \"sip_reason\": \"Trying\",\n  \"call_status\": \"trying\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let credentials = Data("<username>:<password>".utf8).base64EncodedString()

let headers = [
  "Authorization": "Basic \(credentials)",
  "Content-Type": "application/json"
]
let parameters = [
  "call_sid": "d2515c3b-b79a-41a2-971a-445e769c823c",
  "call_id": "d2515c3b-b79a-41a2-971a-445e769c823c",
  "application_sid": "72c5c38f-9bba-40ce-aa83-aaa6be55e1b5",
  "account_sid": "bad98250-b34d-459d-9e90-f97dfb9bc519",
  "direction": "inbound",
  "from": "+12125551212",
  "to": "+14155551234",
  "caller_name": "John Doe",
  "sip_status": 100,
  "sip_reason": "Trying",
  "call_status": "trying"
] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://{yourserver}/webhooks/call")! 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()
```