GUIDE · API

API reference

All endpoints are HTTPS, JSON, and behind api.debrisguard.deepfieldlabs.dev. Authenticate with a Cognito JWT (interactive) or an API key (for scripts).

Auth: JWT vs API key

Every request needs an Authorization: Bearer <token> header. Two kinds of token:

Cognito JWTAPI key
Lifetime~60 minUntil revoked
Best forInteractive use, CLI scripts you run by handCI, cron, backend services, automation
How to get oneDashboard → profile → CLI access → Copy access tokenDashboard → profile → API keys → + New key
Tier requiredAny (Watcher included)Analyst+ (Watcher returns 403)
HeaderAuthorization: Bearer <token-or-key>
Why two tokens? JWTs roll over automatically when you refresh the dashboard. API keys give you a stable secret you can paste into a CI variable; they survive password resets and don't need a browser. Use whichever fits your workflow.

Quotas & rate-limits

Two limits, both enforced atomically:

Check your live quota:

curl -H "Authorization: Bearer $DG_TOKEN" \
  https://api.debrisguard.deepfieldlabs.dev/v1/usage/today

GET /v1/objects/{norad_id}

Catalog lookup for a single NORAD ID. Costs one lookup against your daily quota.

curl -H "Authorization: Bearer $DG_TOKEN" \
  https://api.debrisguard.deepfieldlabs.dev/v1/objects/25544

Response (Analyst+):

{
  "schema": "debrisguard.public.object_lookup.v2",
  "norad_cat_id": "25544",
  "available": true,
  "enrichment": {
    "name": "ISS (ZARYA)",
    "orbit_class": "LEO",
    "epoch": "2026-05-18T12:14:08Z",
    "subpoint_lat": -22.4,
    "subpoint_lon": 145.7,
    "subpoint_alt_km": 433.0,
    "detectors_active": ["bstar_drift","catalog","manoeuvre"],
    "bstar_drift": {
      "score": 0.04, "z_score": 0.3, "trend_14d": "stable",
      "decay_roster": false
    },
    "manoeuvre": {
      "detected_in_window_d": 14,
      "last_burn_epoch": "2026-05-12T01:03:00Z",
      "advice_chip": "monitor",
      "advice_confidence": 0.51
    },
    "catalog_detector": {
      "d_squared": 0.0021, "outlier": false
    }
  },
  "score": { "fused_score": 0.18, "severity": "info", "is_alert": false }
}

Watcher tier: identical enrichment.name / orbit_class / subpoint_* but bstar_drift, manoeuvre, and catalog_detector blocks are omitted.

GET /v1/reports/daily/latest

Today's anomaly report. Free for all tiers; historical dates (/v1/reports/daily/2026-05-12) are Analyst+ only.

curl -H "Authorization: Bearer $DG_TOKEN" \
  https://api.debrisguard.deepfieldlabs.dev/v1/reports/daily/latest

Response:

{
  "schema": "debrisguard.public.daily_report.v2",
  "report_date": "2026-05-19",
  "alerts_total": 8,
  "pipeline_coverage": {
    "tracked_objects": 27411,
    "scored_objects": 27411,
    "manoeuvre_window_d": 14,
    "burns_detected_14d": 1667,
    "burn_confirmation_rate": 0.745,
    "decay_roster_size": 63
  },
  "top_objects": [
    { "norad_cat_id":"58712","name":"STARLINK-32115",
      "fused_score":0.71,"detectors":["manoeuvre","catalog"] },
    …
  ]
}

GET /v1/manoeuvres/recent

Pipeline-wide manoeuvre detections from the rolling 14-day window. Analyst+ only. Watcher → HTTP 403.

curl -H "Authorization: Bearer $DG_TOKEN" \
  'https://api.debrisguard.deepfieldlabs.dev/v1/manoeuvres/recent?limit=20'

Query params: limit (default 25, max 100), chip=escalate|review|monitor, kind=thrust_event_detected|manoeuvre_or_orbit_drift, watchlist=1 (your watchlist only).

Response:

