> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stophy.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Every Stophy API error code with its HTTP status, what it means and whether to retry. A failed call costs nothing. Try the free ones yourself.

Leave out the required field and read the error. No key needed.

```bash theme={null}
curl -X POST https://api.stophy.dev/v1/google/search \
  -H "content-type: application/json" \
  -d '{}'
```

<Accordion title="Response">
  ```json theme={null}
  {
    "error": {
      "code": "invalidRequest",
      "message": "query: Invalid input: expected string, received undefined",
      "retryable": false,
      "requestId": "8667f9a7-7548-41a1-9d68-2a1d81229b91"
    },
    "success": false
  }
  ```
</Accordion>

The status is `400`. Every error has this shape, and a failed call costs nothing.

| Field | What it is |
| - | - |
| `code` | A stable code from the table below |
| `message` | What went wrong, in plain words |
| `retryable` | `true` when the same request may work later |
| `retryAfterSeconds` | Present when you should wait a set time. The `Retry-After` header has the same value. |
| `requestId` | The ID of this request. Include it when you contact support. |

## Error codes

| Code | Status | Retryable | What it means |
| - | - | - | - |
| `invalidRequest` | 400 | No | The input is not valid. The message names the field. |
| `unauthorized` | 401 | No | The API key is missing or not valid. |
| `insufficientCredits` | 402 | No | Your balance is too low for this call. The error adds `requiredCredits`, `availableCredits` and `billingUrl`. [Add credits](/billing). |
| `notFound` | 404 | No | The endpoint, or the thing you asked for, does not exist. |
| `rateLimited` | 429 | Yes | Too many requests. Wait for `Retry-After`. |
| `tooManyInFlight` | 429 | Yes | Too many of your calls are running at once. Wait for one to finish. |
| `internalError` | 500, 503 | Yes | Something went wrong on our side. Try again shortly. |
| `sourceChanged` | 502 | No | The site answered in a shape we could not read. Retrying will not help yet. |
| `sourceUnavailable` | 503 | Yes | The site is not answering right now. Try again in a few seconds. |
| `sourceRefused` | 503 | Yes | The site is refusing requests right now. Try again in a few minutes. |
| `sourceTimeout` | 504 | Yes | The site took too long to answer. Try again. |

## Try the free ones

These calls cost nothing. The first needs no key, and the rest are real responses from today.

**A field the endpoint does not take.** `400 invalidRequest`

```json theme={null}
{ "code": "invalidRequest", "message": "Unknown field `foo`. Fields: query, country, language, includeDomains, excludeDomains, time, safeSearch, page, scrapeResults, scrapeLimit", "retryable": false }
```

**Both of a pair, or neither.** `400 invalidRequest`, from `youtube.transcript` with `videoId` and `videoUrl` together.

```json theme={null}
{ "code": "invalidRequest", "message": "Send exactly one of videoUrl or videoId.", "retryable": false }
```

**A `limit` where the endpoint has none.** `400 invalidRequest`, from `google.search`.

```json theme={null}
{ "code": "invalidRequest", "message": "limit: removed. Each call returns one page from the site; send page for the next one.", "retryable": false }
```

**A cursor that is not from this request.** `400 invalidRequest`, from `reddit.search` with a key.

```json theme={null}
{ "code": "invalidRequest", "message": "cursor: This is not a cursor returned for this request. Send the cursor from the last response to the same request, unchanged, or leave cursor out to start again from page 1 and get a fresh one.", "retryable": false }
```

**Paging with no key.** `400 invalidRequest`, from `google.search` with `page: 2`.

```json theme={null}
{ "code": "invalidRequest", "message": "Paging needs an API key: https://stophy.dev/signup", "retryable": false }
```

**An endpoint that needs a key, with no key.** `401 unauthorized`, from `reddit.post`.

```json theme={null}
{ "code": "unauthorized", "message": "Send an API key as Authorization: Bearer <key>. Get a key: https://stophy.dev/signup", "retryable": false }
```

**A path that is not an endpoint.** `404 notFound`, sent with a key.

```json theme={null}
{ "code": "notFound", "message": "No endpoint at this path. See every endpoint at https://api.stophy.dev/v1/endpoints", "retryable": false }
```

**Something that does not exist.** `404 notFound`, from `youtube.video` with a made-up id.

```json theme={null}
{ "code": "notFound", "message": "YouTube has no playable video with that id. Check videoUrl or videoId; the video may be private, removed or age-restricted.", "retryable": false }
```

## Account codes

These come from your account and the dashboard, not from a data endpoint.

| Code | Status | Retryable | What it means |
| - | - | - | - |
| `forbidden` | 403 | No | This request is not allowed. |
| `unsupportedMediaType` | 415 | No | Send the body as JSON with `content-type: application/json`. |
| `invalidCliSession` | 400 | No | The sign-in session is not valid. |
| `invalidCliVerifier` | 400 | No | The sign-in verifier is not valid. |
| `cliSessionNotFound` | 404 | No | The sign-in session was not found or has expired. |
| `cliSessionExists` | 409 | No | The sign-in session already exists. |
| `cliSessionCompleted` | 409 | No | The sign-in session is no longer pending. |
| `inviteClaimed` | 409 | No | You already claimed this invite. |
| `inviteDisabled` | 410 | No | This invite link was turned off. |
| `inviteExpired` | 410 | No | This invite link has expired. |
| `inviteUsedUp` | 410 | No | This invite link has been used up. |

## Retrying

Retry only when `retryable` is `true`. Wait for `retryAfterSeconds` or `Retry-After` when present, and back off otherwise. The [retry guide](/guides/errors-and-retries) has a loop for Node.js and Python.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.