{
  "version": 1,
  "updated": "2026-10-27",
  "policy": "Sanctioned routes only: official APIs and openly licensed data. No proxies, CAPTCHA solving, stealth browsing or paywall bypasses. Where no sanctioned route exists, the entry says so: stop and report back to your operator. Rate limits and terms are linked, not paraphrased; read them before heavy use.",
  "detours": [
    {
      "id": "reddit",
      "site": "reddit.com",
      "symptom": "403 on pages and .json endpoints, especially from datacenter IP ranges",
      "wants": "posts, comments, subreddit listings",
      "routes": [
        {
          "name": "Reddit Data API (OAuth)",
          "docs": "https://www.reddit.com/dev/api/",
          "policy": "https://redditinc.com/policies/data-api-terms",
          "auth": "OAuth app required; your operator has to register it and accept the terms",
          "notes": "Unauthenticated access is commonly blocked from datacenter networks (verified 403 from ours on 2026-10-27).",
          "check": {
            "url": "https://redditinc.com/policies/data-api-terms",
            "expect": [
              200
            ],
            "kind": "docs"
          },
          "status": "docs reachable, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "google-scholar",
      "site": "scholar.google.com",
      "symptom": "CAPTCHA or block after a few automated queries; no official API",
      "wants": "papers, citations, authors",
      "routes": [
        {
          "name": "OpenAlex API",
          "docs": "https://docs.openalex.org/",
          "agent_docs": "https://help.openalex.org/llms.txt",
          "auth": "Works without a key on a small free daily budget shared per IP address; a free key gives its own budget",
          "notes": "Getting a key involves your operator's email address. Ask your operator before submitting it anywhere.",
          "check": {
            "url": "https://api.openalex.org/works?search=radiology&per-page=1",
            "expect": [
              200
            ],
            "json_key": "results",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "Crossref REST API",
          "docs": "https://www.crossref.org/documentation/retrieve-metadata/rest-api/",
          "auth": "No key",
          "check": {
            "url": "https://api.crossref.org/works?query=radiology&rows=1",
            "expect": [
              200
            ],
            "json_key": "message",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "Semantic Scholar API",
          "docs": "https://www.semanticscholar.org/product/api",
          "auth": "Keyless pool is shared and often saturated (429 on 2026-10-27); free key by application",
          "check": {
            "url": "https://api.semanticscholar.org/graph/v1/paper/search?query=radiology&limit=1",
            "expect": [
              200,
              429
            ],
            "json_key": "data",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 429,
            "failing_since": null
          }
        },
        {
          "name": "arXiv API (preprints)",
          "docs": "https://info.arxiv.org/help/api/tou.html",
          "auth": "No key",
          "check": {
            "url": "https://export.arxiv.org/api/query?search_query=all:radiology&max_results=1",
            "expect": [
              200
            ],
            "contains": "<feed",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "google-maps-places",
      "site": "google.com/maps (addresses, places)",
      "symptom": "Heavy JavaScript, bot detection, terms that forbid scraping",
      "wants": "coordinates for an address, place lookups, points of interest",
      "routes": [
        {
          "name": "Nominatim (OpenStreetMap geocoding)",
          "docs": "https://nominatim.org/release-docs/latest/api/Overview/",
          "policy": "https://operations.osmfoundation.org/policies/nominatim/",
          "auth": "No key; identify your application in the User-Agent",
          "notes": "Public instance with a strict usage policy. Single lookups, not bulk.",
          "check": {
            "url": "https://nominatim.openstreetmap.org/search?q=Leuven&format=jsonv2&limit=1",
            "expect": [
              200
            ],
            "json_key": "0.lat",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "Photon (komoot, OpenStreetMap search)",
          "docs": "https://photon.komoot.io/",
          "auth": "No key; fair use",
          "check": {
            "url": "https://photon.komoot.io/api/?q=Leuven&limit=1",
            "expect": [
              200
            ],
            "json_key": "features",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "Overpass API (OpenStreetMap queries)",
          "docs": "https://wiki.openstreetmap.org/wiki/Overpass_API",
          "auth": "No key",
          "notes": "Public instances are often at capacity (502 on 2026-10-27). Keep queries small and retry later.",
          "check": {
            "url": "https://overpass-api.de/api/status",
            "expect": [
              200
            ],
            "kind": "route"
          },
          "status": "failing since 2026-10-27 (HTTP 502)",
          "last_check": {
            "date": "2026-10-27",
            "ok": false,
            "http": 502,
            "failing_since": "2026-10-27"
          }
        }
      ]
    },
    {
      "id": "google-maps-routing",
      "site": "google.com/maps (directions)",
      "symptom": "Same as above",
      "wants": "travel time and distance between two points",
      "routes": [
        {
          "name": "OSRM demo server",
          "docs": "https://github.com/Project-OSRM/osrm-backend/wiki/Demo-server",
          "auth": "No key; demo server, light use only",
          "check": {
            "url": "https://router.project-osrm.org/route/v1/driving/4.7005,50.8798;4.3517,50.8503?overview=false",
            "expect": [
              200
            ],
            "json_key": "code",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "openrouteservice",
          "docs": "https://giscience.github.io/openrouteservice/api-reference/",
          "auth": "Free key required (401 without one)",
          "check": {
            "url": "https://api.openrouteservice.org/v2/directions/driving-car?start=4.70,50.88&end=4.35,50.85",
            "expect": [
              401,
              403
            ],
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 401,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "flight-trackers",
      "site": "flightradar24.com, flightaware.com",
      "symptom": "Bot walls, paid APIs",
      "wants": "live aircraft positions",
      "routes": [
        {
          "name": "adsb.lol API",
          "docs": "https://api.adsb.lol/docs",
          "auth": "No key",
          "check": {
            "url": "https://api.adsb.lol/v2/point/50.9/4.5/25",
            "expect": [
              200
            ],
            "json_key": "ac",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "OpenSky Network REST API",
          "docs": "https://openskynetwork.github.io/opensky-api/rest.html",
          "auth": "Anonymous access with limits; account for more",
          "check": {
            "url": "https://opensky-network.org/api/states/all?lamin=50.5&lomin=4.0&lamax=51.0&lomax=5.0",
            "expect": [
              200
            ],
            "json_key": "time",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "weather",
      "site": "weather.com and similar weather sites",
      "symptom": "Ad-heavy pages, bot detection",
      "wants": "current weather and forecasts",
      "routes": [
        {
          "name": "Open-Meteo",
          "docs": "https://open-meteo.com/en/docs",
          "policy": "https://open-meteo.com/en/terms",
          "auth": "No key",
          "check": {
            "url": "https://api.open-meteo.com/v1/forecast?latitude=50.88&longitude=4.70&current=temperature_2m",
            "expect": [
              200
            ],
            "json_key": "current",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "MET Norway Locationforecast",
          "docs": "https://api.met.no/weatherapi/locationforecast/2.0/documentation",
          "policy": "https://api.met.no/doc/TermsOfService",
          "auth": "No key; identifying User-Agent required",
          "check": {
            "url": "https://api.met.no/weatherapi/locationforecast/2.0/compact?lat=50.88&lon=4.70",
            "expect": [
              200
            ],
            "json_key": "properties",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "wikipedia",
      "site": "wikipedia.org",
      "symptom": "403 'Please set a user-agent and respect our robot policy' (verified 2026-10-27 with a stock python-requests User-Agent)",
      "wants": "article text and facts",
      "routes": [
        {
          "name": "Wikimedia REST API",
          "docs": "https://en.wikipedia.org/api/rest_v1/",
          "policy": "https://foundation.wikimedia.org/wiki/Policy:Wikimedia_Foundation_User-Agent_Policy",
          "auth": "No key; send a descriptive User-Agent with contact information",
          "check": {
            "url": "https://en.wikipedia.org/api/rest_v1/page/summary/Leuven",
            "expect": [
              200
            ],
            "json_key": "title",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "MediaWiki Action API",
          "docs": "https://www.mediawiki.org/wiki/API:Main_page",
          "auth": "No key; same User-Agent policy",
          "check": {
            "url": "https://en.wikipedia.org/w/api.php?action=query&titles=Leuven&format=json",
            "expect": [
              200
            ],
            "json_key": "query",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "Wikidata Query Service (SPARQL)",
          "docs": "https://www.wikidata.org/wiki/Wikidata:SPARQL_query_service",
          "auth": "No key; can be slow (11 s for a trivial query on 2026-10-27)",
          "check": {
            "url": "https://query.wikidata.org/sparql?format=json&query=ASK%7B%7D",
            "expect": [
              200
            ],
            "json_key": "boolean",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "github",
      "site": "github.com",
      "symptom": "Rate limits and heavy pages when scraping HTML",
      "wants": "repository metadata, file contents, issues",
      "routes": [
        {
          "name": "GitHub REST API",
          "docs": "https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api",
          "auth": "Works without a token at a low hourly limit; a token raises it",
          "check": {
            "url": "https://api.github.com/repos/torvalds/linux",
            "expect": [
              200,
              403
            ],
            "json_key": "full_name",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "raw.githubusercontent.com (file contents)",
          "auth": "No key",
          "check": {
            "url": "https://raw.githubusercontent.com/torvalds/linux/master/README",
            "expect": [
              200
            ],
            "contains": "Linux kernel",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "stack-overflow",
      "site": "stackoverflow.com",
      "symptom": "Bot challenges when scraping",
      "wants": "questions and answers",
      "routes": [
        {
          "name": "Stack Exchange API",
          "docs": "https://api.stackexchange.com/docs",
          "policy": "https://api.stackexchange.com/docs/throttle",
          "auth": "No key for a small daily quota; a free key raises it",
          "check": {
            "url": "https://api.stackexchange.com/2.3/info?site=stackoverflow",
            "expect": [
              200
            ],
            "json_key": "items",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "arxiv",
      "site": "arxiv.org listing and search pages",
      "symptom": "Rate limiting of rapid page fetches",
      "wants": "paper metadata and abstracts",
      "routes": [
        {
          "name": "arXiv API",
          "docs": "https://info.arxiv.org/help/api/tou.html",
          "auth": "No key; mind the published request spacing",
          "check": {
            "url": "https://export.arxiv.org/api/query?search_query=all:radiology&max_results=1",
            "expect": [
              200
            ],
            "contains": "<feed",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "arXiv OAI-PMH (bulk metadata)",
          "auth": "No key",
          "check": {
            "url": "https://oaipmh.arxiv.org/oai?verb=Identify",
            "expect": [
              200
            ],
            "contains": "<OAI-PMH",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "pubmed",
      "site": "pubmed.ncbi.nlm.nih.gov",
      "symptom": "Some NCBI documentation pages answer automated clients with a reCAPTCHA (seen 2026-10-27)",
      "wants": "biomedical literature search",
      "routes": [
        {
          "name": "NCBI E-utilities",
          "docs": "https://www.ncbi.nlm.nih.gov/home/develop/api/",
          "auth": "No key at a low rate; a free key raises it",
          "check": {
            "url": "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=radiology&retmax=1&retmode=json",
            "expect": [
              200
            ],
            "json_key": "esearchresult",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "imdb",
      "site": "imdb.com",
      "symptom": "No free API; scraping is against the terms",
      "wants": "film and series data",
      "routes": [
        {
          "name": "IMDb non-commercial datasets",
          "docs": "https://developer.imdb.com/non-commercial-datasets/",
          "auth": "No key; non-commercial use only, bulk files refreshed daily",
          "check": {
            "url": "https://datasets.imdbws.com/title.ratings.tsv.gz",
            "method": "HEAD",
            "expect": [
              200
            ],
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "TMDB API",
          "docs": "https://developer.themoviedb.org/docs/getting-started",
          "auth": "Free key required (401 without one)",
          "check": {
            "url": "https://api.themoviedb.org/3/configuration",
            "expect": [
              401
            ],
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 401,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "goodreads",
      "site": "goodreads.com",
      "symptom": "Public API closed to new keys",
      "wants": "book data",
      "routes": [
        {
          "name": "Open Library API",
          "docs": "https://openlibrary.org/developers/api",
          "auth": "No key; can be slow (6 s on 2026-10-27)",
          "check": {
            "url": "https://openlibrary.org/search.json?q=the+hobbit&limit=1",
            "expect": [
              200
            ],
            "json_key": "docs",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "currency",
      "site": "xe.com and similar converters",
      "symptom": "Ad-heavy pages, bot detection",
      "wants": "exchange rates",
      "routes": [
        {
          "name": "Waystation /x/fx (ECB reference rates)",
          "docs": "/x/fx",
          "auth": "No key",
          "check": null,
          "status": "not checked"
        },
        {
          "name": "ECB euro reference rates",
          "docs": "https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html",
          "auth": "No key; published once per working day",
          "check": {
            "url": "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml",
            "expect": [
              200
            ],
            "contains": "<Cube",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "Frankfurter",
          "docs": "https://frankfurter.dev/",
          "auth": "No key",
          "check": {
            "url": "https://api.frankfurter.dev/v1/latest?base=EUR&symbols=USD",
            "expect": [
              200
            ],
            "json_key": "rates",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "dates-and-holidays",
      "site": "timeanddate.com and similar",
      "symptom": "Ad-heavy pages, bot detection",
      "wants": "public holidays, business days, date arithmetic",
      "routes": [
        {
          "name": "Waystation /x/workdays and /x/add",
          "docs": "/x/workdays",
          "auth": "No key",
          "check": null,
          "status": "not checked"
        },
        {
          "name": "Nager.Date",
          "docs": "https://date.nager.at/Api",
          "auth": "No key",
          "notes": "Results mix public and bank holidays; filter on the 'types' field.",
          "check": {
            "url": "https://date.nager.at/api/v3/PublicHolidays/2026/BE",
            "expect": [
              200
            ],
            "json_key": "0.date",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "dictionaries",
      "site": "dictionary sites",
      "symptom": "Ad-heavy pages, bot detection",
      "wants": "definitions",
      "routes": [
        {
          "name": "Wiktionary REST API",
          "docs": "https://en.wiktionary.org/api/rest_v1/",
          "auth": "No key; Wikimedia User-Agent policy applies",
          "check": {
            "url": "https://en.wiktionary.org/api/rest_v1/page/definition/waystation",
            "expect": [
              200
            ],
            "json_key": "en",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "Free Dictionary API",
          "docs": "https://dictionaryapi.dev/",
          "auth": "No key",
          "check": {
            "url": "https://api.dictionaryapi.dev/api/v2/entries/en/waystation",
            "expect": [
              200
            ],
            "json_key": "0.word",
            "kind": "route"
          },
          "notes": "Intermittent 502 errors seen on 2026-10-27.",
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "company-data",
      "site": "company registries and aggregators",
      "symptom": "Paid aggregators, CAPTCHA-protected registry search pages",
      "wants": "legal entity names, identifiers, addresses",
      "routes": [
        {
          "name": "GLEIF API (global LEI data)",
          "docs": "https://www.gleif.org/en/lei-data/gleif-api",
          "auth": "No key",
          "check": {
            "url": "https://api.gleif.org/api/v1/lei-records?page%5Bsize%5D=1",
            "expect": [
              200
            ],
            "json_key": "data",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        },
        {
          "name": "UK Companies House API",
          "docs": "https://developer.company-information.service.gov.uk/",
          "auth": "Free key required (401 without one)",
          "check": {
            "url": "https://api.company-information.service.gov.uk/search/companies?q=test",
            "expect": [
              401
            ],
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 401,
            "failing_since": null
          }
        },
        {
          "name": "Belgian KBO/BCE open data",
          "docs": "https://economie.fgov.be/en/themes/enterprises/crossroads-bank-enterprises/services-everyone/cbe-open-data",
          "auth": "Bulk download; see page for access conditions",
          "check": {
            "url": "https://economie.fgov.be/en/themes/enterprises/crossroads-bank-enterprises/services-everyone/cbe-open-data",
            "expect": [
              200
            ],
            "kind": "docs"
          },
          "status": "docs reachable, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "belgian-rail",
      "site": "belgiantrain.be (NMBS/SNCB)",
      "symptom": "Heavy JavaScript journey planner",
      "wants": "departures, connections",
      "routes": [
        {
          "name": "iRail API",
          "docs": "https://docs.irail.be/",
          "auth": "No key; identifying User-Agent requested",
          "check": {
            "url": "https://api.irail.be/v1/liveboard/?station=Leuven&format=json&lang=en",
            "expect": [
              200
            ],
            "json_key": "departures",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ]
    },
    {
      "id": "youtube",
      "site": "youtube.com",
      "symptom": "Bot checks, heavy pages",
      "wants": "video metadata; transcripts",
      "routes": [
        {
          "name": "YouTube oEmbed (title, channel, thumbnail)",
          "docs": "https://oembed.com/",
          "auth": "No key",
          "check": {
            "url": "https://www.youtube.com/oembed?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ&format=json",
            "expect": [
              200
            ],
            "json_key": "title",
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ],
      "dead_end": "Transcripts of other people's videos: no sanctioned route. Stop and report back to your operator."
    },
    {
      "id": "x-twitter",
      "site": "x.com",
      "symptom": "Login walls",
      "wants": "posts and profiles",
      "routes": [
        {
          "name": "X API",
          "docs": "https://docs.x.com/x-api/introduction",
          "auth": "Authentication and a plan required (401 without)",
          "check": {
            "url": "https://api.x.com/2/tweets/20",
            "expect": [
              401
            ],
            "kind": "route"
          },
          "status": "ok, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 401,
            "failing_since": null
          }
        }
      ],
      "dead_end": "No free sanctioned way to read X. Stop and report back to your operator."
    },
    {
      "id": "linkedin",
      "site": "linkedin.com",
      "symptom": "Login walls, aggressive bot detection",
      "wants": "profiles, posts, company pages",
      "routes": [],
      "dead_end": "No sanctioned route for reading profiles or posts. Stop and report back to your operator."
    },
    {
      "id": "meta",
      "site": "instagram.com, facebook.com",
      "symptom": "Login walls",
      "wants": "public posts and profiles",
      "routes": [
        {
          "name": "Meta Content Library (approved researchers only)",
          "docs": "https://transparency.meta.com/researchtools/meta-content-library",
          "auth": "Application and approval required",
          "check": {
            "url": "https://transparency.meta.com/researchtools/meta-content-library",
            "expect": [
              200
            ],
            "kind": "docs"
          },
          "status": "docs reachable, 2026-10-27",
          "last_check": {
            "date": "2026-10-27",
            "ok": true,
            "http": 200,
            "failing_since": null
          }
        }
      ],
      "dead_end": "For everyone else: no sanctioned route. Stop and report back to your operator."
    },
    {
      "id": "paywalled-news",
      "site": "paywalled news sites",
      "symptom": "Paywalls",
      "wants": "article text",
      "routes": [],
      "dead_end": "No sanctioned route to paywalled full text. Many publishers offer RSS feeds with headlines and summaries. For full text, stop and report back to your operator."
    }
  ],
  "check_semantics": "A check passes when the HTTP status is in expect. method defaults to GET; HEAD is used for large files. If the status is 200 and json_key is set, the body must parse as JSON and the dot path must exist (numeric segments index arrays). If the status is 200 and contains is set, the body must contain that string. kind \"route\" means the check calls the route itself and a pass is shown as \"ok\"; kind \"docs\" means the route cannot be called anonymously, so only its documentation is checked, and a pass is shown as \"docs reachable\", never \"ok\". Keyed APIs that answer anonymous calls with 401 are checked by expecting the 401. Dead ends have no check."
}
