Documentación

Qué lee Metricaas de cada gateway, qué asume cuando el gateway no lo registra, y cómo obtener cada número de vuelta.

En esta página

Guía

Qué hace la API, cómo autenticarte, cómo mandar tus datos y qué esperar cuando algo sale mal. Léela una vez, de arriba abajo, antes de la primera llamada.

Cómo empezar

Visión general

Una clave, dos cosas. La lectura sirve a cualquier cuenta; el envío solo hace falta si la fuente de datos eres tú.

  • LEER tus métricas: MRR, churn, LTV, ingresos y 14 más, en el período y la agregación que pidas. Vale para cualquier fuente (Stripe, Asaas o datos personalizados).
  • ENVIAR tus datos: suscripciones, clientes y pagos, para quien no usa una pasarela que integramos. En ese caso también puedes cargarlos en la pantalla o subir una planilla, con las mismas reglas.
Dirección base: https://api.metricaas.ai/v1

Todo es JSON, todo se autentica con clave, y las fechas son AAAA-MM-DD en la zona horaria de tu cuenta.

Los endpoints

MétodoEndpointQué es
GET/v1/metrics/{metric}Serie de una métrica
GET/v1/metricsCatálogo de métricas
POST/v1/subscriptionsCrear o actualizar suscripciones
DEL/v1/subscriptions/{id}Borrar una suscripción
GET/v1/subscriptionsListar suscripciones
POST/v1/customersCrear o actualizar clientes
DEL/v1/customers/{id}Borrar un cliente
GET/v1/customersListar clientes
POST/v1/paymentsCrear o actualizar pagos
DEL/v1/payments/{id}Borrar un pago
GET/v1/paymentsListar pagos

Autenticación

Cada llamada lleva tu clave en la cabecera. La clave pertenece a tu EMPRESA (no a ti), y cada una carga solo los permisos que marcaste al crearla.

Authorization: Bearer mtc_live_...
  • metrics:read - leer métricas. Es lo que necesitas para traer tus números.
  • data:write - enviar datos. Solo existe en cuentas con una fuente de datos personalizados, y la clave escribe en esa fuente.

Solo guardamos un resumen criptográfico de la clave, así que ni nosotros podemos mostrarla de nuevo. ¿La perdiste? Genera otra y revoca la anterior. Genérala en Configuración > API.

La primera llamada

El MRR de los últimos 12 meses, mes a mes. Cambia mrr por cualquier métrica del catálogo.

curl "https://api.metricaas.ai/v1/metrics/mrr?from=2026-01-01&to=2026-12-31&interval=month" \
  -H "Authorization: Bearer mtc_live_..."
{
  "metric": "mrr",
  "unit": "money",
  "aggregation": "point_in_time",
  "currency": "BRL",
  "timezone": "America/Sao_Paulo",
  "interval": "month",
  "from": "2026-01-01",
  "to": "2026-12-31",
  "points": [
    {
      "start": "2026-01-01",
      "end": "2026-02-01",
      "value": 1250000,
      "count": 42
    },
    {
      "start": "2026-02-01",
      "end": "2026-03-01",
      "value": 1310000,
      "count": 44
    }
  ]
}

Es el mismo número de la pantalla, y no por disciplina: por construcción. La API llama al mismo motor que el panel, pide la misma fila y no hace ninguna cuenta encima. No hay un lugar donde los dos puedan divergir.

Cómo leer el valor

unit dice cómo leer el value: money son CENTAVOS en la moneda de la cuenta (1250000 = $12.500,00), percent es una FRACCIÓN (0.0312 = 3,12%), count es un entero.

aggregation dice qué SIGNIFICA el número. point_in_time es una foto al final del bucket (MRR, ARR, suscriptores, LTV). sum_over_period es la suma de lo que pasó en el bucket (ingresos, trials). rate_over_period es una tasa del bucket (churn, crecimiento).

Sumar fotos es el error más común de quien consume métricas de SaaS por API. El MRR de enero más el de febrero no es el MRR del bimestre: es un número que no existe. Los ingresos, en cambio, sí se suman. Por eso el aggregation viaja en cada respuesta.

El calendario es el DE TU CUENTA (la zona horaria que configuraste), nunca UTC. Es lo que hace que "marzo" signifique marzo para ti.

Enviar tus datos

Solo quien NO usa un gateway integrado necesita esta parte. Si tus datos vienen de Stripe o Asaas, ya llegan solos: salta a la Referencia.

Empezando

En la fuente de datos personalizados, quien declara los datos eres tú. No hay un gateway del otro lado que verifique nada, así que lo que declares aquí es la verdad sobre la que se calcula cada número de tu cuenta. Si tu sistema deja de enviar, tu panel se congela en el último dato que llegó.

  1. En Metricaas, agrega una fuente de tipo Datos personalizados y responde las tres preguntas (si vas a informar pagos, si cada suscripción tiene plan, si vas a registrar clientes).
  2. En Configuración > API, genera una clave. Aparece una sola vez.
  3. Envía tus suscripciones. El panel se mueve en menos de un minuto.

Los tres recursos: uno obligatorio, dos opcionales

La suscripción es lo único que necesitamos. Los otros dos son opcionales, y cada uno DESBLOQUEA una parte del producto: eliges lo que quieres ver, y lo pagas enviando el dato correspondiente.

/v1/subscriptionsObligatorio

El corazón de la fuente. De aquí sale tu MRR -- sin suscripciones no hay ninguna métrica que calcular.

Qué desbloquea: MRR, ARR, churn, expansión, contracción, LTV, ARPA, suscriptores activos, cohortes. Es decir: casi todo.

/v1/customersOpcional

Opcional. Solo hace falta si un mismo cliente tiene más de una suscripción -- sin clientes, cada suscripción cuenta como un cliente. El único campo obligatorio es el id, así que puedes agrupar sin contarnos quiénes son.

Qué desbloquea: Agrupar suscripciones por cliente (el ARPA y el LTV pasan a ser POR CLIENTE, no por suscripción), la pantalla de Clientes con nombre, correo y teléfono, y la búsqueda por cualquiera de ellos.

