> ## Documentation Index
> Fetch the complete documentation index at: https://docs.60db.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Dialer

> Rent phone numbers, manage calls and recordings, and build voice apps

## Overview

60db's **Dialer** API lets you rent Indian phone numbers (E.164 format, e.g. `+919876543210`), place inbound and outbound calls through a SIP client, record conversations, and manage billing per-workspace. Every number costs ₹600/month; calls cost ₹0.30/min, prorated per second, inbound and outbound.

<Info>
  **Setup prerequisites (done in the 60db Dashboard, not via API):**

  * **Trunk setup** — Dashboard → Dialer → Trunks. Configure inbound/outbound SIP trunks and download your SIP credentials. Calls and recordings require this; endpoints return 409 DIALER\_NOT\_PROVISIONED without it.
  * **KYC approval** — Dashboard → Dialer → KYC. Submit PAN/Aadhaar and address proof. Buying numbers requires KYC approval; endpoints return 403 DIALER\_KYC\_REQUIRED/PENDING/REJECTED without it. **KYC is not available through the API.**
</Info>

<CardGroup cols={2}>
  <Card title="Phone Numbers" icon="phone">
    Rent numbers from shared pool; set a default caller ID
  </Card>

  <Card title="Call Management" icon="phone-flip">
    Reserve calls via API; dial through your SIP client
  </Card>

  <Card title="Recordings" icon="microphone">
    Auto-record calls; fetch transcripts and playback links
  </Card>

  <Card title="Webhooks" icon="webhook">
    Real-time call and recording events (SDK & docs only)
  </Card>
</CardGroup>

## How Calls Work

**Important:** The API does **not** dial. Instead:

1. You **reserve a call** via `POST /dialer/calls` with a SIP call ID
2. A SIP client (softphone, PBX, or your phone app) registered with the workspace's SIP credentials **sends the actual SIP INVITE**
3. The API authorizes the call using the reservation

This separation means:

* Your backend reserves calls without initiating them
* Your client-side SIP logic owns call lifecycle (answer, transfer, hang up)
* The API tracks, records, and bills the call

Set up your SIP credentials and inbound/outbound trunks in the **dashboard** under Dialer settings.

## Numbers Lifecycle

<Steps>
  <Step title="Search available numbers">
    See what's in the shared pool via `GET /dialer/pool`
  </Step>

  <Step title="Buy a number">
    Reserve and allocate via `POST /dialer/pool/allocate` (charges $6.00 now + $6.00/month; requires Gate K)
  </Step>

  <Step title="Set a default caller ID">
    Use `PUT /dialer/caller-id` (requires Gate T)
  </Step>

  <Step title="Use for calls">
    Calls show your number as the outbound caller ID
  </Step>

  <Step title="Release the number">
    Call `DELETE /dialer/numbers/{e164}` to cancel the rental and stop monthly charges
  </Step>
</Steps>

