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

# Quickstart

> Push your first lead in 5 minutes.

This walkthrough takes you from zero to a predictive-dial campaign
with one lead queued, using either `curl` or an SDK.

## 1. Get an API key

<Steps>
  <Step title="Log into app.yotel.in as a tenant admin">
    You need the `api_keys:manage` permission (TENANT\_ADMIN role).
  </Step>

  <Step title="Navigate to /developer/keys">
    Click **Issue key**. Give it a label like "Quickstart test".
  </Step>

  <Step title="Copy the key immediately">
    The full `yt_test_…` value is shown **once**. We store only a
    hash — if you lose the key you'll need to issue a new one.
  </Step>
</Steps>

<Warning>
  Start with a **test key** (`yt_test_…`). Test keys behave identically
  to live keys at the API surface — they create campaigns, push leads,
  fire webhooks — but never actually dial the PSTN. Use live keys
  (`yt_live_…`) only once your integration is reviewed.
</Warning>

## 2. Create a campaign

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.yotel.in/api/v1/campaigns \
    -H "Authorization: Bearer $YOTEL_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Quickstart demo",
      "dial_mode": "predictive",
      "predictive_target_abandon": 0.02
    }'
  ```

  ```python Python theme={null}
  import yotel

  client = yotel.Client(api_key=os.environ["YOTEL_KEY"])
  campaign = client.campaigns.create(
      name="Quickstart demo",
      dial_mode="predictive",
      predictive_target_abandon=0.02,
  )
  print(campaign.id)
  ```

  ```typescript TypeScript theme={null}
  import { YotelClient } from "@yotel/client";

  const client = new YotelClient({ apiKey: process.env.YOTEL_KEY! });
  const campaign = await client.campaigns.create({
    name: "Quickstart demo",
    dial_mode: "predictive",
    predictive_target_abandon: 0.02,
  });
  console.log(campaign.id);
  ```
</CodeGroup>

Every successful response carries rate-limit headers:

```
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 599
```

## 3. Push a lead

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST \
    https://api.yotel.in/api/v1/campaigns/$CAMPAIGN_ID/leads \
    -H "Authorization: Bearer $YOTEL_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "phone": "9876543210",
      "name": "Priya Sharma",
      "email": "priya@example.com",
      "metadata": {"crm_id": "A-9912"}
    }'
  ```

  ```python Python theme={null}
  lead = client.leads.create(
      campaign_id=campaign.id,
      phone="9876543210",
      name="Priya Sharma",
      email="priya@example.com",
      metadata={"crm_id": "A-9912"},
  )
  ```

  ```typescript TypeScript theme={null}
  const lead = await client.leads.create({
    campaign_id: campaign.id,
    phone: "9876543210",
    name: "Priya Sharma",
    email: "priya@example.com",
    metadata: { crm_id: "A-9912" },
  });
  ```
</CodeGroup>

For bulk, use the `:bulk` suffix — up to 500 leads in one call:

```bash theme={null}
curl -X POST \
  https://api.yotel.in/api/v1/campaigns/$CID/leads:bulk \
  -H "Authorization: Bearer $YOTEL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"leads":[{"phone":"98...1"},{"phone":"98...2"}]}'
```

## 4. Subscribe a webhook (optional)

<Info>
  Webhooks are managed from the dashboard (not the `/api/v1/*` path).
  Go to **app.yotel.in/developer/webhooks** → *New subscription*.
</Info>

Choose the events you care about:

* `call.ended` — every completed call with disposition + recording URL
* `campaign.paused` — fired on both manual and auto-pause (check
  `data.source`)
* `lead.completed` — lead reaches a terminal state

On create, you'll get a `signing_secret` (shown once). Store it;
you'll need it to [verify signatures](/webhooks/signature-verification).

## 5. Test the integration

<Steps>
  <Step title="DND-scrub your leads">
    Predictive campaigns refuse to start until every lead is
    scrubbed against the TRAI registry. Run
    `POST /api/campaigns/{id}/scrub` (or use the dashboard).
  </Step>

  <Step title="Start the campaign">
    `POST /api/campaigns/{id}/start`. Because your key is
    `yt_test_…`, the dialer registers the intent but doesn't
    originate to PSTN.
  </Step>

  <Step title="Watch the webhook log">
    Your dashboard's webhooks page shows every delivery with
    HTTP status + response snippet. If signatures don't verify,
    the customer-side issue is usually clock skew — see
    [troubleshooting](/webhooks/troubleshooting).
  </Step>
</Steps>

## Done

You've:

* Issued an API key
* Created a predictive campaign with custom tunables
* Pushed a lead
* Optionally subscribed a webhook

Next: read [Authentication](/authentication) for scope + rotation,
then [Webhooks](/webhooks/overview) for event subscription in detail.
