Bidlo API docs
Contents
Developer docs
What can I ask it?
Ask in plain words: an agent turns the question into a query and reads back what matches.
“Show me upcoming asphalt jobs in Bexar County.”
MCP tool: documents_query
{
"collection_id": "Project",
"filters": [
{ "field_id": "County", "operator": "contains",
"value": ["<document_id of Bexar County>"] },
{ "field_id": "Bid Date", "operator": "gte", "value": "today" },
{ "field_id": "Type of Work", "operator": "contains",
"value": "asphalt" }
],
"sorts": [{ "field_id": "Bid Date", "direction": "asc" }],
"fields": ["Bid Date"]
}{
"data": [
{
"id": "<document_id>",
"name": "<job name>",
"collection_id": "<collection_id>",
"created_at": "<timestamp>",
"updated_at": "<timestamp>",
"fields": {
"<field_id>": {
"value": "<bid date>",
"field_name": "Bid Date",
"field_type": "date",
"field_id": "<field_id>",
"field_value_id": "<field_value_id>"
}
}
}
],
"meta": {
"page": 1,
"limit": 100,
"collection_id": "<collection_id>",
"next_cursor": null
}
}“Show me a list of qualified striping subs.”
MCP tool: documents_query
{
"collection_id": "Contractor",
"filters": [
{ "field_id": "Primary Trade", "operator": "contains",
"value": ["<document_id of the striping trade>"] },
{ "field_id": "Status", "operator": "contains",
"value": ["<document_id of the Prequalified option>"] }
],
"fields": ["Phone", "Website"]
}{
"data": [
{
"id": "<document_id>",
"name": "<company name>",
"collection_id": "<collection_id>",
"created_at": "<timestamp>",
"updated_at": "<timestamp>",
"fields": {
"<field_id>": {
"value": "<phone>",
"field_name": "Phone",
"field_type": "text",
"field_id": "<field_id>",
"field_value_id": "<field_value_id>"
},
"<field_id>": {
"value": "<website>",
"field_name": "Website",
"field_type": "text",
"field_id": "<field_id>",
"field_value_id": "<field_value_id>"
}
}
}
],
"meta": {
"page": 1,
"limit": 100,
"collection_id": "<collection_id>",
"next_cursor": null
}
}“Which soils within 10 miles of this point have a plasticity index over 35?”
MCP tool: documents_query
{
"collection_id": "Soil Layer",
"filters": [
{ "field_id": "Plasticity Index", "operator": "gt", "value": 35 },
{ "field_id": "Location", "operator": "within_distance",
"value": { "lat": 29.4241, "lng": -98.4936,
"radiusInMeters": 16093 } }
],
"fields": ["Plasticity Index"]
}{
"data": [
{
"id": "<document_id>",
"name": "<soil layer name>",
"collection_id": "<collection_id>",
"created_at": "<timestamp>",
"updated_at": "<timestamp>",
"fields": {
"<field_id>": {
"value": <plasticity index>,
"field_name": "Plasticity Index",
"field_type": "number",
"field_id": "<field_id>",
"field_value_id": "<field_value_id>"
}
}
}
],
"meta": {
"page": 1,
"limit": 100,
"collection_id": "<collection_id>",
"next_cursor": null
}
}“Who’s on the estimating team at Vantel Heavy Civil?”
MCP tool: documents_query
{
"collection_id": "People",
"filters": [
{ "field_id": "Company", "operator": "contains",
"value": ["<document_id of Vantel Heavy Civil>"] },
{ "field_id": "Dept", "operator": "contains",
"value": ["<document_id of the Estimating option>"] }
],
"fields": ["Email", "Phone"]
}{
"data": [
{
"id": "<document_id>",
"name": "<person’s name>",
"collection_id": "<collection_id>",
"created_at": "<timestamp>",
"updated_at": "<timestamp>",
"fields": {
"<field_id>": {
"value": "<email>",
"field_name": "Email",
"field_type": "text",
"field_id": "<field_id>",
"field_value_id": "<field_value_id>"
},
"<field_id>": {
"value": "<phone>",
"field_name": "Phone",
"field_type": "text",
"field_id": "<field_id>",
"field_value_id": "<field_value_id>"
}
}
}
],
"meta": {
"page": 1,
"limit": 100,
"collection_id": "<collection_id>",
"next_cursor": null
}
}“Give me every bid price on item 3076 in the San Antonio district over the last three years.”
MCP tool: documents_query, three calls
1. The jobs
{
"collection_id": "Project",
"filters": [
{ "field_id": "District", "operator": "contains",
"value": ["<document_id of the San Antonio district>"] },
{ "field_id": "Bid Date", "operator": "relative_range",
"value": { "period": "past", "timeframe": "year", "number": 3 } }
]
}
2. Item 3076 on those jobs
{
"collection_id": "Project Items",
"filters": [
{ "field_id": "Project", "operator": "contains",
"value": ["<document_id of each job>"] },
{ "field_id": "Code", "operator": "starts_with", "value": "3076-" }
]
}
3. Every bid on those items
{
"collection_id": "Bid Items",
"filters": [
{ "field_id": "Project Item", "operator": "contains",
"value": ["<document_id of each item>"] }
],
"fields": ["Price", "Quantity"]
}{
"data": [
{
"id": "<document_id>",
"name": "<bid item name>",
"collection_id": "<collection_id>",
"created_at": "<timestamp>",
"updated_at": "<timestamp>",
"fields": {
"<field_id>": {
"value": <unit price>,
"field_name": "Price",
"field_type": "number",
"field_id": "<field_id>",
"field_value_id": "<field_value_id>"
},
"<field_id>": {
"value": <quantity>,
"field_name": "Quantity",
"field_type": "number",
"field_id": "<field_id>",
"field_value_id": "<field_value_id>"
}
}
}
],
"meta": {
"page": 1,
"limit": 100,
"collection_id": "<collection_id>",
"next_cursor": null
}
}What data is in it?
Bidlo holds public heavy civil lettings from the day a job is advertised to the day it is awarded, with the bid sheets, the unit prices as bid, the contractors, the plants and the agencies behind them. Counted on 2026-09-08, the three largest collections held 2,000,000+ bid items, 87,000+ jobs and 4,800+ agencies. Both surfaces reach every collection below and any other your team can see, except the app's own pages, chats and views.
| Category | Collection | What it holds |
|---|---|---|
| Projects | Project | Jobs from advertisement to award: owner, county, letting date, value. |
| Project Items | The bid sheet: code, description, unit, quantity. | |
| Bid Items | Unit prices as bid, item by item, by contractor. | |
| Pre-Bid Q&A | Questions before a letting, with the owner’s answers. | |
| Change Orders | Line items paid on change orders after award. | |
| Scopes | The trades a company works and an item calls for. | |
| Files | Plans, specs, bid sheets and addenda. | |
| Contractors | Contractors | Every company in a market: primes, subs, vendors, suppliers. |
| Facilities | Where those companies operate: plants, pits, yards, offices, with coordinates. | |
| Permits | Permits pulled for the work, by county. | |
| Geology | Soil Area | Mapped soil units: classification, acreage, drainage, slope. |
| Soil Survey | Components of each soil area: profile depth, water depth, obstructions. | |
| Soil Layer | Layers of a soil profile: depth range, texture, plasticity. | |
| Market | Agency | The owners that let work, from state DOTs to cities and districts. |
| Counties | How a market is cut geographically. | |
| Materials | Standard categories that line items up across agencies and spec books. |
And many more. Anything your team attaches to a job, a contractor or a facility reads through the same key.
How does an agent connect?
An agent connects over MCP: Bidlo runs a streamable HTTP server at https://app.bidlo.ai/api/mcp, and a client needs that URL and one Authorization header carrying a Bidlo API key.
Claude Desktop, Claude Code and Cursor all take the config below.
{
"mcpServers": {
"bidlo": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://app.bidlo.ai/api/mcp",
"--header",
"Authorization: Bearer YOUR_API_KEY"
]
}
}
}The tools follow the key: a read-only key sees 12 read tools, and Full access opens all 34. MCP server has every tool and client config. Querying data has the filters and sorts.
Is there a REST API?
Yes: https://app.bidlo.ai/api/v1 reads and writes documents, collections, fields, files and comments, and reads field history, with the same key and permissions the MCP server takes. REST API has the routes and examples. /openapi.json is the same API as an OpenAPI 3.1 spec.
How do I get access?
Bidlo data needs a Bidlo account, and anyone can get one: book a call, Bidlo sets up your team, and a team owner or admin then mints the key under Settings → Features → API. Both surfaces take that one key. Access and keys covers permissions, expiry and revoking a key.
What can I build with it?
Reports, alerts and price checks with a key that reads, and synced job and contractor lists with one that can also edit data.
With a key that reads:
- A county market report. Filter jobs by county and letting date, then total what was let by owner over the last year.
- A letting watch. Read the jobs advertised since the last run and post the new ones where your estimators read them.
- Subs and suppliers near a job. Filter facilities with within_distance on the job's own coordinates to find the plants, pits and yards that can reach it.
- A unit price check before bid day. Pull the bid items on jobs like yours and compare what they went for against the number on your sheet.
With a key that can also edit data:
- Your own bid results. After each letting, push your numbers from your estimating system into your team's own collection, next to the public tabs.
- Job updates. Write status, dates and notes onto your jobs from the system your project managers already use.
- A contractor list kept in sync. Upsert your subs and suppliers on a name or a license number each night. Matches are updated and new ones added; run it dry first.
## For agents: how to use Bidlo data - Read and write Bidlo data through its MCP server at https://app.bidlo.ai/api/mcp — streamable HTTP, no OAuth. - Get a Bidlo account first: all Bidlo data needs one, https://www.bidlo.ai/developers/access.md says how to get one, and there is no public tier or self-serve signup. - Authenticate with the header `Authorization: Bearer sk_live_...`; the REST API takes the same key, and `me` shows what the key may do. - A team owner or admin mints that key in the app under Settings, then Features, then API, and chooses Read only, Read and write data, or Full access; collection and field changes need `schema:write`. - Read the Bidlo API docs at https://www.bidlo.ai/developers.md, the OpenAPI 3.1 spec for the REST API at https://www.bidlo.ai/openapi.json, and the reference pages: https://www.bidlo.ai/developers/querying.md (filters, operators, dates, places, pages), https://www.bidlo.ai/developers/mcp.md (the tools), https://www.bidlo.ai/developers/rest.md (the routes) and https://www.bidlo.ai/developers/access.md (keys). - Prefer the MCP tools over REST; use `documents_query` with `within_distance` for anything shaped like "near X". - Call `fields_list` before composing a filter — it returns each field’s id, name and type. - Never invent a Bidlo unit price. Read one off the bid items, or say the forecast is not available.