Scoutee

Busca más de 200,000 licitaciones públicas (RFPs, contratos gubernamentales) de 87 fuentes oficiales en 32 países de Europa y Norteamérica.

Documentación

Encuentra licitaciones que se ajusten a tu sector. Fuentes oficiales, filtros de palabras clave y CPV, y alertas diarias en Scoutee.

Encuentra licitaciones que se ajusten a tu sector desde tu script de monitoreo, CRM o panel interno. Scoutee reúne fuentes oficiales en una sola búsqueda. Refina los resultados con palabras clave, presupuesto y filtros opcionales de CPV para contratación pública de la UE, y luego lee los anuncios completos.

Obtén tus códigos CPV, encontrados para ti. Inicia sesión en Scoutee gratis: nuestra IA compara la actividad de tu empresa con nuestra base de conocimientos para identificar códigos relevantes automáticamente. Comienza con un nombre o identificador de empresa, sitio web o descripción de actividad en el buscador gratuito de CPV con IA, revisa tus sugerencias y luego úsalas en la API o en el MCP del espacio de trabajo.

URL base: https://scoutee.org/api

Las respuestas son JSON en UTF-8 (application/json), excepto la descarga opcional de CSV del catálogo. Las fechas están en ISO 8601 (2026-09-05T14:30:00Z).

Alertas diarias por correo electrónico

Crea una cuenta y guarda tu búsqueda en Scoutee. Su alerta diaria por correo se activa automáticamente cuando se establecen criterios y hay un espacio de alerta disponible; puedes desactivarla. Tu cuenta gratuita incluye 1 alerta de búsqueda activa en todos tus espacios de trabajo, solo cuando nuevas licitaciones coinciden, con hasta 20 resultados por búsqueda. El correo muestra un avance de 3 licitaciones; abrir la búsqueda mantiene la asignación gratuita de 20 búsquedas por hora y 1 página(s) de 20 resultados. Los planes de pago admiten alertas para múltiples búsquedas.

Si le pides a tu asistente que te notifique por correo, puede guiarte al registro y a tu búsqueda guardada en Scoutee. La gestión de suscripciones requiere tu sesión de Scoutee; las herramientas MCP actuales y los endpoints REST de licitaciones con OAuth no pueden crear suscripciones ni programar correos. GET /api/public/plans publica la asignación de email_alerts por plan, junto con las cuotas de búsqueda.

CPV para contratación pública de la UE

CPV significa Vocabulario Común de Contratación Pública, el estándar común de contratación pública en toda la UE. Es una forma opcional de hacer coincidir anuncios por actividad. La elegibilidad del mercado sigue la jurisdicción de contratación de la fuente, no el idioma de la interfaz; CPV no reemplaza las clasificaciones de EE. UU. o Canadá.

La búsqueda de licitaciones autenticada acepta hasta 50 valores de cpv, con o sin su dígito de verificación verificado. Un código seleccionado también coincide con sus descendientes oficiales. Los códigos CPV y los valores de keyword se combinan con OR; el país, el presupuesto y otros filtros aún se aplican. Los cpv_codes publicados por el comprador permanecen separados de los cpv_inferred_codes de Scoutee, que se usan para la coincidencia solo cuando el anuncio no tiene un CPV publicado reconocido.

curl -s -G "https://scoutee.org/api/tenders" \
  -H "Authorization: Bearer $SCOUTEE_ACCESS_TOKEN" \
  --data-urlencode "cpv=90911200-8" \
  --data-urlencode "country=France"

API pública del catálogo CPV

Estos endpoints de solo lectura no necesitan cuenta ni credencial. Proporcionan consulta del catálogo, no descubrimiento de empresas con IA; usa el buscador con IA iniciando sesión para sugerencias personalizadas.

EndpointPropósito
GET /public/classifications/cpvBuscar etiquetas/códigos con q, resolver valores exactos repetidos de code, o navegar por un código de parent.
GET /public/classifications/cpv/catalogueDescargar el catálogo completo como format=json (predeterminado) o format=csv.