/v1/paymentsOpcional

Opcional. Sin pagos, el MRR sigue entero: sale del contrato, no del dinero que entró.

Qué desbloquea: Ingresos cobrados, comisiones del medio de pago, reembolsos, ingreso neto y MOROSIDAD -- que sin los pagos simplemente no existe en tu cuenta (no hay forma de saber quién dejó de pagar).

Tú declaras lo que vas a enviar en la configuración de la fuente (los tres interruptores: pagos, planes, clientes). Declarar que vas a enviar y no enviar es peor que no declarar: el panel espera un dato que nunca llega.

El importe es un HISTORIAL, no un número

En una pasarela, el historial del precio vive en las facturas: cada una es un periodo cobrado, con el precio de ese día. Aquí no hay facturas, así que el historial vive dentro de la suscripción, en el campo amounts.

Cada tramo dice cuánto pasó a valer, y desde cuándo. El primero empieza cuando empezó la suscripción. Eso es lo que hace que el MRR de marzo siga siendo el de marzo después de que subes el precio en abril.

{
  "amounts": [
    {
      "from": "2024-01-10",
      "cents": 9900,
      "cycle": "monthly",
      "plan": "Pro"
    },
    {
      "from": "2024-06-10",
      "cents": 99000,
      "cycle": "yearly",
      "plan": "Pro anual"
    }
  ]
}

Por eso, un envío que no PRESERVE un tramo ya declarado se rechaza con 409 (incluso al insertar un tramo antes de otro ya programado). Si el tramo afectado ya comenzó, esto reescribe el MRR de meses que ya cerraron. Si fue un ajuste de precio, agrega un tramo nuevo. Si fue un error de tipeo, confirma que de verdad quieres reescribir:

POST https://api.metricaas.ai/v1/subscriptions?correct_history=true

Cancelar no es borrar

Cancelar es un hecho de tu negocio: el cliente se fue, la suscripción queda en el historial y se vuelve churn en la fecha declarada. Borrar es una errata: nunca existió, y el MRR pasado se rehace sin ella. Confundir las dos corrompe tu churn en ambas direcciones.

# el cliente se fue (se vuelve churn)
POST https://api.metricaas.ai/v1/subscriptions          { "id": "sub_001", "canceled_at": "2026-03-01", ... }

# lo escribi mal (desaparece del historial)
DELETE https://api.metricaas.ai/v1/subscriptions/sub_001

Idempotencia (opcional)

Ya tienes idempotencia sin hacer nada: el id del objeto es tuyo. Enviar la misma suscripción dos veces la ACTUALIZA, no la duplica. Para la mayoría de los casos, eso es todo lo que necesitas saber.

El header de abajo sirve para un caso concreto: conectaste nuestra API a un sistema de webhooks tuyo, y este puede disparar el mismo evento dos veces a la vez. Envía la misma Idempotency-Key en ambas: el trabajo ocurre una vez, y las dos peticiones reciben la misma respuesta.

Idempotency-Key: evt_7f3c9a21
  • Repetiste con la misma clave y el mismo cuerpo: recibes la respuesta guardada (el mismo estado, el mismo JSON), con el header Idempotent-Replay: true. Nada se reprocesa.
  • La primera todavía está en curso: la segunda recibe 409 (in_progress). Reintenta en unos segundos para recibir su respuesta.
  • La misma clave con un cuerpo distinto se rechaza con 400. Una clave es una petición: usa una clave nueva para un contenido nuevo.
  • Si la petición falló, la clave se libera. Corriges el cuerpo y la envías de nuevo con la misma clave, con normalidad.

Errores y límites

Errores

El rechazo lista TODOS los problemas de una vez, con el campo (y, en la planilla, la línea). No vas a arreglar uno por petición.

{
  "error": {
    "code": "invalid_request",
    "message": "a declaracao tem 2 problema(s)",
    "details": [
      {
        "field": "subscription.cycle (sub_002)",
        "line": 4,
        "reason": "invalid option"
      },
      {
        "field": "subscription.amounts (sub_007)",
        "line": 9,
        "reason": "..."
      }
    ]
  }
}
  • 200 - éxito (la lectura de métricas).
  • 202 - aceptado (el envío de datos). Tu panel se mueve en hasta un minuto.
  • 400 - la petición tiene problemas: parámetro inválido, o declaración rechazada. No se grabó nada.
  • 401 - clave inválida, revocada, o sin permiso para esta operación.
  • 402 - el plan de la cuenta no permite leer las métricas ahora (el MRR pasó el techo del gratis, o el de la franja contratada). Resuélvelo en metricaas.ai/billing.
  • 404 - la métrica no existe. Pide GET /v1/metrics para la lista completa.
  • 409 - esto reescribiría el historial de valor ya declarado (o hay una petición igual en curso).
  • 429 - demasiadas peticiones. Envía en lote.

Límites

  • 120 peticiones por minuto, por clave. Cada respuesta trae las cabeceras X-RateLimit-* con lo que queda.
  • Hasta 1000 objetos por envío (un array en el cuerpo). O entra todo, o no entra nada.
  • Hasta 1000 puntos por serie. Por encima de eso la respuesta es un 400 pidiendo un intervalo mayor: nunca una serie cortada por la mitad, que se lee como un negocio que se detuvo.
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 1781827200

Fuentes de datos

De dónde vienen tus números: qué registra cada gateway, qué no registra, y qué asumimos en su lugar.

Introducción

Qué es una fuente

De dónde vienen tus números. Cada gateway tiene una sección abajo con lo que registra, lo que no registra y las premisas que asumimos en su lugar. ¿No usas ningún gateway integrado? La fuente de Datos personalizados cubre el mismo terreno, y eres tú quien declara los datos en lugar del gateway.

Cómo se arma el número

Una fuente es de donde vienen tus números. El motor lee lo que la fuente registró, lo traduce al modelo interno de Metricaas y calcula tus métricas a partir de eso. Donde la fuente no registra algo, no lo inventamos: o la métrica desaparece de la pantalla, o asumimos una premisa, y tienes derecho a leer cuál de las dos fue antes de confiar en el número. Lo que necesita esa decisión nuestra está escrito en la sección de cada una.

