API Docs v 3.0

Access bulk data

API Documentation

Simplified JSON outputs for procurement documents

Spend Network’s summary endpoint provides a simplified JSON output that provides a flatter, smaller, more consistent output. This enables lower volumes of data to travel into databases and more consistent and easier parsing of the data.

JSON Output Structure and Information Design Principles

The JSON output for the API has been meticulously structured to ensure clarity, consistency, and ease of use. The following key principles have been adopted in its design:

1. A single document structure for all records

  • Consistency: All records, whether tender notice, planning or contract awards contain the same fields and all fields deploy consistent data structures at all times. This ensures that simple validation routines can be written for each document (e.g. a checksum for the total number of fields).

  • Use: Tender documents will contain fields for awards data, which will not be populated, it is critical for developers to use release_tags to determine the nature of the published document before accessing the appropriate data.

2. Clear and Descriptive Naming Conventions

  • Consistency: Each key follows a consistent naming pattern that aids in easy identification and understanding. For example, all monetary values related to awards are prefixed with award_, making it straightforward to locate and differentiate from other values like tender_.

  • Descriptiveness: Keys are named descriptively to convey the precise information they hold. For instance, buyer_address_country_name clearly indicates it stores the country name of the buyer's address.

3. Logical Grouping of Related Information

  • Categorisation: Related data points are grouped together logically. For example, all keys related to buyer information start with buyer_ (e.g., buyer_name, buyer_address_country_name), ensuring that similar information can be found in proximity.

  • Hierarchical Structure: Our data is broadly flat, but the small amount of hierarchy helps users navigate the data efficiently, recognizing patterns and relationships between different pieces of information.

4. Effective handling of one to many relationships

  • Managing edge cases: In rare cases contract award notices are published as an extension to a tender notice, in still rarer circumstances there are more than one award published against a given tender. We handle this dynamically, collating data where appropriate (e.g in the award_titles ) and using the first award found in fields where referential integrity is essential. This is the case in fields with the _first suffix.

  • Implications: In some cases it is possible that only the first award from a set of multiple awards is being documented. In this context developers can use our complete API to gather additional records from the original published releases where necessary.

5. Comprehensive Data Coverage

  • Detailed Information: The JSON structure includes extensive details covering various aspects such as buyer details, award values in multiple currencies, tender specifics, and more. This comprehensive coverage ensures users have all necessary data in one place.

  • Multiple Data Types: The structure accommodates various data types including strings, numbers, arrays, and booleans, to accurately represent different kinds of information.

6. Timestamp and Date Management

  • ISO 8601 Format: All date and time values are provided in ISO 8601 format (e.g., 2021-12-17T08:27:49Z), a widely accepted standard that supports interoperability and ease of parsing across different systems.

  • Clear Distinction Between Dates: Different types of dates such as release_date, start_date, and closing_date are clearly differentiated, ensuring precise tracking of timelines.

7. Nullability for Optional Fields

  • Explicit Nulls: Fields that might not always have a value (e.g., contact_url, buyer_address_street_address) are included with a null value when applicable, maintaining a consistent structure while signalling optional data.

8. Array Utilization for Multiple Entries

  • Lists for Multiple Items: Fields that can have multiple entries, such as supplier_names, cpv_names, and supplier_ids, are represented as arrays. This approach ensures flexibility and scalability in handling multiple values.

9. Identification and Referencing

  • Unique Identifiers: Keys like ocid and tender_id are used to provide unique identifiers for contracts and tenders, supporting traceability and integration with other datasets. Where we are able to we will supply identifiers for suppliers with a unique id for companies to reconcile to the source.

  • References: Fields such as references_ocids allow for linking related documents or entities, facilitating comprehensive data analysis.

10. Currency and Value Clarity

  • Explicit Currency Indicators: Monetary values are accompanied by currency indicators (e.g., award_currency_first, tender_currency), ensuring that users can accurately interpret financial data.

  • Multiple Currency Representations: Values are provided in different currencies (USD, GBP, EUR) to cater to a diverse range of users and use cases.

11. Status and Metadata Information

  • Status Indicators: Fields like tag_status and dps_pred offer status information, helping users understand the current state and categorization of the data.

  • Metadata for Traceability: Metadata fields such as date_created and date_updated provide insights into the data's lifecycle, aiding in version control and auditing.

This structured approach ensures that the JSON output is both user-friendly and comprehensive, facilitating efficient data retrieval and analysis for diverse applications.

Example document

This example document shows how our summary api data is structured and published.