Pasa locale=fr, en u otro idioma de etiqueta compatible. La búsqueda exacta de code tiene prioridad sobre parent, luego q. q acepta hasta 100 caracteres y devuelve hasta 50 coincidencias; la búsqueda exacta acepta hasta 50 códigos. Los valores exactos desconocidos o inválidos de code se omiten de items. Un parent desconocido devuelve 422; los sistemas de clasificación no compatibles devuelven 404.

La consulta devuelve system, items, total_codes y catalogue. Cada elemento incluye code, display_code, label, parent, retired y replaced_by. total_codes es el tamaño completo del catálogo. Los metadatos del catálogo incluyen la instantánea version, el nomenclature_version oficial, sha256 y la procedencia de la fuente. Conserva la versión al almacenar etiquetas para que los códigos históricos puedan identificarse. La descarga JSON incluye esos metadatos; el CSV contiene las filas de códigos.

curl -s "https://scoutee.org/api/public/classifications/cpv?q=90911200-8&locale=en"
curl -s "https://scoutee.org/api/public/classifications/cpv/catalogue?locale=en&format=csv"

También puedes navegar por el catálogo en Scoutee.

Claves de API

Una clave pertenece a un espacio de trabajo, no a una persona: sobrevive a quien la creó, y los administradores del espacio de trabajo pueden revocarla en cualquier momento.

Una clave solo puede crearse, y solo funciona, mientras el espacio de trabajo esté en un plan de pago — Pro o Team (un espacio de trabajo de pago heredado mantiene los límites de Pro y Team respectivamente). Si el espacio de trabajo vuelve al plan gratuito, las claves existentes permanecen listadas pero las llamadas responden 403.

Para crear una clave, abre tu espacio de trabajo desde el menú superior, selecciona su pestaña API y luego haz clic en "Crear una clave". El valor completo se muestra una sola vez, en la creación. Scoutee solo almacena su resumen SHA-256 y no puede mostrártelo de nuevo; si la pierdes, revoca la clave y crea otra.

Formato de clave: sct_ seguido de 40 caracteres hexadecimales. Los primeros 12 caracteres (el prefijo, por ejemplo sct_1a2b3c4d) se muestran en la lista de claves para que puedas reconocer una clave.

Un espacio de trabajo puede tener como máximo 10 claves activas. Más allá de eso, la creación responde 409: revoca una clave antes de crear otra.

Autenticación

Conéctate mediante OAuth en cualquier plan, incluido Free, con el alcance tenders.read. Envía el token de acceso como Authorization: Bearer $SCOUTEE_ACCESS_TOKEN. El descubrimiento de OAuth está disponible en https://scoutee.org/.well-known/oauth-authorization-server. El token otorga acceso al espacio de trabajo seleccionado; su plan actual y membresía se verifican en cada llamada. Revocar la conexión detiene el acceso de inmediato.

Para scripts, una clave de API de espacio de trabajo en un plan de pago funciona en X-API-Key: $SCOUTEE_API_KEY. Ambas credenciales están restringidas a buscar y leer licitaciones. No otorgan acceso a facturación, memoria de empresa ni ejecución de análisis. Mantén las credenciales en el almacén de secretos de tu cliente.

Cuotas

Cada búsqueda autenticada consume una unidad. Leer un anuncio individual no se mide. OAuth comparte un depósito por espacio de trabajo; cada clave de API tiene un depósito. REST y MCP comparten el depósito de esa credencial.

PlanBúsquedas/horaRáfaga/minutoResultados/páginaMáx. páginaOAuthClave API
free2020201SíNo
pro100105020SíSí
team3003010050SíSí

Standard hereda los límites de Pro; Premium hereda los límites de Team. Estos son límites de tráfico por proceso de API, no créditos de análisis comprados. Las respuestas incluyen X-Quota-Plan, X-Quota-Limit y X-Quota-Remaining. MCP devuelve quota_plan, quota_limit y quota_remaining. Respeta Retry-After en HTTP 429. El tamaño/profundidad de página devuelto puede estar limitado: no asumas que cada anuncio coincidente es accesible.

GET /tenders

Búsqueda paginada. Por defecto: solo licitaciones abiertas, más recientes primero. Un anuncio publicado en varios portales se lista una vez: una fila por anuncio, a través de su portal nacional antes que TED, y las copias en los otros portales se nombran en also_on (nunca ocultas: cada una mantiene su propia fila en GET /tenders/{id}). total cuenta anuncios, no copias.