Stripe

Qué sabe Stripe

Tu MRR se reconstruye desde cero a partir de lo que Stripe registra. Donde registra todo, medimos. Donde no registra, o la métrica desaparece de la pantalla, o asumimos una premisa, y tienes derecho a leer cuál es antes de confiar en el número. Esta sección se genera de la propia ficha del adaptador, así que no puede quedar desactualizada.

Cada fila es un dato que Stripe registra, o no. Un "no" nunca es solo un "no": es una métrica que cambia.

Catálogo de productosPuedes filtrar todas las métricas por producto.
Prueba gratuitaLas pruebas iniciadas, convertidas y la tasa de conversión se miden en el dato, sin premisa nuestra.
Plan gratuito (freemium)Una suscripción de valor cero es representable, y tus usuarios gratuitos aparecen.
Fecha de cancelaciónEl churn se fecha el día en que el cliente canceló.
Historial de eventosUn webhook perdido se recupera del historial de la pasarela.
Clave de solo lecturaLa clave que pedimos es restringida y de solo lectura: no mueve dinero.

Asaas

Qué sabe Asaas

Tu MRR se reconstruye desde cero a partir de lo que Asaas registra. Donde registra todo, medimos. Donde no registra, o la métrica desaparece de la pantalla, o asumimos una premisa, y tienes derecho a leer cuál es antes de confiar en el número. Esta sección se genera de la propia ficha del adaptador, así que no puede quedar desactualizada.

Cada fila es un dato que Asaas registra, o no. Un "no" nunca es solo un "no": es una métrica que cambia.

Catálogo de productosLa segmentación por producto desaparece de toda la cuenta. La pasarela no tiene productos: un cobro solo lleva una descripción en texto libre, y un filtro que cubre la mitad de la cuenta es peor que ningún filtro, porque parece completo.
Prueba gratuitaLa pasarela no tiene ese concepto. Dar 7 días gratis y emitir el primer cobro dentro de 7 días son la misma operación para ella. Si de verdad ofreces prueba gratuita, decláralo en Premisas y leeremos ese intervalo como prueba.
Plan gratuito (freemium)La pasarela rechaza cobros por debajo de R$5,00. Un usuario de tu plan gratuito no tiene ni suscripción ni cobro allí: existe solo en tu base de datos. No hay nada que leer, y no inventamos lo que nunca se registró.
Fecha de cancelaciónLa suscripción borrada no dice cuándo se borró. El churn se fecha al final del último período pagado, que es la pregunta que el dato responde: no "¿cuándo canceló?", sino "¿hasta cuándo pagó?".
Historial de eventosNo existe historial de eventos: un webhook perdido se pierde para siempre, y no hay a quién pedirle el reenvío. Por eso la pantalla de Fuentes de Datos avisa cuando la entrega falla, y reimportar la fuente, que vuelve a leer tu cuenta entera, es la única red que queda.
Clave de solo lecturaLa pasarela no tiene clave de solo lectura: toda clave suya es full-access, así que la clave que nos entregas puede retirar dinero. Solo la usamos para leer y para registrar nuestro propio webhook, y eso está bloqueado por un test en nuestro código, pero el riesgo es tuyo y tienes derecho a saberlo antes de pegarla. Puedes revocarla cuando quieras en el panel de Asaas, o crearla con fecha de vencimiento (cuando venza, la sincronización se detiene y la pantalla de Fuentes te avisa).

Por qué preguntamos esto

Tu pasarela no sabe responder. En ella, dar 7 días gratis y emitir el primer cobro dentro de 7 días son exactamente la misma operación: no hay un campo que distinga una de la otra. Si lo adivináramos por el intervalo entre la suscripción y el primer cobro, toda suscripción se convertiría en una prueba (ese intervalo existe siempre), y tu embudo mostraría cientos de pruebas que nunca ocurrieron. Por eso preferimos preguntar. Actívalo solo si de verdad das un período gratuito antes del primer cobro.

La opción está en Configuración, en Premisas de Cálculo, y viene desactivada. Activarla recalcula tu historial al instante.

Lo que Asaas no proporciona

Cada elemento a continuación es un dato que el gateway no registra. No es una decisión nuestra, y no hay forma de sortearlo leyendo mejor: el dato no existe del otro lado.

Asaas no tiene catálogo de productos

Asaas no tiene catálogo de productos: un cobro lleva un campo "description" de texto libre, escrito en cada emisión, y no existe un objeto de producto ni de precio al que la suscripción se enganche. Dos clientes del mismo plan pueden llegar con descripciones distintas, y nada en el dato dice que son el mismo plan. Por eso la segmentación por producto queda no disponible en toda la cuenta mientras exista una fuente Asaas, y no solo en las suscripciones que vinieron de ella: un filtro que respondiera por la mitad de tu cuenta e ignorara la otra mitad parecería completo sin serlo, y eso es peor que no tener ningún filtro. Tu MRR, tu churn y tus ingresos no cambian de valor por esto; lo que desaparece de Métricas es el desglose por producto. No hay premisa que declarar aquí: el dato no existe del otro lado, y ninguna lectura más cuidadosa lo inventa.

Asaas no registra el trial en ningún campo

La suscripción de Asaas no tiene un solo campo de trial: no existe "trialDays", ni "trialEndDate", ni equivalente, y mandar cualquiera de ellos al crear la suscripción se acepta con HTTP 200 y se ignora en silencio (medido en la cuenta de homologación). No es un hueco que podamos sortear leyendo mejor: para Asaas, dar 7 días gratis y emitir el primer cobro dentro de 7 días son la misma operación, y así es como su propia documentación manda hacer un trial. Ni Asaas sabe decir quién tuvo trial. Consecuencia: en el Embudo de ventas, Trials Iniciados queda en cero para esta fuente, y la Conversión de Trial no tiene qué medir. Tu MRR no cambia, porque una suscripción sin cobro confirmado ya vale cero en nuestro cálculo: lo que se pierde es la etiqueta, no el dinero. Si de verdad das un período gratuito antes del primer cobro, este solo pasa a existir cuando declaras la premisa en Configuración, en Premisas de Cálculo.

