# Status callbacks

Status callbacks are delivered only for calls created through the REST API. Inbound calls never emit status callbacks. Use a [voice URL](/voice/receiving-calls) to handle those instead.

For an API-created call, status callbacks notify your server as the call moves through its lifecycle, so you can react to a call being answered, or track its final outcome, without polling the call resource.

## Configure a status callback

Set `StatusCallback` (the URL) and, optionally, `StatusCallbackMethod` (`GET` or `POST`, defaulting to `POST`) when you create a call. By default, only the `completed` event is delivered. Subscribe to additional events by repeating `StatusCallbackEvent` in the create-call request.

## Events

A call moves through up to four lifecycle events, each with a monotonically increasing `SequenceNumber`:

| Event | SequenceNumber | CallStatus | Delivered by default |
|-------|-----------------|------------|-----------------------|
| `initiated` | `0` | `queued` | No |
| `ringing` | `1` | `ringing` | No |
| `answered` | `2` | `in-progress` | No |
| `completed` | `3` | `completed`, `busy`, `no-answer`, `canceled`, or `failed` | Yes |

The `completed` event is terminal: it fires exactly once per call, and its `CallStatus` carries the specific outcome rather than always being `completed`. A call that never rings still reaches the `completed` event, with `CallStatus` set to `no-answer`, `busy`, or `failed` as appropriate.

## Payload

Each status callback carries the [standard parameters](/voice/webhooks) plus the following:

| Parameter | Description |
|-----------|-------------|
| `Timestamp` | Time the status transition occurred, formatted per RFC 2822 (for example, `Tue, 14 Nov 2023 22:13:20 +0000`). |
| `CallbackSource` | Always `call-progress-events`. |
| `SequenceNumber` | The event's position in the call lifecycle. See the table above. |
| `CallDuration` | Duration of the call, in seconds. Present only on the terminal `completed` event. |

## Delivery

Status callbacks are signed the same way as any other webhook. See [verify webhook signatures](/voice/webhooks). If your server does not respond with a 2xx status code, PressOne retries delivery, up to 5 attempts in total. A call can reach its terminal state through more than one internal transition (for example, both legs of a hangup); PressOne collapses these into a single `completed` delivery rather than sending duplicates.

Respond quickly and with a 2xx status code once you have durably recorded the event. Do not perform slow work such as external API calls before responding, since a delayed response counts against the same 10-second timeout used for other webhook requests.

## Receiver example

The following server logs every transition and responds immediately. It is complete and runnable.

<CodeTabs syncKey="lang">

```javascript title="Node.js"
const express = require("express");
const app = express();
app.use(express.urlencoded({ extended: false }));

app.post("/voice/status-callback", (req, res) => {
  console.log("Call status transition:", {
    callSid: req.body.CallSid,
    callStatus: req.body.CallStatus,
    sequenceNumber: req.body.SequenceNumber,
    timestamp: req.body.Timestamp,
    callDuration: req.body.CallDuration,
  });

  res.sendStatus(200);
});

app.listen(3000);
```

```python title="Python"
from flask import Flask, request

app = Flask(__name__)

@app.route("/voice/status-callback", methods=["POST"])
def status_callback():
    print("Call status transition:", {
        "callSid": request.form.get("CallSid"),
        "callStatus": request.form.get("CallStatus"),
        "sequenceNumber": request.form.get("SequenceNumber"),
        "timestamp": request.form.get("Timestamp"),
        "callDuration": request.form.get("CallDuration"),
    })

    return "", 200

if __name__ == "__main__":
    app.run(port=3000)
```

</CodeTabs>

## Next steps

- [Webhooks](/voice/webhooks): standard parameters, transport, and signature verification.
- [Quickstart](/voice/quickstart): create the outbound call that triggers these events.
- [API reference](/api/voice): the `StatusCallback`, `StatusCallbackMethod`, and `StatusCallbackEvent` fields on create-call.
