Documentação

O que o Metricaas lê de cada gateway, o que ele assume quando o gateway não registra, e como puxar cada número de volta.

Nesta página

Guia

O que a API faz, como autenticar, como mandar os seus dados e o que esperar quando algo dá errado. Leia uma vez, de cima a baixo, antes da primeira chamada.

Como começar

Visão geral

Uma chave, duas coisas. A leitura serve a qualquer conta; o envio só é preciso se a sua fonte de dados for você mesmo.

  • LER as suas métricas: MRR, churn, LTV, receita e mais 14, no período e na agregação que você pedir. Vale para qualquer fonte (Stripe, Asaas ou dados customizados).
  • ENVIAR os seus dados: assinaturas, clientes e pagamentos, para quem não usa um gateway que integramos. Nesse caso você também pode digitá-los na tela ou subir uma planilha, pelas mesmas regras.
Endereço base: https://api.metricaas.ai/v1

Tudo é JSON, tudo é autenticado por chave, e as datas são AAAA-MM-DD no fuso da sua conta.

Os endpoints

MétodoEndpointO que é
GET/v1/metrics/{metric}Série de uma métrica
GET/v1/metricsCatálogo de métricas
POST/v1/subscriptionsCriar ou atualizar assinaturas
DEL/v1/subscriptions/{id}Apagar uma assinatura
GET/v1/subscriptionsListar assinaturas
POST/v1/customersCriar ou atualizar clientes
DEL/v1/customers/{id}Apagar um cliente
GET/v1/customersListar clientes
POST/v1/paymentsCriar ou atualizar pagamentos
DEL/v1/payments/{id}Apagar um pagamento
GET/v1/paymentsListar pagamentos

Autenticação

Toda chamada leva a sua chave no cabeçalho. A chave pertence à sua EMPRESA (não a você), e cada uma carrega só as permissões que você marcou ao criá-la.

Authorization: Bearer mtc_live_...
  • metrics:read - ler métricas. É o que você precisa para puxar os seus números.
  • data:write - enviar dados. Só existe em conta com uma fonte de dados customizados, e a chave escreve nessa fonte.

Guardamos apenas um resumo criptográfico da chave, então nem nós conseguimos mostrá-la de novo. Perdeu, gere outra e revogue a antiga. Gere em Configurações > API.

A primeira chamada

O MRR dos últimos 12 meses, mês a mês. Troque mrr por qualquer métrica do 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
    }
  ]
}

É o mesmo número da tela, e não por disciplina: por construção. A API chama o mesmo motor que o painel, pede a mesma linha e não faz conta nenhuma em cima. Não existe um lugar onde os dois possam divergir.

Como ler o valor

unit diz como ler o value: money é CENTAVOS na moeda da conta (1250000 = R$ 12.500,00), percent é FRAÇÃO (0.0312 = 3,12%), count é inteiro.

aggregation diz o que o número SIGNIFICA. point_in_time é uma foto no fim do bucket (MRR, ARR, assinantes, LTV). sum_over_period é a soma do que aconteceu no bucket (receita, trials). rate_over_period é uma taxa do bucket (churn, crescimento).

Somar fotos é o erro mais comum de quem consome métrica de SaaS por API. O MRR de janeiro mais o de fevereiro não é o MRR do bimestre: é um número que não existe. Receita, sim, se soma. Por isso o aggregation vem em toda resposta.

O calendário é o DA SUA CONTA (o fuso que você configurou), nunca UTC. É o que faz "março" querer dizer março para você.

Enviar seus dados

Só quem NÃO usa um gateway integrado precisa desta parte. Se os seus dados vêm da Stripe ou do Asaas, eles já chegam sozinhos: pule para a Referência.

Começando

Na fonte de dados customizados, quem informa os dados é você. Não há gateway do outro lado para conferir nada, então o que você declarar aqui é a verdade sobre a qual todo número da sua conta é calculado. Se o seu sistema parar de enviar, o seu painel congela no último dado que chegou.

  1. No Metricaas, adicione uma fonte do tipo Dados customizados e responda às três perguntas (se você vai informar pagamentos, se cada assinatura tem plano, se vai cadastrar clientes).
  2. Em Configurações > API, gere uma chave. Ela aparece uma única vez.
  3. Mande as suas assinaturas. O painel se move em até um minuto.

Os três recursos: um obrigatório, dois opcionais

A assinatura é a única coisa de que precisamos. Os outros dois são opcionais, e cada um DESTRAVA uma parte do produto: você escolhe o que quer ver, e paga o preço de mandar o dado correspondente.

/v1/subscriptionsObrigatório

O coração da fonte. É daqui que sai o seu MRR -- sem assinaturas, não há métrica nenhuma para calcular.

O que destrava: MRR, ARR, churn, expansão, contração, LTV, ARPA, assinantes ativos, coortes. Ou seja: quase tudo.

/v1/customersOpcional

Opcional. Só é preciso se um mesmo cliente tiver mais de uma assinatura -- sem clientes, cada assinatura conta como um cliente. O único campo obrigatório é o id, então dá para agrupar sem nos contar quem eles são.

O que destrava: Agrupar assinaturas por cliente (o ARPA e o LTV passam a ser POR CLIENTE, não por assinatura), a tela de Clientes com nome, e-mail e telefone, e a busca por qualquer um deles.

/v1/paymentsOpcional