Un plan gratuito no es representable en Asaas

Asaas rechaza cualquier cobro por debajo de R$ 5,00, y lo medimos en las cuatro formas de pago: valor cero devuelve 400 (para él, cero es lo mismo que no informar), un centavo devuelve 400 ("el valor mínimo es R$ 5,00") y R$ 100 con 100% de descuento también se rechaza. No es una limitación de nuestra lectura: un usuario de tu plan gratuito no tiene ni suscripción ni cobro en Asaas, existe solo en tu base de datos. Consecuencia: en el Embudo de ventas, Freemiums Iniciados queda en cero, la Conversión de Freemium no tiene qué medir, y tu base gratuita no aparece en el conteo de Suscriptores. Tu MRR no cambia, porque un usuario gratuito no trae ingreso recurrente, pero la parte alta de tu embudo se ve más pequeña de lo que es en la vida real. No hay premisa que lo resuelva: no hay nada que leer, y no inventamos lo que nunca se registró. Si necesitas medir tu freemium, tendría que declararse por otra fuente: la de Datos personalizados acepta suscripciones de valor cero.

Asaas no tiene historial de eventos

No existe en Asaas nada equivalente al historial de eventos de Stripe: no se puede listar lo que pasó, ver la cola pendiente ni pedir el reenvío de una entrega. Si un evento se pierde, no hay a quién preguntarle qué perdimos. Consecuencia: el hecho que llevaba, un pago o una cancelación, quedaría fuera de tus métricas, y nada en la pantalla lo delataría, porque no existe una segunda lista que discrepe de la primera. Como no podemos preguntar, alarmamos: la pantalla de Fuentes de Datos avisa cuando el webhook fue borrado o desactivado, cuando Asaas pausó la cola de entrega tras fallos repetidos (guarda los eventos pausados 14 días, así que retomar dentro de ese plazo no pierde nada; pasado ese plazo, se pierden para siempre) y cuando llegó un evento y no logramos guardarlo. De esos avisos, solo el último no desaparece solo: los demás salen de la pantalla cuando la fuente vuelve a estar sana. Un evento perdido no vuelve, así que cuando hubo pérdida, la cura es reimportar la fuente, que vuelve a leer tu cuenta de Asaas y rehace tu historial a partir de lo que él responde. No hay nada que configurar ni que declarar: lo que te pedimos es atender el aviso cuando aparezca.

Asaas no avisa cuando un cliente cambia

Asaas no tiene webhook de cliente: los cuatro eventos "CUSTOMER_*" se rechazan con HTTP 400 al crear el webhook, mientras que otros 24 se aceptan (los medimos uno por uno). Un cliente NUEVO igual llega hasta nosotros de forma indirecta, porque el evento de su suscripción o de su cobro nos manda a buscarlo. Lo que no llega es el CAMBIO de quien ya está aquí: corregir el nombre, el correo o el documento en el registro de Asaas no genera ningún evento, y el dato nuevo solo aparece cuando reimportas la fuente. Ninguna métrica cambia por esto: el MRR, el churn y el conteo de Suscriptores no dependen del nombre de nadie, y lo que queda viejo es la etiqueta que lees en Clientes. Reverificar cada cliente en cada cobro lo arreglaría, y no lo hacemos: gastaría la cuota de API de tu cuenta para corregir un dato que no mueve ningún número. No hay nada que declarar.

Lo que nosotros asumimos

Donde el gateway no responde, alguien tiene que decidir. Estas son nuestras decisiones, escritas antes de que mires el número que sale de ellas.

El trial solo existe si lo declaras

Como Asaas no distingue "siete días gratis" de "primer cobro dentro de siete días", el trial solo existe si DECLARAS que tu operación lo tiene, en Configuración, en Premisas de Cálculo. Sin declararlo, ningún cliente cuenta como trial: sería una suposición, y una suposición se convierte en un número en tu pantalla. Al declararlo, el intervalo entre la creación de la suscripción y el primer cobro pasa a leerse como período de prueba, y la duración sale del propio dato, no de un número que tú escribes (por eso la pregunta es sí o no, y no "cuántos días"). El efecto colateral se dice de frente: si también aplazas el primer cobro por otro motivo, una negociación o un acuerdo puntual, esas suscripciones entran como trial y tus métricas de trial sobreestiman. La premisa viene desactivada, mueve solo el Embudo de ventas y nunca el MRR, y activarla o desactivarla recalcula tu historial al instante.

El churn se fecha al final del último período pagado

La suscripción borrada en Asaas no dice cuándo se borró: quedan "dateCreated" y "nextDueDate", no existe "deletedDate", "canceledDate" ni "endDate", y no hay historial de eventos de donde pescar la fecha. Sellar el instante en que nuestro barrido vio que la suscripción desapareció sería peor que no tener fecha: el día de tu churn dependería de cuándo corrió nuestro robot, y reprocesar el historial movería el gráfico de ayer. Así que cambiamos la pregunta: "¿cuándo canceló?" Asaas no lo sabe, pero "¿hasta cuándo pagó?" está registrado en cada cobro liquidado, y se queda ahí para siempre. El intervalo de MRR de una suscripción Asaas es la unión de sus períodos pagados, y el churn se fecha al final del último. En la práctica: quien pagó hasta el 10 de marzo y no renovó aparece como churn el 10 de marzo, y no el día en que borraste la suscripción en el panel, así que el Churn de Clientes y el Churn de MRR siguen la fecha del dato, no la de tu clic. No hay nada que declarar: es la lectura más fiel que el dato de Asaas permite.

El ciclo quincenal (BIWEEKLY) se trata como 14 días

