# Quickstart

> Create an account, generate a sandbox key, register a webhook, and send your first message in a few minutes.

This walkthrough uses the **sandbox**: nothing is billed and no real recipient is contacted. The examples run in your terminal; each block is available in curl, Node.js, Python, and PHP (your language choice is remembered).

First, set the API address:

```bash
export INBOX_API="https://YOUR-HOST/api/v1"
```

<Steps>

### Create your account

Creating an account also creates its first member (the owner) and opens a session.

<ApiExample method="POST" path="/auth/signup" />

The password must be **at least 10 characters** long. Keep the `sessionToken`: it is the console key, valid for 30 days.

```bash
export INBOX_SESSION="ses_…"
```

### Create an app

An app has **two environments**: `sandbox` for testing and `production` for sending to real recipients. They are strictly separate.

<ApiExample method="POST" path="/apps" />

### Generate a sandbox key

Choose its **scopes**: a key can only do what you grant it.

<ApiExample method="POST" path="/apps/{appId}/keys" />

<Callout type="warning" title="The secret is shown only once">
Copy the `secret` field now. It is stored nowhere: if you lose it, generate a new key and revoke the old one.
</Callout>

```bash
export INBOX_KEY="pk_test_…"
```

### Register your customer's business

A **connected business** represents your customer, the owner of a WhatsApp Business account. `externalRef` is your own identifier for that customer.

<ApiExample method="POST" path="/connected-businesses" />

### Connect their WhatsApp account

Your customer completes Meta's Embedded Signup in the browser; you receive a `code`, a `wabaId`, and a `phoneNumberId`, which you pass to the API. See [Connect a WhatsApp account](/docs/guides/connect-whatsapp).

<ApiExample method="POST" path="/connected-businesses/{businessId}/waba-connections" />

Note the number's `id` (`phoneNumber.id`): it identifies the sending number.

### Receive events

Register your webhook endpoint. The signing secret is shown only once.

<ApiExample method="POST" path="/webhook-endpoints" />

Check that your server responds correctly, using a signed test event:

<ApiExample method="POST" path="/webhook-endpoints/{id}/test" />

### Send your first message

<ApiExample method="POST" path="/messages" />

The response is immediate (`202`, status `queued`): the actual send is asynchronous. Track the status with `GET /messages/{id}` or, better, with your webhooks.

<Callout type="note" title="Why a template?">
A free-form message (`type: text`) is only accepted within the 24-hour window after a message from the recipient. An approved template works at any time. See [Send messages](/docs/guides/send-messages).
</Callout>

### Simulate a customer reply

Without a phone, make a message "arrive": your `message.received` webhook fires exactly as it does in production.

<ApiExample method="POST" path="/sandbox/simulate/inbound-message" />

</Steps>

## What's next

- [Authentication and keys](/docs/authentication): scopes, rotation, best practices.
- [Webhooks](/docs/guides/webhooks): verify the signature, deduplicate, replay.
- [Reliability](/docs/guides/reliability): idempotency and automatic retries.
- [Go to production](/docs/guides/usage-billing): plan, quotas, costs.
