Sandbox: entorno de pruebas con tiendas y productos de ejemplo. Los pedidos no llegan a tiendas reales y las claves de aquí (abd_test_…) no funcionan en producción. Ir a producción

Resumen

BridgesAgents reúne productos, precios e inventario de tiendas de cualquier segmento del comercio minorista (supermercado, electrónica, farmacia, moda...) en un formato listo para agentes de IA de compra.

Hay tres formas de consultar el catálogo, todas con la misma clave de agente:

  • MCP, para agentes de IA (Claude, ChatGPT, agentes propios): el agente descubre y llama las tools por sí solo.
  • API REST, para sistemas e integraciones tradicionales.
  • UCP (Universal Commerce Protocol), para agentes que ya hablan ese estándar.

Empieza aquí: crea una cuenta de desarrollador, genera la clave de agente en Claves de agente en el panel y envíala en cada consulta en el header Authorization: Bearer abd_… (detalles en Autenticación).

RecursoURL
Servidor MCP (Streamable HTTP)https://api.sandbox.bridgesagents.com/mcp
API RESThttps://api.sandbox.bridgesagents.com/api/v1
Referencia interactiva (Swagger)https://api.sandbox.bridgesagents.com/swagger-ui.html

Conceptos

ConceptoQué es
ComercioLa empresa (identificada por su CNPJ, el registro fiscal de empresas de Brasil) que vende.
TiendaUnidad física de un comercio, con dirección, coordenadas, cómo atiende (retiro en tienda, entrega por radio o por rangos de CEP, el código postal de Brasil) y horario. El precio y el inventario varían por tienda. El registro lo hace el comercio.
ProductoEl artículo en sí, igual en cualquier tienda: nombre, marca, categoría, GTIN/EAN y unidad. No tiene precio.
OfertaProducto × tienda: precio, precio promocional e inventario. Es lo que el agente compara para decidir dónde comprar.

Detalles que el agente debe tener en cuenta:

  • effectivePrice es el precio a pagar: el promocional cuando existe; si no, el normal.
  • updatedAt indica cuándo se actualizaron el precio y el inventario. stale: true marca una oferta sin actualizar hace más de 7 días (el precio puede haber cambiado); con más de 30 días ya no aparece para los agentes.
  • soldByWeight indica venta por peso (p. ej., frutas y verduras): el precio es por kg y el valor final solo se conoce al preparar el pedido.
  • Unidades (unit): UN (unidad), KG, G, L, ML.
  • requiresPrescription: medicamento que exige receta. El agente no debe concluir la compra; indícale al consumidor que presente la receta en la farmacia.
  • adult: true: producto para mayores de 18 (bebidas alcohólicas, tabaco). BridgesAgents solo lo marca; quien confirma la edad es el agente.
  • inStoreOnly: true: solo se vende en el local (combustible). No entra en el carrito y no tiene retiro ni entrega: muestra el precio, la distancia y mapsUrl (ruta hasta la tienda). Para seguir el precio de la gasolina, busca con radiusKm.
  • storeVerified: la empresa de la tienda tiene CNPJ activo en la Receita Federal (autoridad fiscal de Brasil). storeRating y storeRatingCount: calificación media (1 a 5) y cuántas calificaciones de quienes compraron por BridgesAgents.
  • kind: GOOD (producto físico), FUEL (combustible), SERVICE (servicio), BOOKABLE (viaje, reserva) o DIGITAL (curso, gift card). Solo GOOD entra en el carrito; los demás se compran con el buyUrl de la tienda.
  • currency es la moneda de los precios (ISO 4217, ej.: BRL). priceType dice cómo leer el precio: FIXED (cerrado), FROM (desde), PER_NIGHT (por noche), PER_PERSON (por persona).
  • fulfillment dice cómo llega: DELIVERY, PICKUP, IN_STORE (en el local), AT_CUSTOMER (a domicilio), BOOKING (reserva) o DIGITAL. Servicios y reservas no tienen stock (stock nulo); lo digital puede ser ilimitado. Reservas y digitales valen desde cualquier lugar.
  • En el producto: taxonomyId (categoría de la Google Product Taxonomy), mpn (código del fabricante) y attributes (datos del tipo: color, size, duration_minutes, max_guests...).

Ubicación del consumidor

La búsqueda y las ofertas aceptan la ubicación del consumidor. Con ella, solo aparecen tiendas que entregan allí o que están cerca para retirar (hasta 30 km), y cada oferta indica cómo atiende la tienda.

  • Prefiere latitude y longitude: son precisas. Solo con el postalCode (CEP), la coordenada viene de un servicio de CEP y muchas veces es apenas el centro de la ciudad; en ese caso la distancia viene con distanceApproximate: true.
  • La entrega aplica si el consumidor está dentro del radio de la tienda o en uno de los rangos de CEP que atiende. Los rangos de CEP funcionan incluso sin coordenadas, así que envía el CEP siempre que lo tengas.

Conectar vía MCP

El servidor usa el transporte Streamable HTTP en https://api.sandbox.bridgesagents.com/mcp.

Claude Code

claude mcp add --transport http bridgesagents https://api.sandbox.bridgesagents.com/mcp \
  --header "Authorization: Bearer abd_SUA_CHAVE"

Clientes que solo aceptan servidores locales (stdio)

Usa mcp-remote como puente. Ejemplo de configuración (Claude Desktop, Cursor y similares):

{
  "mcpServers": {
    "bridgesagents": {
      "command": "npx",
      "args": ["mcp-remote", "https://api.sandbox.bridgesagents.com/mcp", "--header", "Authorization:Bearer ${BRIDGESAGENTS_KEY}"],
      "env": { "BRIDGESAGENTS_KEY": "abd_SUA_CHAVE" }
    }
  }
}

Probar sin agente

MCP Inspector lista y ejecuta las tools desde el navegador. Elige Streamable HTTP, ingresa la URL de arriba y agrega el header Authorization con Bearer abd_….

Los clientes compatibles con OAuth (como Claude y MCP Inspector) no necesitan header: en el primer acceso reciben 401 con WWW-Authenticate, descubren el servidor de autorización, se registran solos y abren la página donde el consumidor inicia sesión (o crea una cuenta) y permite el acceso. Consulta Autenticación.

npx @modelcontextprotocol/inspector

Tools MCP

search_products

