{"openapi":"3.1.0","info":{"title":"TenderGraph API","version":"0.3.0","description":"Worldwide tender intelligence: public notices from 53 countries with provenance, deduplicated per procurement, with extracted document text where it has been processed (open tenders first). The UK and Irish national notice services are held in full; other countries at varying depth — call /v1/sources for exactly what is held and when each source last synced. Auth: Bearer tg_live_… key. Every list endpoint that takes format=csv streams the same result as an Excel-ready file under the same key and rate limit; the format parameter on each is the data dictionary."},"servers":[{"url":"https://tendergraph.ai"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"},"apiKeyHeader":{"type":"apiKey","in":"header","name":"X-Api-Key"}}},"security":[{"bearer":[]},{"apiKeyHeader":[]}],"paths":{"/api/v1/tenders":{"get":{"summary":"Search tenders","parameters":[{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"},{"in":"query","name":"q","schema":{"type":"string"},"description":"Full-text (websearch syntax)"},{"in":"query","name":"status","schema":{"type":"string"},"description":"Comma list: open,closed,awarded,cancelled,planned"},{"in":"query","name":"notice_type","schema":{"type":"string"},"description":"planning,opportunity,award,update"},{"in":"query","name":"country","schema":{"type":"string","example":"GB"}},{"in":"query","name":"source","schema":{"type":"string"},"description":"Source keys (see /api/v1/sources)"},{"in":"query","name":"cpv","schema":{"type":"string"},"description":"CPV prefixes, e.g. 45,72"},{"in":"query","name":"region","schema":{"type":"string"},"description":"ITL/NUTS prefixes, e.g. UKD,IE"},{"in":"query","name":"buyer","schema":{"type":"string"}},{"in":"query","name":"published_from","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"published_to","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"deadline_from","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"deadline_to","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"expires_from","schema":{"type":"string","format":"date-time"},"description":"Contract END date at or after this date — the publisher's stated end of an awarded contract (contract_end_at; the same value as extras.contractEnd). With notice_type=award and expires_to this lists the incumbents' contracts coming up for renewal. A notice whose publisher stated no end date never matches; nothing is inferred."},{"in":"query","name":"expires_to","schema":{"type":"string","format":"date-time"},"description":"Contract END date at or before this date. See expires_from."},{"in":"query","name":"value_from","schema":{"type":"number"}},{"in":"query","name":"value_to","schema":{"type":"number"}},{"in":"query","name":"framework","schema":{"type":"boolean"}},{"in":"query","name":"sort","schema":{"type":"string","enum":["published_desc","deadline_asc","value_desc","relevance","expires_asc"]},"description":"expires_asc orders by contract end date, soonest first; notices with no stated end date come last."},{"in":"query","name":"page","schema":{"type":"integer","minimum":1}},{"in":"query","name":"per_page","schema":{"type":"integer","maximum":100}},{"in":"query","name":"dedupe","schema":{"type":"boolean","default":true},"description":"Collapse to one row per procurement"},{"in":"query","name":"documents","schema":{"type":"boolean","default":true},"description":"Search inside extracted attachment text as well as the notice. Notices matched this way carry matched_documents naming the attachments, and rank below notice matches. Set false to match the notice only."},{"in":"query","name":"format","schema":{"type":"string","enum":["json","csv"],"default":"json"},"description":"csv streams the result as a file. Columns: id, title, buyer, country, region_codes, cpv_codes, status, notice_type, published_at, deadline_at, awarded_at, value_min, value_max, currency, source, source_url, url (TenderGraph page), framework, suppliers. RFC 4180, UTF-8 with BOM, CRLF line endings, ISO 8601 UTC dates, money as plain numbers beside a currency column (never summed across currencies), lists joined with '; ', text cells starting with = + - @ prefixed with an apostrophe (formula-injection defence). Response headers: Content-Disposition names the file (tendergraph-<what>-<YYYY-MM-DD>.csv), X-TenderGraph-Methodology states how the numbers were made, X-TenderGraph-Truncated: true means the file is a prefix of the result."},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":10000,"default":10000},"description":"CSV only: rows in the file, at most 10,000 (the pager's own reach). A larger value is clamped and the response carries X-TenderGraph-Truncated: true; page/per_page are ignored for CSV."}],"responses":{"200":{"description":"Tender list with pagination (application/json), or with format=csv the rows as text/csv","content":{"application/json":{},"text/csv":{}}}}}},"/api/v1/tenders/{id}":{"get":{"summary":"Get one tender in full","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"include_raw","schema":{"type":"boolean"},"description":"Include the verbatim source release"},{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"}],"responses":{"200":{"description":"Full record incl. parsed documents and related notices"},"404":{"description":"Not found"}}}},"/api/v1/tenders/{id}/summarize":{"post":{"summary":"Generate Claude summaries for a tender's documents (on demand, capped)","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"}],"responses":{"200":{"description":"Summaries generated"},"429":{"description":"Daily summarisation cap reached"},"501":{"description":"Summarisation not enabled on this deployment"}}}},"/api/v1/qualify":{"post":{"summary":"Deterministic bid/no-bid qualification of a tender against a company profile","parameters":[{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"tender_id":{"type":"string"},"profile_id":{"type":"string"},"profile":{"type":"object","description":"Inline profile: {cpv[], regions[], keywords[], value_min, value_max}"}},"required":["tender_id"]}}}},"responses":{"200":{"description":"Score 0–100, verdict pursue/review/pass, criteria with evidence, unknowns"}}}},"/api/v1/profiles":{"get":{"summary":"List company profiles for this key","parameters":[{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"}],"responses":{"200":{"description":"Profiles"}}},"post":{"summary":"Store a company profile","parameters":[{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"}],"responses":{"201":{"description":"Created"}}}},"/api/v1/profiles/{id}":{"delete":{"summary":"Delete a profile","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"}],"responses":{"200":{"description":"Deleted"}}}},"/api/v1/analytics/awards":{"get":{"summary":"Award analytics: totals, top suppliers/buyers, monthly trend, sector split","parameters":[{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"},{"in":"query","name":"buyer","schema":{"type":"string"}},{"in":"query","name":"supplier","schema":{"type":"string"}},{"in":"query","name":"cpv","schema":{"type":"string"},"description":"CPV prefixes, comma-separated"},{"in":"query","name":"region","schema":{"type":"string"}},{"in":"query","name":"country","schema":{"type":"string"}},{"in":"query","name":"awarded_from","schema":{"type":"string","format":"date"}},{"in":"query","name":"awarded_to","schema":{"type":"string","format":"date"}},{"in":"query","name":"format","schema":{"type":"string","enum":["json","csv"],"default":"json"},"description":"csv streams the result as a file. One board per file, chosen by `table`. by_supplier: supplier, company_key, awards, shared_awards, value_gbp, value_eur, value_<ccy>… by_buyer: buyer, awards, value_*. by_month: month, awards, value_*. by_cpv_division: cpv_division, awards, value_*. Value columns are per currency and never summed; X-TenderGraph-Truncated: true means the board is a top-N. RFC 4180, UTF-8 with BOM, CRLF line endings, ISO 8601 UTC dates, money as plain numbers beside a currency column (never summed across currencies), lists joined with '; ', text cells starting with = + - @ prefixed with an apostrophe (formula-injection defence). Response headers: Content-Disposition names the file (tendergraph-<what>-<YYYY-MM-DD>.csv), X-TenderGraph-Methodology states how the numbers were made, X-TenderGraph-Truncated: true means the file is a prefix of the result."},{"in":"query","name":"table","schema":{"type":"string","enum":["by_supplier","by_buyer","by_month","by_cpv_division"],"default":"by_supplier"},"description":"CSV only: which board the file holds."}],"responses":{"200":{"description":"Aggregates (application/json), or with format=csv one board as text/csv","content":{"application/json":{},"text/csv":{}}},"400":{"description":"Unscoped query, or an unknown table"}}}},"/api/v1/companies":{"get":{"summary":"Search suppliers across the all-time award history","description":"Published spellings of one company are grouped under a normalised key; separate legal entities stay separate. Sterling and euro totals are reported side by side and never summed.","parameters":[{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"},{"in":"query","name":"q","required":true,"schema":{"type":"string","minLength":2},"description":"Company name; legal suffix optional"},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"Companies with award counts, attributed value per currency, buyer counts and active period"},"400":{"description":"q shorter than two characters"}}}},"/api/v1/companies/{key}":{"get":{"summary":"One supplier's full award history","description":"Attributed value, top buyers, sector split, year-on-year and recent awards. Value is attributed only where the publisher stated it; awards naming several suppliers with no published split are counted, never valued.","parameters":[{"in":"path","name":"key","required":true,"schema":{"type":"string"},"description":"Company key from /api/v1/companies"},{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"},{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"description":"Walks award_history (JSON only)"},{"in":"query","name":"format","schema":{"type":"string","enum":["json","csv"],"default":"json"},"description":"csv streams the result as a file. The award lines — every page of award_history in one file, newest first. Columns: tender_id, title, buyer, value, currency, awarded_at, shared (true = named alongside others with no published split: counted, never valued), source_url, url (TenderGraph page). RFC 4180, UTF-8 with BOM, CRLF line endings, ISO 8601 UTC dates, money as plain numbers beside a currency column (never summed across currencies), lists joined with '; ', text cells starting with = + - @ prefixed with an apostrophe (formula-injection defence). Response headers: Content-Disposition names the file (tendergraph-<what>-<YYYY-MM-DD>.csv), X-TenderGraph-Methodology states how the numbers were made, X-TenderGraph-Truncated: true means the file is a prefix of the result."},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":10000,"default":10000},"description":"CSV only: rows in the file, at most 10,000 (the pager's own reach). A larger value is clamped and the response carries X-TenderGraph-Truncated: true; page/per_page are ignored for CSV."}],"responses":{"200":{"description":"Company profile (application/json), or with format=csv the award lines as text/csv","content":{"application/json":{},"text/csv":{}}},"404":{"description":"Not found"}}}},"/api/v1/buyers":{"get":{"summary":"Search public-sector buyers across the notices","description":"Every word of the query of three or more letters must appear in the published buyer name; spellings are grouped by case, punctuation and spacing only. Counts are notices naming the buyer within a capped read (`capped: true` means narrow the query).","parameters":[{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"},{"in":"query","name":"q","required":true,"schema":{"type":"string","minLength":2},"description":"Buyer name, or one distinctive word of it"},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"Buyers with their key, most common published spelling, notice count and profile URL"},"400":{"description":"q shorter than two characters, or with no word of three letters"}}}},"/api/v1/buyers/{key}":{"get":{"summary":"One buyer's profile: suppliers, spend, open notices, contracts ending","description":"Awards naming a supplier, attributed value per currency, top suppliers (with company keys), what they buy by CPV division, year-on-year, the notices open now and the awards whose notice published a contract end date in the next eighteen months. Value is attributed only where the publisher stated it; shared awards are counted, never valued.","parameters":[{"in":"path","name":"key","required":true,"schema":{"type":"string"},"description":"Buyer key from /api/v1/buyers, or the buyer's name as published"},{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"}],"responses":{"200":{"description":"Buyer profile with a methodology string"},"404":{"description":"No notice names the buyer"}}}},"/api/v1/monitors":{"get":{"summary":"List monitors saved under this key","parameters":[{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"}],"responses":{"200":{"description":"Monitor list"}}},"post":{"summary":"Save a search profile as a monitor (optionally webhook-delivered)","parameters":[{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"query":{"type":"object","description":"Same filters as /api/v1/tenders"},"webhook_url":{"type":"string","description":"https endpoint; new matches POST here HMAC-signed (X-TenderGraph-Signature); the response shows webhook_secret exactly once"}},"required":["name"]}}}},"responses":{"201":{"description":"Created"},"409":{"description":"Per-key monitor limit reached"}}}},"/api/v1/monitors/{id}":{"get":{"summary":"Read one monitor","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"}],"responses":{"200":{"description":"Monitor"},"404":{"description":"Not found"}}},"delete":{"summary":"Delete a monitor","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"}],"responses":{"200":{"description":"Deleted"},"404":{"description":"Not found"}}}},"/api/v1/monitors/{id}/check":{"get":{"summary":"Preview new tenders since the last check (does not advance the watermark)","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"},{"in":"query","name":"per_page","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Batch size"},{"in":"query","name":"format","schema":{"type":"string","enum":["json","csv"],"default":"json"},"description":"csv streams the result as a file. This check's batch as a file; X-TenderGraph-Truncated: true means has_more (keep draining). Columns: id, title, buyer, country, region_codes, cpv_codes, status, notice_type, published_at, deadline_at, awarded_at, value_min, value_max, currency, source, source_url, url (TenderGraph page), framework, suppliers. RFC 4180, UTF-8 with BOM, CRLF line endings, ISO 8601 UTC dates, money as plain numbers beside a currency column (never summed across currencies), lists joined with '; ', text cells starting with = + - @ prefixed with an apostrophe (formula-injection defence). Response headers: Content-Disposition names the file (tendergraph-<what>-<YYYY-MM-DD>.csv), X-TenderGraph-Methodology states how the numbers were made, X-TenderGraph-Truncated: true means the file is a prefix of the result."}],"responses":{"200":{"description":"New tenders since the watermark (application/json, or text/csv with format=csv)","content":{"application/json":{},"text/csv":{}}}}},"post":{"summary":"Consume new tenders since the last check (advances the watermark)","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"api_key","schema":{"type":"string"},"description":"API key (alternatively Authorization: Bearer or X-Api-Key header)"},{"in":"query","name":"per_page","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Batch size"},{"in":"query","name":"format","schema":{"type":"string","enum":["json","csv"],"default":"json"},"description":"csv streams the result as a file. This check's batch as a file; the watermark advances exactly as for JSON. Columns: id, title, buyer, country, region_codes, cpv_codes, status, notice_type, published_at, deadline_at, awarded_at, value_min, value_max, currency, source, source_url, url (TenderGraph page), framework, suppliers. RFC 4180, UTF-8 with BOM, CRLF line endings, ISO 8601 UTC dates, money as plain numbers beside a currency column (never summed across currencies), lists joined with '; ', text cells starting with = + - @ prefixed with an apostrophe (formula-injection defence). Response headers: Content-Disposition names the file (tendergraph-<what>-<YYYY-MM-DD>.csv), X-TenderGraph-Methodology states how the numbers were made, X-TenderGraph-Truncated: true means the file is a prefix of the result."}],"responses":{"200":{"description":"New tenders; watermark advanced (application/json, or text/csv with format=csv)","content":{"application/json":{},"text/csv":{}}}}}},"/api/v1/sources":{"get":{"summary":"Coverage registry with each source's last sync (public)","responses":{"200":{"description":"Registry"}}}},"/api/v1/stats":{"get":{"summary":"Store statistics (public)","responses":{"200":{"description":"Totals"}}}}}}