UK and Ireland tender data API

Live tenders collected from buyers' own portals, not counted from national notices, and contracts due back on the market. Read-only JSON, one key, and a free demo to start.

38,000+ live tenders. 670+ of them not on the national portals. 330,000+ contracts tracked for renewal.

Data that free feeds do not have

Find a Tender and Contracts Finder publish open data, and plenty of tools repackage it. Around one in four live tenders is not on any national portal: it is published only on the buyer's own procurement portal. TenderSignal collects those tenders alongside the national notices, and the API gives you both in one feed, with a hard_to_find flag on every tender that is not on the national portals.

What you can build

  • Bring new tenders in your sectors into your CRM or bid tracker, and tell the right person on your team.
  • Follow the buyers you sell to, with their live and past notices and, on API Pro, their procurement contact.
  • See contracts due back on the market, with the month we expect each to return, and plan your pipeline months ahead.
  • Pull award notices to see who won what, for how much, and when each contract ends.

Simple to use

The API is read-only JSON over HTTPS with one key in the Authorization header. Lists are paged with cursors that also work for polling: keep the last cursor you received and pass it next time to get only what is new. Allowances count records, not calls, and a record you have already received this month is free, so polling for new tenders costs nothing extra.

Every response tells you your plan, your allowance and what you have used, in its headers, so your integration can keep an eye on its own usage. Errors come back as JSON with a short code and a plain explanation.

Start free

Every verified TenderSignal account can create a demo key with a one-off allowance. Try real requests against live data, then choose API Starter or API Pro when you are ready. There are no sales calls and no demos to book: sign up, create a key and start. If you need more than API Pro includes, email [email protected] and we will set up a larger allowance.

Plans

Demo

Free
  • 100 records, once
  • Tenders and awards
  • No buyer contact details
  • One key

API Starter

£49/month + VAT
  • 2,500 records a month
  • Tenders, awards and buyers
  • Buyer contacts on tenders also on the national portals, for accounts billed in the UK, the EEA or a country with UK adequacy
  • Up to 5 keys

API Pro

£149/month + VAT
  • 10,000 records a month
  • Everything in API Starter, plus renewals
  • Buyer contacts on every tender, including hard-to-find ones, for accounts billed in the UK, the EEA or a country with UK adequacy
  • Links to buyers' portals, up to 2,000 records a month
  • Up to 5 keys

Buyer contact details are included for accounts billed in the UK, the EEA or a country with UK adequacy.

Need more than 10,000 records a month? Email [email protected]. API plans are separate from the website plans and are billed monthly; cancel any time from your billing page.

Your keys

Create a free TenderSignal account to get a demo key. Already have one? Log in.

Quick start

Keep your key in an environment variable and send it in the Authorization header. Each example asks for five live tenders that are not on the national portals.

curl
curl -H "Authorization: Bearer $TENDERSIGNAL_API_KEY" \
  "https://tendersignal.co.uk/api/v1/tenders?hard_to_find=true&limit=5"
JavaScript
const res = await fetch("https://tendersignal.co.uk/api/v1/tenders?hard_to_find=true&limit=5", {
  headers: { Authorization: `Bearer ${process.env.TENDERSIGNAL_API_KEY}` },
});
const { data, next_cursor } = await res.json();
Python
import os, requests

r = requests.get(
    "https://tendersignal.co.uk/api/v1/tenders",
    params={"hard_to_find": "true", "limit": 5},
    headers={"Authorization": f"Bearer {os.environ['TENDERSIGNAL_API_KEY']}"},
)
data = r.json()["data"]

Use it from your AI assistant

The same data is available to AI assistants through our MCP server, so you can ask Claude, Cursor or another MCP client for tenders, awards, buyers and renewals in plain English. It uses the same API key, the same plan and the same record allowance as the API: a record your assistant fetches counts once, exactly as it would over the API.

Server address https://www.tendersignal.co.uk/mcp. Send your key in the Authorization header. Assistants that only connect through a sign-in button, such as the connector screens in claude.ai and ChatGPT, are not supported yet.

