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

# Quickstart (API)

> Answer your first phone call with an AI agent in four REST calls.

This guide walks you through the four REST calls it takes to answer
your first phone call with an AI agent.

<Info>
  You'll need a [ThunderPhone account](https://app.thunderphone.com).
  Sign up is free and takes under a minute. Prefer clicking to curling?
  The [dashboard quickstart](/quickstart-dashboard) reaches the same
  first call without writing any code.
</Info>

## Step 1: Get an API key

<Steps>
  <Step title="Log in">
    Open [app.thunderphone.com](https://app.thunderphone.com).
  </Step>

  <Step title="Navigate to Keys">
    Go to **Organization → Keys** in the dashboard.
  </Step>

  <Step title="Create a key">
    Click **Create key**, give it a name, and copy the
    `sk_live_...` value. The raw key is shown **only once** — store it
    in your secret manager immediately.
  </Step>
</Steps>

<Tip>
  Stuck? [Create a server API key](/guides/api-keys) walks
  this flow in step-by-step detail, and the in-app copilot can
  spotlight each control for you live.
</Tip>

Throughout this guide, swap `sk_live_YOUR_API_KEY` with the value you
just copied. The key identifies your organization automatically, so
you never need to put an org id in URLs.

## Step 2: Create an agent

An agent defines how the AI handles conversations — prompt, voice,
product tier, tools, and widget eligibility.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.thunderphone.com/v1/agents \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name":   "Customer Support",
      "prompt": "You are a friendly support agent for Acme Corp. Help with orders, returns, and product info. Be concise and helpful.",
      "voice":  "john",
      "product": "spark"
    }'
  ```

  ```python Python theme={null}
  import os, requests

  agent = requests.post(
      "https://api.thunderphone.com/v1/agents",
      headers={"Authorization": f"Bearer {os.environ['THUNDERPHONE_API_KEY']}"},
      json={
          "name":   "Customer Support",
          "prompt": "You are a friendly support agent for Acme Corp. Help with orders, returns, and product info. Be concise and helpful.",
          "voice":  "john",
          "product": "spark",
      },
  ).json()
  print("Agent id:", agent["id"])
  ```

  ```javascript Node.js theme={null}
  const agent = await fetch("https://api.thunderphone.com/v1/agents", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.THUNDERPHONE_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name:    "Customer Support",
      prompt:  "You are a friendly support agent for Acme Corp. Help with orders, returns, and product info. Be concise and helpful.",
      voice:   "john",
      product: "spark",
    }),
  }).then((r) => r.json());
  console.log("Agent id:", agent.id);
  ```
</CodeGroup>

<Tip>
  Product tiers: `spark` is optimized for cost, `bolt` for speed, and
  `storm-base` / `storm-extra` for intelligence on complex prompts. See
  [Agents](/api-reference/agents#product-tiers-at-a-glance) for the full
  comparison.
</Tip>

## Step 3: Provision a phone number

This call asks ThunderPhone's demo pool for a number and assigns your
new agent as the inbound handler. (To bring your own number from a VoIP
provider, see [VoIP connections](/api-reference/voip-connections)
instead.)

<CodeGroup>
  ```bash cURL theme={null}
  # First provision
  curl -X POST https://api.thunderphone.com/v1/phone-numbers \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"area_code": "415"}'

  # Then assign the agent you created in Step 2
  curl -X PATCH https://api.thunderphone.com/v1/phone-numbers/<id-from-previous> \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"inbound_agent_id": 12}'
  ```

  ```python Python theme={null}
  number = requests.post(
      "https://api.thunderphone.com/v1/phone-numbers",
      headers={"Authorization": f"Bearer {os.environ['THUNDERPHONE_API_KEY']}"},
      json={"area_code": "415"},
  ).json()
  requests.patch(
      f"https://api.thunderphone.com/v1/phone-numbers/{number['id']}",
      headers={"Authorization": f"Bearer {os.environ['THUNDERPHONE_API_KEY']}"},
      json={"inbound_agent_id": agent["id"]},
  )
  print("Your ThunderPhone number:", number["number"])
  ```
</CodeGroup>

Your new number starts in `status="provisioning"` and transitions to
`active` within a few seconds; by the time you hang up your browser the
number is ready to take calls.

## Step 4 (optional): Set up a webhook

For real-time events (dynamic call routing, post-call processing) add
a webhook endpoint. Subscribe only to the events you need.

```bash theme={null}
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label":  "Prod webhook",
    "url":    "https://your-server.com/thunderphone-webhook",
    "events": ["telephony.incoming", "telephony.complete"]
  }'
```

The response contains a one-shot `secret` — copy it to your secret
manager. Use that secret to verify the `X-ThunderPhone-Signature`
header on incoming requests (see
[Webhooks overview](/webhooks/overview#signature-verification)).

## Step 5: Test your agent

Call the number you just provisioned. The agent picks up, introduces
itself, and follows your prompt.

Inspect the call after it ends:

```bash theme={null}
curl https://api.thunderphone.com/v1/calls \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```

Drill into a specific call to fetch the transcript and recording URL:

```bash theme={null}
curl https://api.thunderphone.com/v1/calls/{call_id}/transcript \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
curl https://api.thunderphone.com/v1/calls/{call_id}/audio \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```

***

## Next steps

<CardGroup cols={2}>
  <Card title="Add function tools" icon="screwdriver-wrench" href="/tools/overview">
    Let your agent call your APIs during a conversation.
  </Card>

  <Card title="Place outbound calls" icon="arrow-up-right" href="/api-reference/outbound-calls">
    Trigger calls from your own code.
  </Card>

  <Card title="Handle webhooks" icon="bolt" href="/webhooks/overview">
    React to call events in real time.
  </Card>

  <Card title="Full API reference" icon="book" href="/api-reference/introduction">
    Every public endpoint, documented.
  </Card>
</CardGroup>
