Neutral ZoneLabelwatch

For developers

Use the observations

Two public surfaces answer different questions: aggregate facts describe the observatory; account views show the public label events recorded for one account and its records.

Aggregate Facts API

Anonymous, read-only JSON. No API key or account required. No subject identities or account lookup are published by this API.

Full API reference · OpenAPI specification · Facts API on GitHub

curl --fail-with-body https://api.neutral.zone/atproto/v1/labelwatch/overview
GET /atproto/v1/labelwatch/overview
Observation counts, coverage and collection freshness for the rolling window.
GET /atproto/v1/instruments
Contributing instruments and source availability. PRESENT means readable, not necessarily fresh or servable.

Read the envelope before the counts

The response contains contract, instrument, generated_at, retrieved_at, age_seconds, freshness, facts, caveats and provenance.

Within facts, counts describes observed events; coverage describes the observed interval, warm-up and gaps. acquisition identifies the observation epoch. current_label_state is unknown. Alert counts may be null: unknown is not zero.

freshness.state describes publication and collection freshness. A fresh response can still have partial coverage. HTTP 200 is served for fresh or warming-up Labelwatch observations. Stale, held or unavailable observations return HTTP 503 with an error object; do not treat that as a quiet period or zero labels. Read the returned freshness bounds rather than assuming an update cadence.

Account views and bounded downloads

Use account lookup for subject-specific public observations. Labels attached directly to the account DID appear first; post labels and other record labels are separate. These are observed applications and removals, not a list of currently active labels.

# Replace with the account DID you want to inspect.
DID='did:plc:YOUR_ACCOUNT_DID'
curl --get 'https://labelwatch.neutral.zone/exports'   --data-urlencode "did=$DID" --data-urlencode 'days=7'

/account?did=…&days=7 returns HTML. /exports?did=…&days=7 creates a bounded JSON export. Supported shortcuts are 7 and 30 days, clipped to the available window. Explicit start and end timestamps use a start-inclusive, end-exclusive interval.

Export creation returns a manifest and cursor. Request /exports?cursor=…, then follow next_cursor until terminal is true. Pages contain rows. Keep the manifest with the rows: it carries the interval, filters, coverage and expiry. The account page's download link uses a separate snapshot cursor; export cursors cannot be used with /download.

HTTP 409 is an explicit refusal, including an unsupported interval or an export beyond the bound. HTTP 410 means an expired or unavailable snapshot. A busy store returns HTTP 503 with Retry-After. An interrupted or expired export is incomplete; start again or use the narrower intervals returned by the service.

Account and export reference on GitHub

What the data cannot tell you

The service retains a fixed rolling 30-day window. It does not reconstruct earlier history, infer missing events, or establish current label state. No observations does not mean no labels exist. Provider outages and incomplete coverage remain explicit. Account data is not added to the aggregate Facts API, and operational health endpoints remain private.

Read the coverage explanation