Skip to content

Todos los artículos

Provider API v1

Emperor obtiene usuarios registrados y actividad diaria de las aplicaciones con un contrato compartido. Cualquier aplicación puede implementarlo, no solo las propias. La aplicación queda como origen; las sincronizaciones posteriores actualizan los datos. La misma persona en varias apps no crea un Person duplicado.

Esta página es para equipos que implementan el contrato. El documento OpenAPI 3.1 está en la especificación de Provider API. Genere tipos de cliente desde esa ruta en el mismo origen que este sitio.

v1 es un borrador y puede cambiar hasta que Emperor lo finalice. Después de la finalización, los cambios incompatibles salen como /v2.

Recursos

La aplicación sirve tres recursos GET bajo /v1, relativos al baseUrl de la conexión Facility:

  • /v1/manifest — versión del contrato (1), nombre de la aplicación, zona horaria IANA para agrupar días de actividad y el catálogo de claves de actividad con etiquetas.
  • /v1/users — usuarios. Consulta: updatedSince, cursor, limit.
  • /v1/activity — agregados diarios, una fila por usuario, día y clave del catálogo. Los mismos parámetros de consulta que users.

Si contractVersion no es 1, Emperor rechaza la conexión con un error explícito.

Cursores y sobrescritura de actividad

updatedSince es un datetime ISO-8601 con desplazamiento o Z. Devuelva registros con updatedAt mayor o igual que ese valor. Sin el parámetro, exportación completa. cursor es una cadena opaca del nextCursor de la página anterior. limit vale 100 por defecto y no debe superar 100.

Las listas responden { "data": [...], "nextCursor": null | string }. nextCursor es null en la última página.

Una fila de actividad posterior para el mismo (externalUserId, day, metricKey) sustituye el recuento guardado. Las aplicaciones envían totales diarios, no eventos crudos.

Correo o teléfono

Cada usuario debe incluir email, phone (E.164, por ejemplo +79991234567) o ambos. Un registro sin ninguno lo rechaza el contrato. Emperor lo cuenta como rechazado en la sincronización y no crea un Person.

Cómo Emperor relaciona contactos

Una persona en el CRM es Person. El correo y el teléfono son filas Contact (tipos EMAIL y TELEPHONE). La identidad de la aplicación vive en un enlace aparte: una persona, varias apps.

  • El correo se normaliza. El teléfono se guarda en E.164.
  • Una identidad ya vinculada a un Person se actualiza.
  • Una identidad nueva sin coincidencias crea un Person.
  • Cualquier coincidencia con un Person existente, incluido un conflicto de correo/teléfono, va a una cola de revisión manual. No hay fusión automática.

Lista de conexión

  1. Publicar /v1/manifest, /v1/users y /v1/activity solo por HTTPS en producción.
  2. Emitir un token Bearer de alta entropía por par proyecto–aplicación, solo lectura de esta API. No reutilizar una clave de servicio.
  3. Comparar el token en tiempo constante. Una petición sin Bearer válido responde 401 como RFC 7807 application/problem+json. No distinguir si faltaba el token o era incorrecto.
  4. Aceptar User-Agent: Emperor-AppProvider/1.0 y X-Request-Id (UUID). Devolver ese id en documentos problem al responder errores.
  5. En 429, enviar Retry-After.
  6. Rotación: aceptar el token actual y el anterior durante la ventana de rotación; después revocar el antiguo.
  7. En desarrollo local, Emperor permite baseUrl HTTP en claro solo si APP_PROVIDER_ALLOW_PLAIN_HTTP=true (lo pone el script de desarrollo del frontend). En producción solo se acepta HTTPS.

Seguridad y registro de auditoría de la aplicación

v1 es HTTPS más un token Bearer en el par proyecto–aplicación. HMAC, mTLS y OAuth2 no forman parte de esta versión.

Recomendado (no es un requisito de esquema): registrar cada petición de Provider API con hora, IP de origen, X-Request-Id, User-Agent, recurso (manifest / users / activity), updatedSince, estado HTTP y número de registros devueltos. No registrar el token, la cabecera Authorization, el correo, el teléfono ni los cuerpos de respuesta.

También: un token solo para esta API; límite de ritmo; alertas ante un ráfaga de 401, un User-Agent ajeno, una IP inesperada o un salto brusco de volumen. No exigir una allowlist de IP: el egress de Emperor en Kubernetes no es una dirección fija.

Artículos