# Errors

API errors return JSON with a stable `code`, a plain `message`, and a `doc_url` that links to the matching section below:

```json
{
  "statusCode": 401,
  "error": "Unauthorized",
  "code": "unregistered_sender",
  "message": "Unregistered sender. Send a valid project key in the X-Api-Key header, or set this site's domain on a web property.",
  "doc_url": "https://analytics.specvista.com/docs/errors#unregistered_sender"
}
```

Match on `code`, never on `message`, which may change. Some older responses, such as validation from the account page, have no `code`. Each `doc_url` opens this page; agents can read the same section as Markdown at `https://analytics.specvista.com/docs/errors.md`.

## Sending events

### unregistered_sender

401 from `/ingest`, `/ingest/identify`, `/ingest/batch` and `/sdk/linked-domains`. No property matches the `X-Api-Key` header, or, without a key, the `X-Domain` header or `domain` field. Copy the key again from the Properties page or `GET /projects`. The key may have been rotated. For keyless browser tracking, set the property's domain to the site's hostname without `www.`.

### invalid_api_key

401 from `/forget`. The `X-Api-Key` header is missing or matches no property. Send a backend property's key.

### backend_key_required

403 from `/forget`. Only keys of backend properties can forget users. Create a backend property and call `/forget` from your server.

### forget_forbidden

403 from `/forget`. The `projectId` in the body belongs to another account. Use a backend key from the account that owns that property.

### user_id_required

400 from `/forget`. Send `userId` as a non-empty string or number.

### invalid_project_id

400 from `/forget`. `projectId` must be an integer.

### rate_limited

429 from `/forget`. Too many requests for this key in the last minute. Wait a minute, then retry.

## Signing in

### missing_token

401. The request has no `Authorization: Bearer` header. Sign in with `POST /auth/login` and send `user.token`.

### invalid_token

401. The token is malformed or more than 90 days old. Sign in again.

### invalid_credentials

401 from `/auth/login`. The email or password is wrong. The same message is used for both. There is no self-serve password reset yet.

### credentials_required

400 from `/auth/login`. Send both `email` and `password`.

### email_required

400 from `/auth/register`. Send `email`.

### first_name_required

400 from `/auth/register`. Send `firstName`.

### password_too_short

400 from `/auth/register` and `/auth/password`. Passwords need at least 8 characters.

### email_taken

409 from `/auth/register`. An account already uses this email. Sign in instead.

### current_password_incorrect

400 from `/auth/password`. `currentPassword` does not match.

### admin_required

403. The endpoint is for the Specvista Analytics operator only and is not part of the public API.

## Properties and reports

### project_name_required

400 from `POST /projects`. Send a non-empty `name`.

### invalid_project_type

400 from `POST /projects`. `type` must be `web`, `mobile`, `backend` or `other`, or left out for `web`.

### project_not_found

404. No property has that id. List yours with `GET /projects`.

### project_forbidden

403. The property belongs to another account. Use an id from your own `GET /projects`.

### invalid_funnel_events

400 from `/analytics/{id}/funnel`. `from` and `to` must both be event names of up to 100 characters. Get names from `/analytics/{id}/event-names`.

### same_funnel_events

400 from `/analytics/{id}/funnel`. `from` and `to` must be different events.

## Responses that are not errors

- `202 {"ok":true,"skipped":true}`: this browser has the `sa_ignore` cookie, so nothing was stored. Clear it with `GET /ingest/ignore-off` from that browser.
- `202 {"ok":false,"error":"userId required"}` from `/ingest/identify`: send `userId`.
- `202` but the event is missing from reports: it was stored as bot or internal traffic. See the common errors in [Add tracking to a Node.js server](https://analytics.specvista.com/docs/track-node.md) and [Add tracking to a website](https://analytics.specvista.com/docs/track-web.md).