Busca productos por nombre o marca, en cualquier segmento. Ignora acentos y mayúsculas, acepta comienzos de palabra (arro → arroz) y sinónimos, incluso regionales de Brasil (bateria → pilha, bolacha → biscoito, macaxeira → mandioca). Tolera errores de tipeo (arros → arroz) y entiende términos en inglés y español (rice → arroz, frijoles → feijão, haircut → corte).

ParámetroTipoObligatorioDescripción
querystringsíTexto de búsqueda, en portugués. Ej.: "fone bluetooth" (audífonos Bluetooth).
limitnúmeronoMáximo de resultados, de 1 a 50. Predeterminado: 10.
postalCodestringnoCEP (código postal de Brasil) del consumidor. Con ubicación, solo productos que alguna tienda atiende allí.
latitude, longitudenúmeronoCoordenadas del consumidor (más precisas que el CEP).
radiusKmnúmeronoSolo tiendas hasta esta distancia del consumidor, en km (hasta 100). Requiere ubicación. Ej.: gasolineras en un radio de 5 km.
[
  {
    "id": "00000000-0000-0000-0000-0000000000b8",
    "gtin": "7890000000103",
    "name": "Amoxicilina 500mg 21 cápsulas",
    "brand": "Marca F",
    "category": "Medicamentos",
    "unit": "UN",
    "requiresPrescription": true,
    "imageUrl": "https://img.example.com/amoxicilina.png"
  }
]

get_offers

Lista las ofertas de un producto por tienda, de la más barata a la más cara (en empate, la más cercana).

ParámetroTipoObligatorioDescripción
productIdUUIDsíid obtenido de search_products.
postalCodestringnoCódigo postal del consumidor (en Brasil, el CEP; cep también se acepta).
countrystringnoPaís del consumidor, 2 letras (BR, US, PT). Por defecto: BR. Fuera de Brasil, el código postal se convierte en coordenada aproximada (OpenStreetMap).
latitude, longitudenúmeronoCoordenadas del consumidor.
radiusKmnúmeronoSolo tiendas hasta esta distancia del consumidor, en km (hasta 100). Requiere ubicación. Ej.: gasolineras en un radio de 5 km.
[
  {
    "storeId": "00000000-0000-0000-0000-0000000000a4",
    "storeName": "Farmácia Exemplo Savassi",
    "city": "Belo Horizonte",
    "region": "MG",
    "price": 32.90,
    "promoPrice": null,
    "effectivePrice": 32.90,
    "stock": 20.000,
    "inStock": true,
    "soldByWeight": false,
    "requiresPrescription": true,
    "updatedAt": "2026-10-25T21:51:47Z",
    "stale": false,
    "distanceKm": 0.2,
    "distanceApproximate": false,
    "pickup": true,
    "delivery": { "fee": 0.00, "etaMinutes": 40, "minOrder": null, "coveredBy": "radius" },
    "openNow": true,
    "buyUrl": "https://api.sandbox.bridgesagents.com/r/00000000-0000-0000-0000-0000000000cb"
  }
]
CampoQué significa
distanceKmDistancia en línea recta hasta la tienda. Nula si alguna de las partes no tiene coordenadas.
pickupSe puede retirar en la tienda (retiro habilitado y tienda cerca del consumidor).
deliveryCondiciones de entrega (costo, plazo en minutos, pedido mínimo) si la tienda entrega allí; null si no entrega. coveredBy: cep_range (seguro), radius (coordenadas exactas) o radius_approximate (calculado con la coordenada del CEP: puede no aplicar, confírmalo con la tienda). Sin ubicación, muestra las condiciones con coveredBy null.
openNowSi la tienda está abierta ahora, en su zona horaria. Nulo si la tienda no informó horario.
buyUrlEnlace para que el consumidor compre directo en la tienda: lleva al WhatsApp de la tienda (con el mensaje listo, con producto y precio) o a su sitio web. Nulo si la tienda no informó un canal de compra. Muéstraselo al consumidor cuando elija la oferta.

create_cart

Arma un carrito en una tienda y devuelve confirmUrl: el enlace que el consumidor abre para revisarlo, ingresar su nombre y WhatsApp (y la dirección, si es entrega) y confirmar. El agente no cierra la compra solo ni recibe datos personales. El pedido llega al panel y al correo de la tienda; el pago es con la tienda. Si la tienda registró una clave Pix, el enlace muestra un código QR y un copiar y pegar con el monto del pedido.

ParámetroTipoObligatorioDescripción
storeIdUUIDsíTienda (de get_offers). Un carrito es de una sola tienda.
itemslistasíDe 1 a 50 artículos { productId, quantity }. Cantidad fraccionada solo en productos vendidos por peso.
fulfillmentstringsíProductos: pickup (retiro) o delivery (entrega). Servicios: in_store o at_customer (a domicilio). Reservas: booking. Digital: digital. Usa lo que acepta la oferta (fulfillment en get_offers).
postalCodestringen entregaCódigo postal del consumidor (CEP en Brasil); la tienda debe entregar allí.
notestringnoNota para la tienda (aparece en el pedido).
scheduledForstringen serviciosFecha y hora pedidas, con zona horaria (ej.: 2026-11-05T14:00-03:00). Usa un horario libre de check_availability; fuera del horario de atención o completo se rechaza.
checkIn / checkOutstringen reservasFechas AAAA-MM-DD. checkOut es obligatorio con precio por noche (la línea multiplica por las noches).
guestsnúmeroen reservasPersonas. Obligatorio con precio por persona (la línea multiplica por los huéspedes).
externalReferencestringnoTu id para este carrito (conversación o usuario en tu sistema), hasta 100 caracteres. Vuelve en get_cart, en Pedidos de los agentes y en los webhooks del desarrollador.
{
  "id": "f4e2add5-0103-4fc2-aebb-77dbabff2241",
  "status": "OPEN",
  "store": { "id": "00000000-0000-0000-0000-0000000000a4", "name": "Farmácia Exemplo Savassi", … },
  "fulfillment": "PICKUP",
  "items": [
    { "productId": "00000000-0000-0000-0000-0000000000b6", "name": "Protetor Solar FPS 50 200ml",
      "unit": "UN", "quantity": 2, "unitPrice": 52.90, "lineTotal": 105.80 }
  ],
  "subtotal": 105.80,
  "deliveryFee": null,
  "total": 105.80,
  "expiresAt": "2026-10-27T02:39:54Z",
  "confirmUrl": "https://bridgesagents.com/compras/c/abc_…",
  "order": null
}

