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

# Polling and the 202 flow

> What to do when a wallet has no fresh snapshot yet.

A wallet nobody has looked up recently has no snapshot yet, so the positions endpoint answers **`202`** with a scan job.
Try [`?wait=8`](https://docs.lucidblock.xyz/guides/wait) first; keep this flow as the fallback.

**1. Request the wallet**

`GET /v1/solana/wallets/{wallet}/defi-positions` (cost 5). A fresh snapshot returns `200` at once. Otherwise you get
`202` with `job_id`, `poll_url` and `retry_after_seconds`, plus a `Retry-After` header.

**2. Wait, then poll the job**

Wait `retry_after_seconds`, then `GET` the `poll_url` (cost 1). Poll the job, not the wallet (cost 5). Repeat with
backoff while `status` is `queued` or `running`.

**3. Request the wallet again**

On `succeeded` or `partial`, request the wallet again for the `200` snapshot. On `failed` or `expired`, stop: the
positions request returns `503` (see [Errors](https://docs.lucidblock.xyz/reference/errors.md)).

## The async flow (202)

```text theme={null}
client                                   API
  | GET /v1/solana/wallets/W/defi-positions  (cost 5)
  |------------------------------------------>|  no fresh snapshot: queue a bounded scan
  |<------------------------------------------|  202 {job_id, poll_url, retry_after_seconds} + Retry-After
  | wait retry_after_seconds
  | GET poll_url  (cost 1)  … repeat with backoff
  |------------------------------------------>|
  |<------------------------------------------|  200 {status: queued | running | succeeded | partial | failed | expired}
  | on succeeded / partial:
  | GET /v1/solana/wallets/W/defi-positions  (cost 5)
  |<------------------------------------------|  200 snapshot
```

Job `status` is `queued`, `running`, `succeeded`, `partial` (finished with some protocols incomplete), `failed` (the
positions request then returns 503 `SCAN_FAILED`) or `expired` (503 `SNAPSHOT_UNAVAILABLE`). A stale snapshot is
returned immediately with `refreshing: true`. The [quickstart loop](https://docs.lucidblock.xyz/quickstart.md#your-first-request-in-60-seconds)
implements this.

**Long-poll shortcut: `?wait=N`** (0 to 10 seconds, default 0). The API kicks the scan as above, then holds the request
open for up to `N` seconds. If the scan finishes in time you get the normal fresh `200` for the new snapshot in one
call; if not, you get exactly the `202` (or the stale `200` with `refreshing: true`) you would have got without `wait`,
and the flow above continues. A waiting request costs 5 units once.

> [accordion] Captured example
>
> `GET /v1/solana/wallets/BWJUG6W67qRq7Xbkv3cLo7m4zEr21oJKg93ens3mLmBg/defi-positions/jobs/600aa76a-4e8b-4a66-ae70-9410c8eaa601` → `200` (captured 2026-11-12 from local `job-succeeded`)
>
> ```json theme={null}
> {
>   "job_id": "600aa76a-4e8b-4a66-ae70-9410c8eaa601",
>   "wallet": "BWJUG6W67qRq7Xbkv3cLo7m4zEr21oJKg93ens3mLmBg",
>   "status": "succeeded",
>   "trigger": "kick",
>   "attempts": 1,
>   "requested_at": "2026-11-12T20:33:28Z",
>   "started_at": "2026-11-12T20:33:28Z",
>   "finished_at": "2026-11-12T20:33:32Z",
>   "next_retry_at": null,
>   "retry_reason": null,
>   "snapshot_id": "80b3c313-8521-4d42-990d-806902449f11",
>   "observed_slots": {
>     "minimum": 468660573,
>     "maximum": 468660588
>   },
>   "errors": []
> }
> ```


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