Parámetros

Todos opcionales, pasados en la cadena de consulta.

ParámetroTipoPredeterminadoDescripción
workspace_identeroningunoIgnorado con una clave de API: la clave ya está vinculada a un espacio de trabajo.
pageentero, mínimo 11Página solicitada. Limitada a 500.
page_sizeentero, 1 a 50050Resultados por página. Limitados a 200.
qcadena, máximo 200 caracteresningunoTexto libre sobre el título, el comprador y la descripción. Cada palabra debe coincidir con el inicio de una palabra en el anuncio (nettoy encuentra nettoyage); una subcadena dentro de una palabra no coincide. Insensible a mayúsculas y acentos.
keywordcadena, repetibleningunoPalabras clave. Coincidencia de palabra completa (plural tolerado), insensible a mayúsculas y acentos, en el título, el comprador o la descripción, más las traducciones en caché de la palabra clave en las fuentes de ese idioma; con un country seleccionado, solo se buscan las traducciones en los idiomas de ese país y en inglés. Varios keyword amplían la búsqueda (cualquiera de ellos).
cpvcadena, repetibleningunoCódigos CPV opcionales: ocho dígitos, con un dígito de verificación verificado opcional. Incluye descendientes en el catálogo oficial. Los códigos y las palabras clave se combinan con OR; otros filtros aún se aplican. Solo las fuentes en jurisdicciones CPV pueden coincidir. Máximo 50 códigos; códigos desconocidos o inválidos devuelven 422.
exclude_termentero, repetibleningunoIdentificadores de términos (traducciones o variantes de una palabra clave) para excluir de la búsqueda.
countrycadena, repetibleningunoPaíses del portal, por su nombre en inglés (France, Germany, United States, Canada; Europe para TED). Varios country se suman. El objeto by_country de cualquier respuesta lista los valores exactos en uso.
sectorcadena de dos dígitos, repetibleningunoSectores, es decir, divisiones CPV 2008: los primeros dos dígitos de un código CPV (45 trabajos de construcción, 72 servicios de TI, 85 salud y trabajo social). Un anuncio coincide cuando pertenece a cualquiera de los sectores dados. Nunca se aplica a menos que se solicite: sin sector, se busca en todos los sectores. Un valor fuera de las 45 divisiones responde 422 con el código invalid_sector. El objeto by_sector de una respuesta lista las divisiones en uso.
min_valuenúmeroningunoValor estimado mínimo, en la moneda del anuncio.
max_valuenúmeroningunoValor estimado máximo.
sortnewest, oldest o deadlinenewestPublicación descendente, publicación ascendente o fecha límite ascendente.
include_closedbooleanofalseIncluir anuncios cerrados.
seen_afterfecha-hora ISO 8601ningunoMantener solo los anuncios recopilados por primera vez después de ese instante. Útil para monitoreo incremental.

| seen_before | ISO 8601 | ninguno | Mantener anuncios recopilados por primera vez en o antes de este instante. Fija este valor mientras paginas una ventana incremental. |

Respuesta

200 OK, un objeto TenderPage:

CampoTipoDescripción
itemsmatriz de TenderLos anuncios de esta página.
totalenteroNúmero total de anuncios que coinciden con los criterios.
pageenteroPágina realmente devuelta.
page_sizeenteroTamaño de página realmente aplicado.
pagesenteroNúmero de páginas accesibles, limitado por el plan.
by_countryobjeto, código de país a enteroAnuncios por país del portal, con todos los demás filtros aplicados pero sin el filtro country. Diseñado para construir una faceta.
by_sectorobjeto, división de dos dígitos a enteroAnuncios por sector, con todos los demás filtros aplicados — country incluido — pero sin el filtro sector. Diseñado para construir una faceta. Un anuncio con varios sectores se cuenta una vez por sector, por lo que los valores no suman total.

Un objeto Tender:

