# Status endpoint

`GET /v1/status` tells you, per platform, whether Onekey is currently able to fetch from it. It is public: no API key, no credits, no rate limit. The [status page](https://onekey.dev/status) shows the overall API state; this endpoint is the per-platform detail behind it, for your code.

## The request

```bash
curl "https://api.onekey.dev/v1/status"
```

```json
{
  "status": "ok",
  "generated_at": "2026-09-30T02:51:35.090514+00:00",
  "cache_ttl_s": 30,
  "counts": { "ok": 5, "degraded": 0, "down": 0, "unknown": 261 },
  "platforms": { "bluesky": "ok", "github": "ok", "hackernews": "ok", "reddit": "unknown", "youtube": "ok", "...": "..." }
}
```

| Field | Meaning |
| --- | --- |
| `status` | Overall state across the platforms that have been observed: `ok` when every one of them is ok, `down` when every one of them is down, `degraded` otherwise, `unknown` when nothing has been observed yet. |
| `generated_at` | When this answer was computed (ISO 8601). It is recomputed at most every `cache_ttl_s` seconds. |
| `cache_ttl_s` | `30`. The response also carries `Cache-Control: public, max-age=30`, so a shared cache may serve it. |
| `counts` | How many platforms are in each state. |
| `platforms` | Platform id to state, for every platform in the catalog, sorted by id (the example is shortened). |

## The four states

| State | Meaning | What to do |
| --- | --- | --- |
| `ok` | Recent fetches from the platform through Onekey's own connections are succeeding. | Call as usual. |
| `degraded` | Part of the path to this platform is failing: at least one connection is being probed after failures, or a recent check had some failures. Calls may succeed, fail with a `502`, or come back as a stale copy. | Call, but expect some `502`s; retry those with backoff. |
| `down` | Every connection to this platform is currently failing. Fresh fetches will fail; cached copies are still served where they exist. | Wait and poll this endpoint rather than retrying data calls in a loop. |
| `unknown` | Onekey has no recent observation for this platform: nothing has been fetched from it since the service last started and no saved check covers it. It says nothing about whether the platform is up. | Call as usual; the first fetch will tell. |

The state comes from Onekey's own fetches to each platform (the same circuit breakers the data pipeline uses) and, for platforms that have not been exercised yet, from the last saved verification sweep of their stable endpoints. Platforms reached only through third-party routes are not observed here and stay `unknown`. The endpoint never names a host, a route or a cost, only platform ids and states, and it knows nothing about your account.

## Using it before you retry

If a data call fails with `502 UPSTREAM_ERROR`, `UPSTREAM_TIMEOUT`, `UPSTREAM_BLOCKED` or `UPSTREAM_RATE_LIMITED`, check the platform's state before retrying:

```python
import time, requests

def wait_until_ok(platform, key, path, params, max_wait_s=300):
    started = time.time()
    while time.time() - started < max_wait_s:
        state = requests.get("https://api.onekey.dev/v1/status", timeout=10).json()["platforms"].get(platform, "unknown")
        if state != "down":
            r = requests.get(f"https://api.onekey.dev{path}", params=params, headers={"x-api-key": key}, timeout=30)
            if r.status_code != 502:
                return r.json()
        time.sleep(30)  # the answer only changes every 30 seconds anyway
    raise TimeoutError(f"{platform} still down after {max_wait_s}s")
```

```javascript
async function waitUntilOk(platform, key, path, params, maxWaitMs = 300_000) {
  const started = Date.now();
  while (Date.now() - started < maxWaitMs) {
    const { platforms } = await (await fetch("https://api.onekey.dev/v1/status")).json();
    if ((platforms[platform] ?? "unknown") !== "down") {
      const res = await fetch(`https://api.onekey.dev${path}?${new URLSearchParams(params)}`, { headers: { "x-api-key": key } });
      if (res.status !== 502) return res.json();
    }
    await new Promise((r) => setTimeout(r, 30_000));
  }
  throw new Error(`${platform} still down`);
}
```

Polling faster than every 30 seconds is pointless: you get the same cached answer. Failed data calls are refunded, so a retry that runs into a `down` platform costs nothing but time.

## Edge cases

- `unknown` is common right after a deploy, before any traffic has reached a platform. Treat it as "no information", not as a warning.
- A platform can be `ok` while a single endpoint on it is broken (the state is per platform, from the hosts it is fetched from). An endpoint that keeps failing while its platform is `ok` is worth reporting with a `request_id`.
- The overall `status` is `degraded` as soon as one observed platform is not `ok`, so with hundreds of platforms it is degraded more often than not. Read the per-platform value for the platforms you use.
- This endpoint reports fetch health only. It does not say whether an endpoint's fields are complete (see [Data availability](https://onekey.dev/docs/data-availability.md)) and it does not know about your balance or rate limit.

## What it costs

Nothing. No key, no credits, not rate limited; the answer is recomputed at most every 30 seconds.
