# Quickstart

This guide walks you through placing your first call with the Programmable Voice API in a few minutes.

## Before you begin

You need:

- Your account SID and auth token, available from the dashboard.
- A phone number your account owns, to use as the caller ID (`From`).
- A destination number to call (`To`). Your own phone works well for testing.

## Make your first call

The following examples create an outbound call that speaks a short greeting. The call script is passed inline with `Twiml`, so no webhook server is required for this first call.

<CodeTabs syncKey="lang">

```bash title="curl"
curl -X POST "https://api.helios.pressone.co/2010-04-01/Accounts/ACCOUNT_SID/Calls.json" \
  -u ACCOUNT_SID:AUTH_TOKEN \
  -d "To=+2341800000001" \
  -d "From=+2341700000000" \
  -d "Twiml=<Response><Say>Hello from PressOne. Your first call works.</Say></Response>"
```

```javascript title="Node.js"
const accountSid = "ACCOUNT_SID";
const authToken = "AUTH_TOKEN";

const params = new URLSearchParams({
  To: "+2341800000001",
  From: "+2341700000000",
  Twiml: "<Response><Say>Hello from PressOne. Your first call works.</Say></Response>",
});

const response = await fetch(
  `https://api.helios.pressone.co/2010-04-01/Accounts/${accountSid}/Calls.json`,
  {
    method: "POST",
    headers: {
      Authorization: `Basic ${Buffer.from(`${accountSid}:${authToken}`).toString("base64")}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: params,
  },
);

const call = await response.json();
console.log(call.sid, call.status);
```

```python title="Python"
import requests

account_sid = "ACCOUNT_SID"
auth_token = "AUTH_TOKEN"

response = requests.post(
    f"https://api.helios.pressone.co/2010-04-01/Accounts/{account_sid}/Calls.json",
    auth=(account_sid, auth_token),
    data={
        "To": "+2341800000001",
        "From": "+2341700000000",
        "Twiml": "<Response><Say>Hello from PressOne. Your first call works.</Say></Response>",
    },
)

call = response.json()
print(call["sid"], call["status"])
```

</CodeTabs>

<OpenPlaygroundButton
  server="https://api.helios.pressone.co"
  url="/2010-04-01/Accounts/{AccountSid}/Calls.json"
  method="POST"
  pathParams={[{ name: "AccountSid", defaultValue: "ACCOUNT_SID" }]}
  headers={[{ name: "Content-Type", defaultValue: "application/x-www-form-urlencoded" }]}
  body={"To=+2341800000001&From=+2341700000000&Twiml=<Response><Say>Hello from PressOne. Your first call works.</Say></Response>"}
>
  Try it in the playground
</OpenPlaygroundButton>

## The response

A successful request returns `201` with the new call resource. The call starts in the `queued` status, and `direction` is `outbound-api` because it originated through the REST API rather than as an inbound call:

```json
{
  "sid": "CA5388f7a5e04d0ed71cac5cdf1ea17a53",
  "account_sid": "AC9ce1cd445308e3ec5080c6126288aa09",
  "api_version": "2010-04-01",
  "date_created": "Thu, 02 Jul 2026 12:00:00 +0000",
  "date_updated": "Thu, 02 Jul 2026 12:00:00 +0000",
  "to": "+2341800000001",
  "to_formatted": "+2341800000001",
  "from": "+2341700000000",
  "from_formatted": "+2341700000000",
  "direction": "outbound-api",
  "status": "queued",
  "start_time": null,
  "end_time": null,
  "duration": null,
  "price": null,
  "price_unit": null,
  "queue_time": "0",
  "phone_number_sid": "PN9992109eed74a671cdc4e192a934d43e",
  "parent_call_sid": null,
  "annotation": null,
  "answered_by": null,
  "caller_name": null,
  "forwarded_from": null,
  "group_sid": null,
  "trunk_sid": null,
  "subresource_uris": {
    "recordings": "/2010-04-01/Accounts/AC9ce1cd445308e3ec5080c6126288aa09/Calls/CA5388f7a5e04d0ed71cac5cdf1ea17a53/Recordings.json"
  },
  "uri": "/2010-04-01/Accounts/AC9ce1cd445308e3ec5080c6126288aa09/Calls/CA5388f7a5e04d0ed71cac5cdf1ea17a53.json"
}
```

Save the `sid`: it identifies this call in every subsequent request.

## Verify the result

Fetch the call resource to check on its progress:

```bash
curl -u ACCOUNT_SID:AUTH_TOKEN \
  "https://api.helios.pressone.co/2010-04-01/Accounts/ACCOUNT_SID/Calls/CA5388f7a5e04d0ed71cac5cdf1ea17a53.json"
```

<OpenPlaygroundButton
  server="https://api.helios.pressone.co"
  url="/2010-04-01/Accounts/{AccountSid}/Calls/{CallSid}.json"
  method="GET"
  pathParams={[
    { name: "AccountSid", defaultValue: "ACCOUNT_SID" },
    { name: "CallSid", defaultValue: "CA5388f7a5e04d0ed71cac5cdf1ea17a53" },
  ]}
>
  Try it in the playground
</OpenPlaygroundButton>

The `status` field moves through the following values as the call progresses:

| Status | Meaning |
|--------|---------|
| `queued` | The call has been accepted and is waiting to be placed. |
| `ringing` | The destination phone is ringing. |
| `in-progress` | The call was answered and is connected. |
| `completed` | The call ended normally. |

If the destination does not answer within the ring timeout (60 seconds by default, configurable with the `Timeout` field on create-call), the status becomes `no-answer` instead of `completed`. Poll the call resource, or use a [status callback](/voice/status-callbacks) to be notified of the transition instead of polling.

## Next steps

- [Receiving calls](/voice/receiving-calls): handle inbound calls and build an IVR menu.
- [OneML overview](/voice/oneml/overview): every verb available for scripting a call.
- [API reference](/api/voice): complete REST endpoint documentation.
