> ## Documentation Index
> Fetch the complete documentation index at: https://developers.cloudtalk.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart: Make Your First CloudTalk REST API Call

> Get up and running with the CloudTalk REST API in minutes. List calls, initiate outbound calls, and explore the full endpoint library.

This guide gets you from zero to a working API integration in under five minutes. You'll retrieve a list of calls from your CloudTalk account and trigger a live outbound call — two of the most common operations in any CloudTalk integration. By the end, you'll understand the request format, the response envelope, and where to go next.

## Prerequisites

Before you start, make sure you have:

* A **CloudTalk account** with at least one agent. Outbound calls are placed from the agent, so that agent needs an outbound number configured.
* An **API Access Key ID** and **API Access Key Secret**. If you haven't generated these yet, follow the [Authentication guide](/guides/authentication) first.
* `curl` installed, or an HTTP client of your choice (Python, Node.js, Postman, etc.).

<Tip>
  All examples use `curl` for brevity. The same requests work identically in any language — just swap the tooling. Python and Node.js equivalents are shown where helpful.
</Tip>

***

<Steps>
  <Step title="Confirm Your API Keys">
    You need your API Access Key ID and Secret before any request can succeed. Retrieve them from the CloudTalk Dashboard:

    1. Go to **Account → Settings → API Keys** — or open [https://dashboard.cloudtalk.io/menu/account/settings/API-keys](https://dashboard.cloudtalk.io/menu/account/settings/API-keys) directly.
    2. Copy your **API Access Key ID** (username) and **API Access Key Secret** (password).

    For the rest of this guide, replace `YOUR_KEY_ID` and `YOUR_KEY_SECRET` in every example with your actual values. To keep things tidy, you can export them as environment variables:

    ```bash theme={"system"}
    export CLOUDTALK_KEY_ID="YOUR_KEY_ID"
    export CLOUDTALK_KEY_SECRET="YOUR_KEY_SECRET"
    ```

    <Warning>
      Never paste real credentials directly into a terminal that logs history, and never commit them to source control. Use environment variables or a secrets manager.
    </Warning>
  </Step>

  <Step title="List Your Calls">
    Send a `GET` request to the calls index endpoint. This returns a paginated list of call records from your account:

    <CodeGroup>
      ```bash curl theme={"system"}
      curl -u $CLOUDTALK_KEY_ID:$CLOUDTALK_KEY_SECRET \
        -H "Accept: application/json" \
        https://my.cloudtalk.io/api/calls/index.json
      ```

      ```python Python theme={"system"}
      import requests
      import os

      response = requests.get(
          "https://my.cloudtalk.io/api/calls/index.json",
          auth=(os.environ["CLOUDTALK_KEY_ID"], os.environ["CLOUDTALK_KEY_SECRET"]),
          headers={"Accept": "application/json"},
      )
      response.raise_for_status()
      print(response.json())
      ```

      ```javascript Node.js theme={"system"}
      const creds = Buffer.from(
        `${process.env.CLOUDTALK_KEY_ID}:${process.env.CLOUDTALK_KEY_SECRET}`
      ).toString("base64");

      const res = await fetch("https://my.cloudtalk.io/api/calls/index.json", {
        headers: {
          Authorization: `Basic ${creds}`,
          Accept: "application/json",
        },
      });

      console.log(await res.json());
      ```
    </CodeGroup>

    A successful response returns HTTP `200` with a JSON body.
  </Step>

  <Step title="Understand the Response Envelope">
    Paginated collection endpoints wrap their result set in a `responseData` envelope. Here's an abridged response for the calls list — each element of `data` groups its fields into nested objects rather than one flat record:

    ```json theme={"system"}
    {
      "responseData": {
        "itemsCount": 3,
        "pageCount": 1,
        "pageNumber": 1,
        "limit": 3,
        "data": [
          {
            "Cdr": {
              "id": "27",
              "type": "outgoing",
              "billsec": "0",
              "talking_time": "21",
              "public_external": 421904247371,
              "public_internal": 421221291400,
              "user_id": "1234",
              "recorded": true,
              "started_at": "2017-10-04T06:33:37.000Z",
              "answered_at": "2017-10-04T06:33:37.000Z",
              "ended_at": "2017-10-04T06:33:49.000Z",
              "recording_link": "https://analytics.cloudtalk.io/call-details/27"
            },
            "Contact": { "id": "1234", "name": "Jon Doe", "company": "First ltd." },
            "CallNumber": { "id": "12345", "internal_name": "Sales support" },
            "BillingCall": { "price": "0.000000" },
            "Agent": { "id": "1234", "fullname": "Max Yellow", "status": "online" },
            "Notes": [{ "id": "23", "note": "Call later" }],
            "Tags": [{ "id": "123", "name": "Missed" }]
          }
        ]
      }
    }
    ```

    <Warning>
      Read call fields from the nested objects, not from the top of the record. The call's own ID, direction and timings live under `Cdr`; the external number is `Cdr.public_external`; the agent who handled it is `Cdr.user_id` and the `Agent` object. See [Call history](/api-reference/calls/call-history) for the complete field list.
    </Warning>

    The envelope fields mean:

    | Field        | Type    | Description                                                  |
    | ------------ | ------- | ------------------------------------------------------------ |
    | `itemsCount` | integer | Total number of records matching your query across all pages |
    | `pageCount`  | integer | Total number of pages available                              |
    | `pageNumber` | integer | The current page (1-indexed)                                 |
    | `limit`      | integer | Number of records returned per page                          |
    | `data`       | array   | The actual records for this page                             |

    To fetch the next page, append `?page=2` to your request URL. To set the page size, append `?limit=50` — valid values are `1` to `1000`. Omitting `limit` lets the server apply its own default; the `limit` field in the envelope tells you what was actually applied.

    <Note>
      Not every collection endpoint paginates. [List countries](/api-reference/utilities/list-countries), for example, returns a plain array inside `responseData` with no pagination metadata. Check the endpoint's reference page.
    </Note>

    <Note>
      Date and time values are UTC, but the exact representation varies by endpoint — call records use `2017-10-04T06:33:37.000Z`, while the `date_from` / `date_to` filters take `2017-12-24 12:22:00`. Take the format from the endpoint's reference page.
    </Note>
  </Step>

  <Step title="Make an Outbound Call">
    Once you've confirmed your credentials work, you can trigger a live outbound call. Send a `POST` request to the calls create endpoint, passing the agent ID that should place the call and the phone number to dial:

    <CodeGroup>
      ```bash curl theme={"system"}
      curl -u $CLOUDTALK_KEY_ID:$CLOUDTALK_KEY_SECRET \
        -X POST \
        -H "Content-Type: application/json" \
        -H "Accept: application/json" \
        -d '{"agent_id": 1234, "callee_number": "+442012345678"}' \
        https://my.cloudtalk.io/api/calls/create.json
      ```

      ```python Python theme={"system"}
      import requests
      import os

      response = requests.post(
          "https://my.cloudtalk.io/api/calls/create.json",
          auth=(os.environ["CLOUDTALK_KEY_ID"], os.environ["CLOUDTALK_KEY_SECRET"]),
          headers={"Content-Type": "application/json", "Accept": "application/json"},
          json={"agent_id": 1234, "callee_number": "+442012345678"},
      )
      response.raise_for_status()
      print(response.json())
      ```

      ```javascript Node.js theme={"system"}
      const creds = Buffer.from(
        `${process.env.CLOUDTALK_KEY_ID}:${process.env.CLOUDTALK_KEY_SECRET}`
      ).toString("base64");

      const res = await fetch("https://my.cloudtalk.io/api/calls/create.json", {
        method: "POST",
        headers: {
          Authorization: `Basic ${creds}`,
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        body: JSON.stringify({ agent_id: 1234, callee_number: "+442012345678" }),
      });

      console.log(await res.json());
      ```
    </CodeGroup>

    Replace `1234` with a real agent ID from your account and `+442012345678` with the number you want to dial. CloudTalk rings the agent first — they have 20 seconds to pick up — and dials the callee once the agent answers.

    A successful response returns HTTP `200` with a status-only body. It does **not** return a call record, so there is no call ID to read here:

    ```json theme={"system"}
    {
      "responseData": {
        "status": 200
      }
    }
    ```

    To find the resulting call afterwards, poll [Call history](/api-reference/calls/call-history) filtered by `user_id` and `date_from`.

    <Note>
      The **core API** maps HTTP verbs differently from many REST APIs: `PUT` creates resources, `POST` updates them, and `DELETE` removes them. The `/calls/create.json` endpoint is an exception — it uses `POST` because it triggers an action rather than persisting a new data record. The newer surfaces (Dialer, VoiceAgent, Conversation Intelligence, CueCard) use the conventional mapping instead, though most expose only part of it — `PATCH`, `PUT` and `DELETE` appear on Dialer alone. Always check an endpoint's reference page for the correct HTTP method.
    </Note>
  </Step>

  <Step title="Explore More">
    You've made your first two API calls. Here's where to go next depending on what you're building:

    <CardGroup cols={2}>
      <Card title="API Reference" icon="code" href="/api-reference/overview">
        Browse every endpoint — contacts, agents, SMS, campaigns, AI insights, and more — with full parameter docs and a live request playground.
      </Card>

      <Card title="Conversation Intelligence" icon="brain" href="/api-reference/conversation-intelligence/transcription">
        Pull AI transcriptions, sentiment scores, smart notes, and call topics from completed calls.
      </Card>
    </CardGroup>

    <Tip>
      The CloudTalk API enforces a rate limit of **60 operations per minute per company**. The quota is shared across every API key in your account. If you exceed this limit, you'll receive an HTTP `429 Too Many Requests` response. Build in exponential back-off retry logic for any production integration to handle occasional limit hits gracefully.
    </Tip>
  </Step>
</Steps>


## Related topics

- [CloudTalk REST API: Call Center Automation Platform](/guides/introduction.md)
- [How to Authenticate Requests to the CloudTalk REST API](/guides/authentication.md)
- [Make a call](/api-reference/calls/make-a-call.md)
