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

# Quickstart

> Send a code and verify it, end to end, with a sandbox key.

<Steps>
  <Step title="Get a sandbox key">
    Sign in to the [dashboard](https://tawked.com/en/login), finish onboarding, and open **Applications**. A sandbox key (`tk_test_...`) is issued the moment onboarding completes, before your application is reviewed. Copy it once: keys are shown a single time.

    <Note>
      A sandbox key sends real messages, but only to numbers you have proven you own in the dashboard, and only 10 times per application. The [Sandbox](/sandbox) page has the details.
    </Note>
  </Step>

  <Step title="Start a verification">
    Send a code to the destination. Any accepted Saudi mobile format works; `lang` picks the message language (Arabic unless it is exactly `en`).

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://tawked.com/v1/verify/start \
        -H "Authorization: Bearer tk_test_xxxxxxxxxxxxxxxxxxxx" \
        -H "Content-Type: application/json" \
        -d '{ "to": "0551234567", "lang": "ar" }'
      ```

      ```javascript Node.js theme={null}
      const res = await fetch('https://tawked.com/v1/verify/start', {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${process.env.TAWKED_KEY}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ to: '0551234567', lang: 'ar' }),
      });
      const { id } = await res.json(); // keep the id for the check
      ```

      ```php PHP theme={null}
      $res = Http::withToken(env('TAWKED_KEY'))
          ->post('https://tawked.com/v1/verify/start', ['to' => '0551234567', 'lang' => 'ar']);
      $id = $res->json('id'); // keep the id for the check
      ```

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

      res = requests.post(
          "https://tawked.com/v1/verify/start",
          headers={"Authorization": f"Bearer {os.environ['TAWKED_KEY']}"},
          json={"to": "0551234567", "lang": "ar"},
      )
      verification_id = res.json()["id"]  # keep the id for the check
      ```
    </CodeGroup>

    The answer is `201` with the id you will check against and when the code expires:

    ```json theme={null}
    {
      "id": "b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44",
      "status": "pending",
      "expires_at": "2026-09-01T12:34:56.789Z"
    }
    ```
  </Step>

  <Step title="Check the code">
    Post the id and the code the person typed. The code is compared exactly as sent: never trimmed, never normalised.

    ```bash theme={null}
    curl -X POST https://tawked.com/v1/verify/check \
      -H "Authorization: Bearer tk_test_xxxxxxxxxxxxxxxxxxxx" \
      -H "Content-Type: application/json" \
      -d '{ "id": "b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44", "code": "482913" }'
    ```

    Every outcome is a `200`. Read `verified` first, then `status` for the reason:

    ```json theme={null}
    { "verified": true, "status": "verified" }
    ```

    ```json theme={null}
    { "verified": false, "status": "invalid_code", "attempts_remaining": 2 }
    ```

    `status` is one of `verified`, `invalid_code`, `too_many_attempts`, `failed`, `expired` or `canceled`. An unknown id is the one exception: `404 { "error": "not_found" }`. A verified request stays verified and ignores later codes.
  </Step>

  <Step title="Go live">
    Once your application is approved, create a live key (`tk_live_...`) on the same **Keys** page and swap it in. The endpoints and shapes are identical; the `[TEST]` stamp disappears and the sandbox caps no longer apply.
  </Step>
</Steps>

## Defaults you can tune

Each application sets its own verification settings in the dashboard. The defaults, and their bounds:

| Setting                        | Default     | Bounds    |
| ------------------------------ | ----------- | --------- |
| Code length                    | 6 digits    | 4 to 8    |
| Code lifetime                  | 300 seconds | 60 to 900 |
| Attempts per code              | 3           | 1 to 5    |
| Sends per destination per hour | 5           | 1 to 10   |
| Resends per verification       | 3           | fixed     |

## What next

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/authentication">
    Key modes, scopes, expiry and IP allowlists.
  </Card>

  <Card title="Reliability" icon="shield-check" href="/reliability">
    Idempotency keys, rate limits and the protection guard.
  </Card>

  <Card title="Webhooks" icon="bell" href="/webhooks">
    Get told when a verification is verified, fails or expires.
  </Card>

  <Card title="Resend and cancel" icon="rotate" href="/api-reference/verify/resend-a-code">
    A new code on the same id, or a clean cancel.
  </Card>
</CardGroup>
