Emisso Connect
Conceptos

La bitácora

Cada llamada deja exactamente una fila inmutable: auditoría, correlación con soporte y fuente de verdad de la facturación.

Toda ejecución de una tool, entre por REST, por MCP, desde el dashboard o disparada por el scheduler, escribe exactamente una fila en la bitácora. La tabla es append-only por doble candado (ningún rol de aplicación tiene UPDATE ni DELETE, y no existe política que los permita), así que una fila escrita no se edita nunca. Sobre ese registro se apoyan tres cosas a la vez: la auditoría, el soporte y la facturación. No hay un contador de cobro separado que pueda divergir de lo que de verdad pasó.

La anatomía de una fila

Las columnas que vas a usar, de la tabla real bitacora_execution:

ColumnaQué guardaPor qué importa
request_idEl req_… de esta llamada, generado por el servidorLa llave de correlación: viaja en el meta de cada respuesta y dentro de cada error
tool_id / connector_codeQué se ejecutó (sii.rcv.consultar) y de qué sistemaEl grano de todo análisis de uso
connection_idLa conexión (conn_…); null en conectores sin conexiónAtribuye la llamada a una empresa concreta
planeaction o readDistingue una consulta barata de una sincronización real (Los dos planos)
surfacerest, mcp_meta, mcp_native, dashboard o hostedPor dónde entró la llamada
actor_id / actor_typeQuién actuó: user, agent, system o connect_sessionLa atribución (abajo)
credential_idLa credencial que autenticó (el id de la API key)Separada del actor a propósito
input_digestsha256 del input canonicalizado y redactadoCompara inputs sin poder reconstruirlos
result_status / error_codeok o error, y con qué códigoLas fallas también dejan fila
latency_msDuración de la ejecuciónEl mismo valor que viaja en meta.latency_ms
parent_request_idEn MCP, la fila del delegado apunta a la del execute que lo invocóReconstruye la cadena meta-tool → tool del catálogo
meter_category / billable_units / billableLa clasificación de cobroLa facturación (abajo)
created_atCuándoJunto a un id monotónico para paginar por cursor

Atribución: humano o agente, nunca confundidos

Una API key autentica como agente: actor_type: "agent", con el id de la clave como actor_id. Un token OAuth o una sesión del dashboard autentican como usuario. En ningún caso la acción de un agente se atribuye al humano dueño de la credencial, porque la fila diría una mentira y la bitácora existe para lo contrario. Por eso credential_id es una columna aparte: revocar una clave no reescribe la autoría de nada.

El input no se guarda: se guarda su huella

input_digest es sha256(canonicalize(redact(input))). Antes de calcular el hash, todo campo con forma de secreto (token, password, credential, api key) se reemplaza por un marcador; después, el objeto se serializa con las llaves ordenadas, para que el mismo input produzca siempre el mismo digest. El resultado permite responder «¿estas dos llamadas llevaron el mismo input?» sin poder reconstruir el input. La credencial de una conexión ni siquiera llega aquí: se resuelve server-side y jamás aparece en un resultado, en un log ni en la bitácora.

De un request_id a su fila

Toda respuesta lleva meta.request_id, y todo error lo repite dentro del envelope junto al suggested_fix. Con ese req_… encuentras la fila en el dashboard, y es el dato que soporte te va a pedir. El meta.audit_status de la respuesta cierra el círculo: recorded significa que la fila quedó escrita en línea; degraded, que el registro cayó a un respaldo durable. Una acción que ya se ejecutó con éxito nunca se convierte en un 5xx porque falló su auditoría; ese 5xx invitaría a reintentar una acción regulada ya hecha.

Qué se factura

La bitácora es la fuente de verdad de la facturación, y la columna billable la calcula la base de datos, no el código de aplicación: exige result_status = 'ok', una categoría facturable y billable_units > 0. Las consecuencias prácticas:

  • Un error nunca factura. billable_units queda en 0 en toda fila fallida.
  • meter_category clasifica cada llamada. action_call, read_sync y read_query cuentan contra el plan; meta (las meta-tools de MCP), internal (conectores abiertos como core e indicadores) y unclassified son overhead y no cuentan.
  • Los conectores abiertos dejan fila igual, con billable_units: 0: auditar y cobrar son ejes distintos.
  • Lo que haces en tu propio dashboard no gasta tu cuota. Una llamada con surface: "dashboard" o "hosted" se audita idéntica a cualquier otra y factura 0: guardar tu credencial o paginar tus propios datos no puede consumir la cuota de tu integración.

Lo que no está en la bitácora

Dos registros vecinos completan el cuadro. Las fallas de autenticación no tienen organización que las reciba (el token no resolvió a ningún tenant), así que van a security_events, que guarda el prefijo de la credencial y nunca el token completo. Y los cambios de configuración (crear una clave, deshabilitar una conexión, rotar una credencial) van a audit_control, el registro del plano de control, con su before y su after.

Dónde verla

En connect.emisso.ai/bitacora: las columnas Actor, Herramienta, Scope, Plano, Resultado, Latencia, request_id y Fecha, con filtro por API key. Cada conexión tiene además su propia pestaña de bitácora, con las ejecuciones y los cambios de configuración que la tocaron.

Próximos pasos

  • Autenticación: quién puede escribir estas filas y cómo.
  • Conexiones: la unidad a la que se atribuye cada llamada.
  • Errores: el catálogo completo, con suggested_fix por código.

On this page