Qué permite
- Definiciones: el documento de una encuesta (páginas, preguntas, condiciones y bloques informativos). Se guarda como borrador, se compila en una vista previa y se publica como una versión numerada e inmutable.
- Campañas: una edición de una versión publicada para una audiencia, con fechas, modalidad y reglas de privacidad. Se guarda como borrador y se lleva por su ciclo: programar, abrir, pausar, reanudar, cerrar, cancelar y archivar.
- Resultados: el agregado que permite la política de privacidad de una campaña propia.
No existen rutas de exportación, de respuestas individuales ni de participantes. Tampoco hay rutas para borrar objetos.
Autenticación y concesión
Las solicitudes se autentican como las de la API de datos: un token OAuth 2.0 o una API key, enviados como Authorization: Bearer. El scope read:surveys lee los objetos propios. El scope write:surveys además escribe, pero no publica ni lee resultados: can_publish y can_read_results se otorgan por separado y valen false por omisión.
El scope no basta. El administrador de la empresa otorga a la integración, en Empresa › Integraciones de la aplicación, el permiso de datos del dominio surveys. Ese permiso exige el grupo de campos confidential y, para nombrar personas en una audiencia, también people. Sin permiso o sin scope, la API responde 403 insufficient_scope. Quien otorga o amplía el permiso necesita en la aplicación los permisos equivalentes a lo que delega, y queda como la persona responsable: lo que prepara la integración figura a su nombre para separar las funciones.
La concesión se lee de nuevo en cada solicitud: lo que se revoque deja de valer de inmediato. Una extensión ausente equivale a una vacía y todo se deniega.
Rutas de campo
| Ruta | Qué permite |
|---|---|
definitions | Redactar y previsualizar definiciones, y publicarlas con can_publish. |
campaigns | Redactar campañas y llevarlas por su ciclo. Las audiencias y los contextos solo se otorgan con esta ruta. |
Sin rutas explícitas se otorgan ambas. El permiso es de escritura (access: write) para escribir.
Qué limita la concesión
| Campo del permiso | Efecto |
|---|---|
allowed_version_ids (hasta 200) | Versiones publicadas de otras definiciones de la empresa que la integración puede usar en una campaña. Las versiones de sus propias definiciones no necesitan otorgarse. |
allowed_group_ids (hasta 100) | Grupos que puede usar en una audiencia selected. |
allowed_user_ids (hasta 200) | Personas que puede usar en una audiencia selected. Exige el grupo de campos people. |
allowed_channel_ids (hasta 100) | Canales de Comunicados que puede usar como contexto de una campaña. |
allowed_modalities | Modalidades que puede usar: confidential y identified. La modalidad anónima no existe. |
can_create | Crear definiciones y campañas nuevas. |
can_publish | Publicar versiones y programar, abrir y reanudar campañas. |
can_read_results | Leer los resultados agregados. |
allow_tenant_audience | Audiencia tenant, que alcanza a toda la empresa. |
Versión del contrato
Cada solicitud puede enviar X-Surveys-Contract: 1. Sin la cabecera rige la versión 1, y cualquier otro valor responde 406 unsupported_contract sin tocar nada. Las respuestas llevan X-Surveys-Contract: 1, Cache-Control: private, no-store y el cuerpo { "contract_version": 1, "data": … }.
Rutas
Todas cuelgan de https://daas.masnet.com/api/v1/integrations/data/surveys. Cada escritura exige Idempotency-Key, incluidas las vistas previas.
| Método y ruta | Uso | Exige | Éxito |
|---|---|---|---|
PUT /definitions/{external_id} | Crea o actualiza el borrador de una definición. | definitions. Crear exige can_create | 201 al crear, 200 al actualizar |
GET /definitions/{external_id} | Lee una definición propia. | Lectura | 200 |
POST /definitions/{external_id}/preview | Compila el borrador y emite el resumen que consume publish. No cambia el borrador. | definitions | 200 |
POST /definitions/{external_id}/publish | Publica el borrador como una versión. | definitions y can_publish | 200 |
PUT /campaigns/{external_id} | Crea o actualiza el borrador de una campaña. | campaigns. Crear exige can_create | 201 al crear, 200 al actualizar |
GET /campaigns/{external_id} | Lee una campaña propia. | Lectura | 200 |
POST /campaigns/{external_id}/launch-preview | Calcula el resumen del lanzamiento. Nunca lista personas. | campaigns | 200 |
POST /campaigns/{external_id}/transition | Cambia el estado de la campaña con una acción. | campaigns. schedule, open y resume exigen can_publish | 200 |
GET /campaigns/{external_id}/results | Lee los resultados agregados. | can_read_results | 200 |
Los cuerpos son JSON y se rechazan si traen un campo desconocido. Un campo de empresa, autoría, entorno, propiedad, privilegios, permisos, aprobación, cohorte, estado o respuestas se rechaza con un código propio, no se ignora. Las vistas previas y los comandos llevan el cuerpo {}, y publish y transition llevan los suyos.
Cada respuesta correcta lleva el objeto en data y, cuando corresponde, la cabecera ETag. Una creación responde además Location, y la repetición de una operación ya aplicada, Idempotency-Replayed: true.
Identidad y concurrencia
El external_id de la ruta es el identificador estable del objeto en su sistema: de 1 a 128 caracteres ASCII que empiezan con letra o dígito y admiten . _ - (^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$). Identifica al objeto dentro del espacio de la integración, el entorno y el tipo: dos integraciones pueden usar el mismo external_id, y un objeto de otra integración, entorno o empresa, o que la concesión de hoy ya no cubre, responde 404 unavailable, igual que uno inexistente.
| Mecanismo | Cómo se usa |
|---|---|
source_revision | Entero mayor o igual que 1 que su sistema hace crecer con cada cambio del objeto. La API lo guarda como la última revisión aceptada. |
Idempotency-Key | De 8 a 128 caracteres A-Z a-z 0-9 . _ : -, una por intención. La misma clave con la misma solicitud (ruta, cuerpo y precondiciones) devuelve el resultado anterior sin repetir el efecto y marca Idempotency-Replayed: true. Con otra solicitud responde 409 idempotency_conflict. Se conserva 72 horas. |
If-None-Match: * | Obligatoria para crear. Sin ella, 428 precondition_required. |
If-Match | Obligatoria para actualizar, publicar y cambiar el estado, con el etag vigente del objeto (cabecera ETag o miembro etag). Otro valor responde 409 version_conflict. Las vistas previas no la exigen. |
Qué responde un PUT
| Situación | Resultado |
|---|---|
| El objeto no existe | Con If-None-Match: * y can_create, lo crea y responde 201. Sin la cabecera, 428 precondition_required. |
source_revision mayor que la última aceptada | Con If-Match y el etag vigente, aplica el cambio y responde 200. Con If-None-Match, 409 already_exists. Una campaña que ya no es borrador responde 409 campaign_not_draft. |
Misma source_revision y mismo cuerpo | Devuelve la vista vigente sin escribir. |
Misma source_revision o menor, con otro cuerpo | 409 source_revision_conflict, con details.current_source_revision. |
| Una persona tomó el control del objeto | 409 manual_control, sin efecto. |
Ante un tiempo de espera o un 503, repita la solicitud con la misma Idempotency-Key. Publicar un borrador idéntico a la última versión devuelve esa versión sin crear otra. Véanse idempotency_key_required, idempotency_conflict, version_conflict, source_revision_conflict.
Definiciones
| Campo | Descripción |
|---|---|
source_revision | Obligatorio. Entero mayor o igual que 1. |
title | Obligatorio. De 1 a 160 caracteres. |
owner_label | Opcional. Rótulo del área responsable, hasta 120 caracteres. |
allowed_modalities | Opcional. Modalidades que admite la definición, entre las otorgadas. Si se omite, todas las otorgadas. |
document | Obligatorio. El documento de la encuesta, un objeto JSON de hasta 512 KiB. |
El documento
El documento es del contrato schema_version 1 y rule_engine_version 1. Sus miembros son schema_version, rule_engine_version, default_locale, locales, title y pages, obligatorios, y description y estimated_minutes, opcionales. Los textos son objetos por idioma, como { "es": "…" }. Cada página lleva items de dos clases: question, con su type, y info, un bloque informativo cuyo body usa el mismo formato de contenido de Comunicados.
| Aspecto | Detalle |
|---|---|
| Tipos de pregunta | short_text, long_text, single_choice, multiple_choice, yes_no, integer, decimal, date, scale, matrix_single |
Condiciones (visible_when, required_when, skip) | Lenguaje cerrado: all, any, not, answered, equals, in, gt, gte, lt y lte. |
| Preguntas | Hasta 100 |
| Páginas | Hasta 25 |
| Opciones por pregunta | Hasta 100 |
| Predicados por documento | Hasta 200, con una profundidad de condición de hasta 8 |
| Tamaño de las respuestas | 256 KiB, de los cuales 16 KiB se reservan para metadatos. La vista previa lo informa en budget. |
Un documento que no compila responde 422 invalid_rule con details.errors, hasta 50 problemas, y la vista previa informa los mismos con ok: false. Más allá del tamaño de 512 KiB, la respuesta es 422 field_length con details.max_bytes.
Vista previa y publicación
POST /definitions/{external_id}/previewcompila el borrador y responde{ ok, digest, compiled_digest, allowed_modalities, budget, expires_at, requires_approval, environment, simulation }. Eldigestes el que consumepublish.POST /definitions/{external_id}/publishlleva{ "digest": "…" }yIf-Match, y exigecan_publishy una vista previa vigente. Crea la versión siguiente, que es inmutable y traeversion_no,digestysurvey_version_id, el identificador que usan las campañas.- La vista de la definición informa
draft_state(draft,readyoapproved, que son estados del borrador en la aplicación),draft_digest,latest_version_noylatest_version.
Campañas
| Campo | Descripción |
|---|---|
source_revision | Obligatorio. Entero mayor o igual que 1. |
survey_version_id | Obligatorio. UUID de una versión publicada: una de las definiciones de la propia integración o una otorgada. Una versión retirada responde 409 version_retired. |
title | Obligatorio. De 1 a 160 caracteres. |
owner_label | Opcional. Hasta 120 caracteres. |
modality | Obligatorio. identified o confidential, entre las que admite la versión y las otorgadas. |
audience | Obligatorio. { "mode": "selected", "group_ids": ["…"], "user_ids": [12] } con grupos y personas otorgados (hasta 100 grupos y 200 personas), o { "mode": "tenant" } con allow_tenant_audience. |
context | Opcional. { "channel_id": "…", "publication_external_id": "…" }: un canal otorgado y, si se indica, una publicación de Comunicados de la misma integración y entorno, que debe estar publicada. Exige que la empresa tenga Comunicados. |
starts_at, ends_at | Opcionales mientras es borrador. Instantes RFC 3339 con zona explícita. El fin es posterior al inicio y la campaña dura como máximo 365 días. Programar exige ambas, y abrir exige ends_at. |
timezone | Zona horaria IANA. Por omisión, America/Santiago. |
allow_revisions | true permite que una persona corrija su respuesta. Por omisión, false. |
retention_days | Entero de 30 a 365. Si se omite, rige el valor de la empresa. |
min_k | Entero de 10 a 1.000, no menor que el mínimo de la empresa. Si se omite, rige ese mínimo. Es el umbral bajo el cual no se publican cifras. |
- Un
PUTsolo escribe borradores. Guardar un borrador descarta el resumen de lanzamiento y la aprobación que tuviera. - La vista de la campaña informa
stateyeffective_state, que incorpora el reloj: una campaña abierta cuya fecha de fin pasó figura como cerrada. Los estados sondraft,scheduled,open,paused,blocked,closed,cancelledyarchived. Informa tambiénblocked_reason,audience,context, las fechas,launch_digest,approved,cohort(fixed_atysize) yresults_ready. - La audiencia de la vista trae
user_county solo traeuser_idssi el permiso incluyepeople. La vista nunca lista personas ni respuestas.
Resumen del lanzamiento
POST /campaigns/{external_id}/launch-preview solo vale en una campaña en borrador o bloqueada. Responde { digest, expires_at, counts, warnings, context_state, cohort_fixed, requires_approval, snapshot, environment, simulation }: los conteos de la cohorte, las advertencias, el estado del contexto y el resumen que consumen schedule, open y resume. No incluye personas. La cohorte se fija al programar o al abrir.
Acciones del ciclo
| Acción | Desde | Hacia | Exige |
|---|---|---|---|
schedule | draft | scheduled | can_publish, el digest vigente, starts_at futuro y ambas fechas. La campaña se abre sola en starts_at |
open | draft o scheduled | open | can_publish, ends_at futuro y, desde draft, el digest vigente |
pause | open | paused | Escritura |
resume | paused o blocked | open, o el estado previo si estaba bloqueada | can_publish. Desde blocked, también el digest vigente |
close | open, paused o blocked | closed | Escritura. Publica el resultado final |
cancel | draft, scheduled, open, paused o blocked | cancelled | Escritura |
archive | closed | archived | Escritura |
El cuerpo es { "action": "…", "digest": "…" }, con If-Match. Una acción que no corresponde al estado responde campaign_not_draft, campaign_not_open, campaign_paused, campaign_not_paused, campaign_blocked, campaign_closed, campaign_not_closed. Una campaña bloqueada porque cambió o dejó de estar disponible su contexto (context_changed o context_unavailable) no se reanuda por la API: revalidar el contexto es una decisión de una persona, y la acción revalidate_context responde 422 invalid_field.
Vistas previas y aprobación
- Publicar una definición, y programar, abrir o reanudar desde
blockeduna campaña, exigen eldigestde la última vista previa emitida sobre ese objeto. Si falta,409 preview_required. Si venció,409 preview_expired. Si es otro, o se calculó con otra concesión osource_revision,409 preview_stale. - La vista previa vive 5 minutos, medidos con el reloj de la base de datos. Repetirla con la misma clave de idempotencia no prolonga su vigencia. Escribir el objeto la descarta, y un cambio aplicado la consume.
- Con doble control en la empresa, o si el objeto es confidencial, la vista previa informa
requires_approval: truey la credencial no basta: una persona debe aprobar en la aplicación el resumen exacto. Debe ser una persona distinta de las autoras del borrador y de la responsable del permiso. Si falta,409 approval_required(details.reasonesseparation_of_dutiessi la persona no es válida). - Pausar, cerrar, cancelar y archivar no exigen
can_publishni resumen, pero sí escritura y cobertura de la concesión.
Resultados
GET /campaigns/{external_id}/results exige can_read_results y una campaña propia con vínculo activo. Entrega solo el agregado que permite la política de privacidad: nunca filas, textos libres, nombres ni filtros libres. Cada consulta queda registrada con la misma política que la aplicación.
state | Cuándo | Contenido |
|---|---|---|
not_started | La campaña es un borrador o está programada. | Solo el estado. |
collecting | Una campaña confidencial está abierta, pausada o bloqueada. | Solo el estado: sin cifras, contador ni progreso. |
live | Una campaña identificada está abierta, pausada, bloqueada o cancelada. | Agregados y denominadores al momento de la consulta. |
ready | La campaña se cerró o se archivó. | El resultado final, con snapshot_id y published_at. |
cancelled | Una campaña confidencial se canceló. | Solo el estado. |
Un resultado con cifras trae privacy (min_k y rules_version), respondents y, en una campaña identificada, denominators. Cada pregunta trae sus grupos, con el conteo de cada opción, n y suppressed: una cifra de un grupo menor que min_k se suprime. Una consulta consume la cuota de lecturas y la de resultados.
Integraciones de pruebas
Una integración de ambiente de pruebas trabaja en su propio espacio, que nunca ven las personas, y simula en lugar de rechazar. publish y toda transition validan el esquema, la concesión, can_publish y el resumen, y responden 200 con simulation: true, would_state y requires_approval, más would_version_no al publicar. No crean versión, cohorte ni eventos, ni consumen una aprobación. Los resultados son un ejemplo rotulado con simulation, fixture y notice, nunca datos reales.
El resumen de una vista previa de pruebas lleva el ambiente y la integración: no sirve en producción (409 preview_stale).
Límites y cuotas
| Alcance | Límite | Al excederlo |
|---|---|---|
| Cuerpo de la solicitud | 640 KiB | 413 payload_too_large |
| Documento de una definición | 512 KiB | 422 field_length |
| Por integración, cada minuto | 120 lecturas, 30 escrituras y 10 consultas de resultados | 429 rate_limited con Retry-After: 60 |
| Por empresa, cada minuto | 600 lecturas, 150 escrituras y 30 consultas de resultados | 429 rate_limited con Retry-After: 60 |
| Objetos nuevos por integración, borradores incluidos | 300 por hora | 429 object_quota_exceeded con Retry-After: 600 |
| Objetos vinculados vivos por integración | 10.000 | 409 binding_limit_reached |
| Campañas programadas, abiertas, pausadas o bloqueadas por empresa | 200 | 409 tenant_content_limit |
Las cuotas por minuto se miden con un contador compartido y no pasan sin medir: si el contador no responde, la solicitud se rechaza con 503 quota_unavailable y Retry-After: 30, no se ejecuta y no tiene efecto. Reintente con la misma Idempotency-Key. Una consulta de resultados consume el cupo de lecturas y el de resultados, de la integración y de la empresa. Los topes son máximos y pueden estar fijados en un valor menor. Los demás límites se miden en la base de datos.
Si la empresa está en modo de solo lectura por mantenimiento, toda escritura nueva responde 503 surveys_read_only con Retry-After: 60, sin efecto. Las lecturas y la repetición de operaciones ya confirmadas siguen disponibles. Si el plan de la empresa no incluye Encuestas, la respuesta es 403 module_unavailable.
Control y revocación
Cada objeto informa control: integration mientras lo gobierna la integración y local si una persona tomó el control en la aplicación. Con control: local, toda escritura externa responde 409 manual_control y no tiene efecto. Una persona puede devolver el control desde la aplicación: la última source_revision aceptada queda como piso, y solo una revisión estrictamente mayor avanza, incluso la misma revisión con el mismo cuerpo responde 409 source_revision_conflict.
- Quitar el permiso de Encuestas o revocar la integración libera sus objetos: pasan a control local, las campañas programadas quedan
blocked(blocked_reasongrant_removedointegration_revoked), se cancelan los trabajos pendientes y se conservan la identidad, las respuestas y el historial. - Volver a otorgar el permiso no reclama lo liberado: la integración recibe
409 manual_controlhasta que una persona devuelva el control. - El sistema revalida contra la concesión de hoy lo que la integración dejó programado antes de abrirlo. Si ya no cubre la versión, la audiencia, el canal, la modalidad o
can_publish, bloquea la campaña conauthority_losty nunca la abre con una autoridad más amplia que la vigente.
Errores
Los errores usan application/problem+json (RFC 9457) con type, title, status, detail, code y correlation_id. Algunos añaden un miembro details: fields (hasta cinco campos), field, max_bytes, current_source_revision, reason, errors, supported o required. El detalle nunca repite el contenido enviado ni revela datos de otra empresa.
La lista completa, con la causa y la acción de cada código, está en Errores.
Ejemplos
Los identificadores, las fechas y los resúmenes del lanzamiento son de ejemplo. El resumen de la definición y los de su vista previa se calcularon con el código de la API sobre el documento que se muestra.
1. Crear la definición
PUT /api/v1/integrations/data/surveys/definitions/erp-encuesta-abastecimiento HTTP/1.1
Host: daas.masnet.com
Authorization: Bearer <token>
X-Surveys-Contract: 1
Idempotency-Key: 41e7b0c9-85d2-4a36-9f1e-6c0d3a8b5e72
If-None-Match: *
Content-Type: application/json
{
"source_revision": 1,
"title": "Satisfacción con el área de abastecimiento",
"owner_label": "Área de abastecimiento",
"allowed_modalities": ["identified"],
"document": {
"schema_version": 1,
"rule_engine_version": 1,
"default_locale": "es",
"locales": [
"es"
],
"title": {
"es": "Satisfacción con el área de abastecimiento"
},
"description": {
"es": "Encuesta anual sobre la atención del área de abastecimiento."
},
"estimated_minutes": 3,
"pages": [
{
"id": "atencion",
"title": {
"es": "Atención recibida"
},
"items": [
{
"kind": "info",
"id": "intro",
"body": {
"format": "markdown",
"value": "Sus respuestas ayudan a **mejorar** el servicio."
}
},
{
"kind": "question",
"id": "calificacion",
"type": "scale",
"required": true,
"min": 1,
"max": 5,
"title": {
"es": "¿Cómo califica la atención del área de abastecimiento?"
},
"labels": {
"min": {
"es": "Muy mala"
},
"max": {
"es": "Muy buena"
}
}
},
{
"kind": "question",
"id": "recomienda",
"type": "yes_no",
"required": true,
"title": {
"es": "¿Volvería a solicitar apoyo al área?"
}
},
{
"kind": "question",
"id": "mejoras",
"type": "long_text",
"required": false,
"title": {
"es": "¿Qué podemos mejorar?"
},
"visible_when": {
"op": "lte",
"question": "calificacion",
"value": 3
}
}
]
}
]
}
}HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Cache-Control: private, no-store
X-Surveys-Contract: 1
ETag: "Zr7LkP3wN0cXq9TuV5aYhB"
Location: /api/v1/integrations/data/surveys/definitions/erp-encuesta-abastecimiento
{
"contract_version": 1,
"data": {
"external_id": "erp-encuesta-abastecimiento",
"kind": "definition",
"control": "integration",
"environment": "production",
"source_revision": 1,
"write_available": true,
"id": "a1c4e7d2-58b3-4f19-8e26-0d93b7c15a64",
"family_id": "5d0b8f31-92c7-4a6e-b1d4-3e7f60a9c2b8",
"title": "Satisfacción con el área de abastecimiento",
"owner_label": "Área de abastecimiento",
"draft_state": "draft",
"draft_digest": "8c754920f8b54805acfeee4c11e08c2f822550b20743cfac3b0d7e3e66e49a3a",
"allowed_modalities": ["identified"],
"latest_version_no": 0,
"latest_version": null,
"row_version": "1",
"etag": "\"Zr7LkP3wN0cXq9TuV5aYhB\"",
"created_at": "2026-11-04T14:40:12.508Z",
"updated_at": "2026-11-04T14:40:12.508Z"
}
}2. Previsualizar el borrador
La solicitud es POST /definitions/erp-encuesta-abastecimiento/preview con el cuerpo {} y las mismas cabeceras de autenticación e idempotencia.
{
"contract_version": 1,
"data": {
"external_id": "erp-encuesta-abastecimiento",
"ok": true,
"digest": "260b7834294b3f41b753c06854f7aff2e3f8833594b737d9013b96c98b19aa67",
"compiled_digest": "03863614ef4cf7f8a63defc0ec182d7809d68b946c9440be3d7d8437009cf6f2",
"allowed_modalities": ["identified"],
"budget": { "max_bytes": 262144, "reserved_bytes": 16384, "used_bytes": 24051 },
"expires_at": "2026-11-04T14:46:40.000Z",
"requires_approval": false,
"environment": "production",
"simulation": false
}
}3. Publicar la versión
POST /api/v1/integrations/data/surveys/definitions/erp-encuesta-abastecimiento/publish HTTP/1.1
Host: daas.masnet.com
Authorization: Bearer <token>
X-Surveys-Contract: 1
Idempotency-Key: 7d2a9f06-3b84-4c15-a0e7-95c1b6e8d340
If-Match: "Zr7LkP3wN0cXq9TuV5aYhB"
Content-Type: application/json
{ "digest": "260b7834294b3f41b753c06854f7aff2e3f8833594b737d9013b96c98b19aa67" }4. Crear la campaña
PUT /api/v1/integrations/data/surveys/campaigns/erp-campana-abastecimiento-2026 HTTP/1.1
Host: daas.masnet.com
Authorization: Bearer <token>
X-Surveys-Contract: 1
Idempotency-Key: e08b5c37-92a1-4d64-8c3f-1a7d0b6e9f25
If-None-Match: *
Content-Type: application/json
{
"source_revision": 1,
"survey_version_id": "c92e1b47-3a85-4d0f-a6b2-7f18d4e95c03",
"title": "Satisfacción con el área de abastecimiento, noviembre 2026",
"modality": "identified",
"audience": { "mode": "selected", "group_ids": ["7b3e5a90-2c14-4e8d-a5f7-91d6c0b48e23"] },
"starts_at": "2026-11-09T09:00:00-03:00",
"ends_at": "2026-11-20T18:00:00-03:00",
"timezone": "America/Santiago"
}{
"contract_version": 1,
"data": {
"external_id": "erp-campana-abastecimiento-2026",
"kind": "campaign",
"control": "integration",
"environment": "production",
"source_revision": 1,
"write_available": true,
"id": "e4a7d036-1b58-4c92-9f3d-6a20b8c71e45",
"survey_id": "a1c4e7d2-58b3-4f19-8e26-0d93b7c15a64",
"survey_version_id": "c92e1b47-3a85-4d0f-a6b2-7f18d4e95c03",
"title": "Satisfacción con el área de abastecimiento, noviembre 2026",
"owner_label": null,
"modality": "identified",
"state": "draft",
"effective_state": "draft",
"blocked_reason": null,
"audience": { "mode": "selected", "group_ids": ["7b3e5a90-2c14-4e8d-a5f7-91d6c0b48e23"], "user_count": 0 },
"context": null,
"starts_at": "2026-11-09T12:00:00.000Z",
"ends_at": "2026-11-20T21:00:00.000Z",
"timezone": "America/Santiago",
"allow_revisions": false,
"retention_days": 180,
"min_k": 10,
"launch_digest": null,
"approved": null,
"cohort": { "fixed_at": null, "size": null },
"opened_at": null,
"closed_at": null,
"cancelled_at": null,
"archived_at": null,
"results_ready": false,
"state_seq": "1",
"etag": "\"Hs2VdM8eJ4gTn1QxC6bWyK\"",
"created_at": "2026-11-04T14:52:30.221Z",
"updated_at": "2026-11-04T14:52:30.221Z"
}
}5. Programar la campaña
Antes se pide POST /campaigns/erp-campana-abastecimiento-2026/launch-preview, y su digest va en la acción.
POST /api/v1/integrations/data/surveys/campaigns/erp-campana-abastecimiento-2026/transition HTTP/1.1
Host: daas.masnet.com
Authorization: Bearer <token>
X-Surveys-Contract: 1
Idempotency-Key: 5c91d8a3-0e47-4b2f-96d1-a3f7e2b04c68
If-Match: "Hs2VdM8eJ4gTn1QxC6bWyK"
Content-Type: application/json
{
"action": "schedule",
"digest": "9e07c3b5a1d84f6270b3e5c98a1d47f06b2e8c35d9a07f14e6b3c0a28d5f9174"
}6. Leer los resultados de una campaña confidencial en curso
La solicitud es GET /campaigns/erp-campana-clima-2026/results.
{
"contract_version": 1,
"data": {
"external_id": "erp-campana-clima-2026",
"contract_version": 1,
"server_now": "2026-11-12T13:05:44.912Z",
"modality": "confidential",
"state": "collecting"
}
}Una vista previa vencida
HTTP/1.1 409 Conflict
Content-Type: application/problem+json; charset=utf-8
{
"type": "https://masnet.com/developers/errors/preview_expired",
"title": "Conflicto",
"status": 409,
"detail": "El recurso cambió o la operación no corresponde a su estado.",
"code": "preview_expired",
"correlation_id": "7e3c0b92-6d14-4a85-b1f7-20c9d5a8e413"
}Cuota no disponible
HTTP/1.1 503 Service Unavailable
Content-Type: application/problem+json; charset=utf-8
Retry-After: 30
{
"type": "https://masnet.com/developers/errors/quota_unavailable",
"title": "Cuota no disponible",
"status": 503,
"detail": "No se pudo medir la cuota; la solicitud no se ejecutó.",
"code": "quota_unavailable",
"correlation_id": "b27e90c4-1d63-4a58-8f0b-7c5a2e9d1f36"
}