UK Public Procurement API
Planned This API is not available yet: no data is published, and requests answer 503 until it launches. The reference is published early so you can review the contract.
Download OpenAPI (uk-procurement.yaml) · Base URL https://api.olympus.new-odyssey.com
The notices the two official UK public procurement services publish, in one schema: Find a Tender (above-threshold notices, and every notice under the Procurement Act 2023 since 24 February 2025) and Contracts Finder (mostly award notices of procurements under the earlier regulations). Search notices and awards by buyer, supplier, CPV code, value, date and status; read an award with its suppliers and the notices of its procurement; summarise a supplier by Companies House number and a buyer by the identifier its notices publish. Served by the Olympus Go gateway.
Sources. Read only through the services' documented OCDS APIs (Find a Tender GET /api/1.0/ocdsReleasePackages, Contracts Finder GET /Published/Notices/OCDS/Search), by day windows of each service's last-updated (Find a Tender) or published (Contracts Finder) date. No web page is read. Every API page is kept under its SHA-256. Both services publish under the Open Government Licence v3.0.
As published. Values, dates and names are as the notices publish them: no currency conversion (value.currency), no deduplication of a procurement that appears on both services, no categorisation beyond the CPV codes and notice types published. Every response repeats this in meta.notices (as_published).
Awards are compiled per procurement (ocid) and award id from every loaded notice that carries them: the latest notice's value of each field, earlier notices filling gaps (notice_ids). An award's value is the value of the whole award, not one supplier's share; where a notice gives no award value the sum of its contract values is used (value.source).
Suppliers are listed as published. A supplier is summarised only by the Companies House number a notice publishes for it (GET /suppliers/{company_number}); supplier totals add only awards where the company is the sole supplier, in pounds (shared_awards notice). Name filters match a prefix of a normalised name and are not an identity (grouped_by_name). Contact points are never stored.
Buyers are identified by the identifier their notices publish (buyer_id: a PPON, a company number, a Contracts Finder or Find a Tender organisation id, an SRS id, a GB-LAE register code, ...); one organisation can appear under several. No published identifier links these buyers to ONS council codes, so they are not linked to the UK Council Spending API (not_linked_to_council).
Coverage. GET /v1/uk-procurement/coverage lists the days loaded from each service, the days missing between them and the days fetched before they had ended.
Pagination. GET /notices and GET /awards return the newest first with a cursor (meta.pagination.next_cursor; pass it back unchanged with the same filters). A cursor is tied to the publication it was issued under: after the data is republished, start again.
Identifiers. Supplier and buyer summaries carry entity_id, identifiers and related from the shared identifier registry (GET /v1/entities/{entity_id}, GET /v1/resolve): companies by the Companies House number (GB-COH) notices publish, with the PPON (OLY-GB-PPON) the same party publishes. People are never registered.
Provenance. Every notice, award, supplier and buyer row carries a provenance block: the notice's own API URL (source_url), the day window it was fetched in (source_version), when this version was published and the validation status of the publication. Responses list the active publication in meta.datasets.
Authenticate with an API key in X-API-Key or Authorization: Bearer. The organization's plan must include uk-procurement; requests count against its monthly quota. Every response carries X-Request-Id. Errors share the Error body.
Notices
Search notices
/v1/uk-procurement/noticesPublished notices (planning, tender, award and contract notices), newest publication date first, filtered by any combination of buyer, CPV code, value, date, status, stage, notice type, source and legal regime. Without filters every loaded notice is searched.
Authentication: API key (X-API-Key or Bearer)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| buyer | query | string | A Example: GB-PPON-PBZB-4962-TVLR |
| buyer_name | query | string | Buyer name prefix, normalised (at least 3 letters or digits). Example: Essex County |
| cpv | query | string | CPV code (8 digits, a check digit like Example: 72 |
| value_min | query | string | Minimum value (inclusive) in the value's own currency. Example: 100000 |
| value_max | query | string | Maximum value (inclusive) in the value's own currency. |
| published_from | query | string (date) | First publication date ( Example: 2026-04-01 |
| published_to | query | string (date) | Last publication date ( |
| status | query | string | Tender status as published ( Example: active |
| stage | query | enum: planning | tender | award | contract | implementation | Stage of the procurement the notice belongs to, from its OCDS tags. |
| notice_type | query | string | Find a Tender notice form as published (e.g. Example: UK4 |
| source | query | enum: fts | cf |
|
| regime | query | string | Legal regime from the published legal basis ( Example: procurement_act_2023 |
| limit | query | integer | Page size. |
| cursor | query | string |
|
Responses
| 200 | One page of notices. | NoticesResponse |
| 400 | Invalid parameter ( | Error |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
| 503 | The procurement dataset has no active publication yet ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/uk-procurement/notices" \
-H "X-API-Key: $OLYMPUS_API_KEY"Awards
Search awards
/v1/uk-procurement/awardsAwards compiled per procurement, newest award date first (award_sort_date: the award date, else the contract signature date, else the notice date), filtered by buyer, supplier, CPV code, value, date, status, source and legal regime. Each award lists its suppliers.
Authentication: API key (X-API-Key or Bearer)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| buyer | query | string | A Example: GB-PPON-PBZB-4962-TVLR |
| buyer_name | query | string | Buyer name prefix, normalised (at least 3 letters or digits). Example: Essex County |
| supplier_name | query | string | Prefix of any supplier's name, normalised (at least 3 letters or digits). Example: Capita |
| supplier_company_number | query | string | Companies House number a notice publishes for any supplier of the award (8 digits, or 2 letters and 6 digits; shorter numbers are zero padded). Example: 02165592 |
| cpv | query | string | CPV code (8 digits, a check digit like Example: 72 |
| value_min | query | string | Minimum value (inclusive) in the value's own currency. Example: 100000 |
| value_max | query | string | Maximum value (inclusive) in the value's own currency. |
| date_from | query | string (date) | First award date ( Example: 2026-01-01 |
| date_to | query | string (date) | Last award date ( |
| status | query | string | Award status as published ( Example: active |
| source | query | enum: fts | cf |
|
| regime | query | string | Legal regime from the published legal basis ( Example: procurement_act_2023 |
| limit | query | integer | Page size. |
| cursor | query | string |
|
Responses
| 200 | One page of awards. | AwardsResponse |
| 400 | Invalid parameter ( | Error |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
| 503 | The procurement dataset has no active publication yet ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/uk-procurement/awards" \
-H "X-API-Key: $OLYMPUS_API_KEY"Get an award
/v1/uk-procurement/awards/{award_id}One award, its supplier rows (each with its provenance) and the loaded notices of the same procurement, newest first (at most 50).
Authentication: API key (X-API-Key or Bearer)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| award_idrequired | path | string |
Example: fts:ocds-h6vhtk-0510f8:6 |
Responses
| 200 | The award. | AwardResponse |
| 400 | Invalid parameter ( | Error |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 404 | No loaded award, supplier or buyer with this id ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
| 503 | The procurement dataset has no active publication yet ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/uk-procurement/awards/fts:ocds-h6vhtk-0510f8:6" \
-H "X-API-Key: $OLYMPUS_API_KEY"Suppliers
Summarise a supplier by Companies House number
/v1/uk-procurement/suppliers/{company_number}Every loaded award whose notice publishes this Companies House number for a supplier: the names it was published under, its PPONs, totals, awards by buyer and by year, and the ten latest awards. Totals add only awards where the company is the sole supplier, in pounds (shared_awards notice).
Authentication: API key (X-API-Key or Bearer)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| company_numberrequired | path | string | Companies House number (8 digits, or 2 letters and 6 digits; shorter numbers are zero padded). Example: 02165592 |
| date_from | query | string (date) | First award date ( Example: 2026-01-01 |
| date_to | query | string (date) | Last award date ( |
Responses
| 200 | The supplier summary. | SupplierResponse |
| 400 | Invalid parameter ( | Error |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 404 | No loaded award, supplier or buyer with this id ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
| 503 | The procurement dataset has no active publication yet ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/uk-procurement/suppliers/02165592" \
-H "X-API-Key: $OLYMPUS_API_KEY"Buyers
Summarise a buyer
/v1/uk-procurement/buyers/{buyer_id}A buyer as its latest notice publishes it, with its notices by year and type, its awards by year, its top suppliers and CPV codes.
Authentication: API key (X-API-Key or Bearer)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| buyer_idrequired | path | string |
Example: GB-PPON-PBZB-4962-TVLR |
Responses
| 200 | The buyer summary. | BuyerResponse |
| 400 | Invalid parameter ( | Error |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 404 | No loaded award, supplier or buyer with this id ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
| 503 | The procurement dataset has no active publication yet ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/uk-procurement/buyers/GB-PPON-PBZB-4962-TVLR" \
-H "X-API-Key: $OLYMPUS_API_KEY"Coverage
What is loaded
/v1/uk-procurement/coverageFor each service: whether it is published, the day windows loaded (first, last, count), the days missing between them, the days fetched before they had ended, and counts of releases, notices, awards and supplier rows. Answers 200 before anything is published (every source not_loaded).
Authentication: API key (X-API-Key or Bearer)
Responses
| 200 | Coverage. | CoverageResponse |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/uk-procurement/coverage" \
-H "X-API-Key: $OLYMPUS_API_KEY"Schemas
Error object
The error body shared by every Olympus service.
| Field | Type | Description |
|---|---|---|
| error * | string | Human-readable message. |
| code * | string | Stable machine-readable code. |
| product | string | Product that produced the error, when applicable. |
| details | object |
Money string
An amount as a decimal string with two places.
Date string (date)
DateRange object
Period object
| Field | Type | Description |
|---|---|---|
| start * | string (date) | null | |
| end * | string (date) | null |
Provenance object
Where this record came from and which publication introduced this version of it.
| Field | Type | Description |
|---|---|---|
| dataset_id * | enum: uk_procurement.notices | |
| source_id * | enum: cabinet_office.find_a_tender_ocds | cabinet_office.contracts_finder_ocds | |
| source_url * | string (uri) | The notice's own OCDS API URL (for an award or supplier, the latest notice it was compiled from). |
| source_version * | string | The day window and fetch the notice came from. |
| source_date * | string (date) | null | The day window's date. |
| published_at * | string (date-time) | When this version of the record was first published. Unchanged records keep their original time. |
| schema_version * | string | |
| validation_status * | enum: passed | passed_with_warnings | |
| record_id * | string | Stable record key, e.g. |
DatasetPublication object
| Field | Type | Description |
|---|---|---|
| dataset_id * | string | |
| publication_id * | integer (int64) | |
| published_at * | string (date-time) | |
| freshness * | enum: fresh | stale |
|
Notice object
A caveat about the response (not a procurement notice).
| Field | Type | Description |
|---|---|---|
| code * | enum: as_published | grouped_by_name | not_published | shared_awards | not_linked_to_council | |
| message * | string |
Pagination object
| Field | Type | Description |
|---|---|---|
| limit * | integer | |
| has_more * | boolean | |
| next_cursor * | string | null |
Meta object
| Field | Type | Description |
|---|---|---|
| request_id | string | |
| datasets * | DatasetPublication [] | Active publication of the dataset this response read (empty before the first publication). |
| notices * | Notice [] | Caveats about this response. Always includes |
| pagination | Pagination |
Value object
A value as published, in its own currency (no conversion).
AwardValue object
PartyIdentifier object
An identifier a party publishes, as published.
| Field | Type | Description |
|---|---|---|
| scheme * | string | |
| id * | string |
OrganisationType object
| Field | Type | Description |
|---|---|---|
| scheme * | string | null | |
| id * | string | null | |
| description * | string | null |
BuyerRef object
| Field | Type | Description |
|---|---|---|
| buyer_id * | string | null | |
| name * | string | null | |
| company_number * | string | null | Companies House number when the notice publishes one. |
| buyer_path * | string | null |
ProcurementNotice object
One published notice (OCDS release).
| Field | Type | Description |
|---|---|---|
| notice_id * | string | Find a Tender notice id ( |
| source * | enum: fts | cf | |
| release_id * | string | OCDS release id as published. |
| ocid * | string | OCDS id of the procurement. |
| published_date * | Date | |
| release_date * | string (date-time) | |
| stage * | enum: planning | tender | award | contract | implementation | |
| tags * | array of string | |
| notice_type * | string | null | |
| notice_type_description * | string | null | |
| notice_url * | string (uri) | The notice on the service's website. |
| title * | string | null | |
| description * | string | null | |
| buyer * | BuyerRef | |
| cpv_code * | string | null | Main CPV code (8 digits). |
| cpv_codes * | array of string | Every CPV code of the tender, its items and lots. |
| main_category * | string | null | |
| procurement_method * | string | null | |
| procurement_method_details * | string | null | |
| legal_basis * | string | null | |
| regime * | string | null | |
| status * | string | null | Tender status as published. |
| value * | Value | |
| tender_deadline * | string (date-time) | null | |
| contract_period * | Period | |
| lots * | integer | |
| awards * | integer | |
| suitable_for_sme * | boolean | null | |
| suitable_for_vcse * | boolean | null | |
| provenance * | Provenance |
NoticesResponse object
| Field | Type | Description |
|---|---|---|
| data * | ProcurementNotice [] | |
| meta * | Meta |
AwardSupplierRef object
A supplier as the award lists it.
| Field | Type | Description |
|---|---|---|
| supplier_id * | string | null | The party id the notice publishes. |
| name * | string | null | As published. |
| normalised_name * | string | null | |
| company_number * | string | null | Companies House number |
| ppon * | string | null | Public Procurement Organisation Number, when published (e.g. |
| identifiers * | PartyIdentifier [] | |
| scale * | string | null | |
| vcse * | boolean | null | |
| supplier_path * | string | null |
Award object
One award, compiled from every loaded notice that carries it.
| Field | Type | Description |
|---|---|---|
| award_id * | string |
|
| source * | enum: fts | cf | |
| ocid * | string | |
| published_award_id * | string | The award's id within the procurement |
| notice_id * | string | The latest notice that carries the award. |
| notice_url * | string (uri) | |
| notice_ids * | array of string | Every loaded notice the award was compiled from. |
| title * | string | null | |
| description * | string | null | |
| status * | string | null | |
| award_date * | string (date) | null | |
| date_signed * | string (date) | null | |
| award_sort_date * | Date | |
| value * | AwardValue | |
| contract_period * | Period | |
| buyer * | BuyerRef | |
| cpv_code * | string | null | |
| cpv_codes * | array of string | |
| main_category * | string | null | |
| procurement_method * | string | null | |
| regime * | string | null | |
| supplier_count * | integer | |
| suppliers * | AwardSupplierRef [] | |
| provenance * | Provenance |
AwardsResponse object
AwardSupplier object
A supplier row of an award, with its provenance.
| Field | Type | Description |
|---|---|---|
| supplier_id * | string | null | |
| name * | string | null | |
| normalised_name * | string | null | |
| company_number * | string | null | |
| ppon * | string | null | |
| identifiers * | PartyIdentifier [] | |
| scale * | string | null | |
| vcse * | boolean | null | |
| shared * | boolean | The award lists more than one supplier. |
| supplier_path * | string | null | |
| provenance * | Provenance |
AwardDetail object
| Field | Type | Description |
|---|---|---|
| award * | Award | |
| suppliers * | AwardSupplier [] | |
| notices * | ProcurementNotice [] | Loaded notices of the same procurement, newest first (at most 50). |
AwardResponse object
| Field | Type | Description |
|---|---|---|
| data * | AwardDetail | |
| meta * | Meta |
NameCount object
| Field | Type | Description |
|---|---|---|
| name * | string | |
| awards * | integer |
SupplierTotals object
| Field | Type | Description |
|---|---|---|
| awards * | integer | |
| sole_awards * | integer | Awards where the company is the only supplier. |
| shared_awards * | integer | Awards listing other suppliers too (frameworks |
| value_gbp_sole_awards * | Money | |
| non_gbp_sole_awards * | integer | Sole awards valued in another currency (not added). |
| sole_awards_without_value * | integer |
SupplierBuyerTotal object
SupplierYearTotal object
| Field | Type | Description |
|---|---|---|
| year * | integer | |
| awards * | integer | |
| sole_awards * | integer | |
| value_gbp_sole_awards * | Money |
SupplierDetail object
| Field | Type | Description |
|---|---|---|
| company_number * | string | |
| names_as_published * | NameCount [] | |
| ppons * | array of string | |
| award_dates * | DateRange | null | First and last award date in the dates asked; null when there are none. |
| totals * | SupplierTotals | |
| by_buyer * | SupplierBuyerTotal [] | Top 50 buyers by sole-award value. |
| by_year * | SupplierYearTotal [] | |
| recent_awards * | Award [] | |
| entity_id * | string | null | |
| identifiers * | Identifier [] | |
| related * | RelatedLink [] |
SupplierResponse object
| Field | Type | Description |
|---|---|---|
| data * | SupplierDetail | |
| meta * | Meta |
Buyer object
| Field | Type | Description |
|---|---|---|
| buyer_id * | string | |
| name * | string | As the latest notice publishes it. |
| normalised_name * | string | |
| identifiers * | PartyIdentifier [] | |
| organisation_types * | OrganisationType [] | |
| company_number * | string | null | |
| ppon * | string | null | |
| locality * | string | null | |
| region * | string | null | |
| country * | string | null | |
| url * | string | null | |
| last_notice_id * | string | |
| last_notice_date * | string (date-time) | |
| provenance * | Provenance |
YearCount object
| Field | Type | Description |
|---|---|---|
| year * | integer | |
| notices * | integer |
NoticeTypeCount object
| Field | Type | Description |
|---|---|---|
| stage * | string | |
| notice_type * | string | null | |
| notices * | integer |
BuyerNotices object
| Field | Type | Description |
|---|---|---|
| total * | integer | |
| by_year * | YearCount [] | |
| by_type * | NoticeTypeCount [] |
BuyerAwardTotals object
| Field | Type | Description |
|---|---|---|
| total * | integer | |
| with_gbp_value * | integer | |
| value_gbp_total * | Money |
AwardYearTotal object
| Field | Type | Description |
|---|---|---|
| year * | integer | |
| awards * | integer | |
| value_gbp_total * | Money |
BuyerSupplierTotal object
| Field | Type | Description |
|---|---|---|
| supplier_key * | string | The company number when published |
| company_number * | string | null | |
| name * | string | null | |
| awards * | integer | |
| sole_awards * | integer | |
| value_gbp_sole_awards * | Money | |
| supplier_path * | string | null |
CPVCount object
| Field | Type | Description |
|---|---|---|
| cpv_code * | string | |
| awards * | integer |
BuyerDetail object
| Field | Type | Description |
|---|---|---|
| buyer * | Buyer | |
| notices * | BuyerNotices | |
| awards * | BuyerAwardTotals | |
| awards_by_year * | AwardYearTotal [] | |
| top_suppliers * | BuyerSupplierTotal [] | |
| top_cpv * | CPVCount [] | |
| entity_id * | string | null | |
| identifiers * | Identifier [] | |
| related * | RelatedLink [] |
BuyerResponse object
| Field | Type | Description |
|---|---|---|
| data * | BuyerDetail | |
| meta * | Meta |
SourceCoverage object
| Field | Type | Description |
|---|---|---|
| source * | enum: fts | cf | |
| source_id * | string | |
| name * | string | |
| licence * | string | null | |
| status * | enum: published | not_loaded | |
| date_filter * | string | null |
|
| windows_from * | string (date) | null | |
| windows_to * | string (date) | null | |
| days_loaded * | integer | |
| days_incomplete * | array of string (date) | Days fetched before they had ended (fetched again on the next run). |
| days_missing * | array of string (date) | Days between windows_from and windows_to with no window loaded. |
| releases * | integer | |
| notices * | integer | |
| awards * | integer | |
| award_suppliers * | integer | |
| award_suppliers_with_company_number * | integer | |
| last_fetched_at * | string (date-time) | null |
CoverageData object
| Field | Type | Description |
|---|---|---|
| data_vintage * | object | null | |
| sources * | SourceCoverage [] |
CoverageResponse object
| Field | Type | Description |
|---|---|---|
| data * | CoverageData | |
| meta * | Meta |
Identifier object
One identifier of an entity, with how and where it was linked.
| Field | Type | Description |
|---|---|---|
| scheme * | string | Scheme code (org-id.guide prefix, or an Olympus OLY- scheme). |
| value * | string | Normalised value. |
| method * | enum: published | exact | derived |
|
| confidence * | number | 1 for published and exact links. |
| source * | IdentifierSource |
IdentifierSource object
Provenance of the link.
| Field | Type | Description |
|---|---|---|
| dataset_id * | string | Registry dataset that published the link. |
| source_id * | string | |
| source_url * | string | |
| source_version * | string | |
| source_date * | string (date) | null | |
| published_at * | string (date-time) |
RelatedLink object
The record a product serves for the same entity.
| Field | Type | Description |
|---|---|---|
| product * | string | Public product ID. |
| resource * | string | |
| path * | string | Public path of the record. |
| via * | RelatedVia |
RelatedVia object
The identifier the link goes through.
| Field | Type | Description |
|---|---|---|
| scheme * | string | |
| value * | string |
* required field