{
  "version": "sources-2026.3",
  "effectiveDate": "2026-09-15",
  "note": "The source catalogue is the honesty contract of this API: it states what is ingested, from where, under what licence, how often, and — just as importantly — what is NOT covered. GET /v1/ingest/runs reports how fresh each source actually is right now.",
  "sources": [
    {
      "id": "ted",
      "kind": "ted",
      "name": "Tenders Electronic Daily (TED)",
      "jurisdiction": "EU/EEA",
      "publisher": "Publications Office of the European Union",
      "endpoint": "https://api.ted.europa.eu/v3/notices/search",
      "method": "POST",
      "auth": "none",
      "licence": "EU reuse — Commission Decision 2011/833/EU, attribution required",
      "attribution": "Source: Tenders Electronic Daily, Supplement to the Official Journal of the European Union",
      "cadence": "hourly",
      "constraints": {
        "fieldsRequired": true,
        "maxLimit": 250,
        "deepPagination": "paginationMode=ITERATION with iterationNextToken",
        "rateLimitHeaders": false,
        "note": "No rate-limit headers are returned, so the client paces itself."
      },
      "covers": [
        "Above-threshold notices from all EU/EEA contracting authorities",
        "Contract notices, contract award notices, prior information notices, modifications",
        "Buyer and winner national registration identifiers"
      ],
      "doesNotCover": [
        "Below-threshold national procurement that never reaches TED",
        "Tender documents and attachments",
        "Notices withdrawn before publication"
      ],
      "identityStrength": {
        "buyer": "strong",
        "winner": "strong"
      },
      "enabled": true,
      "ingest": {
        "windowDays": 2,
        "maxRecords": 20000,
        "note": "TED is queried by time window, not by watermark, so a cap that is smaller than the window silently drops the rest of it — the run would re-read the same first N notices every hour and never reach the others. Two days of overlap costs nothing because re-seeing a notice is a no-op."
      }
    },
    {
      "id": "sam",
      "kind": "sam",
      "name": "SAM.gov Contract Opportunities",
      "jurisdiction": "US federal",
      "publisher": "U.S. General Services Administration",
      "endpoint": "https://sam.gov/api/prod/fileextractservices/v1/api/download/Contract%20Opportunities/datagov/ContractOpportunitiesFullCSV.csv?privacy=Public",
      "method": "GET",
      "auth": "none",
      "licence": "Public domain (work of the U.S. federal government)",
      "attribution": "Source: SAM.gov Contract Opportunities, U.S. General Services Administration",
      "cadence": "daily",
      "constraints": {
        "transport": "bulk CSV extract, streamed",
        "approximateSize": "194-244 MB",
        "approximateRows": "80000-100000 active opportunities",
        "whyNotTheApi": "The SAM.gov Get Opportunities JSON API caps a non-federal public key at roughly 10 requests per day, which cannot sustain a feed. The bulk extract is the supported path for data reusers and needs no key."
      },
      "covers": [
        "Active US federal contract opportunities: presolicitations, solicitations, combined synopses, sources sought, special notices, award notices",
        "NAICS code and PSC classification code",
        "Agency hierarchy: department, sub-tier, office, CGAC and AAC codes"
      ],
      "doesNotCover": [
        "Archived opportunities that have dropped out of the active extract",
        "State, local and tribal procurement",
        "Awardee UEI or CAGE codes — the extract gives an unparsed name-and-address string only"
      ],
      "identityStrength": {
        "buyer": "strong",
        "winner": "weak"
      },
      "identityNote": "US buyers resolve on stable agency codes (CGAC, AAC). US winners have no identifier in this feed, so they resolve on parsed name and location and stay merge candidates rather than merges.",
      "enabled": true,
      "ingest": {
        "maxRecords": null,
        "watermarkOrdered": false,
        "note": "The extract is NOT sorted by date, so a record cap takes an arbitrary slice of the file. Worse, the watermark would then advance past everything older in that slice and exclude it permanently. The whole extract is processed instead, filtered by the watermark after the first run, which is cheap because unchanged rows are a no-op. The timeout covers the entire streamed response, so it is sized for the whole extract rather than for connecting.",
        "timeoutMs": 1800000
      }
    },
    {
      "id": "uk-find-a-tender",
      "kind": "ocds",
      "name": "UK Find a Tender",
      "jurisdiction": "United Kingdom",
      "publisher": "UK Cabinet Office",
      "endpoint": "https://www.find-tender.service.gov.uk/api/1.0/ocdsReleasePackages",
      "method": "GET",
      "auth": "none",
      "licence": "Open Government Licence v3.0 — attribution required",
      "attribution": "Contains public sector information licensed under the Open Government Licence v3.0",
      "cadence": "hourly",
      "ocdsVersion": "1.1.5",
      "constraints": {
        "pagination": "cursor via links.next",
        "watermark": "updatedFrom / updatedTo"
      },
      "covers": [
        "UK above-threshold notices published to Find a Tender",
        "OCDS releases with ocid, parties, buyer, tender and awards"
      ],
      "doesNotCover": [
        "Contracts Finder below-threshold notices",
        "Devolved portals that do not publish to Find a Tender"
      ],
      "identityStrength": {
        "buyer": "strong",
        "winner": "strong"
      },
      "identityNote": "Strength depends on the publisher populating parties[].identifier; releases without one fall back to name matching and are flagged weak.",
      "enabled": true,
      "ingest": {
        "maxRecords": 5000,
        "pauseMs": 5500,
        "note": "A cursor walk in update order, so a capped run simply resumes from its watermark next time. Paced at 5.5s per page because the publisher allows about 12 requests per window and advertises no limit on success."
      }
    }
  ],
  "plannedSources": [
    {
      "note": "Additional OCDS publishers are configuration, not code — the ocds adapter already handles the release-package shape. Each is added only after its licence is checked and recorded, and after a recorded fixture is committed.",
      "candidates": [
        "Further national and subnational OCDS publishers listed in the Open Contracting Partnership data registry"
      ]
    }
  ]
}
