Bidsandtenders APIopportunities.bidsandtenders.com ↗
Search public bid opportunities on Bids & Tenders by keyword, status, org, and date. Retrieve full bid details, documents, and direct download links via 4 endpoints.
What is the Bidsandtenders API?
The Bids & Tenders Opportunities API exposes 4 endpoints covering public procurement listings on opportunities.bidsandtenders.com. The search_bids endpoint lets you filter active tenders by keyword, status, organization, bid type, and publish date with pagination returning up to 50 results per page. Companion endpoints retrieve the full organization filter list, bid detail pages with descriptions, key dates, meetings, categories, and documents, plus direct download URLs for bid documents and addenda.
curl -X GET 'https://api.parse.bot/scraper/ed96455f-4c22-4e61-acc1-f77b45aec981/search_bids?query=Services&status=Open' \ -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 and documents."""
from parse_apis.opportunities_bidsandtenders_com_api import (
BidsAndTenders, BidStatus, SortField, SortDirection, InputNotFound,
)
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)
# Resolve the first document's downloadable file metadata.
if bid.documents:
bid_doc = bid.get_document(document_id=bid.documents[0].document_id)
print(" download:", bid_doc.file_name, bid_doc.size_bytes, "bytes")
print(" url:", bid_doc.download_url)
# Point-lookup by URL when the detail_url is already known.
if hit is not None:
try:
detail = client.bids.get(detail_url=hit.detail_url)
print(detail.bid_name, detail.bid_status)
except InputNotFound:
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 / get_document / 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 and get_bid_document). 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
Search and Filter Bid Opportunities
The search_bids endpoint is the primary entry point. It accepts query for free-text keyword matching against bid names and organization names, a status parameter that accepts a single value or comma-separated list (e.g. Open,Closed), bid_type, organization_id, and publish-date range via publish_from and publish_to (ISO date format). Pagination is controlled via page and page_size; note that page_size must be exactly 10, 25, or 50 — other values are rejected. Each bid in the response includes a name (reference number and title), status, published_date_utc, closing_date_utc (both as ISO UTC timestamps, null for Planned bids with no dates yet), and a detail_url for fetching full bid details.
Organization Lookup and Bid Details
The list_organizations endpoint takes no parameters and returns the complete list of buyer organizations with their numeric organization_id and display name. Pass the organization_id directly into search_bids to narrow results to a single buyer. Once you have a detail_url from search results, get_bid_details returns the full detail page: bid_number, bid_name, bid_status, bid_type, a free-text and HTML description, a details object mapping every labelled table row (including deadline fields like Question Deadline) to its text value, categories as Parent > Child strings, meetings with location, start/end times, mandatory flag, and timezone, plus documents and addenda arrays each containing document_id, name, pages, and created.
Document Resolution
The get_bid_document endpoint takes a detail_url and a document_id from get_bid_details.documents or get_bid_details.addenda and resolves it to the publicly accessible preview file. The response includes download_url (a direct fetchable link requiring no authentication), file_name, file_extension, content_type (e.g. application/pdf), and size_bytes. The access field is always public_preview, indicating this is the unauthenticated copy of the document.
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 newly published tenders for specific keywords or categories to alert sales teams to relevant opportunities
- Aggregate open bids from multiple buyer organizations by iterating
list_organizationsand filteringsearch_bidsbyorganization_id - Track bid status changes over time by polling
search_bidswith a date range and comparingstatusfields - Build a procurement dashboard that surfaces closing deadlines using
closing_date_utcfrom search results - Download bid documents and addenda programmatically using
get_bid_documentto feed into document analysis pipelines - Extract meeting details from
get_bid_details.meetingsto calendar mandatory pre-bid meetings - Compile category-level procurement spend reports using the
categoriesfield fromget_bid_details
| 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 beyond what `search_bids` includes?+
search_bids returns a summary per bid: name, status, published and closing UTC timestamps, and a detail_url. get_bid_details adds the full HTML and plain-text description, every row of the detail table (including Question Deadline and other key dates), meeting entries with mandatory flags and timezones, document and addendum lists with document_id values for resolution, and categories in Parent > Child format.Are there any quirks with the page_size parameter in `search_bids`?+
page_size parameter only accepts exactly 10, 25, or 50. Any other integer value will be rejected. If you need to retrieve all results across multiple pages, use one of these fixed values and iterate via the page parameter, checking has_more or comparing page against total_pages.Can the API return full document content or only metadata and a download link?+
get_bid_document endpoint resolves a document to its file metadata — file_name, content_type, size_bytes, and a direct download_url — but does not return the file content inline in the API response. Full-text extraction or parsing of the document itself is not covered. You can fork this API on Parse and revise it to add an endpoint that fetches the file and extracts its text content.