Claude Code
claude mcp add --transport http tendersignal https://www.tendersignal.co.uk/mcp --header "Authorization: Bearer $TENDERSIGNAL_API_KEY"
Cursor (mcp.json)
{
  "mcpServers": {
    "tendersignal": {
      "url": "https://www.tendersignal.co.uk/mcp",
      "headers": {
        "Authorization": "Bearer ts_live_your_key"
      }
    }
  }
}
Claude Desktop (claude_desktop_config.json)
{
  "mcpServers": {
    "tendersignal": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://www.tendersignal.co.uk/mcp",
        "--header",
        "Authorization:${TENDERSIGNAL_AUTH}"
      ],
      "env": {
        "TENDERSIGNAL_AUTH": "Bearer ts_live_your_key"
      }
    }
  }
}

Tools

  • search_tenders: Search tenders with the same filters as /tenders, including hard_to_find. (Every plan)
  • get_tender: One tender by id. (Every plan)
  • search_awards: Search award notices with the same filters as /awards. (Every plan)
  • list_renewals: Contracts expected to be re-tendered, as /renewals. (API Pro)
  • search_buyers: Find buyers and their slugs, as /buyers. (API Starter and API Pro)
  • get_buyer: One buyer by slug. (API Starter and API Pro)
  • get_usage: Your plan, allowance and usage. Free. (Every plan)

Fields by plan

Every record carries the fields marked for your plan. Buyer contact details are included for accounts billed in the UK, the EEA or a country with UK adequacy. Where details are withheld the field is absent and the response says why.

tenders

