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

# Health Check APIs

> Verify liveness and readiness of the backend and its dependencies (Hasura, Keycloak, Postgres). Used for load balancer and Kubernetes probes. No authentication required.

Health check endpoints for monitoring and orchestrator probes. **`GET /health/live`** confirms the process is running. **`GET /health/ready`** verifies dependencies (Hasura, Keycloak, Postgres) are reachable. Both work for self-hosted and cloud deployments.

<Note>
  **Base URL:** Health is mounted at `/health`. If your deployment uses a path prefix (e.g. `/api`), use `/api/health/live` and `/api/health/ready`. For self-hosted, replace the host with your instance URL.
</Note>

***

## Endpoint (Cloud)

```
GET https://api.usedatabrain.com/health/live
GET https://api.usedatabrain.com/health/ready
```

## Self-hosted Databrain Endpoint

```
GET <SELF_HOSTED_URL>/health/live
GET <SELF_HOSTED_URL>/health/ready
```

***

## Guide: How to check health

1. **Liveness** — Call `GET /health/live`. Expect `200` and `{"status":"live"}`. Use for liveness probes.
2. **Readiness** — Call `GET /health/ready`. Expect `200` and `{"status":"ready","checks":{...}}` when all dependencies are up. Inspect `checks` for per-service status.
3. If any check is `DOWN` or `UNKNOWN`, the response is `503` and `status` is `not_ready`.

***

## Authentication

None. Health endpoints do not require authentication.

***

## Headers

None required.

***

## Query Parameters

None.

***

## Response

### GET /health/live (200 OK)

<ResponseField name="status" type="string">
  Always `"live"` when the server responds. Indicates the process is running.
</ResponseField>

### GET /health/ready – Success (200 OK)

<ResponseField name="status" type="string">
  `"ready"` when all configured dependency checks pass.
</ResponseField>

<ResponseField name="checks" type="object">
  Map of service names to their health result. Keys present depend on configuration.
</ResponseField>

<ResponseField name="checks.hasura" type="object">
  **Always present.** Hasura GraphQL engine health. Uses `{HASURA_ENDPOINT}/healthz`. No change required on Hasura; backend uses the existing endpoint.
</ResponseField>

<ResponseField name="checks.hasura.status" type="string">
  `"UP"` when Hasura is reachable, `"DOWN"` when unreachable, `"UNKNOWN"` when `HASURA_ENDPOINT` is not configured.
</ResponseField>

<ResponseField name="checks.hasura.statusCode" type="number">
  HTTP status from `{HASURA_ENDPOINT}/healthz`. Present when a response was received. Absent on network/fetch errors.
</ResponseField>

<ResponseField name="checks.hasura.error" type="string">
  Present when `status` is `"DOWN"` or `"UNKNOWN"`. Error message or configuration hint (e.g. `"HASURA_ENDPOINT not configured"`).
</ResponseField>

<ResponseField name="checks.keycloak" type="object">
  **Present only when** `KEYCLOAK_SERVER_URL` is set. Keycloak health via `{KEYCLOAK_SERVER_URL}/health/live`.
</ResponseField>

<ResponseField name="checks.keycloak.status" type="string">
  `"UP"` or `"DOWN"`.
</ResponseField>

<ResponseField name="checks.keycloak.statusCode" type="number">
  HTTP status from Keycloak. Present when a response was received.
</ResponseField>

<ResponseField name="checks.keycloak.error" type="string">
  Present when `status` is `"DOWN"`. Error message.
</ResponseField>

<ResponseField name="checks.postgres" type="object">
  **Present only when** `HASURA_ENDPOINT` is set. Postgres reachability via Hasura strict health (`{HASURA_ENDPOINT}/healthz?strict=true`).
</ResponseField>

<ResponseField name="checks.postgres.status" type="string">
  `"UP"` or `"DOWN"`.
</ResponseField>

<ResponseField name="checks.postgres.statusCode" type="number">
  HTTP status from Hasura strict health. Present when a response was received.
</ResponseField>

<ResponseField name="checks.postgres.error" type="string">
  Present when `status` is `"DOWN"`. Error message.
</ResponseField>

### GET /health/ready – Failure (503 Service Unavailable)

<ResponseField name="status" type="string">
  `"not_ready"` when one or more checks failed.
</ResponseField>

<ResponseField name="checks" type="object">
  Same structure as success. At least one entry has `status: "DOWN"` or `"UNKNOWN"`.
</ResponseField>

***

## Services summary

| Service  | Config                  | Check URL                               | In `checks` when          |
| -------- | ----------------------- | --------------------------------------- | ------------------------- |
| Hasura   | `HASURA_ENDPOINT`       | `{endpoint}/healthz`                    | Always                    |
| Keycloak | `KEYCLOAK_SERVER_URL`   | `{url}/health/live`                     | When config is set        |
| Postgres | (via `HASURA_ENDPOINT`) | `{HASURA_ENDPOINT}/healthz?strict=true` | When Hasura config is set |

***

## Examples

<Panel>
  <RequestExample>
    ```bash cURL – Liveness theme={"dark"}
    curl -s https://api.usedatabrain.com/health/live
    ```

    ```bash cURL – Readiness theme={"dark"}
    curl -s https://api.usedatabrain.com/health/ready
    ```

    ```bash cURL – Self-hosted theme={"dark"}
    curl -s https://your-databrain-instance.com/health/live
    curl -s https://your-databrain-instance.com/health/ready
    ```
  </RequestExample>

  <ResponseExample>
    ```json GET /health/live – Success (200) theme={"dark"}
    {
      "status": "live"
    }
    ```

    ```json GET /health/ready – Success (200) theme={"dark"}
    {
      "status": "ready",
      "checks": {
        "hasura": { "status": "UP", "statusCode": 200 },
        "keycloak": { "status": "UP", "statusCode": 200 },
        "postgres": { "status": "UP", "statusCode": 200 }
      }
    }
    ```

    ```json GET /health/ready – Failure (503) theme={"dark"}
    {
      "status": "not_ready",
      "checks": {
        "hasura": { "status": "DOWN", "statusCode": 503, "error": "Service Unavailable" },
        "postgres": { "status": "DOWN", "error": "connect ECONNREFUSED" }
      }
    }
    ```
  </ResponseExample>
</Panel>

***

## HTTP Status Code Summary

| Status Code | Endpoint            | Description                                                                                  |
| ----------- | ------------------- | -------------------------------------------------------------------------------------------- |
| `200`       | `GET /health/live`  | **OK** – Process is running; `{"status":"live"}`                                             |
| `200`       | `GET /health/ready` | **OK** – All configured checks pass; `{"status":"ready","checks":{...}}`                     |
| `503`       | `GET /health/ready` | **Service Unavailable** – One or more checks failed; `{"status":"not_ready","checks":{...}}` |

***

## Notes

* Each dependency check uses a **3 second timeout**.
* `statusCode` is omitted when the check fails due to network/connection errors (e.g. `ECONNREFUSED`).
* For Kubernetes: use `GET /health/live` for liveness and `GET /health/ready` for readiness.
* **Graceful shutdown:** On `SIGTERM` or `SIGINT`, the server stops accepting new connections and waits for in-flight requests to complete. If shutdown is not complete within **30 seconds**, the process exits forcefully. Set `terminationGracePeriodSeconds` to at least 35 when using Kubernetes.
