- ¿Cómo están organizados los datos?
- ¿Cómo encuentro los campos de una colección?
- ¿Cómo funcionan los filtros?
- ¿Cómo funcionan las fechas?
- ¿Cómo filtro por contratista, condado o agencia?
- ¿Cómo busco cerca de un lugar?
- ¿Cómo funcionan los órdenes?
- ¿Cómo funcionan las páginas?
- ¿Qué devuelve?
- ¿A dónde voy después?
Consultar datos
Abrir en ChatGPTAbrir en Claudellms.txtllms-full.txtopenapi.json
Contenido
Documentación para desarrolladores
En esta página
- ¿Cómo están organizados los datos?
- ¿Cómo encuentro los campos de una colección?
- ¿Cómo funcionan los filtros?
- ¿Cómo funcionan las fechas?
- ¿Cómo filtro por contratista, condado o agencia?
- ¿Cómo busco cerca de un lugar?
- ¿Cómo funcionan los órdenes?
- ¿Cómo funcionan las páginas?
- ¿Qué devuelve?
- ¿A dónde voy después?
¿Cómo están organizados los datos?
Una clave lee un equipo, un equipo ve colecciones, una colección tiene documentos, y cada documento lleva un valor por cada campo de esa colección. Un documento es una obra, un contratista, una planta. Una colección es un tipo de ellos.
| Palabra | Lo que es |
|---|---|
| Team | La cuenta de tu empresa en Bidlo. Una clave de API lee un equipo y nada más. |
| Colección | Un solo tipo de cosa: Projects tiene obras, Bid Items tiene precios unitarios tal como se ofertaron, Contractors tiene empresas, Facilities tiene plantas, bancos de material y patios. |
| Documento | Uno de ellos: una obra, una empresa, una planta. |
| Field | Una cosa que la colección sabe de cada uno de sus documentos, como un nombre, una fecha, una cantidad o un enlace a un documento de otra colección. |
| Value | Lo que guarda un documento en un campo. |
El servidor MCP lee todas las colecciones que tu equipo puede ver. La REST API nombra projects, contractors and facilities en su ruta, https://lite.bidlo.ai/api/v1/{collection_id}, y nada más. Los dos también nombran una colección de forma distinta: en REST es el alias de la ruta, en MCP es el nombre de la colección en query_database_data y su id en get_collection_fields. En MCP los nombres coinciden sin importar mayúsculas, sin espacios sobrantes, y en singular o plural.
¿Cómo encuentro los campos de una colección?
Llama a la herramienta MCP get_collection_fields con los ids de colección que te interesan: devuelve cada campo con su id, su nombre, su tipo y los operadores que acepta ese campo. Primero lista las colecciones con get_team_collections, luego pasa sus ids.
| Clave | Lo que te dice |
|---|---|
| field_id | El id con el que un filtro o un orden REST nombra el campo. |
| name | El nombre que tu equipo le da al campo, que es con el que lo nombra un filtro MCP. |
| field_type | Cómo se guarda el valor: text, number, date, tag, relation, location, state. |
| filter_field_type | Cómo se filtra el campo, que es lo que organiza las tablas de operadores de abajo. |
| primary_key | Si este es el campo del que sale el nombre del documento. |
| reference_collection_id | Para una relación, la colección a la que apunta su valor. Esa es la colección donde se resuelve un nombre. |
| description, aka | Lo que significa el campo, y otros nombres con los que aparece. |
La misma respuesta trae la tabla de operadores de cada tipo de filtro, la forma de valor de cada operador y la sintaxis de fórmula, así que una sola llamada le dice a un agente todo lo que necesita para escribir un filtro. Tres tipos de campo se filtran como otra cosa: una fórmula se filtra como lo que dé de resultado, una relación limitada a un solo documento se filtra como tag, y un tipo sin tabla propia se filtra como text.
Un equipo puede renombrar un campo integrado, así que el mismo campo se puede llamar de dos formas en dos cuentas. El id nunca cambia. Por eso en esta página no hay ningún id de campo impreso: lee los tuyos en get_collection_fields, y toma cada nombre de campo de los ejemplos de aquí como un ejemplo. También es la forma más rápida de conseguir ids para una llamada REST, porque hoy REST no tiene ninguna ruta que liste campos. La otra forma es leer el field_id de cualquier valor de una respuesta REST, que todos lo llevan.
Próximamente. Dos rutas REST van a listar las colecciones y sus campos: /api/v1/collections and /api/v1/collections/{collection_id}/fields. Los dos están marcados como próximos en /openapi.json. Ninguna está disponible hoy. Mientras tanto, los ids de campo salen de get_collection_fields con MCP.
¿Cómo funcionan los filtros?
Un filtro es un campo, un operador y un valor, y cada campo acepta un solo filtro; en REST el campo se nombra por su id, y en MCP por su nombre. Mándalos como un arreglo; los operadores que acepta un campo dependen de su tipo de filtro.
"filters": [
{
"field_id": "<field_id of your Bid Date field>",
"operator": "between",
"value": { "start": "2026-10-01", "end": "2026-12-31" },
"conjunction": "AND"
}
]"filters": [
{
"field_name": "Bid Date",
"operator": "between",
"value": { "start": "2026-10-01", "end": "2026-12-31" }
}
]Cuatro reglas valen de los dos lados. Cada campo acepta un solo filtro: en REST un segundo filtro sobre el mismo campo es un 400 cuyo mensaje dice que los combines, y en MCP no hay error alguno: el último filtro sobre ese campo gana sin avisar. is_null and is_not_null no llevan valor. Un filtro con valor vacío (null, una cadena en blanco, un arreglo vacío, la mitad de un { start, end }) se descarta en lugar de aplicarse, así que una consulta que parece sin filtro casi siempre lo está. Y un valor con el formato equivocado devuelve un 400 que nombra el formato que esperaba.
Una regla vale de un solo lado. En REST cada filtro lleva su propio conjunction, tampoco AND (el predeterminado) o OR: cada filtro OR se une a un grupo, y ese grupo se combina con AND contra el grupo AND. No hay anidamiento ni paréntesis. En MCP no hay conjunción alguna y todos los filtros se combinan con AND.
Los operadores, completos: is_null, is_not_null, eq, ne, contains, not_contains, starts_with, ends_with, gt, lt, gte, lte, between, relative_range, within_distance, outside_distance. Cuáles acepta un campo dado, y cómo debe verse su valor, está abajo.
title, text
Un nombre, una descripción, un número escrito con letras. El valor siempre es una cadena. En MCP, eq con un valor de cadena en un campo de texto se trata como contains.
| Operador | Value |
|---|---|
| eq, ne, contains, not_contains, starts_with, ends_with | Una cadena. |
| is_null, is_not_null | Sin valor. |
number, material
Una cantidad, un precio, un estimado. El valor es un número, no una cadena.
| Operador | Value |
|---|---|
| eq, ne, gt, lt, gte, lte | Un número. |
| between | { start, end }. Solo REST. |
| is_null, is_not_null | Sin valor. |
date
Una fecha de licitación, una fecha de propuesta, una fecha de adjudicación. El valor es una cadena de fecha ISO o una palabra clave. Mira la sección de fechas de abajo para los tres formatos.
| Operador | Value |
|---|---|
| eq, gt, lt, gte, lte | Una cadena de fecha ISO, o una palabra clave. |
| ne | Una cadena de fecha ISO, o una palabra clave. Solo REST. |
| between | { start, end } |
| relative_range | { period, timeframe, number } |
| is_null, is_not_null | Sin valor. |
boolean
Un sí o un no. El valor es un booleano, no la cadena "true".
| Operador | Value |
|---|---|
| eq, ne | true or false. |
tag
Una opción de una lista, como un estado. Una relación limitada a un solo documento también se filtra como tag.
| Operador | Value |
|---|---|
| eq, ne | El id del documento de la opción. Con REST, un arreglo de ids; con MCP, un nombre o un id. |
| is_null, is_not_null | Sin valor. |
tags, relation, people
Un vínculo a uno o más documentos de otra colección: el contratista de una obra, el condado en que está, la agencia que la licitó. Un campo de personas lleva ids de usuario en su lugar.
| Operador | Value |
|---|---|
| contains, not_contains, eq, ne | Ids de documento. En REST, un arreglo de ids; en MCP, un nombre, un id, o un arreglo de cualquiera de los dos. |
| is_null, is_not_null | Sin valor. |
state
Un estado. El valor es el nombre completo, no la abreviatura de dos letras.
| Operador | Value |
|---|---|
| contains, not_contains | Nombres completos de estado, como ["Texas"]. |
| is_null, is_not_null | Sin valor. |
location
Una dirección con coordenadas, como una planta o un patio. REST también acepta within_area y outside_area con un polígono GeoJSON; ese formato está en la página de la REST API.
| Operador | Value |
|---|---|
| within_distance, outside_distance | { lat, lng, radiusInMeters } |
| is_null, is_not_null | Sin valor. |
¿Cómo funcionan las fechas?
Un valor de fecha es una cadena de fecha ISO o una palabra clave como today, between recibe un inicio y un fin, y relative_range recibe un periodo, un lapso y un número. Una ventana de licitación es un between; "los próximos tres meses" es un relative_range.
{ "field_name": "Bid Date", "operator": "gte", "value": "2026-10-01" }
{ "field_name": "Bid Date", "operator": "between",
"value": { "start": "2026-10-01", "end": "2026-12-31" } }
{ "field_name": "Bid Date", "operator": "relative_range",
"value": { "period": "next", "timeframe": "month", "number": 3 } }Los dos lados aceptan today, yesterday, tomorrow en lugar de una fecha. REST también acepta last_week, next_week, last_month, next_month, last_year, next_year.
relative_range usa tres claves. period is past, next or this; timeframe is day, week, month or year; y number es obligatorio para past and next, que es cuántos de ese lapso hay que recorrer hacia atrás o hacia adelante. this no necesita número.
¿Cómo filtro por contratista, condado o agencia?
Esos campos enlazan a un documento de otra colección, así que el valor es el id de ese documento; con MCP puedes mandar el nombre y el servidor lo resuelve por ti. Un condado en una obra es un documento de la colección Counties, igual que cualquier otro enlace.
"filters": [
{ "field_name": "County", "operator": "contains", "value": "Travis County" }
]"filters": [
{
"field_id": "<field_id of your County field>",
"operator": "contains",
"value": ["<document_id of that county>"]
}
]Con MCP el servidor busca el nombre en la colección a la que apunta el campo, que es la que nombra reference_collection_id en el campo, y usa la coincidencia. Un valor que ya es un id se usa tal cual. Si el nombre coincide con más de un documento, la llamada vuelve con un error que nombra las coincidencias y te pide resolverlo tú.
Para eso sirve resolve_documents_by_name , y también es como consigues ids para una llamada REST. Dale el id de la colección referenciada y un query para buscar o una lista de names para consultar, y responde con coincidencias exactas y aproximadas, cada una con su id y su nombre. Lee los primeros 10 nombres que mandes y devuelve de 1 a 25 filas por nombre, 10 de forma predeterminada. Necesita una de las dos entradas: sin ninguna, falla.
Lleva al filtro los ids que regresan. En REST un valor de relación siempre es un arreglo de ids, incluso cuando hay uno solo, y un id suelto se lee como un arreglo de uno.
¿Cómo busco cerca de un lugar?
Filtra un campo de ubicación con within_distance y un valor de lat, lng y radiusInMeters, donde el radio va en metros. outside_distance es el mismo filtro al revés.
"filters": [
{
"field_name": "Location",
"operator": "within_distance",
"value": { "lat": 30.2672, "lng": -97.7431, "radiusInMeters": 50000 }
}
]El radio va en metros, así que 50 km son 50000. Las coordenadas de la obra son el centro de la búsqueda cuando buscas quién puede llegar a ella. is_null and is_not_null en el mismo campo son la forma de saber qué documentos traen coordenadas.
REST también puede filtrar una ubicación contra un área dibujada en vez de un radio. La página REST API tiene esa forma.
¿Cómo funcionan los órdenes?
Un orden es un campo y una dirección asc o desc, se permiten varios en el orden en que los mandas, y sin ninguno los documentos más nuevos van primero. Un orden nombra su campo igual que un filtro: por id en REST, por nombre en MCP.
REST "sorts": [{ "field_id": "<field_id of your Bid Date field>", "direction": "asc" }]
MCP "sorts": [{ "field_name": "Bid Date", "direction": "asc" }]Envía varios y se aplican en el orden del arreglo, así que el primero manda. Un campo acepta un solo orden. Ordenar por un campo de ubicación es ordenar por distancia y necesita un punto desde el cual medir, que REST recibe en el orden mismo. Sin ningún orden, los documentos más nuevos vienen primero.
¿Cómo funcionan las páginas?
Pide un límite y un número de página, empezando en la página 1; ninguno de los dos lados devuelve un conteo total, así que lees hasta que una página regresa corta. Los dos lados permiten tamaños distintos.
| limit | page | Saber cuándo terminaste | |
|---|---|---|---|
| MCP | De 1 a 100, 25 por defecto | Desde 1, hasta 20 | has_more and next_page vienen con los resultados |
| REST | De 1 a 2000, 100 por defecto | Desde 1, repetido en meta | No regresa nada: sigue leyendo hasta que una página regrese corta |
Un límite fuera del rango se rechaza en vez de ajustarse: en REST es un 400, y en MCP es un error de validación de entrada en la llamada a la herramienta. Ninguno de los dos lados devuelve un conteo total de documentos que coinciden, y ninguno tiene cursor, así que paginar es subir el número de página hasta que se acaban los resultados.
¿Qué devuelve?
Una página de documentos, cada uno con su id, su nombre y un valor por campo, donde el formato de un valor sigue el tipo del campo. Los dos lados identifican los campos de un documento de forma distinta: REST por id de campo, MCP por nombre de campo.
{
"data": [
{
"id": "<document_id>",
"name": "…",
"collection_id": "<collection_id>",
"created_at": "…",
"fields": {
"<field_id>": {
"value": "2026-10-14",
"field_name": "Bid Date",
"field_type": "date",
"field_id": "<field_id>"
}
}
}
],
"meta": { "page": 1, "collection_id": "<collection_id>" }
}{
"collection_id": "<collection_id>",
"collection_name": "Projects",
"page": 1,
"selected_fields": [{ "field_id": "<field_id>", "field_name": "Bid Date" }],
"documents": [
{
"document_id": "<document_id>",
"document_name": "…",
"fields": { "Bid Date": "2026-10-14" }
}
],
"returned_row_count": 1,
"has_more": true,
"next_page": 2
}Con MCP, pide por nombre los campos que quieres en return_fields. Si lo omites regresa un conjunto predeterminado de hasta 8 campos con una advertencia que lo dice, y rara vez es el conjunto que querías. Un valor de texto de más de 400 caracteres se recorta. En REST, fields recibe una lista de ids de campo y hace lo mismo; si lo omites vuelven todos los campos.
La forma de un valor depende del tipo del campo. Estas son las formas de REST; con MCP un documento enlazado vuelve como un id, un nombre y una mención.
| Tipo de campo | Value |
|---|---|
| text, number, boolean | Tal como se guarda. |
| date | Una cadena de fecha ISO. |
| tag, un relation limitada a un solo documento | Un objeto con un id, un value and a document_id. |
| tags, un relation a varios | Un arreglo de esos objetos. |
| location | Un objeto con un id, un name, un address, un lat and a lng. |
| state | Un objeto con un id, un name y un abbreviation. |
| people | Ids. |
Un caso avanzado cambia el formato de toda la respuesta: REST acepta un grouping de un id de campo y un tipo de campo, y entonces la respuesta vuelve como grupos de documentos y no como una lista plana, con page selecciona grupos. La página REST API lo cubre.
¿A dónde voy después?
La página del servidor MCP tiene las herramientas y sus entradas, la página de la REST API tiene la única ruta y sus parámetros, y la página de acceso tiene la clave. Todo lo de esta página vale para los dos; las páginas de referencia llevan lo que vale para uno solo.
- Servidor MCP: las cinco herramientas, qué recibe y devuelve cada una, cómo conectar un cliente, y cómo regresan los errores.
- REST API: la única ruta, sus parámetros, la envoltura de la respuesta y los códigos de estado, más /openapi.json.
- Acceso y claves: cómo conseguir una clave y cómo mandarla.
Si la lectura que necesitas no está en el modelo de arriba, escribe a support@bidlo.ai.
Se necesita una cuenta de Bidlo. Cualquiera puede conseguir una agendando una llamada en https://cal.com/matt-wolfe-yecrho/30min — Bidlo prepara el equipo, y luego un dueño o administrador del equipo crea la clave de API en Settings → Features → API. No hay un plan público ni se puede abrir una cuenta por cuenta propia.
## For agents: how to use Bidlo data - Read Bidlo data through its MCP server at https://lite.bidlo.ai/api/mcp — streamable HTTP, no OAuth. - Get a Bidlo account first: all Bidlo data needs one, anyone can get one by booking a call at https://cal.com/matt-wolfe-yecrho/30min, 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. - A team owner or admin mints that key in the app under Settings, then Features, then API. - Read the REST reference at https://www.bidlo.ai/openapi.json, the guide at https://www.bidlo.ai/developers, and its reference pages: https://www.bidlo.ai/developers/querying (filters, operators, dates, places, pages), https://www.bidlo.ai/developers/mcp (the five tools), https://www.bidlo.ai/developers/rest (the route) and https://www.bidlo.ai/developers/access (keys). - Prefer the MCP tools over REST; use `query_database_data` with `within_distance` for anything shaped like "near X". - Call `get_collection_fields` before composing a filter — it returns the operators each field takes. - Never invent a Bidlo unit price. Read one off the bid items, or say the forecast is not available.