# Test mode

> ck_test_ keys capture emails without delivering them and simulate delivery, bounces, complaints and deferrals by recipient address, with real events and webhooks.

Source: https://couryo.com/en/docs/test-mode

With a `ck_test_` key, Couryo does everything it would do for real (validates the request, applies idempotency, creates events and calls your webhooks), **except deliver**. No email leaves for the internet.

## How to use it

1. Create a test key under **Keys** (mode `test`).
2. Use it instead of the `ck_live_` key, with no other code change.
3. The response has `status: "captured"`:

```json title="Response 202"
{ "id": "msg_t3st0k9a1b2c3d4e", "status": "captured" }
```

The email's status stays `captured`; what happened to each recipient shows up in the events.

## Simulated addresses

The part before the recipient's `@` decides what the test simulates, on any domain:

| Recipient | What happens | Events |
|---|---|---|
| `bounced@...` or `bounce@...` | hard bounce | `sent` and `bounced` with `550 5.1.1` (unknown user) |
| `complained@...` or `complaint@...` | delivered, then marked as spam | `sent`, `delivered` and `complained` |
| `deferred@...` | deferred, then delivered | `sent`, `deferred` with `421 4.7.0` and `delivered` |
| anything else | delivered | `sent` and `delivered` with `250 2.0.0` |

Events arrive right after the send, with times (`at`) that mimic the real pace: the complaint 5 seconds after delivery, and the deferred email's delivery 1 minute after the deferral.

```bash title="cURL"
curl https://api.couryo.com/v1/emails \
  -H "Authorization: Bearer $COURYO_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Shop <orders@example.com>",
    "to": ["bounced@example.com", "ana@example.com"],
    "subject": "Bounce test",
    "text": "Hello"
  }'
```

Simulated events go through the same path as real ones: they show up in the timeline (`GET /v1/emails/{id}`), in `GET /v1/events` and in your [webhooks](https://couryo.com/en/docs/webhooks.md), with an SMTP response marked as simulated and a plain-language explanation. It is how you test bounce and complaint handling without hurting anyone's reputation.

## What is different from a live key

- **No verified domain needed** in `from`, and no level 0 (sandbox) restriction.
- **Does not count** toward the level's daily and monthly limits or the plan quota. The per-second request limit applies as usual.
- **Never touches suppression** or the account's bounce and complaint rates: a simulated `bounced@` is not added to your suppression list.
- The content check (shortened links and the like) only runs live. To check an email first, use [`POST /v1/emails/check`](https://couryo.com/en/docs/sending.md#pre-send-check).

## In the dashboard

The email shows up under **Emails** with the `captured` status and the simulated timeline, and webhook calls appear in the delivery history, so you can check your integration. Viewing the rendered content and sharing a review link with your team: coming soon.

## Good for

- Automated tests and CI: no email ever reaches real customers.
- Staging environments with data copied from production.
- Testing how you handle bounce, complaint and deferral webhooks.
- Using the [MCP server](https://couryo.com/en/docs/mcp.md) with your agent at no risk.