Los productos con receta no entran en el carrito. Si algún artículo tiene un problema (sin stock, cantidad, tienda que no lo vende), no se crea nada y la respuesta lista cada problema. Al confirmar, se vuelven a revisar precio y stock: si el precio cambió, el consumidor ve el nuevo valor antes de confirmar.

check_availability

Agenda en tiempo real, antes de create_cart. Servicio: slots con los horarios libres dentro del horario de la tienda (cada duration_minutes) y los cupos que quedan (free, cuando la tienda informa capacity); usa un start como scheduledFor. Reserva: nights con cada noche y las unidades libres (free, cuando la tienda informa units; 0 = completo). El carrito rechaza horarios fuera del horario de atención o completos y sugiere los próximos libres.

ParámetroTipoObligatorioDescripción
storeIdUUIDsíTienda (de get_offers).
productIdUUIDsíServicio o reserva (de search_products).
fromAAAA-MM-DDnoPrimer día; hoy si está vacío.
daysenteronoCuántos días mirar, de 1 a 31 (por defecto 7).

get_cart

Estado de un carrito creado con tu clave: OPEN, CONFIRMED (con el número y el estado del pedido) o EXPIRED. El enlace dura 24 horas. Mientras el pedido está NEW, order.respondBy indica hasta cuándo la tienda puede aceptarlo (2 h; 24 h para reservas y digitales, contando desde que abre la tienda): sin respuesta, se cancela solo con el motivo A loja não respondeu a tempo.

ParámetroTipoObligatorioDescripción
cartIdUUIDsíid devuelto por create_cart.

Próximas tools: quote_delivery y pago por el agente.

UCP y ACP

El mismo catálogo también está disponible en los formatos de comercio para agentes de Google y de OpenAI. Cada producto (el mismo en cualquier tienda, por GTIN) trae las ofertas de todas las tiendas. La compra sigue siendo en la tienda: todavía no hay checkout a través del agente.

UCP (Universal Commerce Protocol)

El perfil en https://api.sandbox.bridgesagents.com/.well-known/ucp anuncia las capacidades dev.ucp.shopping.catalog.search y dev.ucp.shopping.catalog.lookup (versión 2026-08-25). Cada oferta de tienda es una variante: la tienda viene en seller, el precio en centavos ({"amount": 2490, "currency": "BRL"}) y url es el enlace de compra. Distancia, retiro, entrega y horario están en metadata. Envía context.postal_code para ver solo las tiendas que atienden al consumidor.

POST/ucp/v1/catalog/search

Búsqueda por texto, con filtros categories y price (min/max en centavos) y paginación por cursor.

curl -X POST "https://api.sandbox.bridgesagents.com/ucp/v1/catalog/search" -H "Authorization: Bearer abd_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{"query": "pilha aa", "context": {"postal_code": "30140-010"}, "pagination": {"limit": 5}}'

POST/ucp/v1/catalog/lookup

Productos por ids; los que no existen vuelven en messages con not_found.

POST/ucp/v1/catalog/product

Un producto por id, con todas sus ofertas.

ACP (Agentic Commerce Protocol, OpenAI)

Feed de productos de ChatGPT: un JSON por línea, una línea por oferta de tienda, con price en el formato 19.90 BRL e is_eligible_checkout: false. Las ofertas sin marca, sin imagen o sin canal de compra quedan fuera (el formato exige esos campos), al igual que los productos con receta. El header X-BridgesAgents-Skipped indica cuántas quedaron fuera.

El feed es de uso interno: el propio BridgesAgents lo genera en /feeds/acp/products.jsonl.gz y lo envía a OpenAI. Los agentes no necesitan descargarlo; para consultar el catálogo, usa MCP, REST o UCP con la clave de agente.

Importar catálogo

El comercio envía la hoja de cálculo que ya usa, en Excel (.xlsx) o CSV, desde el panel o por la API. Importar de nuevo actualiza precio e inventario, sin duplicar productos.

  • La primera fila es el encabezado. El orden de las columnas no importa, y las columnas desconocidas se ignoran.
  • Los nombres se comparan sin acentos, mayúsculas ni puntuación: Preço de Venda y preco_venda son la misma columna.
  • Los números aceptan el formato brasileño (1.234,56, R$ 27,90; R$ es el real brasileño) y también 27.90.
  • El CSV puede usar punto y coma, coma o tabulación, en UTF-8 o en el formato predeterminado de Excel en portugués.
  • Las filas con problemas no impiden las demás: el resultado lista cada una con el número de fila y el motivo.
  • El combustible (gasolina, etanol, diésel, GNV) se marca solo como venta únicamente en el local: sin carrito, aparece por la distancia a la gasolinera. Armas, munición, explosivos, cigarrillos electrónicos y drogas se rechazan.
  • Límites: 5 MB y 10.000 filas por archivo.

Los encabezados de columna se reconocen por sus nombres en portugués (los de la tabla y de la plantilla). Las columnas de sí/no también aceptan yes/no y true/false.