## Quickstart

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    import { SixtyDBClient } from '60db';

    const client = new SixtyDBClient('your-api-key');

    // Check account status
    const status = await client.dialer.status();
    console.log('Provisioned:', status.data.provisioned);

    // Search available numbers
    const pool = await client.dialer.numbers.search();
    console.log('Available:', pool.data.available);

    // Buy a number (requires confirmation)
    const bought = await client.dialer.numbers.buy({
      number: '+919876543210'
    });
    console.log('Bought:', bought.data.number);

    // Set default caller ID
    await client.dialer.numbers.setCallerId({ caller_id: '+919876543210' });

    // List your numbers
    const myNumbers = await client.dialer.numbers.list();
    console.log('My numbers:', myNumbers.data.numbers);

    // Reserve a call (requires SIP client to send INVITE)
    const call = await client.dialer.calls.reserve({
      to: '+919999999999',
      from: '+919876543210',
      sipCallId: 'call-uuid-from-sip-client'
    });
    console.log('Call reserved:', call.data.call.id);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from sixtydb import SixtyDBClient

    client = SixtyDBClient('your-api-key')

    # Check account status
    status = client.dialer.status()
    print('Provisioned:', status['data']['provisioned'])

    # Search available numbers
    pool = client.dialer.numbers.search()
    print('Available:', pool['data']['available'])

    # Buy a number (requires confirmation)
    bought = client.dialer.numbers.buy(number='+919876543210')
    print('Bought:', bought['data']['number'])

    # Set default caller ID
    client.dialer.numbers.set_caller_id(caller_id='+919876543210')

    # List your numbers
    my_numbers = client.dialer.numbers.list()
    print('My numbers:', my_numbers['data']['numbers'])

    # Reserve a call (requires SIP client to send INVITE)
    call = client.dialer.calls.reserve(
        to='+919999999999',
        from_number='+919876543210',
        sip_call_id='call-uuid-from-sip-client'
    )
    print('Call reserved:', call['data']['call']['id'])
    ```
  </Tab>
</Tabs>

## Recordings & Transcripts

Auto-recorded calls can be played back and transcribed:

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    // List all recordings
    const recordings = await client.dialer.recordings.list({ limit: 50 });

    // Get playback URL (valid ~5 min)
    const playback = await client.dialer.recordings.playbackUrl('recording-id');
    console.log('Listen at:', playback.data.playback_url);

    // Fetch transcript (cached after first call)
    const transcript = await client.dialer.recordings.transcript('recording-id');
    console.log('Transcript:', transcript.data);

    // Delete a recording
    await client.dialer.recordings.delete('recording-id');

    // Toggle recording on/off for all outbound calls
    await client.dialer.recordings.setEnabled(false);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # List all recordings
    recordings = client.dialer.recordings.list(limit=50)

    # Get playback URL (valid ~5 min)
    playback = client.dialer.recordings.playback_url('recording-id')
    print('Listen at:', playback['data']['playback_url'])

    # Fetch transcript (cached after first call)
    transcript = client.dialer.recordings.transcript('recording-id')
    print('Transcript:', transcript['data'])

    # Delete a recording
    client.dialer.recordings.delete('recording-id')

    # Toggle recording on/off for all outbound calls
    client.dialer.recordings.set_enabled(False)
    ```
  </Tab>
</Tabs>

## Setup & Gates

### Gate T (Trunk Setup)

Required for: calls, recordings, line status, caller ID changes

Set up in **Dashboard → Dialer → Trunks**:

* Inbound trunk (to receive calls)
* Outbound trunk (to place calls)
* SIP credentials (used by your SIP client)

Without a trunk, these endpoints return **409 DIALER\_NOT\_PROVISIONED**.

### Gate K (KYC Approval)

Required for: buying numbers

Submit in **Dashboard → Dialer → KYC**:

* PAN (Permanent Account Number)
* Aadhaar or passport
* Address proof

States:

* `DIALER_KYC_PENDING` — submission received, waiting for verification
* `DIALER_KYC_APPROVED` — you can buy numbers
* `DIALER_KYC_REJECTED` — resubmit with correct documents

## Pricing

| Service               | Cost                                                                  |
| --------------------- | --------------------------------------------------------------------- |
| Monthly number rental | ₹600 (\$6.00) per month, charged at purchase + monthly renewal        |
| Inbound calls         | ₹0.30/min (\$0.003/min), prorated per second                          |
| Outbound calls        | ₹0.30/min (\$0.003/min), prorated per second                          |
| Grace period          | 48 hours after renewal date; after grace, unpaid numbers are released |

**Billing:**

* Buying a number charges ₹600 immediately and every month thereafter
* If your wallet is short, purchase returns **402 RECHARGE\_REQUIRED** and is rolled back
* Call minutes are charged later and may take your wallet negative (within the 48 h grace period)

## Error Codes

