Autenticación
El administrador de la empresa crea una integración en la aplicación, le otorga datos autorizados por dominio y grupo de campos, y crea un cliente. Hay dos formas de autenticar las solicitudes; ambas se envían como Authorization: Bearer.
OAuth 2.0, credenciales de cliente (recomendado)
POST https://daas.masnet.com/api/v1/integrations/oauth/token con Content-Type: application/x-www-form-urlencoded. El cliente se autentica con client_secret_basic (Authorization: Basic) o con client_id y client_secret en el cuerpo, pero no con ambos a la vez. El client_id tiene la forma mkc_ más 24 caracteres hexadecimales y el secreto, mks_ más 43 caracteres. Solo se admite grant_type=client_credentials.
POST /api/v1/integrations/oauth/token HTTP/1.1
Host: daas.masnet.com
Authorization: Basic <base64(client_id:client_secret)>
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&scope=read:contracts%20read:guarantees{
"access_token": "<jwt>",
"token_type": "Bearer",
"expires_in": 900,
"scope": "read:contracts read:guarantees"
}- El token es un JWT de 15 minutos. No hay tokens de refresco: solicite uno nuevo al vencer.
- El
scopees opcional. El scope concedido es la intersección entre lo que pide y los datos autorizados de la integración; si la intersección es vacía, la respuesta es400 invalid_scope. - Los errores de este punto siguen RFC 6749:
{ "error": "...", "error_description": "..." }. Un cliente inválido o revocado responde401 invalid_clientconWWW-Authenticate: Basic realm="masnet-integrations", sin distinguir la causa. - El punto admite 60 solicitudes por minuto por dirección IP y, tras fallos repetidos, bloquea temporalmente esa dirección (
429conRetry-After). - Los metadatos RFC 8414 están en
/.well-known/oauth-authorization-servery las claves públicas con que se verifican los tokens, en/jwks.json, ambos bajo la misma base.
API key
Para herramientas sin OAuth: Authorization: Bearer mk_live_… en una integración de producción o mk_test_… en una de pruebas. El valor se muestra una sola vez al crearla. Por omisión vence a los 365 días.
Scopes y datos autorizados
Un scope habilita un dominio, pero los campos que se devuelven dependen de los grupos otorgados (public, business, confidential, people). Revocar el permiso hace que la API responda 403 de inmediato.
| Familia | Scopes |
|---|---|
| Lectura | read:opportunities, read:tenders, read:bids, read:awards, read:contracts, read:guarantees, read:deadlines, read:documents, read:catalog, read:prices, read:exports, read:events, read:audit |
| Escritura | write:catalog, write:prices. Solo catálogo y reglas de precio admiten escritura; escribir implica poder leer el mismo dominio. |
read:events habilita el registro de eventos; read:audit el registro de acciones de usuarios, que además exige una declaración del administrador de la empresa.
Recursos
Cada recurso se lee con GET en la colección y GET …/{id} en el elemento. Las órdenes de compra y los hitos pertenecen al dominio contracts.
| Colección | Scope | Filtros |
|---|---|---|
https://daas.masnet.com/api/v1/integrations/data/bids | read:bids | tender_code, status (draft, ready, submitting, portal_draft, submitted, failed, portal_deleted, abandoned), include_deleted |
https://daas.masnet.com/api/v1/integrations/data/awards | read:awards | tender_code, state (detected, confirmed, dismissed) |
https://daas.masnet.com/api/v1/integrations/data/contracts | read:contracts | contract_code, tender_code, buyer_rut, status, ends_before, ends_after |
https://daas.masnet.com/api/v1/integrations/data/purchase-orders | read:contracts | po_code, contract_id, link_state (suggested, confirmed, rejected) |
https://daas.masnet.com/api/v1/integrations/data/guarantees | read:guarantees | status, expires_before, expires_after, tender_code, issuer_id, include_deleted |
https://daas.masnet.com/api/v1/integrations/data/opportunities | read:opportunities | tender_code, stage, decision (go, no_go, defer), business_line_id, include_deleted |
https://daas.masnet.com/api/v1/integrations/data/milestones | read:contracts | contract_id, type, status, planned_before, planned_after, include_deleted |
https://daas.masnet.com/api/v1/integrations/data/deadlines | read:deadlines | entity_id, kind, status (scheduled, done, cancelled, not_applicable), due_before, due_after |
https://daas.masnet.com/api/v1/integrations/data/catalog-items | read:catalog | is_active (true, false), internal_code |
https://daas.masnet.com/api/v1/integrations/data/price-rules | read:prices | catalog_id, is_active (true, false) |
Todas las colecciones admiten limit, cursor y updated_since (fecha RFC 3339). Un parámetro desconocido se rechaza con 400 invalid_parameter: la empresa nunca es un parámetro, se deduce de la credencial. Los identificadores son UUID, salvo el catálogo y las reglas de precio, que usan enteros decimales como texto. Un objeto de otra empresa o inexistente responde 404.
Los objetos devueltos tienen la misma forma que data.object de los eventos; véanse los esquemas.
Paginación y lecturas condicionales
limit: 100 por omisión, máximo 500.- La respuesta es
{ "data": […], "next_cursor": "…" | null, "has_more": true | false }. Para continuar, repita la solicitud concursor=<next_cursor>y los mismos filtros. - El cursor es opaco, vale 24 horas y solo sirve con los filtros con que se emitió; otro filtro responde
400, uno vencido410 cursor_expired. Si el permiso de datos cambia a mitad del recorrido, responde410 cursor_scope_changed: reinicie el recorrido. Un cambio de permisos no significa que los objetos se hayan eliminado. - Bajas: los recursos con baja lógica (ofertas, garantías, oportunidades e hitos) se omiten por omisión; con
include_deleted=trueaparecen condeleted_at. Leer por identificador un objeto dado de baja responde410 gonecondeleted_atdurante 30 días; después,404. - Lectura individual: la respuesta incluye
ETag; reenvíelo enIf-None-Matchpara recibir304si no cambió.
Carga inicial y sincronización
- Anote la hora del primer evento que reciba por webhook.
- Recorra cada colección sin
updated_sincehasta quehas_moreseafalse. - Aplique los eventos con
sequencemayor que la versión que cargó.
Registro de eventos
GET https://daas.masnet.com/api/v1/integrations/data/events con el scope read:events devuelve los envoltorios de los últimos 30 días, del más reciente al más antiguo, con el mismo formato y los mismos grupos de campos que los webhooks y solo de los dominios autorizados. Sirve para reconciliar tras una caída o para un middleware sin punto público.
typeysubject(filtros exactos),sinceyuntil(RFC 3339),limitycursor.limit: 50 por omisión, máximo 200. Respuesta:data,next_cursoryhas_more.- Un cursor anterior a la retención responde
410 cursor_expired: recargue con la API de datos. Un cursor mal formado responde400 invalid_cursor. - Un evento se obtiene por
GET …/data/events/{id}; un evento ajeno o no autorizado responde404. Un cuerpo que no cabe en una lista se omite de ella.
Registro de acciones de usuarios
GET https://daas.masnet.com/api/v1/integrations/data/audit/actions con read:audit devuelve lotes del registro de acciones por cursor numérico. Exige que el administrador declare que la empresa informó el control a sus usuarios; sin ella responde 403 audit_declaration_required. Parámetros: after_seq, limit (1 a 50, 50 por omisión), since, until, actor, channel, action, origin y result. El nombre, el correo, la IP y el agente de usuario solo se devuelven con el grupo people.
Operaciones y exportaciones del catálogo
Con write:catalog o write:prices la integración puede aplicar cambios al catálogo por operaciones: POST https://daas.masnet.com/api/v1/integrations/data/catalog-operations crea una operación, GET …/catalog-operations/{id} y …/results la consultan, y POST …/{id}/validate, …/apply y …/cancel la gobiernan. POST …/catalog-exports solicita una exportación y GET …/catalog-exports/{id}/items la lee. El scope exigido depende de los campos que toca cada operación; una operación de una integración de pruebas puede validarse, pero solo una de producción la aplica. La idempotencia usa client_request_id (UUID). El contrato del cuerpo (catalog-exchange.v1) lo publica el módulo de catálogo y no se reproduce en esta página.
Cuotas
| Alcance | Cuota |
|---|---|
| Lecturas por cliente | 600 solicitudes por minuto |
| Escrituras por cliente (operaciones y exportaciones) | 60 por minuto, además de la cuota de lectura |
| Punto de tokens | 60 por minuto por dirección IP |
Al excederlas la API responde 429 rate_limited con Retry-After: 60 y las cabeceras RateLimit del borrador 7 de IETF. Ninguna respuesta de esta API se guarda en cachés (Cache-Control: no-store).
Errores
Los errores usan application/problem+json (RFC 9457) con los miembros type, title, status, detail, code y correlation_id. El type es una URL documentada en Errores, por ejemplo https://masnet.com/developers/errors/insufficient_scope. Cite el correlation_id al contactar a soporte. detail nunca incluye mensajes de la base de datos, identificadores internos ni datos de otra empresa.
{
"type": "https://masnet.com/developers/errors/insufficient_scope",
"title": "Alcance insuficiente",
"status": 403,
"detail": "La credencial no tiene el scope read:contracts sobre datos autorizados.",
"code": "insufficient_scope",
"correlation_id": "<identificador>"
}