Opcional. Sem pagamentos, o MRR continua inteiro: ele sai do contrato, não do dinheiro que entrou.

O que destrava: Receita recebida, taxas do meio de pagamento, estornos, receita líquida e INADIMPLÊNCIA -- que sem os pagamentos simplesmente não existe na sua conta (não há como saber quem deixou de pagar).

Você diz o que vai declarar na configuração da fonte (as três chaves: pagamentos, planos, clientes). Declarar que vai mandar e não mandar é pior do que não declarar: o painel espera um dado que nunca chega.

O valor é uma HISTÓRIA, não um número

Num gateway, a história do preço mora nas faturas: cada uma é um período cobrado, com o preço daquele dia. Aqui não há faturas, então a história mora dentro da assinatura, no campo amounts.

Cada faixa diz quanto ela passou a valer, e desde quando. A primeira começa no início da assinatura. É isso que faz o MRR de março continuar sendo o de março depois que você reajusta o preço em abril.

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

Por isso, um envio que não PRESERVE uma faixa já declarada é recusado com 409 (inclusive ao inserir uma faixa antes de outra já agendada). Se a faixa afetada já começou, isso muda o MRR de meses que já fecharam. Se foi um reajuste, acrescente uma faixa nova. Se foi erro de digitação, confirme que você quer mesmo reescrever:

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

Cancelar não é apagar

Cancelar é um fato do seu negócio: o cliente saiu, a assinatura fica no histórico e vira churn na data declarada. Apagar é uma errata: aquilo nunca existiu, e o MRR passado se refaz sem ele. Confundir os dois corrompe o seu churn nas duas direções.

# o cliente saiu (vira churn)
POST https://api.metricaas.ai/v1/subscriptions          { "id": "sub_001", "canceled_at": "2026-03-01", ... }

# eu digitei errado (some da historia)
DELETE https://api.metricaas.ai/v1/subscriptions/sub_001

Idempotência (opcional)

Você já tem idempotência sem fazer nada: o id do objeto é seu. Mandar a mesma assinatura duas vezes ATUALIZA, não duplica. Para a maioria dos casos, é só isso que você precisa saber.

O header abaixo serve para um caso específico: você ligou a nossa API num sistema de webhook seu, e ele pode disparar o mesmo evento duas vezes ao mesmo tempo. Mande a mesma Idempotency-Key nas duas: o trabalho acontece uma vez, e as duas requisições recebem a mesma resposta.

Idempotency-Key: evt_7f3c9a21
  • Repetiu com a mesma chave e o mesmo corpo: você recebe a resposta guardada (o mesmo status, o mesmo JSON), com o header Idempotent-Replay: true. Nada é reprocessado.
  • A primeira ainda está rodando: a segunda recebe 409 (in_progress). Repita em alguns segundos para receber a resposta dela.
  • A mesma chave com um corpo diferente é recusada com 400. Uma chave é uma requisição: use uma chave nova para um conteúdo novo.
  • Se a requisição falhou, a chave é liberada. Você conserta o corpo e manda de novo com a mesma chave, normalmente.

Erros e limites

Erros

A recusa lista TODOS os problemas de uma vez, com o campo (e, na planilha, a linha). Você não vai consertar um por requisição.