{
        "_index": "sn-api-ocds-gold-v3-prod",
        "_id": "ocds-0c46vo-0001-12ef087c-3ad3-4d72-b2bb-e3d416081402",
        "_score": 1,
		"_source": {
		  "has_attachment":"true"
          "cpv_names": [
            "Education and training services",
            "Personnel services except placement and supply services",
            "Specialist training services",
            "Vocational training services",
            "Personal development training services",
            "Business and management consultancy services",
            "Personnel services except placement and supply services",
            "Specialist training services",
            "Vocational training services",
            "Personal development training services",
            "Business and management consultancy services",
            "Education and training services"
          ],
          "tender_url": "https://www.contractsfinder.service.gov.uk/Notice/12ef087c-3ad3-4d72-b2bb-e3d416081402",
          "closing_date": null,
          "awards_usd_value": 0,
          "date_updated": "2024-01-18T02:40:12.144016",
          "buyer_address_country_name": "United Kingdom",
          "tender_eur_value": 0,
          "cpv_aug_names": [
            "Personnel services except placement and supply services",
            "Specialist training services",
            "Vocational training services",
            "Personal development training services",
            "Business and management consultancy services"
          ],
          "cpv_aug_codes": [
            "79630000",
            "80510000",
            "80530000",
            "80570000",
            "79410000"
          ],
          "buyer_name": "DRIVER AND VEHICLE STANDARDS AGENCY",
          "tender_id": "tender_362771/1301350",
          "language": "en",
          "source": "cf_notices",
          "release_tags": "planning",
          "cpv_codes": [
            "80000000",
            "79630000",
            "80510000",
            "80530000",
            "80570000",
            "79410000",
            "79630000",
            "80510000",
            "80530000",
            "80570000",
            "79410000",
            "80000000"
          ],
                    "contracts_eur_value": 0,
          "buyer_address_street_address": "112 Upper Parliament Street",
          "buyer_address_locality": "Nottingham",
          "buyer_address_iso_alpha2": "GB",
          "contracts_gbp_value": 0,
          "contact": "epscategoryteam@dvsa.gov.uk",
          "awards_gbp_value": 0,
          "supplier_names": [],
          "processing_status": "success",
          "supplier_ids": [],
          "ocid": "ocds-0c46vo-0001-12ef087c-3ad3-4d72-b2bb-e3d416081402",
          "buyer_address_region": "England",
          "contracts_usd_value": 0,
          "start_date": null,
          "dps_pred": false,
          "contact_url": null,
          "date_created": "2024-01-16T02:35:38.235781",
          "awards_eur_value": 0,
          "tender_description": """Driver & Vehicle Standards Agency""",
          "award_descriptions": "",
          "tender_gbp_value": 0,
          "tender_usd_value": 0,
          "cpv_aug_data": [
            {
              "cpv_aug_names": "Personnel services except placement and supply services",
              "cpv_aug_codes": "79630000",
              "relevance_score": 16.9238
            },
            {
              "cpv_aug_names": "Specialist training services",
              "cpv_aug_codes": "80510000",
              "relevance_score": 15.2334
            },
            {
              "cpv_aug_names": "Vocational training services",
              "cpv_aug_codes": "80530000",
              "relevance_score": 9.0345
            },
            {
              "cpv_aug_names": "Personal development training services",
              "cpv_aug_codes": "80570000",
              "relevance_score": 8.3424
            },
            {
              "cpv_aug_names": "Business and management consultancy services",
              "cpv_aug_codes": "79410000",
              "relevance_score": 7.7439
            }
          ],
          "release_date": "2024-01-15T12:32:28Z",
          "references_ocids": [],
          "tag_status": "open",
          "tender_title": "Tailored Executive Development",
          "award_titles": ""
        }
      }

The following shows an example of a document where lotting features have been identified and collected.

