---
title: CLI auth (OTP)
description: The two public endpoints behind scripto auth — POST /api/cli/login-request and POST /api/cli/login-complete — that provision a CLI key over email OTP.
---

<Note>

The CLI command equivalents are `scripto auth login-request` and `scripto auth login-complete`. Prefer those — they store the minted key as a profile for you. See [Auth](/cli/auth).

</Note>

These two routes are **public** (no key required). Together they implement open signup over email OTP: an unknown email is registered when the code is verified.

## POST /api/cli/login-request

Send a sign-in OTP to an email.

```text
POST https://scripto.codika.io/api/cli/login-request
```

### Request

```json
{ "email": "you@example.com" }
```

### Response (200)

```json
{ "success": true, "data": { "ok": true, "email": "you@example.com" } }
```

### Errors

| HTTP | `code` | Cause |
|---|---|---|
| 400 | `invalid-argument` | Missing or malformed `email`. |
| 500 | `internal` | OTP send failed — retry shortly. |

### curl

```bash
curl -sS -X POST https://scripto.codika.io/api/cli/login-request \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com"}'
```

## POST /api/cli/login-complete

Verify the OTP and mint a long-lived `scripto_` key. The raw key is returned **once**.

```text
POST https://scripto.codika.io/api/cli/login-complete
```

### Request

```json
{ "email": "you@example.com", "otp": "123456", "name": "scripto-cli" }
```

`name` is optional (defaults to `scripto-cli`) and names the minted key.

### Response (200)

```json
{
  "success": true,
  "data": {
    "apiKey": "scripto_…",
    "keyId": "key_…",
    "userId": "user_…",
    "email": "you@example.com"
  }
}
```

### Errors

| HTTP | `code` | Cause | `nextAction` |
|---|---|---|---|
| 400 | `invalid-argument` | Missing `email`. | — |
| 400 | `invalid-argument` | Missing `otp`. | `request a new code with: scripto auth login-request` |
| 400 | `invalid-argument` | Wrong or expired code. | `request a new code with: scripto auth login-request` |
| 500 | `internal` | Signed in but key mint failed — retry. | — |

### curl

```bash
curl -sS -X POST https://scripto.codika.io/api/cli/login-complete \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","otp":"123456"}'
```

<Warning>

The OTP send is awaited server-side; the raw key in the `login-complete` response is the only time you'll see it. Store it immediately (the CLI does this for you).

</Warning>

## Next

- **[Auth](/cli/auth)** — the CLI flow these routes power.
- **[Authentication](/api-reference/authentication)** — using the minted key.