Asaas tiene un ciclo llamado "BIWEEKLY" y su documentación solo lo llama "quinzenal", una palabra ambigua: en portugués suele significar 15 días (24 cobros al año), en inglés biweekly significa 14 (26 al año). Lo medimos creando una suscripción real en la cuenta de homologación: los cobros salieron el 14/07, el 28/07 y el 11/08, es decir, 14 días. Entonces el MRR de una suscripción quincenal es su importe por 26, dividido entre 12. Suponer 15 días daría cerca de un 8% menos de MRR en cada suscripción de ese ciclo, y el error no aparecería en ninguna parte. Si no usas el ciclo quincenal, esta premisa no toca ningún número tuyo, y no hay nada que declarar.

El cliente eliminado se recupera por sus cobros

El cliente eliminado desaparece de los listados de Asaas: "/v3/customers" no tiene "includeDeleted", así que ni un barrido completo de tu base lo encuentra. Pero sigue respondiendo por id (un GET directo devuelve HTTP 200), y sus suscripciones y cobros siguen citando ese id. Eso es exactamente lo que usamos: cuando una suscripción o un cobro apunta a un cliente que el listado no trajo, buscamos a ese cliente por id y lo traemos de vuelta. Sin esa recuperación tu historial perdería gente: en la cuenta Asaas real en la que medimos, 124 clientes, el 28% de la base histórica, existen solo por ella. Consecuencia: el conteo de Suscriptores, el Churn de Clientes, el ARPA y el LTV también cuentan a quien ya eliminaste de Asaas, que es lo correcto para un historial, porque su pasado ocurrió. No hay nada que declarar.

Lo que necesitas saber

Consecuencias de conectar esta fuente que no cambian tu número, pero sí cambian lo que deberías saber antes de conectar.

Asaas no tiene clave de solo lectura

Toda clave de API de Asaas es de acceso total, y no hay forma de pedir menos: la especificación de la API no tiene "scope", ni "permission", ni "readOnly", y el cuerpo de creación de clave acepta solo "name" y "expirationDate". Esto es distinto de Stripe, donde pedimos una clave restringida que, por construcción, no puede mover dinero: la clave que pegues aquí emite cobros, transfiere dinero fuera de la cuenta y elimina clientes. Lo que hacemos con ella es leer, y una sola escritura: registrar nuestro propio webhook. El cliente HTTP que reciben la importación, el drenaje y el barrido solo sabe hacer GET, y el camino que escribe está bloqueado en el recurso "/webhooks" por una guarda que un test mantiene en pie. Aun así el riesgo es tuyo, y tienes derecho a saberlo antes de pegarla: puedes revocarla cuando quieras en el panel de Asaas, o crearla ya con fecha de vencimiento (cuando venza, la sincronización se detiene y la pantalla de Fuentes de Datos te avisa). Nada de esto cambia ningún número tuyo: es riesgo, no métrica.

La cuota de API de Asaas es tuya, no nuestra

Asaas limita 25.000 peticiones cada 12 horas por CUENTA, y esa cuota es compartida con el uso que tú mismo haces de ella: tu sitio, tu ERP y tu checkout gastan del mismo bolsillo que nuestra lectura. Si nuestro barrido fuera la gota que revienta la cuota, las llamadas de TU operación empezarían a fallar, y eso es inaceptable: una métrica equivocada es mala, trabar tu caja no es negociable. Por eso cada pase tiene un tope declarado de 2.000 llamadas, cerca del 8% de la cuota de 12 horas, y usa 6 llamadas simultáneas aunque Asaas acepte 50; cuando se alcanza el tope, el barrido para, dice que paró y continúa en el pase siguiente, sin perder nada. Y paramos en el primer rechazo por exceso, sin insistir: Asaas no devuelve ninguna cabecera de límite de uso (buscamos en unas 55 peticiones y no vino ni una), así que no podemos distinguir un límite de ráfaga del agotamiento de tu cuota, y en la duda tu operación va primero. Cuando eso pasa, la pantalla de Fuentes de Datos enciende la alarma. No hay nada que declarar ni que configurar.

Datos personalizados

Cuándo tú eres la fuente

En esta fuente no hay gateway para verificar nada: eres tú quien declara suscripciones, clientes y pagos, por la API, por la pantalla o por planilla. Tres preguntas deciden qué puede calcular Metricaas a partir de lo que declares: plan, pagos y clientes. Abajo, pregunta por pregunta, está lo que queda indisponible si la dejas apagada y qué desbloquea si la activas.

Lo que vale siempre

En esta fuente, quien informa los datos eres tú

En las otras fuentes hay una pasarela del otro lado, y lo que ella registró es la referencia contra la que todo se verifica. Aquí no la hay: las suscripciones, los clientes y los pagos de esta fuente son exactamente los que tú declaraste, por la pantalla, por planilla o por la API. Consecuencia: lo que declaras es la verdad, y sobre ella se calcula cada número de esta cuenta. Una suscripción que olvidaste declarar no aparece en ninguna parte, y nada la delata, porque no existe una segunda copia que discrepe de la primera. Por el mismo motivo, esta fuente guarda la ÚNICA copia de estos datos: no hay de dónde reimportarlos, eliminar la fuente borra lo que declaraste y rehace tus métricas sin eso, y por eso la pantalla te pide una copia de seguridad antes. No hay premisa que declarar aquí: es la naturaleza de la fuente, y vale igual para quien declara tres suscripciones y para quien declara tres mil.

La planilla asume un único importe por suscripción

Una fila de planilla lleva UN importe; una suscripción lleva una HISTORIA de importes. No existe columna que diga "costó R$ 99 hasta marzo y R$ 149 después", así que la planilla solo sabe afirmar una cosa: esta suscripción siempre valió esto. Es lo que asumimos al subir el archivo, y el importe de la columna "amount" pasa a valer desde la fecha de inicio de la suscripción. Consecuencia: si el precio cambió por el camino, el MRR de los meses pasados sale con el precio de hoy, y el upgrade desaparece del mes en que ocurrió (en Métricas no habrá expansión ni contracción ahí, y el gráfico sube como si siempre hubiera sido así). Subir la planilla de nuevo con el precio nuevo no lo corrige en silencio: la subida entera se rechaza, porque reescribir un importe ya declarado cambia el MRR de meses que ya cerraron, y eso es una fe de erratas, que tienes que confirmar. Qué hacer: declara los tramos de importe de la suscripción, en la pantalla o por la API, un tramo por precio con la fecha en que empezó a valer, y así cada mes usa el precio de ese mes y el upgrade aparece como expansión el día en que ocurrió.

