Bidsandtenders APIopportunities.bidsandtenders.com ↗
Search public bid opportunities on Bids & Tenders by keyword, status, org, and date. Retrieve full bid details including documents, addenda, and key dates.
What is the Bidsandtenders API?
The Bids & Tenders Opportunities API exposes 3 endpoints covering the public bid listings at opportunities.bidsandtenders.com. Use search_bids to filter and paginate tender opportunities by keyword, status, organization, publish date, and bid type, then call get_bid_details to pull the full record — description, key dates, meetings, documents, and addenda — for any individual listing.
curl -X GET 'https://api.parse.bot/scraper/ed96455f-4c22-4e61-acc1-f77b45aec981/search_bids?query=Services&status=All' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace opportunities-bidsandtenders-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: BidsAndTenders SDK — search open bids, drill into details."""
from parse_apis.opportunities_bidsandtenders_com_api import (
BidsAndTenders, BidStatus, SortField, SortDirection, BidNotFound,
)
client = BidsAndTenders()
# Browse open bids sorted by closing date, newest first.
for bid_summary in client.bid_summaries.search(
status=BidStatus.OPEN,
sort=SortField.CLOSING_DATE,
direction=SortDirection.DESC,
limit=5,
):
print(bid_summary.name, bid_summary.status, bid_summary.organization)
# Drill into the first construction-keyword result for full details.
hit = client.bid_summaries.search(query="Construction", limit=1).first()
if hit is not None:
bid = hit.details()
print(bid.bid_name, bid.bid_number, bid.bid_classification)
print("closing:", bid.closing_date)
for doc in bid.documents:
print(" doc:", doc.name, f"({doc.pages} pages)")
for meeting in bid.meetings:
print(" meeting:", meeting.location, meeting.start, meeting.mandatory)
# Point-lookup by URL when the detail_url is already known.
try:
detail = client.bids.get(detail_url=hit.detail_url)
print(detail.bid_name, detail.bid_status)
except BidNotFound:
print("bid no longer available")
# List buyer organizations and use one to narrow a search.
org = client.organizations.list(limit=1).first()
if org is not None:
for bid_summary in client.bid_summaries.search(
organization_id=org.organization_id,
status=BidStatus.ALL,
limit=3,
):
print(org.name, "—", bid_summary.name)
print("exercised: bid_summaries.search / details / bids.get / organizations.list")
Searches the bid opportunities listing and returns one page of bids. Each bid carries its display name (reference number and title), status, published and closing dates as UTC timestamps plus the buyer's IANA source timezone (all four are null for Planned bids that have no dates yet), buyer organization, whether document fees apply, bid type and the detail page URL (pass it unchanged to get_bid_details). One request per call. Pagination is caller-controlled via page (1-based, default 1) and page_size (10, 25 or 50; default 25); total, total_pages and has_more come from the site's result count. Default status filter is Open (matching the site); pass All to search every status, or a comma-separated list of statuses. The keyword search matches bid name/reference number and organization name. publish_from/publish_to are inclusive ISO dates. Default ordering is closing date descending. A filter combination with no matches returns an empty bids array with total 0.
| Param | Type | Description |
|---|---|---|
| page | integer | 1-based page number. |
| sort | string | Column to sort by. |
| query | string | Free-text keyword matched against bid name/reference number and organization name. Omitted = no keyword filter. |
| status | string | Bid status filter. A single status, or several comma-separated (e.g. Open,Closed). All = every status. |
| bid_type | string | Bid type filter. Omitted = all bid types. |
| direction | string | Sort direction. |
| page_size | integer | Results per page; the site accepts exactly 10, 25 or 50 and other values are rejected. |
| publish_to | string | Latest published date, inclusive, ISO date YYYY-MM-DD. |
| publish_from | string | Earliest published date, inclusive, ISO date YYYY-MM-DD. |
| organization_id | string | Numeric buyer organization id as produced by list_organizations.organizations[*].organization_id. Omitted = all organizations. |
{
"type": "object",
"fields": {
"bids": "array of bid summaries: name (reference number - title), status, published_date_utc / closing_date_utc (ISO UTC timestamps, null for Planned bids), published_date_timezone / closing_date_timezone (buyer's IANA source timezone, null when the date is null), organization, document_fees (boolean, true when document fees apply), bid_type (Public or Prequalification), detail_url (bid detail page URL for get_bid_details)",
"page": "integer 1-based page returned",
"total": "integer total number of matching bids reported by the site",
"has_more": "boolean, true when a later page exists",
"page_size": "integer page size used",
"total_pages": "integer number of pages at this page_size"
},
"sample": {
"data": {
"bids": [
{
"name": "RFSQRF2026046 - Miscellaneous Fleet Services",
"status": "Open",
"bid_type": "Public",
"detail_url": "https://stjohns.bidsandtenders.ca/Module/Tenders/en/Tender/Detail/be187537-9564-49eb-a347-d94554fea702",
"organization": "City of St. John's",
"document_fees": false,
"closing_date_utc": "2036-05-30T02:30:00.0000000Z",
"published_date_utc": "2026-05-26T11:30:00.0000000Z",
"closing_date_timezone": "America/St_Johns",
"published_date_timezone": "America/St_Johns"
}
],
"page": 1,
"total": 1,
"has_more": false,
"page_size": 25,
"total_pages": 1
},
"status": "success"
}
}About the Bidsandtenders API
Searching Bid Opportunities
The search_bids endpoint accepts up to eight input parameters to filter and sort the public tender listing. query matches against bid name, reference number, and organization name. status accepts a single value or comma-separated values such as Open,Closed, or All to bypass the filter entirely. page_size must be exactly 10, 25, or 50 — other values are rejected by the source. Each bid in the response carries a name (formatted as reference number – title), status, published_date_utc, closing_date_utc, and the buyer's IANA source_timezone. Planned bids that have no scheduled dates return null for all four date fields. The response also includes total, total_pages, page, and has_more to support full pagination.
Listing Organizations
list_organizations takes no parameters and returns every buyer organization available in the listing's filter dropdown, each with a string organization_id and display name, ordered alphabetically. Pass organization_id values into search_bids to scope results to a specific buyer. The total field confirms how many organizations are returned.
Bid Detail Extraction
get_bid_details accepts a detail_url exactly as returned in search_bids results and returns the full public record for that bid. Structured fields include bid_number, bid_name, bid_status, bid_type, categories (nested as Parent > Child strings), and a details object containing every labelled row from the detail table — including date fields like Question Deadline that do not appear in search results. The documents and addenda arrays each carry document_id, name, pages, and created. The meetings array includes location, description, start, end, mandatory, and timezone per entry. description is returned as both plain text and HTML.
The Bidsandtenders API is a managed, monitored endpoint for opportunities.bidsandtenders.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when opportunities.bidsandtenders.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official opportunities.bidsandtenders.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Monitor new Open tenders from a specific government buyer using
search_bidswithorganization_idandstatus=Open. - Build a daily digest of recently published bids by filtering
search_bidswithpublish_toand sorting by publish date. - Extract Question Deadlines and closing dates from
get_bid_detailsto populate a procurement calendar. - Track mandatory pre-bid meetings by parsing the
meetingsarray returned fromget_bid_details. - Enumerate all buyer organizations via
list_organizationsto build a filterable procurement directory. - Identify bid documents and addenda for a specific tender by reviewing the
documentsandaddendaarrays inget_bid_details. - Filter tenders by
bid_type(e.g. Request For Quotations) to surface only the procurement categories relevant to a supplier.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Bids & Tenders have an official developer API?+
What does `get_bid_details` return that `search_bids` does not?+
get_bid_details returns the full bid description (plain text and HTML), the labelled details table including fields like Question Deadline, the meetings array with mandatory-meeting flags, and the documents and addenda arrays. search_bids returns only the summary fields — name, status, published and closing dates, and a detail_url — needed to identify and paginate bids.Is there a quirk to be aware of with `page_size` in `search_bids`?+
page_size. Supplying any other integer will result in a rejected request. Plan pagination logic around those three accepted values.Can I retrieve the actual content of bid documents or addenda through this API?+
document_id, name, pages, and created — but does not download or return file content. You can fork this API on Parse and revise it to add an endpoint that fetches individual document files using the document identifiers already returned.