| Status | Code                     | Meaning                                                              |
| ------ | ------------------------ | -------------------------------------------------------------------- |
| 402    | `RECHARGE_REQUIRED`      | Wallet balance too low (buying a number or placing an outbound call) |
| 403    | `DIALER_KYC_REQUIRED`    | KYC not started (buying a number)                                    |
| 403    | `DIALER_KYC_PENDING`     | KYC pending approval (buying a number)                               |
| 403    | `DIALER_KYC_REJECTED`    | KYC rejected; resubmit (buying a number)                             |
| 403    | `CALLER_ID_NOT_OWNED`    | The `from` number in a call reservation isn't your number            |
| 409    | `DIALER_NOT_PROVISIONED` | Trunk not set up (calls, recordings, line status, caller ID)         |
| 409    | `POOL_EMPTY`             | No numbers available (searching or buying)                           |
| 409    | `NUMBER_NOT_AVAILABLE`   | Specific number is taken (buying a specific number)                  |
| 409    | `POOL_EMPTY`             | Shared pool is exhausted                                             |
| 502    | `CARRIER_LINE_DOWN`      | Carrier is unavailable (placing a call)                              |
| 503    | Service unavailable      | Dialer service is temporarily down                                   |

## API Reference

<CardGroup cols={3}>
  <Card title="Status" icon="circle-info" href="/api-reference/dialer/get-status">
    Account provisioning status
  </Card>

  <Card title="Search Numbers" icon="search" href="/api-reference/dialer/search-numbers">
    Browse available pool
  </Card>

  <Card title="Buy Number" icon="plus" href="/api-reference/dialer/buy-number">
    Allocate from pool
  </Card>

  <Card title="List Numbers" icon="phone" href="/api-reference/dialer/list-numbers">
    Your rented numbers
  </Card>

  <Card title="Release Number" icon="trash" href="/api-reference/dialer/release-number">
    Cancel rental
  </Card>

  <Card title="Set Caller ID" icon="id-card" href="/api-reference/dialer/set-caller-id">
    Default outbound ID
  </Card>

  <Card title="List Calls" icon="list" href="/api-reference/dialer/list-calls">
    Call history (CDR)
  </Card>

  <Card title="Get Call" icon="phone-flip" href="/api-reference/dialer/get-call">
    Call details
  </Card>

  <Card title="Live Calls" icon="circle-dot" href="/api-reference/dialer/live-calls">
    In-flight calls
  </Card>

  <Card title="Line Status" icon="signal" href="/api-reference/dialer/line-status">
    Carrier line status
  </Card>

  <Card title="Reserve Call" icon="lock" href="/api-reference/dialer/reserve-call">
    Authorize before SIP INVITE
  </Card>

  <Card title="List Recordings" icon="microphone" href="/api-reference/dialer/list-recordings">
    Call recordings
  </Card>

  <Card title="Playback URL" icon="play" href="/api-reference/dialer/recording-playback-url">
    Listen to recording
  </Card>

  <Card title="Transcript" icon="message" href="/api-reference/dialer/recording-transcript">
    Recording transcript
  </Card>

  <Card title="Delete Recording" icon="trash" href="/api-reference/dialer/delete-recording">
    Remove recording
  </Card>

  <Card title="Toggle Recording" icon="toggle-on" href="/api-reference/dialer/toggle-recording">
    Enable/disable auto-record
  </Card>

  <Card title="Subscriptions" icon="receipt" href="/api-reference/dialer/list-subscriptions">
    Number subscriptions
  </Card>

  <Card title="Usage" icon="chart-simple" href="/api-reference/dialer/get-usage">
    Billing and charges
  </Card>

  <Card title="List Webhooks" icon="webhook" href="/api-reference/dialer/list-webhooks">
    Event subscriptions
  </Card>

  <Card title="Create Webhook" icon="plus" href="/api-reference/dialer/create-webhook">
    Subscribe to events
  </Card>

  <Card title="Update Webhook" icon="pen" href="/api-reference/dialer/update-webhook">
    Modify webhook
  </Card>

  <Card title="Delete Webhook" icon="trash" href="/api-reference/dialer/delete-webhook">
    Unsubscribe
  </Card>

  <Card title="Rotate Secret" icon="key" href="/api-reference/dialer/rotate-webhook-secret">
    New signing secret
  </Card>

  <Card title="Test Webhook" icon="paper-plane" href="/api-reference/dialer/test-webhook">
    Send test event
  </Card>

  <Card title="Deliveries" icon="list" href="/api-reference/dialer/list-webhook-deliveries">
    Event delivery history
  </Card>
</CardGroup>