Las tres preguntas

Tengo previsto informar el plan de cada suscripción

Si lo dejas apagado

Sin plan declarado, no hay qué segmentar

Sin el plan de cada suscripción, estas llegan sin el nombre del producto que contratan. Consecuencia: los filtros y los desgloses por producto quedan no disponibles para lo que vino de esta fuente, y en Métricas no hay forma de responder "cuánto de mi MRR viene del plan Pro". Ningún número cambia de valor: el MRR, el churn y los ingresos son los mismos con o sin plan, lo que falta es el corte. Para tener ese corte, activa esta respuesta y manda el nombre del plan en cada suscripción (Básico, Pro, lo que uses): el recálculo es inmediato, y el filtro por producto pasa a existir.

Tengo previsto informar los pagos realizados

Si lo dejas apagado

Sin pagos declarados, no existe la morosidad

Sin los pagos, esta fuente tiene las suscripciones, pero no el dinero que entró. Entonces no existe la morosidad: nadie aparece como atrasado, y la tolerancia que elegiste en Premisas de Cálculo no se aplica a esta fuente, aquí es decoración. Tampoco existe caja: en Métricas, el Ingreso Bruto, el Ingreso Neto, las Comisiones de Pasarela y la Tasa de Reembolsos quedan en cero para lo que vino de esta fuente. Tu MRR sigue completo, y con él el ARR, los Suscriptores y el churn: el MRR mide lo contratado, no lo cobrado, y sin pago declarado toda suscripción se trata como al día (inventar una morosidad aquí borraría el MRR de quien paga puntual). Para tener las métricas de caja, activa esta respuesta y declara los pagos: pasan a existir a partir de lo que declares, y la tolerancia vuelve a valer.

Si lo activas

El retraso al cargar el pago se ve como atraso en pantalla

Con los pagos declarados, la morosidad de esta fuente sale exactamente de lo que TÚ cargaste: un pago que todavía no llegó aquí, para nosotros, no ocurrió. Consecuencia: un cliente que pagó al día aparece como atrasado hasta que cargues su pago, y si solo cargas una vez al mes, eso es lo que la pantalla muestra durante el mes. Y no se queda en la etiqueta: pasada la tolerancia de tu empresa (en Premisas de Cálculo), la suscripción deja de contar MRR, así que tu MRR y tus Suscriptores caen por un retraso de carga, y no por churn. Esto no es un bug nuestro ni tuyo: es la única lectura posible de un dato que solo existe cuando tú lo declaras, y es el mismo mecanismo que hace que la tolerancia funcione de verdad con quien sí dejó de pagar. Qué hacer: declara los pagos con la frecuencia con la que quieres que la morosidad sea verdad. Subir la tolerancia compra tiempo, pero vale para todos tus clientes, y no solo para los que aún no cargaste.

Tengo previsto informar los datos de mis clientes

Si lo dejas apagado

Sin clientes declarados, cada suscripción cuenta como uno

Sin los datos de los clientes no hay forma de saber que dos suscripciones pertenecen a la misma persona, así que asumimos una suscripción, un cliente. Tu MRR y tus ingresos no cambian con esto: suman por suscripción, y la suma es la misma. Cambian las métricas por cliente: si un suscriptor tuyo tiene dos suscripciones, se convierte en dos clientes, así que los Suscriptores suben, el ARPA baja (el mismo ingreso dividido entre más gente), el LTV baja con él, y una cancelación suya cuenta como dos en el Churn de Clientes. Si cada cliente tuyo tiene como máximo una suscripción, la premisa no se equivoca en nada, y dejarlo desactivado es lo correcto: no necesitas revelarnos quiénes son. Si un mismo cliente puede tener más de una, activa esta respuesta y manda un identificador tuyo para agruparlas: con el identificador basta, el nombre y el correo son opcionales.

Referencia

Los endpoints, uno por uno: qué recibe cada uno, qué devuelve, y un curl que funciona pegado tal cual.

Métricas

Los números ya calculados en la zona horaria y la moneda de tu cuenta. Son los MISMOS que muestra tu panel.

La serie

GET/v1/metrics/{metric}

Un punto por bucket, en el período y la agregación temporal que pidas. Los tres parámetros son opcionales: sin ninguno, recibes los últimos 12 meses, mes a mes.

Parámetros

ParámetroTipoPor defectoQué es
fromAAAA-MM-DDto - 365dEl primer día del período. El bucket que contiene esta fecha entra entero.
toAAAA-MM-DDhojeEl último día del período. Por defecto es hoy, en la zona horaria de tu cuenta.
intervalday | week | month | quarter | yearmonthEl tamaño del bucket. Es lo que convierte "mes a mes" en "día a día".

La respuesta

CampoQué es
metricLa métrica pedida, con el nombre que tiene en el catálogo.
unitmoney, percent o count. Dice cómo leer el value (ver abajo).
aggregationpoint_in_time, sum_over_period o rate_over_period. Dice qué significa el número.
currencyLa moneda de la cuenta, en ISO-4217. Solo tiene sentido cuando unit es money.
timezoneLa zona horaria de la cuenta. Es el calendario en que se cortaron los buckets.
intervalEl intervalo realmente aplicado (el que pediste, o el de por defecto).
from, toEl período realmente aplicado. Revisa aquí lo que el valor por defecto eligió por ti.
points[]La serie. Cada punto trae start, end (EXCLUSIVO), value y, cuando existe, count: cuántos ítems hay detrás del número. La métrica sin conteo omite el campo en vez de mandar cero.

Los buckets están alineados al calendario: con interval=month, un from=2026-03-15 devuelve el bucket que empieza el 2026-03-01. Cada punto lleva su start y su end para que nunca tengas que deducirlos.