ColumnaNombres aceptadosObligatoriaObservación
Nombrenome, produto, descrição, itemsíHasta 300 caracteres.
Preciopreço, valor, preço de venda, valor unitáriosíMayor que cero.
EANean, gtin, código de barrasno8, 12, 13 o 14 dígitos. Es lo que vincula tu producto con el mismo producto de otras tiendas.
Marcamarca, fabricantenoSin EAN, nombre + marca identifican el producto.
Categoríacategoria, departamento, seçãono
Unidadunidade, un, undnoUN (predeterminada), KG, G, L o ML.
Precio promocionalpreço promocional, promoção, preço ofertanoMenor que el precio.
Inventarioestoque, quantidade, qtd, saldonoPredeterminado 0.
Vendido por pesovendido por peso, por peso, granelnosim/não (sí/no). Sin la columna, la unidad KG cuenta como vendido por peso.
Exige recetaexige receita, receita, tarja, venda sob prescriçãonosim/não (sí/no), o "tarja vermelha"/"tarja preta" (medicamentos de franja roja/negra en Brasil). Los agentes no concluyen la compra de estos productos.
Mayor de 18maior de 18, maiores de 18, 18, adultonosim/não (sí/no). Las bebidas alcohólicas y el tabaco se marcan solos; el agente controla la edad.
Imagenimagem, foto, url da imagem, image_linknoDirección https:// pública de la foto del producto.
Tipo de ítemtipo de item, kindnoproducto, combustible, servicio, reserva o digital. Por defecto: producto.
Monedamoeda, currencynoCódigo de 3 letras (BRL, USD, EUR). Por defecto: BRL. En el formato del feed de Google, el precio puede traer la moneda (27.90 BRL).
Tipo de preciotipo de preço, price_typenofijo, desde, por noche o por persona. Por defecto: fijo.
Atenciónatendimento, fulfillmentnoentrega, retiro, en el local, a domicilio, reserva o digital (varios separados por coma). Por defecto: el del tipo.
MPN y SKUmpn / skunoCódigo del fabricante (identifica el ítem sin EAN, junto con la marca) y el código en tu sistema.
Categoría de Googlegoogle_product_categorynoId o ruta de la Google Product Taxonomy (ej.: 2271 o Apparel & Accessories > Clothing).
Atributosatributo_<nombre> (ej.: atributo_duration_minutes), color, sizenoDatos del tipo: color y talla del producto, duración del servicio, huéspedes de la reserva. También se acepta la planilla del feed de Google Merchant Center (title, price, sale_price, image_link...).

Descargar la hoja de cálculo modelo

Registro de tiendas

El comercio es responsable del registro de cada tienda: dirección, ubicación, cómo atiende y horario. Con eso los agentes saben si la tienda entrega al consumidor, si se puede retirar cerca y si está abierta. El panel muestra lo que falta en cada tienda.

  • Coordenadas: ingresa las exactas (en Google Maps, clic derecho sobre la tienda y clic en los números). Si las dejas en blanco, usamos unas aproximadas por el CEP, que pueden ser solo el centro de la ciudad.
  • Entrega: por radio (km desde la tienda), por rangos de CEP o ambos. El costo, el plazo en minutos y el pedido mínimo son por tienda.
  • Canal de compra: WhatsApp de pedidos y/o sitio web. Es adonde el enlace “comprar en esta tienda” (buyUrl) lleva al cliente. En el sitio web, {produto} en la URL se reemplaza por el nombre del producto.
  • Horario: por día de la semana, en la zona horaria del estado (UF) de la tienda. Dos turnos separados por coma, 24h o fechado (cerrado). Cerrar después de medianoche (22:00-02:00) también vale.

Hoja de cálculo de tiendas (cadenas)

En Tiendas → Importar hoja de cálculo, la cadena registra y actualiza todas sus tiendas de una vez. El código identifica cada tienda: si existe, se actualiza; si no, se crea.

Como en el catálogo, los encabezados de columna se reconocen por sus nombres en portugués. Los días son seg, ter, qua, qui, sex, sab, dom (lunes a domingo).

ColumnaNombres aceptadosObligatoriaEjemplo
Códigocódigo, código da loja, filialsíBH-SAVASSI
Nombrenome, loja, unidadesíFarmácia Centro
CEP / código postalcep, codigo postal, zipsí30140-010
Direcciónrua/logradouro, número, complemento, bairro, cidade, UFno*Rua Pernambuco, 1200
Coordenadaslatitude, longitudeno-19.937410 / -43.934170
Atenciónretirada, entreganosim / não (sí / no)
Entregaraio km, taxa de entrega, prazo (min), pedido mínimono4 · 6,90 · 45 · 30,00
Rangos de CEPfaixas cep, ceps atendidosno30100-000 a 30199-999; 30210-000
Horarioseg, ter, qua, qui, sex, sab, domno08:00-12:00, 14:00-20:00 · 24h · fechado
Canal de comprawhatsapp, siteno(31) 99999-0000 · https://minhaloja.com.br/busca?q={produto}
Clave Pixchave_pix, pixnoSolo en Brasil: CPF, CNPJ, correo, celular o clave aleatoria. El consumidor paga por el enlace del pedido.

* La ciudad y la UF (estado) se completan con el CEP cuando quedan en blanco. Descargar la hoja de cálculo modelo de tiendas

Conectar Bling

Quien usa Bling (un ERP brasileño) no necesita hoja de cálculo ni programación: en Integraciones, en el panel, el administrador conecta la cuenta de Bling, autoriza a BridgesAgents (solo lectura de productos, inventario y depósitos) y elige qué depósito abastece a cada tienda.

  • Precio, foto, código de barras, marca y categoría vienen del registro del producto en Bling.
  • El inventario de cada tienda es la suma del saldo disponible de los depósitos vinculados a ella.
  • Los cambios de precio e inventario llegan en segundos; una sincronización completa se ejecuta todos los días de madrugada y aparece en Importaciones con Bling como origen.
  • Un producto desactivado o eliminado en Bling queda con inventario cero.
  • Los productos con variaciones (color, talla) todavía no se incluyen: por ahora, envíalos por la hoja de cálculo.

Conectar Nuvemshop

Quien vende en una tienda online Nuvemshop (Tiendanube) tampoco necesita hoja de cálculo: en Integraciones, en el panel, el administrador conecta la tienda, autoriza a BridgesAgents (solo lectura de productos e inventario) y elige qué tienda de BridgesAgents recibe el inventario de cada ubicación de Nuvemshop (con una sola tienda, esto es automático).

  • Cada variante se convierte en un ítem, con el nombre del producto y los valores de la variante (ej.: "Camiseta Básica – Azul / M").
  • Precio, precio promocional, foto, código de barras (cuando es un GTIN válido), marca y categoría vienen de Nuvemshop.
  • Una variante sin control de inventario en Nuvemshop aparece como disponible, con 999 unidades.
  • Los cambios en los productos llegan en segundos; una sincronización completa se ejecuta todos los días de madrugada y aparece en Importaciones con Nuvemshop como origen.
  • Un producto oculto, fuera de la vitrina o eliminado en Nuvemshop queda con inventario cero. Una variante sin precio ("consultar") no se incluye.

Webhooks de pedidos