FieldPlansWhat it is
idEvery planTenderSignal id, the number in the tender's page address.
urlEvery planThe tender's page on tendersignal.co.uk.
titleEvery planNotice title.
descriptionEvery planFull description. Links to buyers' portals are removed unless your plan includes them.
statusEvery planlive, closed or cancelled.
notice_typeEvery plantender, amendment or pin (an early market notice).
buyerEvery planThe buying organisation: name, slug, type, type_group and website.
contract_typeEvery planworks, services, supplies or null.
procedure_typeEvery planThe procurement procedure as published.
cpv_codesEvery planCPV codes on the notice.
sectorsEvery planTenderSignal sector slugs, the same as the sector parameter.
regionEvery planRegion as published.
nationEvery planengland, scotland, wales, northern-ireland or ireland.
countryEvery planUK, GB, GI or IE.
valueEvery planmin, max and currency, in pounds or euros, or null when no value was published.
published_atEvery planWhen the notice was published, ISO 8601 in UTC.
deadlineEvery planResponse deadline, ISO 8601 in UTC.
enquiry_deadlineEvery planDeadline for clarification questions, when published.
contract_start_dateEvery planYYYY-MM-DD.
contract_end_dateEvery planYYYY-MM-DD.
duration_monthsEvery planContract length in months.
is_frameworkEvery plantrue for a framework agreement.
is_dpsEvery plantrue for a dynamic purchasing system.
hard_to_findEvery plantrue: not on the national portals (we found it on the buyer's own portal); false: also on a national portal; null: not yet checked.
contactEvery plan on tenders also on the national portals; API Pro on every tender. Only for accounts whose billing address is in the UK, the EEA or a country the UK recognises as adequate; otherwise absent, with contacts_withheld_reason in the response.The buyer's contact: name, email and phone. Absent when your plan does not include it for this tender. Contact details are returned only to accounts whose billing address is in the UK, the EEA or a country the UK recognises as adequate for data protection. Otherwise the field is absent and the response carries contacts_withheld_reason.
source_urlAPI ProThe notice on the buyer's portal.
submission_urlAPI ProWhere to respond.
portal_link_cappedAPI ProPresent and true when this month's portal-link limit was reached, so the links were left out.

awards

FieldPlansWhat it is
idEvery planTenderSignal id of the award notice.
urlEvery planThe award's page on tendersignal.co.uk.
titleEvery planNotice title.
buyerEvery planThe buying organisation: name, slug, type, type_group and website.
cpv_codesEvery planCPV codes on the notice.
sectorsEvery planTenderSignal sector slugs, the same as the sector parameter.
regionEvery planRegion as published.
nationEvery planengland, scotland, wales, northern-ireland or ireland.
countryEvery planUK, GB, GI or IE.
suppliersEvery planThe winning suppliers, as a list.
award_valueEvery planamount and currency, or null.
award_dateEvery planYYYY-MM-DD.
published_atEvery planWhen the award notice was published, ISO 8601 in UTC.
contract_start_dateEvery planYYYY-MM-DD.
contract_end_dateEvery planYYYY-MM-DD.
duration_monthsEvery planContract length in months.
source_urlAPI ProThe notice on the buyer's portal.
portal_link_cappedAPI ProPresent and true when this month's portal-link limit was reached, so the links were left out.

renewals

FieldPlansWhat it is
idAPI ProTenderSignal id of the renewal.
titleAPI ProThe current contract's title.
descriptionAPI ProThe current contract's description.
buyerAPI ProThe buying organisation.
incumbentAPI ProThe suppliers that hold the contract now, as a list.
contract_end_dateAPI ProWhen the current contract ends, YYYY-MM-DD.
expected_retender_monthAPI ProThe month we expect it back on the market, YYYY-MM.
valueAPI Promin, max and currency of the current contract, or null.
cpv_codesAPI ProCPV codes of the current contract.
sectorsAPI ProTenderSignal sector slugs.
regionAPI ProRegion as published.
original_awardAPI Proid and url of the award notice for the current contract.
retendered_asAPI Proid and url of the new tender once it is published, otherwise null.
contactAPI ProThe buyer's contact: name, email and phone. Contact details are returned only to accounts whose billing address is in the UK, the EEA or a country the UK recognises as adequate for data protection. Otherwise the field is absent and the response carries contacts_withheld_reason.
source_urlAPI ProThe award on the buyer's portal.
portal_link_cappedAPI ProPresent and true when this month's portal-link limit was reached, so the links were left out.

buyers

FieldPlansWhat it is
slugEvery planUse it with the buyer parameter and /buyers/:slug.
nameEvery planBuyer name.
typeEvery planBuyer type, for example local-council or nhs.
type_groupEvery planThe buyer_type group the type belongs to.
nationEvery planengland, scotland, wales, northern-ireland or ireland.
tender_countEvery planNotices from this buyer.
live_countEvery planLive tenders from this buyer now.
urlEvery planThe buyer's page on tendersignal.co.uk.
procurement_contactAPI ProThe buyer's procurement email and phone, when known. Contact details are returned only to accounts whose billing address is in the UK, the EEA or a country the UK recognises as adequate for data protection. Otherwise the field is absent and the response carries contacts_withheld_reason.

Endpoints and parameters

Base address https://tendersignal.co.uk/api/v1. Every endpoint is a GET that returns JSON. Unknown parameters are refused with a 400 that names them.

GET /usage

Your plan, allowance, usage, what your plan includes and the terms version you accepted. Free. contacts is all, national_portal_tenders or "none"; when it is "none", contacts_withheld_reason says billing_country_unknown or billing_country_not_eligible. (Every plan)

GET /tenders

Tenders in the UK and Ireland, live by default, oldest id first. (Every plan)

  • status: live (default), closed or all.
  • notice_type: tender, amendment or pin. PINs (early market notices) only appear when you ask for them.
  • q: Words in the title or description. Separate phrases with commas to match any of them.
  • sector: Comma list of sector slugs, for example construction,it-software. Every slug is listed under Sector slugs below.
  • cpv: Comma list of CPV codes. 45000000 matches every code that starts 45.
  • region: Comma list from: london, south-east, south-west, east-of-england, east-midlands, west-midlands, yorkshire, north-west, north-east, wales, scotland, northern-ireland, ireland. uk-wide is not accepted: leave region out for no region filter. ireland adds Irish tenders; use nation=ireland for Ireland only.
  • buyer: A buyer slug from /buyers.
  • buyer_name: Part of the buyer's name.
  • buyer_type: Comma list: local-council, nhs, central-gov, housing-association, university, education, emergency-services, utility, public-body.
  • value_min: Minimum value in the notice's own currency, for example 25000.
  • value_max: Maximum value in the notice's own currency.
  • limit: Records per page, 1 to 100. Default 20.
  • cursor: next_cursor or resume_cursor from an earlier response.
  • nation: Comma list: england, scotland, wales, northern-ireland, ireland.
  • closing_after: Deadline on or after this date or time. A date alone means midnight UK time.
  • closing_before: Deadline before this date or time.
  • published_since: Published on or after this date or time.
  • hard_to_find: hard_to_find=true returns only tenders not on the national portals; hard_to_find=false returns every other tender, including ones not yet checked.

GET /tenders/:id

One tender by id. A merged record answers 404 with canonical_id. (Every plan)

GET /awards

Award notices: who won, for how much and when. (Every plan)

  • q: Words in the title or description. Separate phrases with commas to match any of them.
  • sector: Comma list of sector slugs, for example construction,it-software. Every slug is listed under Sector slugs below.
  • cpv: Comma list of CPV codes. 45000000 matches every code that starts 45.
  • region: Comma list from: london, south-east, south-west, east-of-england, east-midlands, west-midlands, yorkshire, north-west, north-east, wales, scotland, northern-ireland, ireland. uk-wide is not accepted: leave region out for no region filter. ireland adds Irish tenders; use nation=ireland for Ireland only.
  • buyer: A buyer slug from /buyers.
  • buyer_name: Part of the buyer's name.
  • buyer_type: Comma list: local-council, nhs, central-gov, housing-association, university, education, emergency-services, utility, public-body.
  • value_min: Minimum value in the notice's own currency, for example 25000.
  • value_max: Maximum value in the notice's own currency.
  • limit: Records per page, 1 to 100. Default 20.
  • cursor: next_cursor or resume_cursor from an earlier response.
  • nation: Comma list: england, scotland, wales, northern-ireland, ireland.
  • supplier: Part of a winning supplier's name.
  • awarded_since: Awarded on or after this date.
  • awarded_before: Awarded before this date.
  • published_since: Published on or after this date or time.

GET /buyers

UK and Irish buyers, by slug. (API Starter and API Pro)

  • q: Part of the buyer's name.
  • buyer_type: Comma list of buyer type groups, as on /tenders.
  • nation: Comma list: england, scotland, wales, northern-ireland, ireland.
  • has_live: true for buyers with live tenders now.
  • limit: Records per page, 1 to 100. Default 20.
  • cursor: next_cursor or resume_cursor from an earlier response.

GET /buyers/:slug

One buyer by slug. (API Starter and API Pro)

GET /renewals

Contracts due back on the market, with the month we expect each to return. (API Pro)

  • q: Words in the title.
  • sector: Comma list of sector slugs, for example construction,it-software. Every slug is listed under Sector slugs below.
  • cpv: Comma list of CPV codes. 45000000 matches every code that starts 45.
  • region: Comma list from: london, south-east, south-west, east-of-england, east-midlands, west-midlands, yorkshire, north-west, north-east, wales, scotland, northern-ireland, ireland. uk-wide is not accepted: leave region out for no region filter. ireland adds Irish tenders; use nation=ireland for Ireland only.
  • buyer: A buyer slug from /buyers.
  • buyer_name: Part of the buyer's name.
  • buyer_type: Comma list: local-council, nhs, central-gov, housing-association, university, education, emergency-services, utility, public-body.
  • value_min: Minimum value in the notice's own currency, for example 25000.
  • value_max: Maximum value in the notice's own currency.
  • limit: Records per page, 1 to 100. Default 20.
  • cursor: next_cursor or resume_cursor from an earlier response.
  • incumbent: Part of the current supplier's name.
  • retender_from: Expected back on the market in or after this month, YYYY-MM.
  • retender_to: Expected back on the market in or before this month, YYYY-MM.

Sector slugs

Use these slugs with the sector parameter, for example sector=construction,it-software. Each sector covers a set of CPV codes; use cpv instead for a narrower match.

  • construction: Construction & Civil Engineering
  • it-software: IT & Software
  • data-digital: Data & Digital
  • healthcare: Healthcare & Medical
  • social-care: Social Care
  • facilities-property: Facilities & Property Management
  • professional-services: Professional Services & Consulting
  • engineering-manufacturing: Engineering & Manufacturing
  • environmental-utilities: Environmental & Utilities
  • energy: Energy
  • transport-logistics: Transport & Logistics
  • security-services: Security Services
  • education-training: Education & Training
  • marketing-communications: Marketing & Communications
  • legal-financial: Legal & Financial Services
  • goods-supplies: Goods & Supplies
  • cultural-recreation: Cultural & Recreation

Records, limits and errors

Allowances count records: each tender, award, buyer or renewal in a response. A record you have already received this month is free, and /usage and errors cost nothing. Paid plans reset on the 1st of each month (UTC); the demo allowance is a one-off.

If a page would go past your allowance you get the records that fit and a cursor to carry on later. Each key may make 60 requests a minute. On API Pro, records past the monthly portal-link limit arrive without their portal links and carry portal_link_capped.

Every response carries these headers:

X-Api-Plan: starter
X-Records-Limit: 2500
X-Records-Used: 340
X-Records-Remaining: 2160
X-Records-Charged: 20
X-Records-Reset: 2026-11-01T00:00:00.000Z
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-Portal-Links-Limit: 2000
X-Portal-Links-Used: 120
X-Portal-Links-Withheld: 0
Cache-Control: no-store
400invalid_parameterAn unknown parameter, a bad value, an id that is too large or a cursor from another endpoint. The response names the parameter.
401invalid_keyA missing, malformed, unknown or revoked key, or a key sent in the URL.
403plan_requiredThe endpoint is not in your plan. The response includes upgrade_url.
403suspendedThe account or its API access is suspended.
404not_foundNo such record or endpoint.
404mergedThe record was merged into another one. The response includes canonical_id.
405method_not_allowedAny method other than GET, HEAD included. The API is read-only. Nothing is charged.
429rate_limitedMore than 60 requests a minute on one key. Wait for the Retry-After header.
429records_exhaustedYour allowance is used. The response says how much you used and when it resets.
503query_timeoutThe query took too long. Add a filter, such as a date or a sector. Nothing is charged.
500server_errorSomething went wrong on our side. Try again, and email [email protected] if it persists.

When your allowance is used, the API answers 429:

{
  "error": "Your record allowance for this month has been used.",
  "code": "records_exhausted",
  "plan": "starter",
  "allowance": 2500,
  "used": 2500,
  "remaining": 0,
  "resets": "2026-11-01T00:00:00.000Z",
  "upgrade_url": "https://tendersignal.co.uk/developers#pricing",
  "attribution": "Contains public sector information licensed under the Open Government Licence v3.0 ..."
}

Pagination, polling and the response envelope

Lists come oldest id first, up to 100 records a page. Pass next_cursor as cursor to get the next page; it is null when there is nothing more right now.

To poll for new records, store resume_cursor from your last response and pass it as cursor next time. You get only records added since. If nothing is new, data is empty and resume_cursor is the cursor you sent, so keep using it. Records you already have this month cost nothing, so polling every few minutes is fine.

Next to data (or error) every JSON response carries these top-level fields.

FieldPlansWhat it is
attributionEvery planThe attribution statement for the public sector information in the data. In every JSON response, errors included. Include it wherever you show records outside your own systems.
contacts_withheld_reasonEvery planPresent on data responses only when contact details are withheld for your billing country: billing_country_unknown (no billing country on your account) or billing_country_not_eligible (outside the UK, the EEA and the countries the UK recognises as adequate). On /usage it sits inside data.

Using the data

  • Use the data for your own internal business purposes: your CRM, reports, analysis, bid process and internal tools.
  • You may share individual records with your own clients or advisers where it is incidental to your service to them, at most fifty records per recipient per month, and never as a feed or a tool your clients can search themselves.
  • Do not resell, sublicense, publish or make the data publicly available.
  • Do not use the data to build a competing product or service, or anything that makes tenders, awards, buyer information or renewal predictions available to others.
  • AI: you may use AI tools on the data for your own internal use, but do not train or fine tune models that are used for others, and do not put the data into any third party AI service that keeps it or trains on it.
  • Do not use the API or the data to map where or how we collect our information.
  • Keep the attribution statement, which is in every response, wherever you show records outside your own systems.
  • Use buyer contact details only to contact the buyer about the opportunity they relate to. You are an independent controller of the contact details you receive and responsible for complying with data protection law.
  • Within 30 days after your plan ends, delete the data, apart from the exceptions in clause 15.2 of the terms.

The full terms are at API Terms. The attribution statement:

Contains public sector information licensed under the Open Government Licence v3.0 (https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). Contains Irish public sector data from the Office of Government Procurement licensed under a Creative Commons Attribution 4.0 International (CC BY 4.0) licence (https://creativecommons.org/licenses/by/4.0/). This information has been modified and combined with other information by TenderSignal.