El catálogo de métricas

GET/v1/metrics

La lista viva de métricas, con la moneda y la zona horaria de tu cuenta. Pide este endpoint en vez de fijar la lista en tu código: una métrica nueva aparece aquí sola.

{
  "currency": "BRL",
  "timezone": "America/Sao_Paulo",
  "metrics": [
    {
      "id": "mrr",
      "group": "revenue",
      "unit": "money",
      "aggregation": "point_in_time",
      "higher_is_better": true
    },
    {
      "id": "mrr-churn",
      "group": "churn",
      "unit": "percent",
      "aggregation": "rate_over_period",
      "higher_is_better": false
    }
  ]
}
MétricaUnidadCómo leerla
mrrDinero (centavos)Foto al final del bucket
arrDinero (centavos)Foto al final del bucket
subscribersConteoFoto al final del bucket
growthTasa (fracción)Tasa del bucket
gross-revenueDinero (centavos)Suma del bucket
gateway-feesTasa (fracción)Tasa del bucket
refund-rateTasa (fracción)Tasa del bucket
net-revenueDinero (centavos)Suma del bucket
one-off-revenueDinero (centavos)Suma del bucket
mrr-churnTasa (fracción)Tasa del bucket
net-mrr-churnTasa (fracción)Tasa del bucket
customer-churnTasa (fracción)Tasa del bucket
ltvDinero (centavos)Foto al final del bucket
arpaDinero (centavos)Foto al final del bucket
trialsConteoSuma del bucket
trial-conversionTasa (fracción)Tasa del bucket
freemiumsConteoSuma del bucket
freemium-conversionTasa (fracción)Tasa del bucket

Suscripciones

El corazón de la fuente. De aquí sale tu MRR -- sin suscripciones no hay ninguna métrica que calcular.

Crear o actualizar suscripciones

POST/v1/subscriptions

Crear y actualizar son la MISMA llamada: el id es tuyo, y mandar el mismo id de nuevo reescribe el objeto en vez de duplicarlo.

CampoTipoObligatorioQué es
idstringEl identificador que TÚ eliges. Enviar el mismo id de nuevo actualiza la suscripción, no la duplica.
customerstringEl id del cliente dueño de esta suscripción. En blanco, la suscripción cuenta como un cliente (no necesitas registrar clientes).
currencyenum(BRL | USD | EUR | GBP | ...)La moneda de esta suscripción, ISO-4217. Una moneda desconocida se rechaza, nunca se asume. Es de toda la suscripción, en la cabecera (nunca dentro de un tramo de amounts), y no cambia.
started_atdateCuándo empezó. El primer tramo de amounts tiene que empezar exactamente aquí.
canceled_atdateCuándo se canceló. Es la fecha del churn, y es declarada: aquí no hay pasarela que nos lo cuente.
trial_enddateCuándo terminó la prueba gratis. El periodo hasta esta fecha nunca se vuelve MRR.
amountsarray<{ from: date, cents: integer, cycle: enum(daily | weekly | biweekly | monthly | bimonthly | quarterly | semiannually | yearly), plan?: string }>El HISTORIAL del importe, fechado. Cada tramo tiene from (desde cuándo ese contrato empezó a valer), cents, cycle (cada cuánto cobras por ella) y plan opcional (la etiqueta del producto en ese periodo, con efecto solo si tu fuente declara planes). El ciclo vive dentro del tramo, no en la cabecera de la suscripción: es lo que permite declarar una mejora de mensual a anual sin cancelar y recrear la suscripción, lo que inventaría un churn que no ocurrió. Los tramos van en orden creciente de fecha, sin repetir el mismo día, y el primero empieza exactamente en started_at. Lee la sección de arriba antes de tocar esto.
curl -X POST https://api.metricaas.ai/v1/subscriptions \
  -H "Authorization: Bearer mtc_live_..." \
  -H "Content-Type: application/json" \
  -d '{"id":"sub_001","currency":"BRL","started_at":"2024-01-10","amounts":[{"from":"2024-01-10","cents":9900,"cycle":"monthly","plan":"Pro"},{"from":"2024-06-10","cents":99000,"cycle":"yearly","plan":"Pro anual"}]}'

El objeto que mandas SUSTITUYE al que estaba: no hay merge. Un campo omitido es un campo BORRADO -- para cambiar solo el teléfono, manda el cliente entero, con el teléfono nuevo. Por eso esta API no tiene PUT: el POST ya es el "sustituir por completo".

Envía en LOTE (un array en el cuerpo, hasta 1000 objetos). O entra todo, o no entra nada: un lote a medias te dejaría sin saber qué entró. La respuesta es 202, y el panel se mueve en hasta un minuto.

Cancelar es este mismo POST, con canceled_at completo: no hay endpoint aparte, porque no hay puerta aparte. La suscripción se queda en el historial y se vuelve churn en la fecha que declares. Cancelar no es borrar

Borrar una suscripción del historial (la fe de erratas)

DEL/v1/subscriptions/{id}

Úsalo cuando el dato entró mal: id equivocado, una prueba en producción, un duplicado. Es irreversible por la API -- para traerlo de vuelta, envía el objeto de nuevo.

DELETE no es cancelar. Borrar dice "esto nunca existió": el objeto desaparece y el MRR pasado se rehace sin él. Para decir que el cliente SE FUE, envía canceled_at -- la suscripción queda en el historial y se vuelve churn en la fecha declarada. Confundir los dos corrompe tu churn en las dos direcciones.

curl -X DELETE https://api.metricaas.ai/v1/subscriptions/sub_001 \
  -H "Authorization: Bearer mtc_live_..."

Listar suscripciones

GET/v1/subscriptions

Devuelve lo que está en tu bóveda, paginado por cursor. Eso es tu declaración en crudo; para los NÚMEROS calculados a partir de ella, mira la lectura de métricas al comienzo de la página.

curl "https://api.metricaas.ai/v1/subscriptions?limit=100&cursor=sub_001" \
  -H "Authorization: Bearer mtc_live_..."

