# Voice OUT Service CDR Streaming

The **Voice OUT CDR Streamer** enables customers to receive near real-time **Call Detail Records (CDRs)** for outbound
calls.

Important

CDRs are **delivered within 3 seconds** after call completion to the customer's designated **HTTP endpoint**.



---

## HTTP request payload examples

The following is an example of an HTTP **POST** request header used for Voice OUT CDR Streaming. It provides key details
such as the destination server, content type, encoding, and request size.

> ```
> POST /cdr HTTP/1.1
> Host: 192.0.2.5
> User-Agent: CDR-streamer
> Accept: */*
> Content-Type: text/plain
> Content-Encoding: gzip
> Content-Length: 2358
> Expect: 100-continue
> ```
>
> Warning
>
> The request payload is **gzip-encoded**. Ensure that your API supports **gzip decompression**
> for proper processing of incoming CDRs.
>
> See [gzip compression](https://en.wikipedia.org/wiki/HTTP_compression) for more details.



### **Example 1: Call Disconnected Before Connection**

This example represents a **failed outbound call attempt** where the call was disconnected before establishing a
connection:
:   - **Call duration is `0` seconds**, meaning the call did not complete successfully.
    - **No `time\_connect` value**, indicating the call never reached the destination.
    - **Disconnect reason:** "Request terminated (Cancel)", meaning the call was canceled before completion.
    - **Disconnect code:** 487 (Request Terminated).
    - **Point of Presence (POP):** "NYC" (New York data center).

    ```
    {
        "type": "outbound-cdr",
        "id": "3d6af8ac-5ed1-11ea-bc9d-005056845b1e",
        "attributes": {
            "source_ip": "192.0.2.1",
            "call_id": "3eab288b2e0eb547122434ce0e648bb5",
            "call_type": "INTERNATIONAL",
            "time_end": "2025-02-14T14:51:41.894121+00:00",
            "pop": "NYC",
            "disconnect_reason": "Request terminated (Cancel)",
            "price": 0,
            "duration": 0,
            "rate": 0.005,
            "dst_number": "441158720600",
            "time_start": "2025-02-14T14:51:41.894121+00:00",
            "original_src_number": "02089643990",
            "time_connect": null,
            "billing_duration": null,
            "disconnect_code": 487,
            "source_port": 5060,
            "source_protocol": "UDP",
            "success": false,
            "initial_billing_interval": 1,
            "src_number": "123439643990",
            "next_billing_interval": 1,
            "user_agent": "Asterisk PBX 1.8.32.3",
            "trunk_name": "Trunk 1",
            "p_charge_info": "<sip:02089643990@customer.example.com;billing-account-id=212>"
        }
    }
    ```

### **Example 2: Call Failed Due to "Not Found" Response**

This example represents a **failed outbound call attempt** where the destination number was not found:
:   - **Call duration is `0` seconds**, meaning the call did not complete successfully.
    - **No `time\_connect` value**, indicating that the call never reached the destination.
    - **Disconnect reason:** "Not Found", meaning the destination number was unavailable.
    - **Disconnect code:** 404 (Not Found).
    - **Point of Presence (POP):** "FRA" (Frankfurt data center).

    ```
    {
        "type": "outbound-cdr",
        "id": "1c3f702a-5ed0-11ea-bc9c-005056845b1e",
        "attributes": {
            "source_ip": "192.0.2.2",
            "call_id": "60de10410b36681c5dcb8e7804e72540",
            "call_type": "INTERNATIONAL",
            "time_end": "2025-02-14T14:41:04.894121+00:00",
            "pop": "FRA",
            "disconnect_reason": "Not Found",
            "price": 0,
            "duration": 0,
            "rate": 0.005,
            "dst_number": "448009778097",
            "time_start": "2025-02-14T14:41:04.894121+00:00",
            "original_src_number": "07795622299",
            "time_connect": null,
            "billing_duration": null,
            "disconnect_code": 404,
            "source_port": 5060,
            "source_protocol": "UDP",
            "success": false,
            "initial_billing_interval": 1,
            "src_number": "1345322299",
            "next_billing_interval": 1,
            "user_agent": "Asterisk PBX 1.8.32.3",
            "trunk_name": "Trunk 1",
            "p_charge_info": "<sip:1345322299@customer.example.com;billing-account-id=11232>"
        }
    }
    ```

---

## Voice OUT CDR Streaming Attributes

Voice OUT (outgoing) service CDR Streaming Descriptions and Examples






| **Attribute** | **Type** | **Description** | **Example** |
| --- | --- | --- | --- |
| **type** | String | CDR type. Voice OUT CDRs will be marked as **outbound-cdr**. | "outbound-cdr" |
| **id** | String | Unique CDR identifier in UUID format. | "3d6af8ac-5ed1-11ea-bc9d-005056845b1e" |
| **attributes** | Hash | Structure containing all CDR attributes. | *See below for attribute details.* |
| **time\_start** | Timestamp | Start time when the initial SIP INVITE is received. | "2025-02-14T14:41:04.894121+00:00" |
| **time\_connect** | Timestamp | Time after the successful handshake (**200 OK SIP** response).  If the call was never connected, this value is null in the **Call End Event**. | "2025-02-14T14:42:04.894121+00:00" |
| **time\_end** | Timestamp | Time when the call was disconnected. | "2025-02-14T14:41:04.894121+00:00" |
| **duration** | Integer | Call duration in seconds. For non-connected calls, the duration is 0. | 10 |
| **success** | Boolean | Indicates whether the call was successful (true) or not (false). | true |
| **disconnect\_code** | Integer | DIDWW internal disconnect code. | 487 |
| **disconnect\_reason** | String | DIDWW internal disconnect reason. | "Request terminated (Cancel)" |
| **call\_id** | String | SIP Call-ID of the call leg between the customer's equipment and DIDWW. | "3eab288b2e0eb547122434ce0e648bb5" |
| **source\_ip** | String | IP address of the call originator. | "192.0.2.1" |
| **source\_port** | Integer | Port of the call originator. | 5060 |
| **source\_protocol** | String | SIP transport protocol used between the customer and DIDWW platform.  Possible values:  - UDP - TCP - TLS | "UDP" |
| **trunk\_name** | String | Outbound trunk friendly name defined by the customer during trunk creation. | "Trunk 1" |
| **call\_type** | String | Call type.  Possible values:  - INTERNATIONAL - ORIGIN - LOCAL | "INTERNATIONAL" |
| **src\_name** | String | Incoming caller name. | "Customer Caller" |
| **original\_src\_number** | String | Incoming Caller-ID before any modifications. | "02089643990" |
| **src\_number** | String | Caller-ID after applying number rewrites. | "123439643990" |
| **dst\_number** | String | Called destination number. | "441158720600" |
| **customer\_vat** | Numeric | Charged VAT amount for the call. | 0.00 |
| **rate** | Numeric | Customer outbound call termination rate. | 0.005 |
| **initial\_billing\_interval** | Integer | Initial billing interval for the outbound call termination. | 1 |
| **next\_billing\_interval** | Integer | Next billing interval for the outbound call termination. | 1 |
| **billing\_duration** | Integer | Call duration rounded to the configured billing interval for the outbound call termination. | 10 |
| **price** | Numeric | Customer accumulated amount for the outbound call termination. | 0.004 |
| **pop** | String | Location of DIDWW equipment that processed the call.  See [DIDWW Point of Presence](../presence/index.html#presence).  Possible values:  - NYC - USA, New York - LAC - USA, Los Angeles - MIA - USA, Miami - FRA - Germany, Frankfurt - AMS - Netherlands, Amsterdam - SG - Singapore - HG - Hong Kong | "NYC" |
| **user\_agent** | String | User-Agent and Server header values from the customer's gateway. | "Asterisk PBX 1.8.32.3" |
| **p\_charge\_info** | String | P-Charge-Info header value received from the call originator.  Using this header, customers can add custom information to the DIDWW CDR for technical and billing purposes.  See [Service description](../voice/outbound-trunks/outbound-sip-information.html#service-termination-sip-details-p-charge-info) for more details. | "<sip:02089643990@customer.example.com;billing-account-id=212>" |

---

## Batching

The **CDR Streaming Interface** delivers Call Detail Records (**CDRs**) in batches to optimize data transmission. A
single HTTP **POST** request can contain multiple CDRs.

Key Details:
:   - The CDRs are separated by new lines.
    - The maximum batch size is 1,000 CDRs per request.
    - The destination API must be capable of processing multiple CDRs within the same request.

### Example: CDRs in a Batch

Below is an example of a payload containing four CDRs.

> ```
> { "type" : "outbound-cdr", "attributes" : { "source_ip" : "1.1.1.1", "call_id" : "J8H0Ngr2KqDI2VHvnM_cug..", "call_type" : "INTERNATIONAL", "time_end" : "2025-05-06T11:31:21.445275+00:00", "pop" : "FRA", "disconnect_reason" : "Bye", "source_protocol" : "UDP", "trunk_name" : "Testing", "time_start" : "2025-05-06T11:31:10.153975+00:00", "p_charge_info" : null, "duration" : 10, "rate" : 0.004, "dst_number" : "18312630056", "price" : 0.0009, "original_src_number" : "1234567890", "time_connect" : "2025-05-06T11:31:11.689451+00:00", "billing_duration" : 10, "disconnect_code" : 200, "source_port" : 55407, "success" : true, "initial_billing_interval" : 1, "src_number" : "1234567890", "next_billing_interval" : 1, "user_agent" : "Z 3.15.40006 rv2.8.20" }, "id" : "a4129ecc-2a6d-11f0-acf8-005056845b1e" }
> { "type" : "outbound-cdr", "attributes" : { "source_ip" : "1.1.1.1", "call_id" : "9RxsZ9Cg49eQyL_4pLMozw..", "call_type" : "INTERNATIONAL", "time_end" : "2025-05-06T11:31:22.004348+00:00", "pop" : "FRA", "disconnect_reason" : "Bye", "source_protocol" : "UDP", "trunk_name" : "Testing", "time_start" : "2025-05-06T11:31:11.095435+00:00", "p_charge_info" : null, "duration" : 10, "rate" : 0.004, "dst_number" : "18312630056", "price" : 0.0009, "original_src_number" : "1234567890", "time_connect" : "2025-05-06T11:31:12.093368+00:00", "billing_duration" : 10, "disconnect_code" : 200, "source_port" : 55407, "success" : true, "initial_billing_interval" : 1, "src_number" : "1234567890", "next_billing_interval" : 1, "user_agent" : "Z 3.15.40006 rv2.8.20" }, "id" : "a4129edb-2a6d-11f0-acf8-005056845b1e" }
> { "type" : "outbound-cdr", "attributes" : { "source_ip" : "1.1.1.1", "call_id" : "tK8RP-FKOat-PQ6w9AGZWg..", "call_type" : "INTERNATIONAL", "time_end" : "2025-05-06T11:31:22.313018+00:00", "pop" : "FRA", "disconnect_reason" : "Bye", "source_protocol" : "UDP", "trunk_name" : "Testing", "time_start" : "2025-05-06T11:31:11.674592+00:00", "p_charge_info" : null, "duration" : 10, "rate" : 0.004, "dst_number" : "18312630056", "price" : 0.0009, "original_src_number" : "1234567890", "time_connect" : "2025-05-06T11:31:13.265197+00:00", "billing_duration" : 10, "disconnect_code" : 200, "source_port" : 55407, "success" : true, "initial_billing_interval" : 1, "src_number" : "1234567890", "next_billing_interval" : 1, "user_agent" : "Z 3.15.40006 rv2.8.20" }, "id" : "a4129ee0-2a6d-11f0-acf8-005056845b1e" }
> { "type" : "outbound-cdr", "attributes" : { "source_ip" : "1.1.1.1", "call_id" : "xhPdn64_8rL6saZuVo0Ehg..", "call_type" : "INTERNATIONAL", "time_end" : "2025-05-06T11:31:23.005127+00:00", "pop" : "FRA", "disconnect_reason" : "Bye", "source_protocol" : "UDP", "trunk_name" : "Testing", "time_start" : "2025-05-06T11:31:12.687149+00:00", "p_charge_info" : null, "duration" : 10, "rate" : 0.004, "dst_number" : "18312630056", "price" : 0.0009, "original_src_number" : "1234567890", "time_connect" : "2025-05-06T11:31:13.816983+00:00", "billing_duration" : 10, "disconnect_code" : 200, "source_port" : 55407, "success" : true, "initial_billing_interval" : 1, "src_number" : "1234567890", "next_billing_interval" : 1, "user_agent" : "Z 3.15.40006 rv2.8.20" }, "id" : "a4129ee9-2a6d-11f0-acf8-005056845b1e" }
> ```
>
> Note
>
> - Ensure that your system is capable of parsing multiple new line separated **JSON objects**.
> - Each CDR object is not enclosed in a larger array or object.

---

## Error Handling

The **CDR Streaming Interface** determines whether a batch of CDRs has been successfully processed based on the HTTP
response from the destination API.

Success Criteria:
:   - If the API responds with a **2xx HTTP status code**, all CDRs in that request are marked as **processed** and
automatically removed from the queue.

Failure & Retry Mechanism:
:   - If the API returns a **non-2xx response** (e.g., 4xx or 5xx) or the request **times out**, the CDRs **remain in
the queue**.
    - A **retry attempt** will occur **after 3 seconds** to ensure delivery.

Warning

1. **Queue Size Limit**
   :   - The **CDR queue is limited to 10,000 records per customer**.
       - Extended downtime or delays in processing requests may result in **CDR loss** at the customer's endpoint.
       - The **CDR Streaming mechanism should not be the sole method** for retrieving CDRs.
       - For alternative retrieval methods, refer to the [API documentation](../api3/2022-05-10/export/index.html#export-v33).
2. **Timeout Handling**
   :   - If the **HTTP endpoint does not respond within 10 seconds**, the request **will time out**, triggering an
**automatic retry**.
       - Ensure the destination API can handle incoming requests efficiently to prevent unnecessary retries.
3. **Idempotency**
   :   - Be aware of possible retries for successfully processed batches due to network issues (sender not received your
*2xx HTTP status code*)
       - CDRs id is guaranteed to be unique so can be used to ensure exactly once processing by API

On this page
