# Agent Sign-up



An AI agent (a skill, an MCP client, a coding assistant) can create a YTAPI account for its user and get an API key without a browser. The user confirms by reading a 6-digit code from their email back to the agent.

1. Ask the user for their email address.
2. `POST https://ytapi.dev/api/agent/signup` with the email. YTAPI emails a code and returns a `signup_token`.
3. Ask the user for the code.
4. `POST https://ytapi.dev/api/agent/verify` with the token and the code. The response holds the new `api_key`.
5. Store the key where the user's tools can read it, for example as `YTAPI_API_KEY`, and use it as a [Bearer token](/authentication).

<Callout type="warn" title="Keep the key out of the conversation">
  Write the verify response to a file or a variable instead of printing it, and do not echo `api_key` into the chat.
</Callout>

***

1. Request a code [#1-request-a-code]

```bash
curl -s -X POST https://ytapi.dev/api/agent/signup \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}'
```

```json
{
  "status": "code_sent",
  "signup_token": "eyJwdXJwb3NlIjoi…",
  "expires_in": 600,
  "next": "A 6-digit code was emailed to user@example.com. Ask the user for it, then POST …"
}
```

The token and the code are valid for 10 minutes. The answer is the same whether or not the email already has an account.

2. Verify the code and get the key [#2-verify-the-code-and-get-the-key]

```bash
curl -s -X POST https://ytapi.dev/api/agent/verify \
  -H "Content-Type: application/json" \
  -d '{"signup_token": "<signup_token>", "code": "123456"}' \
  -o ytapi-signup.json
```

`201 Created`:

```json
{
  "status": "account_created",
  "api_key": "sk_…",
  "credits": 200,
  "limits": { "requests_per_second": 1, "requests_per_day": 100 },
  "next": "Store api_key where the user's tools can read it …",
  "example_request": "GET https://api.ytapi.dev/v1/transcripts?video_id=dQw4w9WgXcQ",
  "docs": "https://docs.ytapi.dev",
  "notes": "The account has 200 free credits; only successful requests use credits. …"
}
```

The user can sign in at [ytapi.dev](https://ytapi.dev/auth/login?utm_source=docs) with the same email to see usage, manage keys, and buy credits.

Existing accounts [#existing-accounts]

If the email already has a YTAPI account, `/api/agent/verify` answers `409 account_exists` once the code is correct, and no key is created. The user signs in at [ytapi.dev/auth/login](https://ytapi.dev/auth/login?utm_source=docs) and creates a key at [ytapi.dev/app/api-keys](https://ytapi.dev/app/api-keys?utm_source=docs).

Free credits and limits [#free-credits-and-limits]

New accounts get **200 free credits**, once per email address: a `+tag` or a Gmail address with dots counts as the same mailbox. Outside large email providers, only a few new accounts per email domain get them each day. Until the account buys a pack, its keys can make **1 request per second** and **100 requests per day** (UTC); any [credit pack](/pricing) removes the daily limit.

Errors [#errors]

Errors use the API's standard envelope:

```json
{
  "error": {
    "code": "invalid_code",
    "message": "That code is wrong. Ask the user to check the email and try again. …",
    "retryable": false
  }
}
```

| Status | Code                    | What to do                                                                                                                               |
| :----- | :---------------------- | :--------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | `invalid_email`         | Ask the user for a valid email address.                                                                                                  |
| 400    | `disposable_email`      | Temporary inboxes are not accepted. Ask for the user's regular address.                                                                  |
| 400    | `undeliverable_email`   | The domain cannot receive mail. Check the address with the user.                                                                         |
| 400    | `invalid_request`       | Send `signup_token` and a 6-digit `code`.                                                                                                |
| 400    | `invalid_signup_token`  | The token is wrong or older than 10 minutes. Start over.                                                                                 |
| 400    | `invalid_code`          | Ask the user to check the code. After 3 wrong codes, start over.                                                                         |
| 400    | `code_expired`          | The code is older than 10 minutes. Start over.                                                                                           |
| 400    | `too_many_attempts`     | 3 wrong codes. Start over.                                                                                                               |
| 409    | `account_exists`        | The user creates a key on the website (see above).                                                                                       |
| 429    | `rate_limited`          | Too many sign-ups or codes for this network or email. Try again later.                                                                   |
| 502    | `email_failed`          | The code email could not be sent. Retry in a minute.                                                                                     |
| 503    | `agent_signup_busy`     | Agent sign-up is paused for a while. Try again later, or the user signs up at [ytapi.dev](https://ytapi.dev/auth/login?utm_source=docs). |
| 503    | `agent_signup_disabled` | Agent sign-up is off. The user can sign up at [ytapi.dev](https://ytapi.dev/auth/login?utm_source=docs).                                 |

"Start over" means calling `/api/agent/signup` again, which sends a new code.