Para que el pedido llegue directo al sistema de la tienda (ERP, punto de venta, agenda, n8n, Zapier): en Integraciones, la administración o el desarrollador de la empresa registra una dirección https y elige la tienda (o todas) y los eventos. Los administradores reciben un correo por cada webhook nuevo.

  • order.created: el consumidor confirmó el pedido (el mismo momento del correo a la tienda).
  • order.status_changed: la tienda aceptó, dejó listo, completó o canceló (con cancelReason).
  • order.paid: la tienda marcó el pedido como pagado (o lo deshizo: paidAt vuelve vacío).
  • Cada envío es un POST con el pedido completo en data.order: artículos con el gtin y el sku de la tienda, cliente, dirección, agenda de la reserva o del servicio, totales y moneda. Pueden aparecer campos nuevos; ninguno se renombra.
  • Los datos del cliente van solo a la tienda del pedido. Para devolver el estado, usa POST /api/v1/me/orders/{id}/status con la clave de la tienda.
  • Número del pedido: al registrar, elige lo que acepta tu sistema. Solo números: "number": 1042. Letras y números: "number": "AB1042". El campo reference ("AB1042", el mismo identificador del Pix y del enlace del consumidor) va siempre.
  • Encabezado de acceso (opcional): si tu sistema exige un token fijo (Authorization: Bearer …, X-Api-Key...), registra el nombre y el valor: va en cada envío, junto con la firma. El valor queda cifrado y el panel solo muestra el final.
  • Cuenta de desarrollador: en Webhooks, el desarrollador del agente recibe los mismos eventos de los pedidos hechos con sus claves, con data.cart (id, externalReference, agentKeyId) y el pedido sin datos personales del comprador (customer y deliveryAddress vacíos). Así el bot avisa al usuario sin consultar get_cart todo el tiempo.

Ejemplo

POST https://seusistema.com.br/agentbridge/pedidos
Content-Type: application/json
X-BridgesAgents-Event: order.created
X-BridgesAgents-Event-Id: 6f1c0d2e-…
X-BridgesAgents-Delivery: 0b9a7c41-…
X-BridgesAgents-Signature: t=1793000000,v1=5d2c…
X-Api-Key: (o cabeçalho de acesso, se você cadastrou um)

{
  "id": "6f1c0d2e-…",
  "event": "order.created",
  "createdAt": "2026-10-27T14:03:11Z",
  "data": {
    "order": {
      "id": "…", "number": 1042, "reference": "AB1042", "status": "NEW",
      "storeId": "…", "storeCode": "CENTRO", "storeName": "Exemplo Centro",
      "fulfillment": "DELIVERY",
      "customer": { "name": "Ana Souza", "phone": "+5511988887777", "email": "ana@exemplo.com", "note": null },
      "deliveryAddress": { "postalCode": "01310100", "street": "Av. Paulista", "number": "1000", "complement": null,
                           "district": "Bela Vista", "city": "São Paulo", "region": "SP" },
      "items": [
        { "productId": "…", "gtin": "7890000000011", "sku": "ARZ-5", "name": "Arroz Branco Tipo 1 5kg", "unit": "UN",
          "quantity": 2, "unitPrice": 24.90, "multiplier": 1, "lineTotal": 49.80, "adult": false }
      ],
      "subtotal": 49.80, "deliveryFee": 8.00, "total": 57.80, "currency": "BRL", "estimated": false,
      "schedule": { "scheduledFor": null, "checkIn": null, "checkOut": null, "guests": null },
      "paidAt": null, "cancelReason": null, "agentNote": null,
      "createdAt": "2026-10-27T14:03:10Z", "updatedAt": "2026-10-27T14:03:10Z",
      "payment": { "status": "PENDING", "method": "PIX" }
    }
  }
}

Verificar la firma

Al registrar, el panel muestra una sola vez el secreto (whsec_…). Cada envío trae X-BridgesAgents-Signature: t=<segundos>,v1=<hex>, donde v1 es el HMAC-SHA256, con el secreto, de t + "." + cuerpo (el cuerpo tal como llegó). Recházalo si no coincide o si t tiene más de 5 minutos.

// Node.js (Express): use o corpo cru, antes de qualquer JSON.parse
import crypto from "node:crypto";