{
  "schema": "debrisguard.public.manoeuvres_recent.v1",
  "window_days": 14,
  "n_objects_with_burns": 1213,
  "chip_legend": {
    "escalate": "High confidence AND (watchlisted OR active CDM)",
    "review":   "High confidence, or medium confidence with priority",
    "monitor":  "Lower confidence or single-pair detection"
  },
  "items": [
    { "norad_cat_id":"58712","name":"STARLINK-32115",
      "last_burn_epoch":"2026-05-18T02:11:00Z",
      "advice_confidence":0.94,"advice_chip":"escalate",
      "n_pairs":3,"watchlisted":true }
  ]
}

/v1/fleet — watchlist

# list your watchlist
curl -H "Authorization: Bearer $DG_TOKEN" \
  https://api.debrisguard.deepfieldlabs.dev/v1/fleet

# pin a NORAD
curl -X POST -H "Authorization: Bearer $DG_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"norad_cat_id":"25544"}' \
  https://api.debrisguard.deepfieldlabs.dev/v1/fleet

# unpin
curl -X DELETE -H "Authorization: Bearer $DG_TOKEN" \
  https://api.debrisguard.deepfieldlabs.dev/v1/fleet/25544

Exceeding the tier cap returns:

HTTP/1.1 409 Conflict
{"error":"tier 'analyst' allows up to 5 watchlist items (currently 5)"}

GET /v1/usage/today

{
  "schema": "debrisguard.public.usage_today.v1",
  "tier": "analyst",
  "catalog_lookups_today": 42,
  "catalog_lookups_limit": 5000,
  "watchlist_size": 3,
  "watchlist_limit": 5,
  "api_keys_active": 2
}

/v1/webhooks (Operator+)

Subscribe a Slack / Teams / generic webhook to new alerts. Watcher and Analyst → HTTP 403.

# create
curl -X POST -H "Authorization: Bearer $DG_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://hooks.slack.com/...","kind":"slack",
       "filter":{"min_severity":"alert"}}' \
  https://api.debrisguard.deepfieldlabs.dev/v1/webhooks

# list
curl -H "Authorization: Bearer $DG_TOKEN" \
  https://api.debrisguard.deepfieldlabs.dev/v1/webhooks

# delete
curl -X DELETE -H "Authorization: Bearer $DG_TOKEN" \
  https://api.debrisguard.deepfieldlabs.dev/v1/webhooks/<id>

Delivery is retried with exponential backoff (1 s → 16 s, 5 attempts) then dead-lettered to SQS for replay via the /v1/webhooks/<id>/replay endpoint.

Common error responses

StatusMeaningWhat to do
401Missing / expired JWTRefresh your access token or use an API key.
403Tier doesn't allow this endpointUpgrade tier, or check that you're not on Watcher for a paid-only endpoint.
404NORAD not in the active catalogTry a different ID, or check that the object hasn't decayed.
409Watchlist fullRemove a pinned NORAD or upgrade tier.
429Quota exhausted (day or minute)Read retry_after_seconds; back off; upgrade if persistent.
5xxServer errorRead x-correlation-id, include it in a support ticket.

Full integration examples

Python — daily decay-roster digest

import os, requests
TOK = os.environ["DG_TOKEN"]                                # API key
BASE = "https://api.debrisguard.deepfieldlabs.dev"
HEAD = {"Authorization": f"Bearer {TOK}"}

report = requests.get(f"{BASE}/v1/reports/daily/latest", headers=HEAD).json()
roster = [o for o in report["top_objects"] if "bstar-drift" in o["detectors"]]
print(f"Re-entry candidates today: {len(roster)}")
for o in roster:
    print(f"  {o['norad_cat_id']:>6}  {o['name']:<25}  {o['fused_score']:.2f}")

Bash — watch a NORAD and ping you on burn detection

NORAD=25544
res=$(curl -sS -H "Authorization: Bearer $DG_TOKEN" \
  "https://api.debrisguard.deepfieldlabs.dev/v1/objects/$NORAD")
chip=$(echo "$res" | jq -r '.enrichment.manoeuvre.advice_chip // "none"')
[[ "$chip" == "escalate" ]] && \
  curl -s -X POST -d "{\"text\":\"BURN ESCALATE on $NORAD\"}" \
    "$SLACK_WEBHOOK_URL"

← Dashboard tour  ·  Next: All features →