CampoTipoDescripción
identeroIdentificador de Scoutee del aviso.
source_identeroIdentificador del portal del que proviene.
source_namecadena, anulableNombre del portal.
source_countrycadena, anulablePaís del portal, dos letras.
external_idcadenaIdentificador del aviso en el portal.
titlecadenaTítulo de la consulta.
buyercadena, anulableComprador público.
descriptioncadena, anulableObjeto del contrato, tal como se publicó.
urlcadenaPágina del aviso en el portal de origen.
locationcadena, anulableLugar de ejecución.
procedurecadena, anulableTipo de procedimiento, tal como se publicó.
cpv_codesmatriz de cadenasCódigos CPV adjuntos al aviso.
cpv_inferred_codesmatriz de cadenasSugerencias de CPV de Scoutee, separadas de los códigos publicados por el comprador. Se usan solo para la búsqueda cuando no existe un CPV publicado reconocido.
sectorsmatriz de cadenas de dos dígitosSectores (divisiones CPV) del aviso: las divisiones de sus códigos CPV cuando los tiene; de lo contrario, la única división que le asignó nuestro clasificador. Vacía cuando no aplica ninguna.
estimated_valuenúmero, anulableValor estimado.
currencycadena, anulableMoneda de ese valor.
published_atfecha-hora, anulableFecha de publicación.
deadline_atfecha-hora, anulableFecha límite para presentaciones.
first_seen_atfecha-horaPrimera recopilación por Scoutee.
last_seen_atfecha-horaÚltima recopilación.
closed_atfecha-hora, anulableCierre observado. null mientras el aviso está abierto.
favoritebooleanotrue cuando la licitación es un favorito del espacio de trabajo. Los favoritos pertenecen al espacio de trabajo y son compartidos por sus miembros; con una clave de API, el espacio de trabajo de la clave.
also_onmatriz de AlsoOnLas copias del mismo aviso en otros portales, primero los portales nacionales. Una copia en el propio portal de la fila (otro lote bajo el mismo título) nunca es una de ellas.

Un objeto AlsoOn: source_id (entero), source_name (cadena), source_country (cadena, anulable), url (cadena), tender_id (entero, anulable: el aviso propio de ese portal), deadline_at (fecha-hora, anulable: la fecha límite de ese portal, que puede diferir de la de la fila).

Ejemplo

curl -s -G "https://scoutee.org/api/tenders" \
  -H "X-API-Key: $SCOUTEE_API_KEY" \
  --data-urlencode "keyword=roadworks" \
  --data-urlencode "keyword=signage" \
  --data-urlencode "country=France" \
  --data-urlencode "sort=deadline" \
  --data-urlencode "page_size=50"
{
  "items": [
    {
      "id": 918233,
      "source_id": 12,
      "source_name": "PLACE",
      "source_country": "FR",
      "external_id": "25-114287",
      "title": "Travaux de voirie et de signalisation horizontale",
      "buyer": "Communauté de communes du Val de Loire",
      "description": "Marché à bons de commande pour la réfection de voirie...",
      "url": "https://www.marches-publics.gouv.fr/?page=Entreprise.EntrepriseAdvancedSearch&id=25-114287",
      "location": "Loiret",
      "procedure": "Procédure adaptée",
      "cpv_codes": ["45233220", "45233221"],
      "sectors": ["45"],
      "estimated_value": 420000.0,
      "currency": "EUR",
      "published_at": "2026-09-01T08:00:00Z",
      "deadline_at": "2026-10-03T12:00:00Z",
      "first_seen_at": "2026-09-01T09:12:44Z",
      "last_seen_at": "2026-09-05T06:03:11Z",
      "closed_at": null,
      "favorite": false,
      "also_on": []
    }
  ],
  "total": 137,
  "page": 1,
  "page_size": 50,
  "pages": 3,
  "by_country": { "France": 137, "Belgium": 12 },
  "by_sector": { "45": 96, "71": 28, "50": 13 }
}

Los avisos se devuelven en el idioma en que se publicaron: la API no los traduce.

En Python, con requests:

import os
import requests

BASE = "https://scoutee.org/api"
HEADERS = {"X-API-Key": os.environ["SCOUTEE_API_KEY"]}