app.post("/agentbridge/pedidos", express.raw({ type: "application/json" }), (req, res) => {
  const header = req.get("X-BridgesAgents-Signature") ?? "";
  const t = header.match(/t=(\d+)/)?.[1];
  const v1 = header.match(/v1=([0-9a-f]+)/)?.[1] ?? "";
  const expected = crypto.createHmac("sha256", process.env.BRIDGESAGENTS_WEBHOOK_SECRET)
    .update(`${t}.${req.body}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
  if (!fresh || v1.length !== expected.length
      || !crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))) {
    return res.sendStatus(401);
  }
  const event = JSON.parse(req.body);
  // Guarde event.id: se chegar de novo (nova tentativa ou reenvio), ignore
  res.sendStatus(200);
});
# Python (Flask)
import hashlib, hmac, os, re, time
from flask import Flask, request, abort

app = Flask(__name__)

@app.post("/agentbridge/pedidos")
def pedidos():
    header = request.headers.get("X-BridgesAgents-Signature", "")
    t = re.search(r"t=(\d+)", header)
    v1 = re.search(r"v1=([0-9a-f]+)", header)
    if not t or not v1 or abs(time.time() - int(t[1])) > 300:
        abort(401)
    body = request.get_data(as_text=True)
    expected = hmac.new(os.environ["BRIDGESAGENTS_WEBHOOK_SECRET"].encode(), f"{t[1]}.{body}".encode(),
                        hashlib.sha256).hexdigest()
    if not hmac.compare_digest(v1[1], expected):
        abort(401)
    event = request.get_json()
    return "", 200

Respuestas, reintentos y reenvío

  • Responde 2xx en hasta 10 segundos y procesa después si tarda. No se siguen redirecciones.
  • Sin 2xx, reintentamos a 1 min, 5 min, 30 min, 2 h y 12 h. Agotados (unas 15 h), el webhook se pausa y los administradores reciben un correo; los pedidos siguen en el panel.
  • El mismo evento puede llegar más de una vez (reintento o reenvío): usa X-BridgesAgents-Event-Id (igual al id del cuerpo) para ignorar repetidos. El orden no está garantizado después de una falla: compara data.order.updatedAt.
  • En el panel quedan los últimos envíos (30 días), con el error de cada uno, y los botones Enviar prueba (pedido ficticio, evento webhook.test), Reenviar, Pausar/Reactivar y Cambiar secreto.

Probar en el sandbox

En el sandbox pruebas todo el flujo de tu agente sin una tienda real: las tiendas, los productos y los pedidos son ficticios, y tú haces el papel de la tienda y del checkout de pago.

  • En el panel: en Pedidos de los agentes, abre un pedido y usa los botones para aceptar, marcar listo, completar o cancelar, y para avisar el pago (pagado con Pix, tarjeta o boleto, rechazado, reembolsado, disputado).
  • Por la API, con la clave de agente (para pruebas automatizadas): POST /api/v1/carts/{id}/sandbox/status con {"status": "ACCEPTED"} (ACCEPTED, READY, COMPLETED, CANCELLED) y POST /api/v1/carts/{id}/sandbox/payment con {"status": "paid", "method": "pix"} (paid, refused, refunded, chargeback, pending; pix, card, boleto).
  • Cada simulación cambia el pedido de verdad: el consumidor recibe el aviso, tus webhooks reciben order.status_changed y order.paid, y get_cart muestra order.status, order.paymentStatus, order.paymentMethod y order.paidAt.
  • Solo pedidos armados por tus claves. En producción estas rutas no existen: responde la tienda.
# Aceitar o pedido e avisar o pagamento aprovado (sandbox, com a chave de agente)
curl -X POST https://api.sandbox.bridgesagents.com/api/v1/carts/$CART_ID/sandbox/status \
  -H "Authorization: Bearer $BRIDGESAGENTS_KEY" -H "Content-Type: application/json" \
  -d '{"status": "ACCEPTED"}'

curl -X POST https://api.sandbox.bridgesagents.com/api/v1/carts/$CART_ID/sandbox/payment \
  -H "Authorization: Bearer $BRIDGESAGENTS_KEY" -H "Content-Type: application/json" \
  -d '{"status": "paid", "method": "pix"}'

Herramienta completa: riesgo y zonas

Las cuentas de desarrollador pueden ver el nivel de riesgo de los pedidos que generaron sus agentes (GET /api/v1/me/agent-orders/{cartId}/risk) y los números por zona de las tiendas de la red (GET /api/v1/me/insights/regions), y buscar pedidos por zona (GET /api/v1/me/insights/orders?q=04001, por el inicio del código postal o por el nombre de la ciudad o del barrio): productos y categoría, pago, rechazos y el motivo, y el contacto (nombre, correo, teléfono) solo de pedidos con consentimiento: el operador del bot recoge el consentimiento del comprador, según la cláusula de su contrato con BridgesAgents. Lo que aparece depende de lo que el contrato libera, campo por campo, y cada búsqueda queda registrada. En el sandbox ya está todo liberado; en producción, mediante contrato con BridgesAgents.

Enviar catálogo por API

Para que el sistema de la tienda (ERP, tienda en línea, script) envíe precios e inventario automáticamente, sin hoja de cálculo. Mismas reglas y mensajes que la importación por hoja de cálculo.

1. Genera la clave

Hay dos tipos:

  • Clave de la empresa (POST /api/v1/me/api-keys): vale para todas las tiendas. Cada artículo indica storeCode, el código de la tienda en tu sistema. Ideal para cadenas.
  • Clave de una tienda (POST /api/v1/stores/{storeId}/api-keys): todo va a esa tienda y storeCode se ignora.

En el panel, en Claves de API, o por la API con la sesión del comercio (ve Autenticación). La clave completa solo aparece en esa respuesta: guárdala de forma segura.

curl -X POST "https://api.sandbox.bridgesagents.com/api/v1/stores/{storeId}/api-keys" \
  -H "Authorization: Bearer abs_…" \
  -H "Content-Type: application/json" -d '{"name": "ERP"}'
{
  "apiKey": { "id": "…", "name": "ERP", "keyPrefix": "abk_Xy12Ab34", "createdAt": "…", "lastUsedAt": null, "revokedAt": null },
  "key": "abk_Xy12Ab34…"
}

2. Envía los artículos con la clave

La clave va en el header X-Api-Key. Con la clave de la empresa, la tienda de cada artículo viene de storeCode; con la clave de una tienda, siempre es esa tienda. Cada artículo crea o actualiza la oferta de la tienda; los artículos que no se envíen quedan como están (para retirarlo de la venta, envía inventario 0). Hasta 1.000 artículos por solicitud.

curl -X POST "https://api.sandbox.bridgesagents.com/api/v1/catalog/items" \
  -H "X-Api-Key: abk_…" -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "storeCode": "BH-SAVASSI", "gtin": "7890000000066", "name": "Pilha Alcalina AA com 4", "price": 17.50, "stock": 60 },
      { "storeCode": "BH-PAMPULHA", "gtin": "7890000000103", "name": "Amoxicilina 500mg 21 cápsulas",
        "price": 29.90, "stock": 8, "requiresPrescription": true }
    ]
  }'
CampoTipoObligatorioObservación
nametextosíHasta 300 caracteres.
pricenúmerosíMayor que cero, con punto decimal (17.50).
gtintextonoEAN con 8, 12, 13 o 14 dígitos. Vincula el artículo con el mismo producto de otras tiendas.
brandtextonoSin GTIN, nombre + marca identifican el producto.
categorytextono
unittextonoUN (predeterminada), KG, G, L o ML.
promoPricenúmeronoMenor que price.
stocknúmeronoPredeterminado 0.
soldByWeighttrue/falsenoSin el campo, la unidad KG cuenta como vendido por peso.
requiresPrescriptiontrue/falsenoMedicamento con receta. Los agentes no concluyen la compra.
adulttrue/falsenoMayores de 18. Las bebidas alcohólicas y el tabaco se marcan solos por el nombre y la categoría.
storeCodetextocon clave de la empresaCódigo de la tienda en tu sistema (registrado en Tiendas).
kindtextonoGOOD, FUEL, SERVICE, BOOKABLE o DIGITAL. Por defecto: GOOD.
currencytextonoISO 4217 (BRL, USD, EUR). Por defecto: BRL.
priceTypetextonoFIXED, FROM, PER_NIGHT o PER_PERSON (cada tipo acepta algunos).
fulfillmentlistanoDELIVERY, PICKUP, IN_STORE, AT_CUSTOMER, BOOKING, DIGITAL. Por defecto: el del tipo.
mpn / skutextonoCódigo del fabricante y código en tu sistema.
googleCategorytextonoId o ruta de la Google Product Taxonomy.
attributesobjetonoDatos del tipo, ej.: {"duration_minutes": 60, "capacity": 2} (servicio: duración y atenciones simultáneas) o {"max_guests": 2, "check_in": "14:00", "units": 3} (reserva: unidades iguales por noche).
imageUrltextonoDirección https:// pública de la foto del producto. Vale la primera que se informe para el producto.

La respuesta indica lo que entró. Los artículos con problemas no impiden los demás y aparecen en errors con su posición en items (empezando en 0):

{
  "received": 2, "imported": 1, "failed": 1,
  "productsCreated": 0, "offersCreated": 0, "offersUpdated": 1,
  "errors": [ { "index": 1, "gtin": null, "name": "Banana Prata", "message": "Preço em branco." } ]
}

Para reemplazar una clave filtrada, genera otra y revoca la anterior en el panel (o con DELETE /api/v1/stores/{storeId}/api-keys/{keyId}).

API REST

Respuestas en JSON. Los campos de producto y oferta son los mismos de las tools MCP.

GET/api/v1/products?q={busca}&limit={1-50}&postalCode=&lat=&lng=

Busca productos. limit es opcional (predeterminado 20); postalCode, lat y lng filtran por las tiendas que atienden al consumidor (ve Ubicación del consumidor).

curl -H "Authorization: Bearer abd_SUA_CHAVE" "https://api.sandbox.bridgesagents.com/api/v1/products?q=pilha%20aa"

GET/r/{offerId}

El buyUrl de las ofertas: cuenta el clic y redirige al WhatsApp o al sitio web de la tienda.

GET/api/v1/products/{id}/offers

Ofertas del producto por tienda, de la más barata a la más cara.

curl -H "Authorization: Bearer abd_SUA_CHAVE" \
  "https://api.sandbox.bridgesagents.com/api/v1/products/00000000-0000-0000-0000-0000000000b7/offers?postalCode=30140-010"

GET/api/v1/products/{id}/availability

Igual que la tool check_availability: ?storeId=...&from=AAAA-MM-DD&days=7.

POST/api/v1/carts

Igual que la tool create_cart. Responde 201 con el carrito y confirmUrl; los artículos con problemas vuelven en problems (HTTP 400).

curl -X POST "https://api.sandbox.bridgesagents.com/api/v1/carts" -H "Authorization: Bearer abd_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{"storeId": "00000000-0000-0000-0000-0000000000a4", "fulfillment": "pickup",
       "items": [{"productId": "00000000-0000-0000-0000-0000000000b6", "quantity": 2}]}'

GET/api/v1/carts/{id}

Igual que la tool get_cart.

Con sesión del comercio (header Authorization: Bearer abs_…)

GET/api/v1/me

Comercio con sesión iniciada.

GET/api/v1/me/stores

Tiendas del comercio con sesión iniciada, con el registro completo y lo que falta en cada una (pending).

POST/api/v1/me/stores

Registra una tienda. PUT /api/v1/me/stores/{id} la actualiza.

POST/api/v1/me/stores/import

Hoja de cálculo de tiendas (multipart/form-data, campo file). Ve Registro de tiendas.

GET/api/v1/me/offers?q=&storeId=&stale=&page=&size=

Ofertas de las tiendas que puedes ver (gerente de tienda: solo las suyas), por nombre del producto: precio, inventario, cuándo se actualizó, stale y hidden. q busca en nombre, marca y código de barras; stale=true trae solo las que llevan más de 7 días sin actualizar. Paginada (size hasta 100).

GET/api/v1/me/offers/freshness

Ofertas desactualizadas por tienda: total, sin actualizar hace más de 7 días (stale) y hace más de 30 (hidden, ya ocultas para los agentes).

GET/api/v1/me/performance?days={1-90}

Rendimiento de las tiendas que la persona puede ver: apariciones para agentes, veces con el menor precio y clics en el enlace de compra, por tienda y por producto.

GET/api/v1/me/price-insights?days={1-90}&storeId=&limit=

Inteligencia de precios: para cada producto tuyo, cómo se compara tu precio con el de otras tiendas de la misma ciudad (sin identificarlas) y cuántas veces dejaste de ser el precio más bajo en las consultas de los agentes. days de 1 a 90.

GET/api/v1/me/agent-orders?status=&keyId=

Cuenta de desarrollador: carritos y pedidos de tus claves de agente, sin datos del comprador (cartStatus OPEN, CONFIRMED o EXPIRED; orderStatus, respondBy, paidAt, externalReference). status: open, confirmed, expired o cancelled. GET .../summary?days=30 trae carritos, confirmados, conversión y pedidos que la tienda no respondió.

GET/api/v1/me/orders?status=&storeId=

Pedidos de las tiendas que ves. status: novos (nuevos), andamento (en curso), concluidos (completados) o cancelados; sin él, todos. GET .../summary trae cuántos hay nuevos y en curso; GET .../{id}, el pedido con los datos del cliente.

POST/api/v1/me/orders/{id}/status

Cambia el estado: ACCEPTED, READY, COMPLETED o CANCELLED (con reason, que el cliente ve). Solo avanza en orden; se avisa al cliente por correo si dejó uno.

POST/api/v1/me/api-keys

Genera la clave de la empresa (todas las tiendas). GET lista y DELETE .../{keyId} revoca.

POST/api/v1/stores/{storeId}/catalog/import

Importa la hoja de cálculo de una de tus tiendas. Envíala como multipart/form-data en el campo file.

curl -H "Authorization: Bearer abs_…" -F "file=@catalogo.xlsx" \
  "https://api.sandbox.bridgesagents.com/api/v1/stores/{storeId}/catalog/import"

GET/api/v1/me/imports?problems={true|false}&limit={1-100}

Historial de importaciones (hoja de cálculo y API) de tus tiendas, de la más reciente a la más antigua. problems=true trae solo las que tienen artículos rechazados o fueron rechazadas.

GET/api/v1/me/imports/{id}

Una importación, con los artículos rechazados (errors): fila de la hoja de cálculo o posición en items, y el motivo.

Con clave de API de la tienda (header X-Api-Key: abk_…)

POST/api/v1/catalog/items

Envía artículos en JSON. Ve Enviar catálogo por API.

POST/api/v1/stores/{storeId}/api-keys

Con sesión del comercio: genera una clave para una de tus tiendas. GET en la misma ruta lista las claves (solo el comienzo de cada una) y DELETE .../api-keys/{keyId} revoca.

{
  "rows": 120,
  "imported": 118,
  "failed": 2,
  "productsCreated": 40,
  "offersCreated": 100,
  "offersUpdated": 18,
  "ignoredColumns": ["Observações"],
  "errors": [
    { "line": 7, "message": "Preço inválido: \"abc\"." },
    { "line": 31, "message": "Nome do produto em branco." }
  ]
}

Para probar los endpoints directamente en el navegador, usa la referencia interactiva (Swagger).

Errores y límites

SituaciónResultado
Búsqueda vacíaLista vacía.
limit fuera de 1 a 50Se ajusta al límite más cercano.
Producto sin ofertas o id inexistenteLista vacía.
id que no es un UUID (REST)HTTP 400.
Parámetro q ausente (REST)HTTP 400.
Importación: archivo vacío, formato no soportado, sin columnas de nombre y precio o más de 10.000 filasHTTP 400.
Importación: archivo de más de 5 MBHTTP 413.
Consulta al catálogo (REST, MCP o UCP) sin clave de agente, o con clave inválida o revocadaHTTP 401.
Más de 120 consultas por minuto con la misma claveHTTP 429, con Retry-After.
Sin sesión o sesión expirada (rutas del panel)HTTP 401.
Cuenta de comercio creando clave de agente, o cuenta de desarrollador creando tiendaHTTP 403.
Tienda o importación que no es tuya (o no existe)HTTP 404.
Envío por API: sin X-Api-Key, clave inválida o revocadaHTTP 401.
Búsqueda: CEP inválido, solo latitud o solo longitud, o coordenadas fuera de BrasilHTTP 400.
Registro de tienda con datos inválidos (CEP, UF, coordenadas, horario, rango de CEP)HTTP 400, con el motivo.
Envío por API: JSON mal formado, sin artículos o más de 1.000 artículosHTTP 400.

Los errores vienen en el formato application/problem+json (RFC 9457). El campo detail trae un mensaje en portugués que se puede mostrar al comercio.

Los mensajes detail de la API siempre están en portugués; el panel de BridgesAgents los traduce. Si los muestras a usuarios en otro idioma, mapéalos por el status HTTP o tradúcelos de tu lado.

Autenticación

QuiénCómoPara qué
Agente (cuenta de desarrollador)Clave de agente: Authorization: Bearer abd_…Buscar productos y ofertas: REST, MCP y UCP. Obligatoria.
Asistente de IA del consumidorOAuth 2.1: Authorization: Bearer abo_…Buscar productos y ofertas en nombre de un consumidor que conectó el asistente. Alcance catalog.
ComercioSesión: Authorization: Bearer abs_…Panel, importar hoja de cálculo, generar claves, ver el historial. Solo ve sus propias tiendas.
Sistema del comercioClave de la tienda: X-Api-Key: abk_…Enviar el catálogo en JSON a esa tienda.

Clave de agente

Ninguna consulta al catálogo es anónima. Crea la cuenta de desarrollador (sin CNPJ) y genera las claves en Claves de agente, en el panel. La clave aparece una sola vez; la base de datos guarda solo el hash. Usa una clave por agente o entorno: si una se filtra, revoca solo esa. El panel muestra cuántas consultas hizo cada clave por día, y el límite es de 120 por minuto por clave.

curl -X POST "https://api.sandbox.bridgesagents.com/api/v1/me/agent-keys" -H "Authorization: Bearer abs_…" \
  -H "Content-Type: application/json" -d '{"name": "Agente em produção"}'
# → { "apiKey": { "id": "…", "keyPrefix": "abd_Xk3…" }, "key": "abd_…" }   (só desta vez)

Planes y franquicia

Cada solicitud autenticada con clave de agente cuenta una consulta (búsqueda, ofertas, carrito o llamada MCP). El plan Gratis incluye 10.000 consultas al mes; al llegar a ellas, la API responde 429 con la explicación en detail hasta el día 1 del mes siguiente. Los planes pagos (Pro y Escala) no bloquean: el excedente se cobra por bloque de 1.000 consultas en la factura de fin de mes. Te avisamos por correo al 80% y al 100% de la franquicia, y el uso del mes aparece en Plan y facturación, en el panel. El sandbox no tiene franquicia.

Sandbox

Para probar sin afectar tiendas reales, usa el sandbox: sitio en https://sandbox.bridgesagents.com y API en https://api.sandbox.bridgesagents.com (MCP en /mcp). Tiene la misma versión que producción (cada cambio se publica en los dos), pero con su propia base de datos de tiendas y productos de ejemplo. Crea allí una cuenta de desarrollador: las claves empiezan con abd_test_ y no funcionan en producción (ni las de producción funcionan allí). Carritos y pedidos funcionan de punta a punta, solo que en las tiendas de ejemplo; los correos llegan con [Sandbox] en el asunto.

OAuth 2.1 (servidor MCP)

Seguimos la autorización de la especificación MCP: metadatos en /.well-known/oauth-protected-resource y /.well-known/oauth-authorization-server, registro dinámico en POST /oauth/register (solo clientes públicos), código con PKCE S256 obligatorio en /oauth/authorize y POST /oauth/token. El token de acceso (abo_) dura 1 hora y el de renovación (abr_) 30 días, y se cambia en cada uso; reutilizar un token de renovación o un código corta la conexión. POST /oauth/revoke revoca. El consumidor ve y desconecta las apps en Mis compras › Apps conectadas.

Solo son públicos el descubrimiento (/.well-known/ucp), esta documentación y el enlace de compra /r/…, que abre el consumidor.

Sesión del panel

La sesión viene del inicio de sesión y dura 30 días:

curl -X POST "https://api.sandbox.bridgesagents.com/api/v1/auth/login" -H "Content-Type: application/json" \
  -d '{"email": "voce@sualoja.com.br", "password": "…"}'
# → { "token": "abs_…", "expiresAt": "…", "user": { … } }

El registro de comercio (POST /api/v1/auth/signup) crea la empresa, la primera tienda y el usuario de una vez; el de desarrollador (POST /api/v1/auth/signup/developer) pide solo el nombre de la empresa o proyecto, tu nombre, correo y contraseña. Ambos ya devuelven la sesión. POST /api/v1/auth/logout cierra la sesión.

La clave de agente sigue funcionando para agentes que no usan OAuth.