{
  "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 - sucesso (a leitura de métricas).
  • 202 - aceito (o envio de dados). O seu painel se move em até um minuto.
  • 400 - a requisição tem problemas: parâmetro inválido, ou declaração recusada. Nada foi gravado.
  • 401 - chave inválida, revogada, ou sem permissão para esta operação.
  • 402 - o plano da conta não permite ler as métricas agora (o MRR passou do teto do grátis, ou da faixa contratada). Resolva em metricaas.ai/billing.
  • 404 - a métrica não existe. Peça GET /v1/metrics para a lista completa.
  • 409 - isto reescreveria o histórico de valor já declarado (ou há uma requisição igual em andamento).
  • 429 - muitas requisições. Mande em lote.

Limites

  • 120 requisições por minuto, por chave. Toda resposta traz os cabeçalhos X-RateLimit-* com o que sobrou.
  • Até 1000 objetos por envio (um array no corpo). Ou tudo entra, ou nada entra.
  • Até 1000 pontos por série. Acima disso a resposta é um 400 pedindo um intervalo maior: nunca uma série cortada pela metade, que se lê como um negócio que parou.
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 1781827200

Fontes de dados

De onde vêm os seus números: o que cada gateway registra, o que ele não registra, e o que assumimos no lugar dele.

Introdução

O que é uma fonte

De onde vêm os seus números. Cada gateway tem uma seção abaixo com o que ele registra, o que não registra e as premissas que assumimos no lugar dele. Não usa nenhum gateway integrado? A fonte de Dados customizados cobre o mesmo terreno, com você declarando os dados em vez do gateway.

Como o número é montado

Uma fonte é de onde os seus números vêm. O motor lê o que ela registrou, traduz para o modelo interno do Metricaas e calcula as suas métricas a partir disso. Onde a fonte não registra algo, nós não inventamos: ou a métrica some da tela, ou assumimos uma premissa, e você tem o direito de ler qual das duas foi antes de confiar no número. O que precisa dessa decisão nossa está escrito na seção de cada uma.

Stripe

O que a Stripe sabe

O seu MRR é reconstruído do zero a partir do que o Stripe registra. Onde ele registra tudo, medimos. Onde ele não registra, ou a métrica some da tela, ou nós assumimos uma premissa, e você tem o direito de ler qual é antes de confiar no número. Esta seção é gerada da própria ficha do adaptador, então ela não pode ficar desatualizada.

Cada linha é um dado que o Stripe registra, ou não. Um "não" nunca é só um "não": é uma métrica que muda.

Catálogo de produtosVocê pode filtrar todas as métricas por produto.
Teste grátis (trial)Trials iniciados, convertidos e a taxa de conversão são medidos no dado, sem premissa nossa.
Plano gratuito (freemium)Assinatura de valor zero é representável, e os seus usuários gratuitos aparecem.
Data do cancelamentoO churn é datado no dia em que o cliente cancelou.
Histórico de eventosUm webhook perdido é recuperado do histórico do gateway.
Chave só de leituraA chave que pedimos é restrita e só de leitura: ela não move dinheiro.

Asaas

O que o Asaas sabe

O seu MRR é reconstruído do zero a partir do que o Asaas registra. Onde ele registra tudo, medimos. Onde ele não registra, ou a métrica some da tela, ou nós assumimos uma premissa, e você tem o direito de ler qual é antes de confiar no número. Esta seção é gerada da própria ficha do adaptador, então ela não pode ficar desatualizada.

Cada linha é um dado que o Asaas registra, ou não. Um "não" nunca é só um "não": é uma métrica que muda.

Catálogo de produtosA segmentação por produto some da conta inteira. O gateway não tem produtos: uma cobrança tem só uma descrição em texto livre, e um filtro que cobre metade da conta é pior que filtro nenhum, porque parece completo.
Teste grátis (trial)O gateway não tem o conceito. Dar 7 dias grátis e emitir a primeira cobrança para daqui a 7 dias são a mesma operação para ele. Se você de fato oferece teste grátis, declare isso nas Premissas e nós lemos esse intervalo como trial.
Plano gratuito (freemium)O gateway recusa cobranças abaixo de R$ 5,00. Um usuário do seu plano gratuito não tem assinatura nem cobrança lá: ele existe só no seu banco de dados. Não há o que ler, e nós não inventamos o que não foi gravado.
Data do cancelamentoA assinatura apagada não diz quando foi apagada. O churn é datado no fim do último período pago, que é a pergunta que o dado responde: não "quando cancelou?", e sim "até quando pagou?".
Histórico de eventosNão existe histórico de eventos: webhook perdido é perdido para sempre, e não há a quem pedir o reenvio. Por isso a tela de Fontes de Dados avisa quando a entrega falha, e a reimportação da fonte, que relê a sua conta inteira, é a única rede que sobra.
Chave só de leituraO gateway não tem chave só de leitura: toda chave dele é full-access, então a chave que você nos entrega tem poder de saque. Nós só a usamos para ler e para registrar o nosso próprio webhook, e isso está travado por teste no nosso código, mas o risco é seu e você tem o direito de saber antes de colar. Você pode revogá-la quando quiser no painel do Asaas, ou criá-la já com data de expiração (quando ela expirar, a sincronização para e a tela de Fontes avisa).

Por que perguntamos isso

O seu gateway não sabe responder. Nele, dar 7 dias grátis e emitir a primeira cobrança para daqui a 7 dias são exatamente a mesma operação: não existe um campo que diga qual das duas foi. Se a gente chutasse pelo intervalo entre a assinatura e a primeira cobrança, toda assinatura viraria um trial (esse intervalo existe sempre), e o seu funil mostraria centenas de testes que nunca aconteceram. Por isso preferimos perguntar. Ligue apenas se você de fato dá um período gratuito antes da primeira cobrança.

A chave fica em Configurações, nas Premissas de Cálculo, e vem desligada. Ligá-la recalcula o seu histórico na hora.

O que o Asaas não fornece

Cada item abaixo é um dado que o gateway não registra. Não é uma escolha nossa, e não há como contorná-lo lendo melhor: o dado não existe do outro lado.

O Asaas não tem catálogo de produtos

O Asaas não tem catálogo de produtos: uma cobrança carrega um campo "description" de texto livre, digitado a cada emissão, e não existe um objeto de produto ou de preço ao qual a assinatura se prenda. Dois clientes do mesmo plano podem chegar com descrições diferentes, e nada no dado diz que se trata do mesmo plano. Por isso a segmentação por produto fica indisponível na conta inteira enquanto houver uma fonte Asaas, e não apenas nas assinaturas que vieram dela: um filtro que respondesse por metade da sua conta e ignorasse a outra metade pareceria completo sem ser, e isso é pior do que não ter filtro nenhum. O seu MRR, o seu churn e a sua receita não mudam de valor por causa disso; o que some das Métricas é a quebra por produto. Não há premissa a declarar aqui: o dado não existe do outro lado, e nenhuma leitura melhor o inventa.

O Asaas não registra trial em campo nenhum

A assinatura do Asaas não tem um único campo de trial: não existe "trialDays", "trialEndDate" nem equivalente, e mandar qualquer um deles na criação da assinatura é aceito com HTTP 200 e ignorado em silêncio (medido na conta de homologação). Não é uma lacuna que a gente contorne lendo melhor: para o Asaas, dar 7 dias grátis e emitir a primeira cobrança para daqui a 7 dias são a mesma operação, e é assim que a documentação oficial dele manda fazer trial. Nem o Asaas sabe dizer quem teve trial. Consequência: no Funil de vendas, Trials Iniciados fica em zero para esta fonte, e a Conversão de Trial não tem o que medir. O seu MRR não muda, porque uma assinatura sem cobrança confirmada já vale zero no nosso cálculo: o que se perde é o rótulo, não o dinheiro. Se você de fato dá um período gratuito antes da primeira cobrança, ele só passa a existir quando você declara a premissa em Configurações, nas Premissas de Cálculo.

Plano gratuito não é representável no Asaas

O Asaas recusa cobrança abaixo de R$ 5,00, e medimos isso nas quatro formas de pagamento: valor zero volta 400 (para ele, zero é o mesmo que não informar), um centavo volta 400 ("o valor mínimo é R$ 5,00") e R$ 100 com 100% de desconto também é recusado. Não é limitação da nossa leitura: um usuário do seu plano gratuito não tem assinatura nem cobrança no Asaas, ele existe só no seu banco de dados. Consequência: no Funil de vendas, Freemiums Iniciados fica em zero, a Conversão de Freemium não tem o que medir, e a sua base gratuita não aparece na contagem de Assinantes. O seu MRR não muda, porque usuário gratuito não traz receita recorrente, mas o topo do seu funil fica menor do que ele é na vida real. Não há premissa que resolva: não há o que ler, e nós não inventamos o que não foi gravado. Se você precisa medir o seu freemium, ele teria que ser declarado por outra fonte: a de Dados customizados aceita assinatura de valor zero.

O Asaas não tem histórico de eventos

Não existe no Asaas nada equivalente ao histórico de eventos da Stripe: não dá para listar o que aconteceu, ver a fila pendente nem pedir o reenvio de uma entrega. Se um evento se perde, não há a quem perguntar o que a gente perdeu. Consequência: o fato que ele carregava, um pagamento ou um cancelamento, ficaria de fora das suas métricas, e nada na tela denunciaria, porque não existe uma segunda lista para discordar da primeira. Como não dá para perguntar, a gente alarma: a tela de Fontes de Dados avisa quando o webhook foi apagado ou desativado, quando o Asaas pausou a fila de entrega depois de falhas repetidas (ele guarda os eventos pausados por 14 dias, então retomar dentro desse prazo não perde nada; passou disso, perdeu para sempre) e quando um evento chegou e não conseguimos guardá-lo. Desses avisos, só o último não some sozinho: os outros saem da tela quando a fonte volta a ficar sadia. Um evento perdido não volta, então, quando houve perda, a cura é reimportar a fonte, que relê a sua conta no Asaas e refaz o seu histórico a partir do que ele responde. Não há o que configurar nem o que declarar: o que se pede de você é atender o aviso quando ele aparecer.

O Asaas não avisa quando um cliente muda

O Asaas não tem webhook de cliente: os quatro eventos "CUSTOMER_*" são recusados com HTTP 400 na criação do webhook, enquanto outros 24 são aceitos (medimos um por um). Um cliente NOVO ainda chega até nós de carona, porque o evento da assinatura ou da cobrança dele nos manda buscá-lo. O que não chega é a MUDANÇA de quem já está aqui: corrigir o nome, o e-mail ou o documento no cadastro do Asaas não gera evento nenhum, e o dado novo só aparece quando você reimporta a fonte. Nenhuma métrica muda com isso: o MRR, o churn e a contagem de Assinantes não dependem do nome de ninguém, e o que fica velho é o rótulo que você lê em Clientes. Reconferir todo cliente a cada cobrança consertaria isso, e nós não fazemos: gastaria a cota de API da sua conta para corrigir um dado que não muda número. Não há o que declarar.

O que nós assumimos

Onde o gateway não responde, alguém tem que decidir. Estas são as nossas decisões, escritas antes de você olhar o número que sai delas.

O trial só existe se você declarar

Como o Asaas não distingue "sete dias grátis" de "primeira cobrança daqui a sete dias", o trial só existe se você DECLARAR que a sua operação tem trial, em Configurações, nas Premissas de Cálculo. Sem declarar, nenhum cliente é contado como trial: seria um chute, e um chute vira número na sua tela. Declarando, o intervalo entre a criação da assinatura e a primeira cobrança passa a ser lido como período de teste, e a duração sai do próprio dado, não de um número que você digita (por isso a pergunta é sim ou não, e não "quantos dias"). O efeito colateral fica dito na cara: se você também adia a primeira cobrança por outro motivo, uma negociação ou um acordo pontual, essas assinaturas entram como trial e as suas métricas de trial superestimam. A premissa vem desligada, mexe só no Funil de vendas e nunca no MRR, e ligá-la ou desligá-la recalcula o seu histórico na hora.

O churn é datado no fim do último período pago

A assinatura apagada no Asaas não diz quando foi apagada: sobram "dateCreated" e "nextDueDate", não existe "deletedDate", "canceledDate" nem "endDate", e não há histórico de eventos de onde pescar a data. Carimbar o instante em que a nossa varredura viu a assinatura sumir seria pior do que não ter data: o dia do seu churn passaria a depender de quando o nosso robô rodou, e reprocessar o histórico moveria o gráfico de ontem. Então trocamos a pergunta: "quando cancelou?" o Asaas não sabe, mas "até quando pagou?" está registrado em cada cobrança quitada, e fica lá para sempre. O intervalo de MRR de uma assinatura Asaas é a união dos períodos pagos, e o churn é datado no fim do último deles. Na prática: quem pagou até 10 de março e não renovou aparece como churn em 10 de março, e não no dia em que você apagou a assinatura no painel, então o Churn de Clientes e o Churn de MRR seguem a data do dado, não a do seu clique. Não há o que declarar: é a leitura mais fiel que o dado do Asaas permite.

O ciclo quinzenal (BIWEEKLY) é tratado como 14 dias

O Asaas tem um ciclo chamado "BIWEEKLY" e a documentação dele só diz "quinzenal", uma palavra ambígua: em português ela costuma significar 15 dias (24 cobranças por ano), em inglês significa 14 (26 por ano). Medimos criando uma assinatura de verdade na conta de homologação: as cobranças saíram em 14/07, 28/07 e 11/08, ou seja, 14 dias. Então o MRR de uma assinatura quinzenal é o valor dela vezes 26, dividido por 12. Chutar 15 dias daria cerca de 8% a menos de MRR em cada assinatura desse ciclo, e o erro não apareceria em lugar nenhum. Se você não usa o ciclo quinzenal, esta premissa não toca em número nenhum seu, e não há o que declarar.

O cliente apagado é recuperado pelas cobranças dele

O cliente apagado some da listagem do Asaas: "/v3/customers" não tem "includeDeleted", então nem uma varredura completa da sua base o encontra. Mas ele continua respondendo por id (um GET direto devolve HTTP 200), e as assinaturas e as cobranças dele continuam citando esse id. Nós usamos exatamente isso: quando uma assinatura ou uma cobrança aponta para um cliente que a listagem não trouxe, buscamos aquele cliente pelo id e o trazemos de volta. Sem essa recuperação o seu histórico perderia gente: na conta Asaas real em que medimos, 124 clientes, 28% da base histórica, só existem por causa dela. Consequência: a contagem de Assinantes, o Churn de Clientes, o ARPA e o LTV também contam quem você já apagou do Asaas, que é o certo para um histórico, porque o passado dele aconteceu. Não há o que declarar.

O que você precisa saber

Consequências de conectar esta fonte que não mudam o seu número, mas mudam o que você deveria saber antes de conectar.

O Asaas não tem chave só de leitura

Toda chave de API do Asaas é full-access, e não há como pedir menos: a especificação da API não tem "scope", "permission" nem "readOnly", e o corpo de criação de chave aceita só "name" e "expirationDate". Isso é diferente da Stripe, onde pedimos uma chave restrita que, por construção, não consegue mover dinheiro: a chave que você colar aqui emite cobrança, transfere dinheiro para fora da conta e apaga cliente. O que fazemos com ela é leitura, e uma única escrita: registrar o nosso próprio webhook. O cliente HTTP que o import, o dreno e a varredura recebem só sabe fazer GET, e o caminho que escreve está trancado no recurso "/webhooks" por uma guarda travada por teste. Ainda assim o risco é seu, e você tem o direito de saber antes de colar: pode revogar a chave quando quiser no painel do Asaas, ou criá-la já com data de expiração (quando ela expirar, a sincronização para e a tela de Fontes de Dados avisa). Isto não muda número nenhum seu: é risco, não métrica.

A cota de API do Asaas é sua, não nossa

O Asaas limita 25.000 requisições a cada 12 horas por CONTA, e essa cota é compartilhada com o uso que você mesmo faz dela: o seu site, o seu ERP e o seu checkout gastam do mesmo bolso que a nossa leitura. Se a nossa varredura fosse a gota que estoura a cota, as chamadas da SUA operação passariam a falhar, e isso é inaceitável: uma métrica errada é ruim, travar o seu caixa não é negociável. Por isso cada passe tem um teto declarado de 2.000 chamadas, cerca de 8% da cota de 12 horas, e usa 6 chamadas simultâneas embora o Asaas aceite 50; quando o teto é atingido, a varredura para, diz que parou e continua no passe seguinte, sem perder nada. E paramos na primeira recusa por excesso, sem insistir: o Asaas não devolve nenhum cabeçalho de limite de uso (procuramos em cerca de 55 requisições e não veio um), então não temos como distinguir um limite de rajada do estouro da sua cota, e na dúvida a sua operação vem primeiro. Quando isso acontece, a tela de Fontes de Dados acende o alarme. Não há o que declarar nem o que configurar.

Dados customizados

Quando você é a fonte

Nesta fonte não há gateway para conferir nada: você é quem declara assinaturas, clientes e pagamentos, pela API, pela tela ou por planilha. Três perguntas decidem o que o Metricaas consegue calcular a partir do que você declarar: plano, pagamentos e clientes. Abaixo, pergunta por pergunta, está o que fica indisponível se você deixar desligada e o que ela destrava se você ligar.

O que vale sempre

Nesta fonte, quem informa os dados é você

Nas outras fontes há um gateway do outro lado, e o que ele registrou é a referência contra a qual tudo é conferido. Aqui não há: as assinaturas, os clientes e os pagamentos desta fonte são exatamente os que você declarou, pela tela, pela planilha ou pela API. Consequência: o que você declara é a verdade, e é sobre ela que cada número desta conta é calculado. Uma assinatura que você esqueceu de declarar não aparece em lugar nenhum, e nada a denuncia, porque não existe uma segunda cópia para discordar da primeira. Pelo mesmo motivo, esta fonte guarda a ÚNICA cópia destes dados: não há de onde reimportar, remover a fonte apaga o que você declarou e refaz as suas métricas sem isso, e é por isso que a tela pede um backup antes. Não há premissa a declarar aqui: é a natureza da fonte, e vale igual para quem declara três assinaturas e para quem declara três mil.

A planilha assume um valor único por assinatura

Uma linha de planilha tem UM valor; uma assinatura tem uma HISTÓRIA de valores. Não existe coluna que diga "custou R$ 99 até março e R$ 149 depois", então a planilha só sabe afirmar uma coisa: esta assinatura sempre valeu isto. É o que assumimos ao subir o arquivo, e o valor da coluna "amount" passa a valer desde a data de início da assinatura. Consequência: se o preço mudou no meio do caminho, o MRR dos meses passados sai com o preço de hoje, e o upgrade some do mês em que ele aconteceu (nas Métricas não haverá expansão nem contração ali, e o gráfico sobe como se sempre tivesse sido assim). Subir a planilha de novo com o preço novo não corrige nada em silêncio: a subida inteira é recusada, porque reescrever um valor já declarado muda o MRR de meses que já fecharam, e isso é uma errata, que você precisa confirmar. O que fazer: informe as faixas de valor da assinatura, na tela ou pela API, uma faixa por preço com a data em que ele passou a valer, e aí cada mês usa o preço daquele mês e o upgrade aparece como expansão no dia em que aconteceu.

As três perguntas

Eu pretendo informar o plano de cada assinatura

Se você deixar desligado

Sem plano declarado, não há o que segmentar

Sem o plano de cada assinatura, elas chegam sem o nome do produto que assinam. Consequência: os filtros e as quebras por produto ficam indisponíveis para o que veio desta fonte, e nas Métricas não há como responder "quanto do meu MRR vem do plano Pro". Nenhum número muda de valor: o MRR, o churn e a receita são os mesmos com ou sem plano, e o que falta é o corte. Para ter esse corte, ligue esta resposta e mande o nome do plano em cada assinatura (Básico, Pro, o que você usar): o recálculo é imediato, e o filtro por produto passa a existir.

Eu pretendo informar os pagamentos realizados

Se você deixar desligado

Sem pagamentos declarados, não existe inadimplência

Sem os pagamentos, esta fonte tem as assinaturas, mas não tem o dinheiro que entrou. Então não existe inadimplência: ninguém aparece como atrasado, e a régua de tolerância que você escolheu nas Premissas de Cálculo não se aplica a esta fonte, ela é decoração aqui. Também não existe caixa: em Métricas, a Receita Bruta, a Receita Líquida, as Taxas de Gateway e a Taxa de Reembolsos ficam em zero para o que veio desta fonte. O seu MRR continua inteiro, e com ele o ARR, os Assinantes e o churn: o MRR mede o contratado, não o recebido, e sem pagamento declarado toda assinatura é tratada como em dia (inventar uma inadimplência aqui apagaria o MRR de quem paga certinho). Para ter as métricas de caixa, ligue esta resposta e declare os pagamentos: elas passam a existir a partir do que você declarar, e a régua de tolerância volta a valer.

Se você ligar

O atraso ao lançar o pagamento vira atraso na tela

Com os pagamentos declarados, a inadimplência desta fonte sai exatamente do que VOCÊ lançou: um pagamento que ainda não chegou aqui, para nós, não aconteceu. Consequência: um cliente que pagou em dia aparece como atrasado até você lançar o pagamento dele, e se você só lança uma vez por mês é isso que a tela mostra durante o mês. E não para no rótulo: passada a régua de tolerância da sua empresa (nas Premissas de Cálculo), a assinatura deixa de contar MRR, então o seu MRR e os seus Assinantes caem por atraso de lançamento, e não por churn. Isso não é bug nosso nem seu: é a única leitura possível de um dado que só existe quando você o declara, e é o mesmo mecanismo que faz a régua funcionar de verdade para quem parou de pagar de fato. O que fazer: declare os pagamentos com a frequência com que você quer que a inadimplência seja verdade. Aumentar a régua compra tempo, mas ela vale para todos os seus clientes, e não só para os que você ainda não lançou.

Eu pretendo informar os dados dos meus clientes

Se você deixar desligado

Sem clientes declarados, cada assinatura conta como um

Sem os dados dos clientes, não há como saber que duas assinaturas pertencem à mesma pessoa, então assumimos uma assinatura, um cliente. O seu MRR e a sua receita não mudam com isso: eles somam por assinatura, e a soma é a mesma. Mudam as métricas por cliente: se um assinante seu tiver duas assinaturas, ele vira dois clientes, então os Assinantes sobem, o ARPA cai (a mesma receita dividida por mais gente), o LTV cai junto, e um cancelamento dele conta como dois no Churn de Clientes. Se cada cliente seu tem no máximo uma assinatura, a premissa não erra nada, e deixar desligado é o certo: você não precisa nos revelar quem eles são. Se um mesmo cliente pode ter mais de uma, ligue esta resposta e mande um identificador seu para agrupá-las: só o identificador já basta, o nome e o e-mail são opcionais.

Referência

As portas, uma por uma: o que cada uma recebe, o que devolve, e um curl que funciona colado como está.

Métricas

Os números prontos, já calculados no fuso e na moeda da sua conta. São os MESMOS que o painel mostra.

A série

GET/v1/metrics/{metric}

Um ponto por bucket, no período e na agregação temporal que você pedir. Os três parâmetros são opcionais: sem nenhum, você recebe os últimos 12 meses, mês a mês.

Parâmetros

ParâmetroTipoPadrãoO que é
fromAAAA-MM-DDto - 365dO primeiro dia do período. O bucket que contém esta data entra inteiro.
toAAAA-MM-DDhojeO último dia do período. O padrão é hoje, no fuso da sua conta.
intervalday | week | month | quarter | yearmonthO tamanho do bucket. É isto que muda "mês a mês" para "dia a dia".

A resposta

CampoO que é
metricA métrica pedida, do jeito que ela se chama no catálogo.
unitmoney, percent ou count. Diz como ler o value (veja abaixo).
aggregationpoint_in_time, sum_over_period ou rate_over_period. Diz o que o número significa.
currencyA moeda da conta, em ISO-4217. Só faz sentido quando unit é money.
timezoneO fuso da conta. É o calendário em que os buckets foram cortados.
intervalO intervalo de fato aplicado (o que você pediu, ou o padrão).
from, toO período de fato aplicado. Confira aqui o que o padrão escolheu por você.
points[]A série. Cada ponto tem start, end (EXCLUSIVO), value e, quando existe, count: quantos itens estão por trás do número. Métrica sem contagem não manda o campo, em vez de mandar zero.

Os buckets são alinhados ao calendário: com interval=month, um from=2026-03-15 devolve o bucket que começa em 2026-03-01. Cada ponto carrega o seu start e o seu end para você nunca ter que deduzi-los.

O catálogo de métricas

GET/v1/metrics

A lista viva das métricas, com a moeda e o fuso da sua conta. Peça este endpoint em vez de fixar a lista no seu código: métrica nova aparece aqui sozinha.

{
  "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étricaUnidadeComo ler
mrrDinheiro (centavos)Foto no fim do bucket
arrDinheiro (centavos)Foto no fim do bucket
subscribersContagemFoto no fim do bucket
growthTaxa (fração)Taxa do bucket
gross-revenueDinheiro (centavos)Soma do bucket
gateway-feesTaxa (fração)Taxa do bucket
refund-rateTaxa (fração)Taxa do bucket
net-revenueDinheiro (centavos)Soma do bucket
one-off-revenueDinheiro (centavos)Soma do bucket
mrr-churnTaxa (fração)Taxa do bucket
net-mrr-churnTaxa (fração)Taxa do bucket
customer-churnTaxa (fração)Taxa do bucket
ltvDinheiro (centavos)Foto no fim do bucket
arpaDinheiro (centavos)Foto no fim do bucket
trialsContagemSoma do bucket
trial-conversionTaxa (fração)Taxa do bucket
freemiumsContagemSoma do bucket
freemium-conversionTaxa (fração)Taxa do bucket

Assinaturas

O coração da fonte. É daqui que sai o seu MRR -- sem assinaturas, não há métrica nenhuma para calcular.

Criar ou atualizar assinaturas

POST/v1/subscriptions

Criar e atualizar são a MESMA chamada: o id é seu, e mandar o mesmo id de novo reescreve o objeto em vez de duplicar.

CampoTipoObrigatórioO que é
idstringO identificador que VOCÊ escolhe. Mandar o mesmo id de novo atualiza a assinatura, não duplica.
customerstringO id do cliente dono desta assinatura. Em branco, a assinatura conta como um cliente (você não precisa cadastrar clientes).
currencyenum(BRL | USD | EUR | GBP | ...)A moeda desta assinatura, em ISO-4217. Moeda desconhecida é recusada, nunca assumida. Ela é da assinatura inteira, no topo (nunca dentro de uma faixa de amounts), e não muda.
started_atdateQuando ela começou. A primeira faixa de amounts tem que começar exatamente aqui.
canceled_atdateQuando ela foi cancelada. É a data do churn, e ela é declarada: não há gateway aqui para nos contar.
trial_enddateQuando o teste grátis terminou. O período até esta data nunca vira MRR.
amountsarray<{ from: date, cents: integer, cycle: enum(daily | weekly | biweekly | monthly | bimonthly | quarterly | semiannually | yearly), plan?: string }>A HISTÓRIA do valor, datada. Cada faixa tem from (desde quando aquele contrato passou a valer), cents, cycle (de quanto em quanto tempo você cobra por ela) e plan opcional (o rótulo do produto naquele período, com efeito só se a sua fonte declarar planos). O ciclo mora dentro da faixa, e não no topo da assinatura: é isso que permite declarar um upgrade de mensal para anual sem cancelar e recriar a assinatura, o que inventaria um churn que não houve. As faixas vão em ordem crescente de data, sem repetir o mesmo dia, e a primeira começa exatamente no started_at. Leia a seção acima antes de mexer aqui.
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"}]}'

O objeto que você manda SUBSTITUI o que estava lá: não há merge. Campo omitido é campo APAGADO -- para trocar só o telefone, mande o cliente inteiro, com o telefone novo. É por isso que esta API não tem PUT: o POST já é o "substituir por inteiro".

Mande em LOTE (um array no corpo, até 1000 objetos). Ou tudo entra, ou nada entra: um lote meio-aplicado deixaria você sem saber o que entrou. A resposta é 202, e o painel se move em até um minuto.

Cancelar é este mesmo POST, com canceled_at preenchido: não há endpoint separado, porque não há porta separada. A assinatura fica no histórico e vira churn na data que você declarar. Cancelar não é apagar

Apagar uma assinatura do histórico (a errata)

DEL/v1/subscriptions/{id}

Use quando o dado entrou errado: id trocado, teste em produção, duplicata. É irreversível pela API -- para trazer de volta, mande o objeto de novo.

DELETE não é cancelar. Apagar diz "isto nunca existiu": o objeto some e o MRR passado se refaz sem ele. Para dizer que o cliente SAIU, mande o canceled_at -- a assinatura fica no histórico e vira churn na data declarada. Confundir os dois corrompe o seu churn nas duas direções.

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

Listar assinaturas

GET/v1/subscriptions

Devolve o que está no seu cofre, paginado por cursor. É o que você declarou, cru; para os NÚMEROS calculados a partir dele, veja a leitura de métricas no começo da página.

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

Até 500 por página (limit, padrão 100). O cursor é o id do último objeto da página anterior.

Clientes

Opcional. Só é preciso se um mesmo cliente tiver mais de uma assinatura -- sem clientes, cada assinatura conta como um cliente. O único campo obrigatório é o id, então dá para agrupar sem nos contar quem eles são.

Criar ou atualizar clientes

POST/v1/customers

Criar e atualizar são a MESMA chamada: o id é seu, e mandar o mesmo id de novo reescreve o objeto em vez de duplicar.

CampoTipoObrigatórioO que é
idstringO identificador que VOCÊ escolhe. Mandar o mesmo id de novo atualiza o cliente, não duplica.
namestringNome do cliente. Opcional: você não precisa nos revelar quem ele é.
emailstringE-mail do cliente.
phonestringO telefone do cliente, como você o escreve. Serve para achá-lo na busca e para falar com ele.
created_atdateQuando ele virou seu 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"}'

O objeto que você manda SUBSTITUI o que estava lá: não há merge. Campo omitido é campo APAGADO -- para trocar só o telefone, mande o cliente inteiro, com o telefone novo. É por isso que esta API não tem PUT: o POST já é o "substituir por inteiro".

Mande em LOTE (um array no corpo, até 1000 objetos). Ou tudo entra, ou nada entra: um lote meio-aplicado deixaria você sem saber o que entrou. A resposta é 202, e o painel se move em até um minuto.

Apagar um cliente do histórico (a errata)

DEL/v1/customers/{id}

Use quando o dado entrou errado: id trocado, teste em produção, duplicata. É irreversível pela API -- para trazer de volta, mande o objeto de novo.

DELETE não é cancelar. Apagar diz "isto nunca existiu": o objeto some e o MRR passado se refaz sem ele. Para dizer que o cliente SAIU, mande o canceled_at -- a assinatura fica no histórico e vira churn na data declarada. Confundir os dois corrompe o seu churn nas duas direções.

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

Listar clientes

GET/v1/customers

Devolve o que está no seu cofre, paginado por cursor. É o que você declarou, cru; para os NÚMEROS calculados a partir dele, veja a leitura de métricas no começo da página.

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

Até 500 por página (limit, padrão 100). O cursor é o id do último objeto da página anterior.

Pagamentos

Opcional. Sem pagamentos, o MRR continua inteiro: ele sai do contrato, não do dinheiro que entrou.

Criar ou atualizar pagamentos

POST/v1/payments

Criar e atualizar são a MESMA chamada: o id é seu, e mandar o mesmo id de novo reescreve o objeto em vez de duplicar.

CampoTipoObrigatórioO que é
idstringO identificador que VOCÊ escolhe.
customerstringO id de quem pagou. Ou este, ou subscription: um pagamento sempre diz de quem é.
subscriptionstringO id da assinatura que este pagamento quita. Em branco, é venda avulsa (não entra no MRR; entra na receita).
amount_centsintegerO valor bruto pago, em centavos.
paid_atdateQuando o dinheiro entrou.
fee_centsintegerA taxa do meio de pagamento, em centavos.
refunded_centsintegerQuanto voltou para o cliente, em centavos. Estorno parcial é válido.
currencyenumSe ficar em branco, usamos a da assinatura (ou a da sua conta, se for avulso).
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}'

O objeto que você manda SUBSTITUI o que estava lá: não há merge. Campo omitido é campo APAGADO -- para trocar só o telefone, mande o cliente inteiro, com o telefone novo. É por isso que esta API não tem PUT: o POST já é o "substituir por inteiro".

Mande em LOTE (um array no corpo, até 1000 objetos). Ou tudo entra, ou nada entra: um lote meio-aplicado deixaria você sem saber o que entrou. A resposta é 202, e o painel se move em até um minuto.

Apagar um pagamento do histórico (a errata)

DEL/v1/payments/{id}

Use quando o dado entrou errado: id trocado, teste em produção, duplicata. É irreversível pela API -- para trazer de volta, mande o objeto de novo.

DELETE não é cancelar. Apagar diz "isto nunca existiu": o objeto some e o MRR passado se refaz sem ele. Para dizer que o cliente SAIU, mande o canceled_at -- a assinatura fica no histórico e vira churn na data declarada. Confundir os dois corrompe o seu churn nas duas direções.

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

Listar pagamentos

GET/v1/payments

Devolve o que está no seu cofre, paginado por cursor. É o que você declarou, cru; para os NÚMEROS calculados a partir dele, veja a leitura de métricas no começo da página.

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

Até 500 por página (limit, padrão 100). O cursor é o id do último objeto da página anterior.