response = requests.get(
    f"{BASE}/tenders",
    headers=HEADERS,
    params={
        "keyword": ["roadworks", "signage"],
        "country": ["France"],
        "sort": "deadline",
        "page_size": 50,
    },
    timeout=30,
)
response.raise_for_status()
page = response.json()

print(page["total"], "notices", "|", response.headers["X-Quota-Remaining"], "searches left")
for tender in page["items"]:
    print(tender["id"], tender["deadline_at"], tender["title"])

Recorriendo cada página:

def iter_tenders(**params):
    """Every page of a search, in the requested order."""
    page = 1
    while True:
        response = requests.get(
            f"{BASE}/tenders",
            headers=HEADERS,
            params={**params, "page": page, "page_size": 200},
            timeout=30,
        )
        response.raise_for_status()
        body = response.json()
        yield from body["items"]
        if page >= body["pages"]:
            return
        page += 1

Para un monitoreo incremental, conserve la marca de tiempo de su última ejecución y pásela de nuevo como seen_after: solo se devuelven los avisos descubiertos desde entonces.

GET /tenders/{id}

Un aviso, enriquecido como un resultado de búsqueda. No consume cuota.

curl -s "https://scoutee.org/api/tenders/918233" \
  -H "X-API-Key: $SCOUTEE_API_KEY"

La respuesta es un objeto Tender, idéntico a los de items. Si el identificador solicitado apunta a la copia de un aviso publicado en varios portales, se devuelve la copia canónica. Un identificador desconocido responde con 404.

Servidor MCP

Las mismas dos operaciones se exponen como un servidor MCP en https://scoutee.org/api/mcp, con el mismo token OAuth o clave de espacio de trabajo, los mismos parámetros y las mismas cuotas, de modo que Claude Code, Cursor, VS Code, Windsurf o cualquier cliente del protocolo pueda buscar licitaciones en su nombre. La configuración, las herramientas y los ejemplos están en la página del servidor MCP.

Errores

Un cuerpo de error siempre es {"detail": "..."}, y el mensaje siempre está en inglés, sea cual sea el idioma de su integración: el inglés es el idioma de trabajo de la API. Cada error que un usuario puede encontrar también lleva un código estable en el encabezado de respuesta X-Error-Code, de modo que su integración pueda ramificar según el código y escribir su propio mensaje en lugar de coincidir con el texto.

CódigoX-Error-CodeCasodetail
401—Sin credenciales en un endpoint de licitaciones (los endpoints de catálogo son públicos)Login required
401invalid_api_keyClave desconocida o revocadaInvalid API key
402plan_requiredCrear o revocar una clave en un espacio de trabajo sin un plan de pagoThis feature requires a paid plan
403api_key_disabledEl espacio de trabajo de la clave no tiene un plan de pago (lo dejó, o nunca lo tuvo)API key disabled: this workspace is not on a paid plan
403api_key_scopeUna ruta protegida fuera de la búsqueda y el detalle de licitacionesThis key only grants access to the tender search
404—Identificador de aviso desconocidoTender not found
429quota_exceededCuota horaria agotadaYou have reached the limit of 100 searches per hour of your plan. Try again in 12 min.
429search_burstDemasiadas solicitudes en un minutoToo many searches at once, try again in a minute

Una respuesta quota_exceeded repite sus números en X-Error-Limit (búsquedas por hora) y X-Error-Minutes (la espera), de modo que un mensaje pueda reconstruirse en cualquier idioma.

Un 429 lleva un encabezado Retry-After, en segundos. Respételo en lugar de reintentar de inmediato:

import time

def search(**params):
    """One search, waiting out the per-minute quota when it is hit."""
    for _ in range(3):
        response = requests.get(f"{BASE}/tenders", headers=HEADERS, params=params, timeout=30)
        if response.status_code != 429:
            response.raise_for_status()
            return response.json()
        time.sleep(int(response.headers.get("Retry-After", "60")))
    raise RuntimeError("quota still exhausted after three attempts")

402 y 403 no se solucionan reintentando: revise el plan del espacio de trabajo, o cree una nueva clave si la suya fue revocada.

A través de MCP, los mismos fallos vuelven como errores de herramienta con los mismos mensajes, en lugar de como códigos de estado HTTP.

Recursos