Hasta 500 por página (limit, por defecto 100). El cursor es el id del último objeto de la página anterior.

Clientes

Opcional. Solo hace falta si un mismo cliente tiene más de una suscripción -- sin clientes, cada suscripción cuenta como un cliente. El único campo obligatorio es el id, así que puedes agrupar sin contarnos quiénes son.

Crear o actualizar clientes

POST/v1/customers

Crear y actualizar son la MISMA llamada: el id es tuyo, y mandar el mismo id de nuevo reescribe el objeto en vez de duplicarlo.

CampoTipoObligatorioQué es
idstringEl identificador que TÚ eliges. Enviar el mismo id de nuevo actualiza el cliente, no lo duplica.
namestringNombre del cliente. Opcional: no necesitas revelarnos quién es.
emailstringCorreo del cliente.
phonestringEl teléfono del cliente, tal como lo escribes. Sirve para encontrarlo en la búsqueda y para hablarle.
created_atdateCuándo se volvió tu cliente.
curl -X POST https://api.metricaas.ai/v1/customers \
  -H "Authorization: Bearer mtc_live_..." \
  -H "Content-Type: application/json" \
  -d '{"id":"cus_001","name":"Empresa Exemplo","email":"contato@exemplo.com","phone":"+55 11 98888-7777"}'

El objeto que mandas SUSTITUYE al que estaba: no hay merge. Un campo omitido es un campo BORRADO -- para cambiar solo el teléfono, manda el cliente entero, con el teléfono nuevo. Por eso esta API no tiene PUT: el POST ya es el "sustituir por completo".

Envía en LOTE (un array en el cuerpo, hasta 1000 objetos). O entra todo, o no entra nada: un lote a medias te dejaría sin saber qué entró. La respuesta es 202, y el panel se mueve en hasta un minuto.

Borrar un cliente del historial (la fe de erratas)

DEL/v1/customers/{id}

Úsalo cuando el dato entró mal: id equivocado, una prueba en producción, un duplicado. Es irreversible por la API -- para traerlo de vuelta, envía el objeto de nuevo.

DELETE no es cancelar. Borrar dice "esto nunca existió": el objeto desaparece y el MRR pasado se rehace sin él. Para decir que el cliente SE FUE, envía canceled_at -- la suscripción queda en el historial y se vuelve churn en la fecha declarada. Confundir los dos corrompe tu churn en las dos direcciones.

curl -X DELETE https://api.metricaas.ai/v1/customers/cus_001 \
  -H "Authorization: Bearer mtc_live_..."

Listar clientes

GET/v1/customers

Devuelve lo que está en tu bóveda, paginado por cursor. Eso es tu declaración en crudo; para los NÚMEROS calculados a partir de ella, mira la lectura de métricas al comienzo de la página.

curl "https://api.metricaas.ai/v1/customers?limit=100&cursor=cus_001" \
  -H "Authorization: Bearer mtc_live_..."

Hasta 500 por página (limit, por defecto 100). El cursor es el id del último objeto de la página anterior.

Pagos

Opcional. Sin pagos, el MRR sigue entero: sale del contrato, no del dinero que entró.

Crear o actualizar pagos

POST/v1/payments

Crear y actualizar son la MISMA llamada: el id es tuyo, y mandar el mismo id de nuevo reescribe el objeto en vez de duplicarlo.

CampoTipoObligatorioQué es
idstringEl identificador que TÚ eliges.
customerstringEl id de quien pagó. O este, o subscription: un pago siempre dice de quién es.
subscriptionstringEl id de la suscripción que este pago salda. En blanco, es una venta suelta (no entra en el MRR; entra en los ingresos).
amount_centsintegerEl importe bruto pagado, en centavos.
paid_atdateCuándo entró el dinero.
fee_centsintegerLa comisión del medio de pago, en centavos.
refunded_centsintegerCuánto volvió al cliente, en centavos. El reembolso parcial es válido.
currencyenumSi lo dejas en blanco, usamos la de la suscripción (o la de tu cuenta, si es suelta).
curl -X POST https://api.metricaas.ai/v1/payments \
  -H "Authorization: Bearer mtc_live_..." \
  -H "Content-Type: application/json" \
  -d '{"id":"pay_001","customer":"cus_001","subscription":"sub_001","amount_cents":9990,"paid_at":"2024-02-10","fee_cents":349}'

El objeto que mandas SUSTITUYE al que estaba: no hay merge. Un campo omitido es un campo BORRADO -- para cambiar solo el teléfono, manda el cliente entero, con el teléfono nuevo. Por eso esta API no tiene PUT: el POST ya es el "sustituir por completo".

Envía en LOTE (un array en el cuerpo, hasta 1000 objetos). O entra todo, o no entra nada: un lote a medias te dejaría sin saber qué entró. La respuesta es 202, y el panel se mueve en hasta un minuto.

Borrar un pago del historial (la fe de erratas)

DEL/v1/payments/{id}

Úsalo cuando el dato entró mal: id equivocado, una prueba en producción, un duplicado. Es irreversible por la API -- para traerlo de vuelta, envía el objeto de nuevo.

DELETE no es cancelar. Borrar dice "esto nunca existió": el objeto desaparece y el MRR pasado se rehace sin él. Para decir que el cliente SE FUE, envía canceled_at -- la suscripción queda en el historial y se vuelve churn en la fecha declarada. Confundir los dos corrompe tu churn en las dos direcciones.

curl -X DELETE https://api.metricaas.ai/v1/payments/pay_001 \
  -H "Authorization: Bearer mtc_live_..."

Listar pagos

GET/v1/payments

Devuelve lo que está en tu bóveda, paginado por cursor. Eso es tu declaración en crudo; para los NÚMEROS calculados a partir de ella, mira la lectura de métricas al comienzo de la página.

curl "https://api.metricaas.ai/v1/payments?limit=100&cursor=pay_001" \
  -H "Authorization: Bearer mtc_live_..."

Hasta 500 por página (limit, por defecto 100). El cursor es el id del último objeto de la página anterior.