{
     "ocid": "ocds-0c46vo-0001-036588-2025_036588-2025",
     "start_date": "2025-09-04T00:00:00+01:00",
     "date_created": "2025-07-03T01:37:44.838811",
     "tender_description": "Nest is on a path to becoming one of the largest pensions schemes in the UK and our growth trajectory means that the operating model for Nest Invest will need to evolve over the next ten years.\nIn order to support the continued strategic growth and development of the investment function Nest Invest will require ongoing specialist consultancy support for the development of the organisational model and development of the investment approach",
     "award_descriptions": "",
     "tender_gbp_value": 10000000,
     "lots": {
         "lot_descriptions": [
              "1: Strategic investment business, organisational strategy and governance advice with extensive proven experience of international investment best practice with large Financial Conduct Authority (FCA) regulated Occupational Pension Schemes (OPS) with assets under management of £25 billion and above",
              "2: Target Operating Model design and delivery including the transition and implementation of operating models for fund administration and custody service including additional SME operational support as needed to large Financial Conduct Authority (FCA) regulated Occupational Pension Schemes (OPS) (or similar) with assets under management of £25 billion and above. 35",
              "3: Specialist investment consultancy services to large Financial Conduct Authority (FCA) regulated occupational pension schemes (OPS) with assets under management of £25 billion and above"
         ],
         "lot_classifications": [],
         "lot_earliest_start_date": "2025-09-04T00:00:00+01:00",
         "lot_statuses": [
              "active"
         ],
         "lot_identifiers": [],
         "lot_ids": [
              "1",
              "2",
              "3"
         ],
         "lot_currencies": [
              "GBP"
         ],
         "lot_total_value": 10000000.0,
         "lot_count": 3,
         "lot_amounts": [
              3500000.0,
              3500000.0,
              3000000.0
         ],
         "lot_titles": [
              "1: LOT 1 Strategic investment business, organisational strategy and governance advice",
              "2: LOT 2 Target Operating Model design and delivery including the transition and implementation of operating models for fund administration and custody service including additional SME operational support as needed",
              "3: Specialist investment consultancy services to large Financial Conduct Authority (FCA) regulated occupational pension schemes (OPS"
         ],
         "lot_latest_end_date": "2029-09-03T23:59:59+01:00",
         "lot_primary_currency": "GBP",
         "lot_procurement_categories": []
},

Field list

Below we have grouped fields and listed each possible field then and provided a field type and description.

Currencies and conversion

Our currency output adheres to international currency standards by using ISO 4217 codes for currency representation. This ensures that monetary values are clearly identified and standardised across different datasets, facilitating accurate interpretation and conversion. By employing ISO currency codes such as GBP (British Pound), USD (US Dollar), and EUR (Euro), the data maintains consistency and interoperability in financial reporting and analysis.

We use https://exchangeratesapi.io/ for currency conversion, which provides several key benefits, including accurate and up-to-date exchange rates sourced from reliable financial data providers, enhancing the reliability of financial reporting, supporting a wide range of currencies, enabling comprehensive and global financial analysis. Integrating this API into our system ensures that all currency-related data is consistent, precise, and reflects the correct conversion rates at the time of publication.

Code

Field type

Description

award_currency_first

String

The original currency of an award notice as published in the source data, where the currency is adequately labelled and can be determined by Spend Network. This currency may be any known currency.

award_amount_sum

Value

The original value of an award as published in the source data, where the value is adequately structured and can be converted to a value field by Spend Network.

awards_usd_value

Value

The value of award_amount_sum converted from the award_currency_first to USD where the original source is not in USD. Conversion completed on the date of collection, we use https://exchangeratesapi.io/ as our source for currency conversion data.

awards_gbp_value

Value

The value of award_amount_sum converted from the award_currency_first to GBP where the original source is not in GBP. Conversion completed on the date of collection, we use https://exchangeratesapi.io/ as our source for currency conversion data.

awards_eur_value

Value

The value of award_amount_sum converted from the award_currency_first to EUR where the original source is not in EUR. Conversion completed on the date of collection, we use https://exchangeratesapi.io/ as our source for currency conversion data.

tender_currency

String

The original currency of a tender notice as published in the source data, where the currency is adequately labelled and can be determined by Spend Network. This currency may be any known currency. This value is only populated when the source is in OCDS format and the contract notice is appended to a tender notice in a manner compliant with the standard.

tender_amount

Value

The original value of a tender as published in the source data and where the value is adequately structured and can be converted to a value field by Spend Network. This value is only populated when the source is in OCDS format and the contract notice is appended to a tender notice in a manner compliant with the standard.

tender_usd_value

Value

The value of tender_amount converted from the tender_amount to USD where the original source is not in USD. Conversion completed on the date of collection, we use https://exchangeratesapi.io/ as our source for currency conversion data. This value is only populated when the source is in OCDS format and the contract notice is appended to a tender notice in a manner compliant with the standard.

tender_gbp_value

Value

The value of tender_amount converted from the tender_amount to GBP where the original source is not in GBP. Conversion completed on the date of collection, we use https://exchangeratesapi.io/ as our source for currency conversion data. This value is only populated when the source is in OCDS format and the contract notice is appended to a tender notice in a manner compliant with the standard.

tender_eur_value

Value

The value of tender_amount converted from the tender_amount to GBP where the original source is not in GBP. Conversion completed on the date of collection, we use https://exchangeratesapi.io/ as our source for currency conversion data. This value is only populated when the source is in OCDS format and the contract notice is appended to a tender notice in a manner compliant with the standard.

Entities and Organisations

During our input process we are cleansing fields to provide, reliable consistent values across both buyer names and addresses. In some cases we also match supplier identifiers. The cleansing of buyer names is primarily for the UK, with new links being developed all of the time across other countries. Addresses are cleansed through a proprietary address management algorithm, splitting up codes, identifying postcodes and allocating clean country names, before then deriving a country code.

Name

Field type

Description

buyer_name

String

This field contains the name of the buying entity or organisation. It identifies the buyer involved in the tender or contract, facilitating recognition and tracking of the entity.

buyer_address_country_name

String

The name of the country where the buyer's address is located. Where the source provides an identifiable country name we will amend this entry to provide a consistent reference, e.g. “UK” is converted to “United Kingdom”

buyer_address_locality

String

The locality or city where the buyer's address is situated. Where we can we seek to extract and separate address features into the correct patterns for greater geographical analysis.

buyer_address_region

String

The region where the buyer's address is situated. Where we can we seek to extract and separate address features into the correct patterns for greater geographical analysis.

supplier_names

String

This field lists the names of the suppliers involved in the contract or tender, the data is provided in a list format.

supplier_ids

List of strings

This field contains unique identifiers for the suppliers, such as registration or company numbers. The source indexes for each ID are added as prefixes e.g. GB_COH is a Companies House number from the United Kingdom. Items in this list correlate to the provided supplier name, null items are recorded so that the third id in the list will correspond to the third supplier name in the supplier_name list.

buyer_address_street_address

String

This field represents the street address of the buyer. Where we can we seek to extract and separate address features into the correct patterns for greater geographical analysis.

buyer_address_iso_alpha2

String

This field uses the ISO 3166-1 alpha-2 code to represent the buyer's country. It provides a standardized and internationally recognized format for country identification.

Dates and Times

The following dates and times are used in the contract award documents.

Field Name

Field type

Description

award_start_date_first

Date time

The contract start date. It indicates when the contract is scheduled to commence, _first denotes that this is the start date for the first published award.

award_end_date_first

Date time

The contract end date. It indicates when the contract is scheduled to be completed, _first denotes that this is the start date for the first published award.

release_date

Date time

The publisher’s own record for the date that the document was published.

date_updated

Date time

This field captures any updates to the document. It indicates the most recent modification date.

tender_end_date

Date time

This field specifies the deadline for submissions on tenders. It represents the final date for submitting tenders.

date_created

Date time

This field indicates the date gathered by Spend Network. It marks when the data was collected and recorded. If there is no release date or start date, this date is the best substitute.

Document identifiers

We use the following document identifiers in the output, these are identifiers for the documents, OCIDs can be used as reliable database keys and are unique. By using these identifiers, we ensure that each document can be accurately tracked, referenced, and integrated into various data systems, supporting robust data management and analysis practices.

Field Name

field type

Description

tender_id

String

This field represents the identifier provided by the publisher. It uniquely identifies the tender within the publisher's system.

ocid

String

This field is Spend Network's unique identifier, compliant with the Open Contracting Data Standard. It ensures consistent and standardised identification of contracts.

references_ocids

String

This field contains additional records that have been linked to the document as potential duplicates. Developers can use this list to suppress likely duplicates or, if required, show likely duplicates.

Status and Metadata

Status and metadata tags provides information on the origin of the data, categorization of document types, the status of contracts, and classification of contract types. Each entry ensures clarity and consistency, facilitating accurate data interpretation and analysis.

Field Name

Data Type

Description

source

String

This field contains the name of the source code used to harvest the data. It indicates the origin of the data collection process.

release_tags

String

This field specifies the document type, which can be 'tender', 'award', or 'planning'. It categorises the type of document being referred to. (List of options from GF)

tag_status

String

This field indicates whether a contract is "open" or "closed". It specifies the current status of the contract, e.g., whether it is finished or underway. (List of options from GF)

dps_pred

Boolean

This field denotes whether Spend Network has identified that this contract is a framework or dynamic purchasing system (DPS) contract. It helps in classifying the type of contract.

language

String

ISO 639 language classification, automatically derived from a Google large language model.

Descriptions and Titles

The following table provides a detailed description of the narrative fields within the JSON output related to tenders and awards.

→ award titles → comes in as a list, converted to a string (never an array)

→ Only for OCDS linked titles and awards

Field Name

Data Type

Description

tender_title

String

This field contains the title of the tender. It provides a brief and specific name for the tender, summarising its main purpose. This value is only populated when the source is in OCDS format and the contract notice is appended to a tender notice in a manner compliant with the standard.

content

String

This field combines both the tender title and description, enabling more efficient in-memory text searching.

tender_description

String

This field provides a detailed description of the tender. It includes the published information about the tender's requirements and objectives. This value is only populated when the source is in OCDS format and the contract notice is appended to a tender notice in a manner compliant with the standard.

award_descriptions

String

This field contains descriptions of the awards associated with the tender. It provides published information about the awards granted. In the event that multiple awards are added as separate releases to a single tender, the awards descriptions will be concatenated in this field

award_titles

String

This field includes the titles of the awards. It gives a concise and specific name for each award associated with the tender. In the event that multiple awards are added as separate releases to a single tender, the awards titles will be concatenated in this field.

Contact Information

The following table provides a detailed description of specific fields within the JSON output related to contact information. Each field is accompanied by its data type and a brief description, facilitating a better understanding of the contact details provided and aiding in efficient data interpretation and analysis.

Field Name

Data Type

Description

contact

String

This field contains the email address of the contact person or entity. It provides a direct communication channel for inquiries or further information.

contact_url

String

This field includes the URL for contact information. It offers an online link for additional contact details or communication methods.

Classification Codes

The following table provides a detailed description of specific fields within the JSON output related to procurement classification. Each field is accompanied by its data type and a brief description, facilitating a better understanding of the procurement categories and aiding in efficient data interpretation and analysis. CPV stands for Common Procurement Vocabulary, the EU procurement classification system, while "aug" stands for augmented, indicating additional codes added by Spend Network.

Field Name

Data Type

Description

cpv_names

Array

This field contains an array of names from the Common Procurement Vocabulary (CPV) that were provided by the original publisher.

cpv_aug_names

Array

This field includes an array of augmented CPV names added by Spend Network. It offers additional classification names that enhance the standard CPV categorisation.

cpv_aug_codes

Array

This field contains an array of augmented CPV codes added by Spend Network. It provides additional classification codes that complement the standard CPV codes.

cpv_codes

Array

This field includes an array of CPV codes from the Common Procurement Vocabulary. that were provided by the original publisher.

 

URLs

The following table provides a detailed description of a specific field within the JSON output related to the URL of the published tender.

Field Name

Data Type

Description

tender_url

String

This field contains the original source URL of the published tender. It provides a direct link to the tender's publication, enabling access to the full tender details and documentation.

Lots

The following table provides a detailed description of a specific field within the JSON output related to lots in a published document.

Field name

Data Type

Description

lots.lot_count

Integer

The number of lots into which the tender or award is divided. Used to identify whether the procurement is split and how many components it includes.

lots.lot_ids

Array of Strings

A list of identifiers for each individual lot. These identifiers are typically numeric strings (e.g., "1", "2").

lots.lot_titles

Array of Strings

Titles of each lot. These provide a concise description of the lot’s scope or purpose. Titles may include a prefix indicating lot number.

lots.lot_descriptions

Array of Strings

Descriptive narrative for each lot. These typically include eligibility criteria, scope, or technical requirements.

lots.lot_amounts

Array of Numbers

Monetary values for each lot, expressed in the primary currency. These represent the estimated or awarded value for each lot.

lots.lot_total_value

Number

The total value of all lots combined. Used for summarizing the overall contract value when split across multiple components.

lots.lot_primary_currency

String

The ISO 4217 currency code used for all monetary amounts within the lot object (e.g., GBP).

lots.lot_currencies

Array of Strings

List of currencies applicable to the lots. Useful in cross-border or multi-currency procurement.

lots.lot_earliest_start_date

DateTime

The earliest scheduled start date for any of the lots.

lots.lot_latest_end_date

DateTime

The latest scheduled end date for any of the lots.

lots.lot_statuses

Array of Strings

Statuses of individual lots (e.g., "active", "cancelled"). Multiple statuses may exist across lots in the same contract.

lots.lot_classifications

Array

A placeholder for CPV or other classification codes relevant to the lots. Currently not populated.

lots.lot_procurement_categories

Array

Reserved for categorisation of lots by procurement category (e.g., goods, services, works). Currently not populated.

Attachments

The following table provides a detailed description of a specific field within the JSON output related to the availability of attachments for a given document.

Field Name

Data Type

Description

has_attachments

Boolean

A field that shows whether a document has attachments associated with it.

attachments

Array

This field contains a list of urls for attachments that have been found for the given search. Each entry has a field for title and url. This field is only present when the user has added [attachment__sho](https://www.notion.so/Documentation-API-Summary-endpoint-Version-3-22ff85179211804b8739c6e2e1c49aae?pvs=21)w to their API request.

attachments.title

String

The title of an attachment gathered from a specific page. This field is only present when the user has added attachment__show to their API request.

attachments.url

URL

The original URL of the attachment. This field is only present when the user has added attachment__show to their API request.

API requests

Accessing the Spend Network API Endpoint

To access the Spend Network API endpoint for fetching records related to tenders, follow these steps:

API Endpoint URL

The endpoint URL is: https://api-test.spendnetwork.cloud/api/v3/notices/records_openopps

Query Parameters

Here are the query parameters you can use:

Name

Type

Description

search_term__is

string

Search term to include (maxLength: 100).

search_term__exclude

string

Search term to exclude (maxLength: 100).

buyer_name__is

string

Buyer name to include (maxLength: 100).

supplier_name__is

string

Supplier name to include (maxLength: 100).

buyer_address_country_name__is

string

Country name of the buyer to include (maxLength: 100).

buyer_address_country_code__is

array[string]

Country codes of the buyer to include.

ocid__is

string

Open Contracting ID to include (maxLength: 100).

language__is

array[string]

Languages to include.

language__exclude

array[string]

Languages to exclude.

tender_deadline__gte

string($date-time)

Tender deadline greater than or equal to.

tender_deadline__lte

string($date-time)

Tender deadline less than or equal to.

contract_start_date__gte

string($date-time)

Contract start date greater than or equal to.

contract_start_date__lte

string($date-time)

Contract start date less than or equal to.

contract_start_date__is

string($date-time)

Contract start date exactly.

contract_end_date__gte

string($date-time)

Contract end date greater than or equal to.

contract_end_date__lte

string($date-time)

Contract end date less than or equal to.

contract_end_date__is

string($date-time)

Contract end date exactly.

release_date__gte

string($date-time)

Release date greater than or equal to.

release_date__gt

string($date-time)

Release date greater than.

release_date__lte

string($date-time)

Release date less than or equal to.

release_date__lt

string($date-time)

Release date less than.

release_tags__is

string

Release tags to include - defined as an array with one or more of the tags published by publishers using OCDS (see below).

tag_status__is

string

Tag status to include (maxLength: 100).

cpv__is

array[string]

CPV codes to include.

source__is

array[string]

Sources to include.

dps_pred__is

boolean

Whether the contract is a dynamic purchasing system contract.

predicted_cpv_values

boolean

Include predicted CPV values.

compiled_only

boolean

Include only compiled records.

original_only

boolean

Include only original records.

date_direction

string

Date sort direction (asc or desc).

offset

integer

Pagination offset (min: 0, max: 9900).

limit

integer

Number of records to return (min: 0, max: 100).

prefix_search

boolean

Enable prefix search.

value__gte

integer

Minimum value (min: 0).

value__gt

integer

Greater than value (min: 0).

value__lte

integer

Less than or equal to value (min: 0).

value__lt

integer

Less than value (min: 0).

currency__is

string

Currency to query for (maxLength: 3, e.g., USD, GBP, EUR).

dedupe__is

boolean

Include duplicate records.

attachment__show

boolean

Call to include original URLs and file names from attachments.

attachment__is

boolean

Show only results with attachments

Release Tags

Release tag items can be one or more of the following and expressed in an array.

tender
award
planning
award contract
contract award
tenderUpdate
awardUpdate
tenderAmendment
planningUpdate
awardUpdate contractUpdate
contractUpdate awardUpdate
tender planning
tenderCancellation
planning tender
contractAmendment
contractTermination
planning award
planningUpdate award
award planning
award planningUpdate

Example Code

import requests

query = {
    "compiled_only": False,
    "original_only": False,
    "date_direction": "desc",
    "offset": 0,
    "limit": 50,
    "prefix_search": False,
    "release_tags__is": "tender",
    "predicted_cpv_values": False,
    "dedupe__is": False,
    # Add additional parameters as needed
}

def object_to_url_search_params(obj):
    params = []
    for key, value in obj.items():
        if isinstance(value, list):
            for item in value:
                params.append((key, item))
        else:
            params.append((key, value))
    return params

url_query = requests.models.PreparedRequest()
url_query.prepare_url("<https://api-test.spendnetwork.cloud/api/v3/notices/records_openopps>", object_to_url_search_params(query))
url = url_query.url
print("Generated URL Query:", url)

def fetch_summary_api_records():
    try:
        response = requests.get(
            url,
            headers={
                "Accept": "application/json",
                "Content-Type": "application/json",
                "Authorization": "Bearer YOUR_ACCESS_TOKEN",  # Replace with your actual access token
            },
        )

        response.raise_for_status()  # Check for HTTP errors

        body = response.json()

        return body
    except requests.RequestException as error:
        print("Fetch error:", error)
        return None

# Fetch the records
records = fetch_summary_api_records()
print(records)

Authentication

To access the API users need to generate a bearer token. This is generated by making a call to the access-token endpoint /api/v2/login/access-token which uses an OAuth2 compatible login, and returns an access token for future requests. Supports both JSON and form data formats. The payload returns a token and the expiration date as follows. To refresh the token just call the access-token endpoint with your credentials.

**{
  "access_token": "string",
  "token_type": "string",
  "expiration_date": "string"
}**

Replace "Bearer YOUR_ACCESS_TOKEN" with your actual API access token.

For detailed API documentation and additional options, visit the Spend Network API Swagger page.

Error Handling

When interacting with the API, it is important to handle potential errors gracefully. This includes checking for HTTP errors and handling exceptions appropriately.

def fetch_summary_api_records():
    try:
        response = requests.get(
            url,
            headers={
                "Accept": "application/json",
                "Content-Type": "application/json",
                "Authorization": "Bearer YOUR_ACCESS_TOKEN",  # Replace with your actual access token
            },
        )

        response.raise_for_status()  # Check for HTTP errors

        body = response.json()
        return body

    except requests.RequestException as error:
        print("Fetch error:", error)
        return None
    except requests.HTTPError as http_err:
        print(f"HTTP error occurred: {http_err}")
    except Exception as err:
        print(f"An error occurred: {err}")

# Fetch the records
records = fetch_summary_api_records()
print(records)

Example Query Parameters

Customise the query parameters for specific use cases to retrieve the desired data.

query = {
    "date_direction": "asc",
    "offset": 0,
    "limit": 10,
    "release_tags__is": "award",
    "buyer_name__is": "MINISTRY OF DEFENCE",
}

Rate Limiting

Be aware of the API's rate limits which are based on all calls to the server rather than just your individual calls. There should be no reason for users collecting daily, paginated data to hit rate limits, however, implementing retry mechanisms and exponential backoff can help manage rate limits effectively.

Pagination

To handle large datasets, use the offset and limit parameters to paginate results. Note that there is a 10,000 record limit on what can be returned from any single query.

query = {
    "offset": 0,
    "limit": 100  # Adjust as necessary, but must be <= 100
}

# Iterate through pages
while True:
    records = fetch_summary_api_records()
    if not records or len(records) < query["limit"]:
        break
    query["offset"] += query["limit"]

How to filter notices by CPV

This guide explains how to use:

  • cpv__is

  • prefix_search

 

Filtering by CPV (cpv__is)
For the OpenOpps notices endpoint (GET request), you repeat the parameter:

GET /api/v3/notices/records_openopps?cpv__is=48000000&cpv__is=72000000&cpv__is=85000000

For the summary endpoints (POST request), you send a list in JSON:

{
  "cpv__is": ["48000000", "72000000", "85000000"]
}

 

Prefix CPV matching (prefix_search)

When should you use prefix search?

Use prefix_search=true when you want to match a family of CPV codes.

Example:

  • If you send 48000000 with prefix_search=true, the API treats it like “anything starting with 48”.

  • That means codes like 48100000, 48200000, etc. can match.

How to enable it

For OpenOpps notices endpoint (GET):

GET /api/v3/notices/records_openopps?cpv__is=48000000&cpv__is=72000000&prefix_search=true

For summary endpoints (POST):

{
  "cpv__is": ["48000000", "72000000"],
  "prefix_search": true
}

What happens with trailing zeros

With prefix_search=true, the system removes trailing zeros to create the prefix:

  • 48000000 becomes prefix 48

  • 72000000 becomes prefix 72


Sample responses

Here is an example of a typical response from the API:

{
    "results": [
        {
            "tender_id": "tender_278767/1024151",
            "buyer_name": "MINISTRY OF DEFENCE",
            "tender_title": "The provision of End Point Assessment for Digital Apprenticeship Standards",
            "release_date": "2021-12-17T08:27:49Z",
            ...
        }
    ],
    "total": 1234,
    "offset": 0,
    "limit": 10
}

Best Practices

  • Optimize Queries: Use specific and relevant query parameters to limit the amount of data returned.

  • Caching: Implement caching strategies to reduce the number of API calls and improve performance.

  • Error Handling: Ensure robust error handling to manage API errors gracefully.

  • Rate Limits: Be mindful of API rate limits and implement retry mechanisms where necessary.

  • Pagination: Use pagination to handle large datasets efficiently.

API Limitations

  • Record Limit: There is a 10,000 record limit on what can be returned from any query. Use pagination to retrieve additional records.

  • Update Frequency: Data is updated daily, so ensure your application accounts for this update cycle.

Contact Information

For further assistance or questions about the API, please contact our support team at contact@spendnetwork.com.

Further code examples

Example Javascript code

The following JavaScript code demonstrates how to access the Spend Network API to fetch records related to tenders, awards, or planning notices. This script constructs a query based on specified parameters and sends an HTTP GET request to the API endpoint. The query includes options such as date direction, result offset, and limit, as well as filters for release tags and CPV values.

The objectToURLSearchParams function converts the query object into URL search parameters, ensuring the correct format for the API request. The fetchSummaryAPIRecords function handles the API call, including setting the appropriate headers for authentication. Upon receiving a response, it checks for errors and parses the JSON response body.

To execute the code, make sure to replace TOKEN HERE with your actual API access token. This code snippet provides a robust foundation for integrating with the Spend Network API and retrieving procurement-related data efficiently.

const query = {
    compiled_only: false,
    original_only: false,
    date_direction: "desc",
    offset: 0,
    limit: 50,
    prefix_search: false,
    release_tags__is: "tender", //tender,award,planning
    predicted_cpv_values: false,
    dedupe__is: false,
};

const objectToURLSearchParams = (obj: Record<string, any>): URLSearchParams => {
    const params = new URLSearchParams();

    for (const key in obj) {
        if (Array.isArray(obj[key])) {
            obj[key].forEach((value: any) => {
                params.append(key, value);
            });
        } else {
            params.append(key, obj[key]);
        }
    }
    return params;
};

// Generate the query string
const urlQuery = objectToURLSearchParams(query).toString();
console.log("Generated URL Query:", urlQuery);
console.log(
    `https://api-test.spendnetwork.cloud/api/v3/notices/records_openopps?${urlQuery}`,
);
export const fetchSummaryAPIRecords = async () => {
    try {
        const response = await fetch(
            `https://api-test.spendnetwork.cloud/api/v3/notices/records_openopps?${urlQuery}`,
            {
                method: "GET",
                headers: {
                    Accept: "application/json",
                    "Content-Type": "application/json",
                    Authorization: `Bearer TOKEN HERE`, // please add your sn-api access token
                },
            },
        );

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const body = await response.json();

        return body;
    } catch (error) {
        console.error("Fetch error:", error);
        return null;
    }
};

Example Python code

The following Python code demonstrates how to access the Spend Network API to fetch records related to tenders, awards, or planning notices. This script constructs a query based on specified parameters and sends an HTTP GET request to the API endpoint. The query includes options such as date direction, result offset, and limit, as well as filters for release tags and CPV values.

  1. Query Parameters: The query dictionary contains the parameters for the API request.

  2. object_to_url_search_params Function: This function converts the dictionary into a list of tuples suitable for URL encoding.

  3. URL Generation: The requests.models.PreparedRequest object is used to generate the URL with query parameters.

  4. fetch_summary_api_records Function: This function sends an HTTP GET request to the API endpoint, including the necessary headers for authentication. It checks for errors and parses the JSON response.

Make sure to replace "Bearer TOKEN HERE" with your actual API access token.

import requests

query = {
    "compiled_only": False,
    "original_only": False,
    "date_direction": "desc",
    "offset": 0,
    "limit": 50,
    "prefix_search": False,
    "release_tags__is": "tender",  # tender, award, planning
    "predicted_cpv_values": False,
    "dedupe__is": False,
}

def object_to_url_search_params(obj):
    params = []
    for key, value in obj.items():
        if isinstance(value, list):
            for item in value:
                params.append((key, item))
        else:
            params.append((key, value))
    return params

# Generate the query string
url_query = requests.models.PreparedRequest()
url_query.prepare_url("https://api-test.spendnetwork.cloud/api/v3/notices/records_openopps", object_to_url_search_params(query))
url = url_query.url
print("Generated URL Query:", url)

def fetch_summary_api_records():
    try:
        response = requests.get(
            url,
            headers={
                "Accept": "application/json",
                "Content-Type": "application/json",
                "Authorization": "Bearer TOKEN HERE",  # please add your sn-api access token
            },
        )

        response.raise_for_status()  # Check for HTTP errors

        body = response.json()

        return body
    except requests.RequestException as error:
        print("Fetch error:", error)
        return None

# Fetch the records
records = fetch_summary_api_records()
print(records)

Document Attachments

Spend Network’s summary API now supports both sourcing and downloading attachments (e.g. PDFs, DOCs) related to individual tender or contract documents. This feature allows users to programmatically access attachments, either via the original source information or through a direct download via Spend Network’s servers.

<aside> 🕓

A note on publishing cadence and attachments. On some occasions publishers release attachments separately from the original data publication. We collect additional documents on significant updates (e.g. when a contract is converted from a tender notice to a contract award) or on a regular data refresh.

To ensure users have the most up-to-date data and files we have created additional endpoints that can be called to return either the source of each attachment or to download each attachment.

</aside>

Filtering For Attachments

Our API contains a boolean that shows when a document has attachments associated with it. Users can use the attachment__is feature in their query to return only documents with attachments, or alternatively only those without attachments.

Example Query Parameters

query = {
    "attachment__is":true,
    "date_direction": "asc",
    "offset": 0,
    "limit": 10,
    "release_tags__is": "award",
    "buyer_name__is": "MINISTRY OF DEFENCE",
}

Show Attachment Sources

In order to be able to provide a source URL for a given attachment we have an additional feature that can be called which adds the sourcing data to the document payload.

To retrieve document metadata (i.e. the titles and source URLs) for attachments associated with published tenders or contracts, API users can include the attachment__show parameter in your request for a specific document:

Parameter

Type

Description

attachment__show

boolean (optional, default: false)

When set to true, the response will include an attachments field with a list of attachment metadata.

Example Query Parameters

Users should use the attachment__show parameter on a document by document basis to retain response time performance. Queries for multiple files will NOT be fast enough for production environments.

{
  "attachment__show": true,
  "ocid__is": "ocds-0c46vo-0001-12ef087c-3ad3-4d72-b2bb-e3d416081402",
}

Example Response Snippet

...
"attachments": [
  {
    "title": "Entwurfsplanung Heizung KG.pdf",
    "url": "<https://www.vergabe-westfalen.de/.../Entwurfsplanung+Heizung+KG.pdf>"
  },
  {
    "title": "LV Heizflächen Altbau.d83",
    "url": "<https://www.vergabe-westfalen.de/.../LV+Heizfl%C3%A4chen+Altbau.d83>"
  }
]
...

Downloading Attachments via Spend Network API

To simplify access to attachment files (bypassing source website restrictions), two dedicated endpoints are provided:

1. List Available Attachment Files

This allows users to list attachment files by title and url for a specific document.

Endpoint:

POST <https://api.spendnetwork.cloud/api/v3/attachments/list>

Authentication Required: Yes (Bearer token)

Parameter

Type

Description

source

string

Internal source identifier (e.g. td_vergabe_westfalen_de)

tender_id

string

Unique tender ID (from the summary API)

Example

The following request allows the user to return a list of attachments associated with a specific document.

curl -X POST \\
  '<https://api.spendnetwork.cloud/api/v3/attachments/list>' \\
  -H 'Authorization: Bearer YOUR_TOKEN' \\
  -H 'Content-Type: application/json' \\
  -d '{
        "source": "td_vergabe_westfalen_de",
        "tender_id": "41878101"
      }'

Response

We use underscores (_) in filename values instead of period characters (.) to ensure compatibility with URL paths and to avoid issues with file extension parsing or routing logic in some systems.

[
  {
    "title": "SubmissionForm.docx",
    "filename": "submissionform_docx"
  }
]

Note: This filename value is required for the download endpoint.

2. Download Specific Attachment File

Endpoint Format:

GET /api/v3/attachments/download/{source}/{tender_id}/{filename}

Note: Use the tender_id field not the ocid identifier.

Example

curl -X GET \\
  '<https://api.spendnetwork.cloud/api/v3/attachments/download/td_vergabe_westfalen_de/41878101/submissionform_docx>' \\
  -H 'Accept: application/json'

Behavior:

Returns the file as a direct download. In the event that the incorrect link has been used the API will return a Attachment file not found error.

🧭 How It Fits Together

  1. If the has__attachment feature of a document is NOT an empty array, then you will get a response from the /attachments/list end point.

  2. Get the source and tender_id from the returned JSON, and check for available attachments using the /attachments/list end point.

  3. Use /attachments/list to retrieve a full list of filenames for that record.

  4. Compile a query using the source , tender_id and filename from memory and send a request to the /attachments/download/... end point to fetch a specific file by filename.

Best Practices

  • Use /attachments/list to get valid filenames for a specific document before calling /attachments/download.

  • Ensure that the source and tender_id match what is returned from the summary API.

  • Always authenticate using your API token on both endpoints.

  • Collect attachments on the basis of user demand, rather than in advance in aggregate.