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

> ## Agent Instructions
> The WebSocket at wss://mobs.ws/v1/ws/metar is the product. The HTTP API is a fallback for backfill only.
> Follow /agents.md for connect, auth, fields, heartbeat, reconnect, and dedupe. Never log MOBS_TOKEN or a URL that includes ?token=.

# HTTP API

> The /v1/metar endpoints: latest report per airport, resync after a reconnect, and latency.

| Endpoint | Access | Use |
| - | - | - |
| `GET /v1/metar` | API key · `latest` | Latest report per airport |
| `GET /v1/metar/latest` | API key · `latest` | Resync after a reconnect |
| `GET /v1/metar/latency` | API key · `latest` | 72 h average per airport |
| `GET /v1/status` | Public | Process state ([Status](https://mobs.ws/status)) |
| `GET /v1/stations` | Public | Station catalog ([Stations](https://docs.mobs.ws/stations.md)) |

## Latest report per airport

```text GET · API key · latest theme={"dark"}
https://mobs.ws/v1/metar?airports=KNYC,KLGA&mode=raw
```

| Parameter | Required | Description |
| - | - | - |
| `airports` | Yes | Comma list of ICAO codes, up to 100. Case-insensitive; duplicates removed. |
| `mode` | No | `raw` (default) or `parsed`, which adds a `parsed` object. |

```bash curl theme={"dark"}
curl -s -H "Authorization: Bearer $MOBS_API_KEY" \
  "https://mobs.ws/v1/metar?airports=KNYC,KLGA&mode=raw"
```

```json Example data · not a live report theme={"dark"}
{"data":[
  {"icao":"KNYC",
   "raw_metar":
    "METAR KNYC 092251Z 31009KT 10SM FEW250 12/M03 A3021 RMK AO2 SLP231 T01171028",
   "obs_time":"2026-11-09T22:51:00+00:00",
   "report_type":"METAR",
   "arrived_at":"<UTC time, ms>"}
]}
```

An airport with no report held is left out of `data`. Records come in request order.

> [!NOTE]
>
> Placeholder · A13

## Resync after a reconnect

```text GET · API key · latest theme={"dark"}
https://mobs.ws/v1/metar/latest?airports=KNYC,KLGA
```

| Parameter | Required | Description |
| - | - | - |
| `airports` | Yes | Comma list of ICAO codes, up to 100. Case-insensitive; duplicates removed. |
| `mode` | No | `raw` (default) or `parsed`. |

Call it after every connect or reconnect, then merge with pushed records. `missing` lists requested airports with no record. Each `versions` value is opaque: compare it for equality only.

```bash curl theme={"dark"}
curl -s -H "Authorization: Bearer $MOBS_API_KEY" \
  "https://mobs.ws/v1/metar/latest?airports=KNYC,KLGA"
```

```python Python theme={"dark"}
import os
import httpx

api_key = os.environ["MOBS_API_KEY"]
r = httpx.get(
    "https://mobs.ws/v1/metar/latest",
    params={"airports": "KNYC,KLGA"},
    headers={"Authorization": f"Bearer {api_key}"},
)
r.raise_for_status()
body = r.json()
for rec in body["data"]:
    print(rec["icao"], rec["obs_time"], rec["raw_metar"])
print("missing:", body["missing"])
```

```json Example data · values elided theme={"dark"}
{"data":[
  {"icao":"KLGA", …},
  {"icao":"KNYC", …}],
 "versions":{
  "KLGA":"<opaque>",
  "KNYC":"<opaque>"},
 "missing":["KDAL"]}
```

`mode` is optional (default `raw`). When every airport is missing the answer is 200 with empty `data` and a full `missing`.

> [!NOTE]
>
> The `versions` rule is Placeholder · A9. The all-missing answer is Placeholder · A10.

## Record fields

The record shape is the same on HTTP and on the socket. The canonical section is [Record fields](https://docs.mobs.ws/websocket.md#record-fields).

### Parsed fields

See [Parsed fields](https://docs.mobs.ws/websocket.md#parsed-fields).

### Corrections

See [Corrections](https://docs.mobs.ws/websocket.md#corrections).

## Latency

```text GET · API key · latest theme={"dark"}
https://mobs.ws/v1/metar/latency?airports=KNYC,KLGA
```

| Parameter | Required | Description |
| - | - | - |
| `airports` | No | Up to 100 codes; without `airports` it lists every covered airport. |

Average `obs_time` to `arrived_at` per airport over a 72 h rolling window by receipt time, to one decimal. `null` means no samples; a genuine zero is `0.0`. Only live receipts count; repeated copies count once and corrections count as new samples. No `mode`: sending one is a 422.

```json Example shape · placeholders, not measurements theme={"dark"}
{"data":[
  {"icao":"KNYC",
   "avg_latency_seconds":<seconds>,
   "sample_count":<n>},
  {"icao":"KLGA",
   "avg_latency_seconds":null,
   "sample_count":0}]}
```

The window is held in memory, so a restart clears it.

> [!WARNING]
>
> To be confirmed · D11

### What is measured

* Report latency: `obs_time` to `arrived_at`, per airport, from `GET /v1/metar/latency` (API key).
* Collection and source lag: per source, server side, on public [Status](https://mobs.ws/status).
* Delivery to your client: not measured. Clock offset and network time are yours to account for.

`null` means no sample, not zero.


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