# Signup

Start a 30-day trial, no card, confirm the email with the 6-digit code, and take an API key. After the trial subscribe for $1 per account/month. Includes 3 pixels and 500 new contacts per UTC calendar month. No extra charges. Resolution pauses at the limit or until subscribed.

Call these paths on the API host you already reached (`https://agentpixel.io` in production). Send `content-type: application/json` on every POST that has a body. A refused call returns JSON `{"detail": "..."}`. A body with the wrong shape returns 400 `{"detail": "invalid request"}` and does not list the fields.

## Store these

- `account_id` from step 2.
- `signup_token` from step 2. Send it as the header `x-signup-token`. It lasts 24 hours. After that, `POST /v1/accounts/{account_id}/signup-token` with the email and a fresh code issues a new one.
- `api_key` from step 3, or from step 6 when the person used the link instead of the code. It is shown once and starts with `px_`. Later calls use `Authorization: Bearer <api_key>`.

Agents in an MCP client run the same steps as tools: `signup_free`, then `confirm_signup(account_id, code, signup_token)`, and `create_api_key` only when the link was used.

## 1. Read the prices

`GET /v1/plans`

No auth. Use the selectable `free` trial. It lasts 30 days without a card. After trial the account costs $1/month. Usage charges and setup fees are zero. Ignore `unlimited`.

## 2. Create the account

`POST /v1/accounts`

```json
{"email": "ada@example.com", "display_name": "Ada"}
```

`external_user_id` is optional. When you send it, the same value cannot be registered twice.

201 returns `account_id`, `status` `pending_email`, `plan` `free`, `signup_token`, and `email_verified` false. When the confirmation email was not sent, the object also has `verification_url`. When that field is absent, the email was sent.

- 400 `invalid email`, `display name is required`, or `invalid request`
- 409 `email already registered` or `external user already registered`
- 502 `could not send the confirmation email`

## 3. Confirm the email with the code

The email starts with a 6-digit code. Ask the person to read it to you. Never guess it.

`POST /v1/accounts/{account_id}/confirm`

```json
{"code": "482913", "signup_token": "<signup_token>"}
```

200 returns `email_verified` true and, on the first confirmation with a signup token, `api_key` and `prefix`. Store `api_key` and skip to step 7.

- 400 `code is incorrect; N attempts left`. A code allows 5 attempts and lasts 24 hours.
- 429 `too many wrong codes; call resend_code for a new one`.
- New code: `POST /v1/signup/resend-code` with `{"email": "..."}`. Limits: 1 per minute, 5 per day. The old code stops working.

### Or the person clicks the link

When `verification_url` is present, GET it. The path is `/v1/email/verify?token=...`. The response is HTML. 200 means the page contains "Email confirmed". The link expires 24 hours after it was sent.

When `verification_url` is absent and the person clicks the email link, poll step 4 every 5 seconds, for up to 10 minutes, until `email_verified` is true. No token needs copying.

Send it again with `POST /v1/accounts/{account_id}/verification-email` and header `x-signup-token`. A second send inside one minute is 429 `wait before sending the confirmation email again`. An address that is already confirmed returns `{"sent": false, "status": "already_verified"}`.

## 4. Watch the account

`GET /v1/accounts/{account_id}` with header `x-signup-token`.

200 returns `status`, `plan`, `email`, and `email_verified`. The trial starts as `pending_email` and becomes `active` after email confirmation. Resolution pauses when the trial expires unless a paid subscription is active. A missing or expired signup token is 401.

## 5. Subscribe after the trial (optional during the trial)

`POST /v1/accounts/{account_id}/checkout` with header `x-signup-token`.

200 returns `url`, `monthly_cents` 100, `setup_fee_cents` 0, and `resolved_contact_cents` 0. Give `url` to a person to authorize the $1 monthly subscription. No usage charges.

You do not call the return URL. After payment, check `/v1/whoami` using your API key until `plan` is `paid` and `paid_until` is in the future. An active trial is not payment confirmation. If they cancel, no subscription is activated; open checkout again when ready.

Use your account Bearer API key for checkout after the signup token expires. Confirm your email first. An already-paid subscription returns 409.

## 6. Take the API key

Wait until `status` is `active` and `email_verified` is true.

`POST /v1/api-keys?account_id={account_id}` with header `x-signup-token`.

201 returns `api_key` and `prefix`. Store `api_key`. 403 `account is not active` or `confirm your email before creating an API key` means step 3 is unfinished.

## 7. Check the key

`GET /v1/whoami` with `Authorization: Bearer <api_key>`.

200 returns `account_id`, `plan` `free` during trial or `paid` after subscription, `status` `active`, and `key_prefix`. It does not return the secret.

Next lesson: [Setup](/docs/setup.md).
