# verify-store

Verifies the **integrity of the store**: its events, its event schemas, and its indexes.

- **Route:** `POST /api/v2/management/verify-store`
- **Category:** `management`
- **Authentication:** required, with the API token
- **Answer:** a stream of NDJSON

A verification checks that **every event can be read** and that the events form an **unbroken chain of hashes**, that every stored **event schema** compiles, is not **[too complex](/docs/eventsourcingdb/errors/event-schema-too-complex)** to validate against, and describes an object, and that **every index** is well-formed and holds what the events say it has to. What it finds is reported as **findings**, while an error means that the verification **could not run to completion**. **Reads and writes go on** while it runs: it checks the store as of the latest event at its start, and leaves what is written meanwhile to the next verification. Only where the latest event is damaged, or does not lie where its ID says, does it check the whole store at once, so that writes wait until it is done. **[Verifying Store Integrity](/docs/eventsourcingdb/verifying-store-integrity)** explains when to run it and how to read its findings.

## Request

The route takes **no body**, and ignores one that is sent. To verify the store:

```shell
curl \
  -X POST \
  -H "authorization: Bearer secret" \
  http://localhost:3000/api/v2/management/verify-store
```

## Answer

The answer is a **stream of items**, one per line. Each finding is a `finding` item:

| Type | Data | When |
| --- | --- | --- |
| `finding` | `severity`, which is `error` for an inconsistency of the store and `warning` for a notice that does not necessarily indicate one, and `description`, which says what was found | Once the verification is done, for every inconsistency and every warning. Each check reports up to 100 inconsistencies, and where it found more, one further finding that says how many. Findings with the severity `error` come first, check by check, followed by the warnings. |
| `error` | `code`, `description`, and `details` | When the verification cannot run to completion, in place of any findings, see **[Errors](#errors)**. |
| `heartbeat` | empty | While nothing else is sent for a while, to keep the connection alive. |
| `end` | empty | Once, as the last item, when the stream ends cleanly. |

**Heartbeats and the `end` item** work as on every stream of the API, see **[Streams](/docs/eventsourcingdb/api#streams)**. A store in which the verification **finds nothing** is answered with the `end` item alone, so **treat only that as a clean result**: a stream with an `error` item, or one that breaks off without its `end`, is a verification that did not finish.

For a store whose events file was changed on disk, the request above is answered with:

```json
{"type":"finding","data":{"severity":"error","description":"structural verification of \"events\" failed: failed to validate file \"events/0.esdb\": file checksum does not match"}}
{"type":"end","data":{}}
```

## Errors

The verification reports these errors as an `error` item, followed by the `end` item:

- **[`indexes-rebuilding`](/docs/eventsourcingdb/errors/indexes-rebuilding)**: The indexes are still being rebuilt after an upgrade, and would differ from the events only because they are not complete yet.
- **[`restore-in-progress`](/docs/eventsourcingdb/errors/restore-in-progress)**: A restore is running when the verification starts. A verification that began before the restore waits until it is over instead.
- **[`store-failed`](/docs/eventsourcingdb/errors/store-failed)**: The store refuses reads for good, after a restore that could not empty it again.
- **[`file-unreadable`](/docs/eventsourcingdb/errors/file-unreadable)**: The verification cannot read a file of the store, for example because the disk returns an input/output error, and stops there without findings.
- **[`server-shutting-down`](/docs/eventsourcingdb/errors/server-shutting-down)**: The server began to shut down after the verification had sent a heartbeat. Before that, the server answers with `503` instead.

## Status Codes

Before the stream begins, the server answers with a status code other than `200` where it cannot take the request at all, as described in **[Errors](/docs/eventsourcingdb/api#errors)**:

- **`401`**: The API token is missing or wrong.
- **`429`**: Too many requests were sent, or the client already holds 256 open streams, see **[Rate Limiting](/docs/eventsourcingdb/rate-limiting)**; the answer says when to try again.
- **`500`**: The server failed unexpectedly before the stream began. Once it has begun, the stream breaks off without its `end` item instead.
- **`503`**: The server is shutting down, or began to shut down before the stream began.
