Visão geral
A API do Manilo é uma API REST JSON para gerenciar programaticamente o mesmo registro financeiro que você usa no app iOS — contas, categorias, orçamentos, grupos compartilhados e transações. Use-a para criar importadores, exportadores, pontes de sincronização e painéis, ou para alimentar as suas próprias automações.
- URL base:
https://api.manilo.app— a URL base anteriorapi.ledgy.appcontinua funcionando. - Prefixo de versão: todos os endpoints deste documento ficam sob
/api/v1/. - Transporte: somente HTTPS. Requisições HTTP não são aceitas.
- Codificação: corpos de requisição e resposta em JSON. UTF-8. Nomes de propriedades em
camelCase. - Autenticação:
Authorization: Bearer …em todas as requisições. - Assinatura do Cloud: obrigatória em todos os endpoints da v1. Veja Exigência de assinatura.
https://api.manilo.app/mcp — veja Integrações. A API REST documentada aqui é para o código que você mesmo escreve.
Início rápido
Três passos até a sua primeira requisição autenticada.
1. Gere um Token de Acesso Pessoal
- Entre no seu painel do Manilo e abra Configurações → Acesso à API.
- Clique em + Novo token.
- Dê ao token um nome descritivo (por exemplo, “Zapier — exportação semanal”), escolha os escopos necessários (veja Escopos) e, se quiser, defina uma expiração.
- Copie o token. Ele é exibido uma única vez. Os tokens começam com o prefixo
lgpat_seguido de 64 caracteres hexadecimais.
A mesma página lista os seus tokens ativos com a data do último uso e a quantidade de permissões, exibe um aviso de “Expira em 30 dias” e permite revogar qualquer token na hora pelo ícone de lixeira. Cada conta pode ter até 25 tokens ativos ao mesmo tempo.
2. Faça uma requisição
# Replace lgpat_… with your token curl "https://api.manilo.app/api/v1/accounts" \ -H "Authorization: Bearer lgpat_a1b2c3d4e5…"
3. Analise a resposta
{
"items": [
{
"id": "acc_01HK8V…",
"name": "Wise EUR",
"currencyCode": "EUR",
"initialBalance": 1240.50,
"icon": "wallet",
"color": "#4A90E2",
"order": 0,
"createdAt": "2026-04-12T08:13:09Z",
"updatedAt": "2026-05-01T17:02:31Z"
}
],
"totalCount": 1
}
Autenticação
Toda requisição a /api/v1/ precisa levar um cabeçalho Authorization. Dois tipos de token são aceitos:
- Token de Acesso Pessoal (PAT) — bearer token de longa duração que você cria na página Configurações → Acesso à API do painel. Formato:
lgpat_+ 64 caracteres hexadecimais. Com escopos, revogável e com expiração opcional. Recomendado para todas as integrações de terceiros. - JWT de sessão — token de curta duração emitido para os apps próprios (iOS e painel). Não tem restrições de escopo. Você pode usá-lo para um teste pontual, se conseguir extraí-lo de uma sessão autenticada, mas os PATs são o caminho suportado.
Formato do cabeçalho
Authorization: Bearer lgpat_a1b2c3d4e5f6…
Limites de token
- Até 25 PATs ativos por conta do Manilo.
- É possível definir uma expiração opcional no momento da criação. Tokens expirados retornam
401 Unauthorized. - Tokens revogados param de funcionar imediatamente — o Manilo guarda apenas um hash SHA-256 do token, nunca o valor, então um token vazado não pode ser recuperado, apenas revogado e substituído.
Falhas comuns de autenticação
- 401
- Token ausente, malformado, expirado ou revogado.
- 403
- O token é válido, mas o endpoint solicitado exige um escopo que o seu PAT não tem, ou a sua assinatura do Cloud não está ativa.
Escopos
Os PATs seguem um modelo de negação por padrão. Um token só pode chamar endpoints cujo escopo exigido ele possui; todo o resto retorna 403 Forbidden. Conceda o conjunto mais restrito de escopos de que a sua integração realmente precisa.
Escopos disponíveis:
accounts:read
accounts:write
categories:read
categories:write
budgets:read
budgets:write
groups:read
groups:write
transactions:read
transactions:write
tags:read
tags:write
recurring:read
recurring:write
settings:read
settings:write
Cada endpoint listado abaixo mostra o escopo exigido em uma pequena etiqueta roxa. Escopos :write não implicam :read — peça os dois se precisar dos dois.
Exigência de assinatura
Todos os endpoints da v1 — inclusive os de somente leitura — exigem que o usuário que faz a chamada tenha uma assinatura ativa do Manilo Cloud. Se a assinatura foi interrompida, expirou ou nunca foi iniciada, a API responde com:
HTTP/1.1 403 Forbidden
X-Subscription-Required: true
Content-Type: application/json
{ "error": "Active cloud subscription required" }
O cabeçalho X-Subscription-Required permite que os clientes distingam um bloqueio por assinatura de uma negação de permissão genérica. Restaure o acesso reativando o Cloud no app iOS ou em dashboard.manilo.app/upgrade.
Erros
Os erros usam códigos de status HTTP padrão. O corpo da resposta é um objeto JSON de um único campo:
{ "error": "Human-readable message" }
Códigos de status que você deve tratar:
- 200
- OK — recurso retornado, ou lista retornada.
- 201
- Created — novo recurso criado. O cabeçalho
Locationaponta para a URL canônica. - 204
- No Content — exclusão bem-sucedida; sem corpo.
- 400
- Falha de validação — campo obrigatório ausente, valor fora do intervalo, JSON malformado.
- 401
- Falha de autenticação — veja Autenticação.
- 403
- Permissão negada — escopo insuficiente ou assinatura inativa.
- 404
- Recurso não encontrado, ou oculto por falta de autorização.
- 409
- Conflito — por exemplo, violação de restrição de unicidade.
- 5xx
- Falha do lado do servidor. É seguro repetir leituras idempotentes com backoff exponencial.
Paginação e filtros
Por padrão, os endpoints de listagem retornam todos os itens correspondentes. As transações, o único recurso que pode crescer muito, aceitam paginação por cursor.
Cursor de transações
curl "https://api.manilo.app/api/v1/transactions?limit=50&type=expense&dateFrom=2026-01-01" \ -H "Authorization: Bearer lgpat_…"
A resposta inclui um nextCursor. Envie-o de volta no parâmetro de consulta cursor para buscar a próxima página; quando nextCursor for null, você chegou ao fim.
limit— tamanho da página, limitado a1..200. Padrão:50.cursor— token opaco. Trate-o como uma caixa-preta.type,dateFrom,dateTo,categoryId,accountId,groupId— filtros opcionais; veja o endpoint Listar transações.
Tipos e formatos
- IDs — strings opacas. Não faça parsing delas; trate-as como identificadores UTF-8 que diferenciam maiúsculas de minúsculas.
- Timestamps — ISO-8601 em UTC com um
Zno final, por exemplo"2026-05-13T10:30:00Z". - Datas (por exemplo, o
dateda transação) — mesmo formato ISO-8601, mas apenas a parte da data é significativa. - Valores monetários — números JSON em unidades principais com até 4 casas decimais (por exemplo,
12.50). Nunca em unidades menores. Sempre acompanhados decurrencyCode. - Códigos de moeda — ISO-4217, exatamente três letras maiúsculas (por exemplo,
"EUR","USD","GBP"). - Exclusões — todas as operações de exclusão são exclusões reversíveis (soft deletes). Os itens excluídos deixam de aparecer nas respostas de listagem e de leitura; parceiros de compartilhamento e recibos históricos são preservados.
- Efeitos colaterais — excluir uma conta, categoria ou grupo mantém intactas as transações dependentes; as referências delas são desvinculadas. O endpoint Excluir conta aceita uma estratégia explícita.
Contas
As contas são os recipientes que guardam saldos — uma conta bancária, um cartão de crédito, uma carteira de dinheiro, uma corretora. Toda transação está ligada a uma (ou a duas, no caso das transferências).
/api/v1/accounts
accounts:read
Retorna todas as contas que o usuário autenticado possui ou às quais tem acesso.
/api/v1/accounts/{id}
accounts:read
Busca uma conta pelo id. Retorna 404 se não for encontrada.
/api/v1/accounts
accounts:write
Cria uma conta. Retorna 201 com o objeto criado e um cabeçalho Location.
| Campo | Tipo | Descrição |
|---|---|---|
| name | string | obrigatórioNome de exibição. Máx. 100 caracteres. |
| currencyCode | string | obrigatórioISO-4217. Exatamente 3 letras. |
| initialBalance | number | obrigatórioSaldo inicial em currencyCode. |
| order | integer | obrigatórioPosição de ordenação. Menor vem primeiro. |
| icon | string | opcionalIdentificador de ícone de /api/v1/icons. Máx. 50. |
| color | string | opcionalCor em hexadecimal, por exemplo "#4A90E2". Máx. 20. |
| iconColor | string | opcionalSobrescreve a cor do ícone. |
POST /api/v1/accounts
{
"name": "Cash",
"currencyCode": "EUR",
"initialBalance": 50.00,
"order": 2,
"icon": "wallet",
"color": "#22C55E"
}
{
"id": "acc_01HK8V…",
"name": "Cash",
"currencyCode": "EUR",
"initialBalance": 50.00,
"order": 2,
"icon": "wallet",
"color": "#22C55E",
"iconColor": null,
"shareInviteToken": null,
"createdAt": "2026-05-13T10:30:00Z",
"updatedAt": "2026-05-13T10:30:00Z"
}
/api/v1/accounts/{id}
accounts:write
Substitui uma conta existente. O corpo é idêntico ao de Criar; todos os campos devem ser informados.
/api/v1/accounts/{id}
accounts:write
Exclui uma conta de forma reversível. Defina o que acontece com as transações dela pelo parâmetro de consulta action.
| Campo | Tipo | Descrição |
|---|---|---|
| action | enum | opcionalDetach (padrão): limpa a referência de conta em cada transação. Move: reatribui as transações para moveTargetAccountId. DeleteAll: exclui de forma reversível todas as transações vinculadas que pertencem a você. |
| moveTargetAccountId | string | opcionalObrigatório quando action=Move. Id da conta de destino. |
Categorias
As categorias identificam para que serve uma transação (mercado, aluguel, renda de freelance). As categorias do sistema são somente leitura e compartilhadas por todos os usuários; as categorias de usuário são suas para gerenciar. Os grupos de categorias reúnem categorias relacionadas.
/api/v1/categories/system-categories
categories:read
Retorna o conjunto curado de categorias “conhecidas” do Manilo — o conjunto inicial que vem com o app iOS. Elas são versionadas globalmente e podem ser cacheadas com segurança por version.
Categorias de usuário
/api/v1/categories
categories:read
Lista todas as categorias definidas pelo usuário.
/api/v1/categories/{id}
categories:read
Busca uma categoria de usuário pelo id.
/api/v1/categories
categories:write
Cria uma categoria de usuário.
| Campo | Tipo | Descrição |
|---|---|---|
| name | string | obrigatórioNome de exibição. Máx. 100. |
| type | string | obrigatório"income" ou "expense". |
| order | integer | obrigatórioPosição de ordenação dentro do grupo. |
| isPinned | boolean | obrigatórioFixa no topo do seletor. |
| categoryGroupId | string | opcionalId do grupo pai, ou null para ficar sem grupo. |
| icon | string | opcionalIdentificador de ícone. |
| color | string | opcionalCor em hexadecimal. |
/api/v1/categories/{id}
categories:write
Substitui uma categoria de usuário. O corpo é idêntico ao de Criar.
/api/v1/categories/{id}
categories:write
Exclui uma categoria de usuário de forma reversível. As transações não são excluídas; o categoryId delas é limpo.
Grupos de categorias
/api/v1/categories/groups
categories:read
Lista os seus grupos de categorias.
/api/v1/categories/groups/{id}
categories:read
Busca um grupo de categorias.
/api/v1/categories/groups
categories:write
Cria um grupo de categorias.
| Campo | Tipo | Descrição |
|---|---|---|
| name | string | obrigatórioNome de exibição. Máx. 100. |
| order | integer | obrigatórioPosição de ordenação. |
| icon | string | opcionalIdentificador de ícone. |
| color | string | opcionalCor em hexadecimal. |
/api/v1/categories/groups/{id}
categories:write
Substitui um grupo de categorias.
/api/v1/categories/groups/{id}
categories:write
Exclui um grupo de forma reversível. As categorias filhas sobrevivem — o categoryGroupId delas é limpo.
Orçamentos
Um orçamento limita os gastos de uma categoria (ou, quando categoryId é nulo, do registro financeiro inteiro) em uma janela recorrente. Compartilhe um orçamento com um grupo definindo groupId.
/api/v1/budgets
budgets:read
Lista todos os orçamentos.
/api/v1/budgets/{id}
budgets:read
Busca um orçamento.
/api/v1/budgets
budgets:write
Cria um orçamento.
| Campo | Tipo | Descrição |
|---|---|---|
| amount | number | obrigatórioLimite por período. Precisa ser maior que 0. |
| currencyCode | string | obrigatórioISO-4217. |
| period | integer | obrigatório0 Semanal · 1 Mensal · 2 Trimestral · 3 Anual. |
| startDate | string (ISO-8601) | obrigatórioInício do primeiro período. |
| isActive | boolean | obrigatórioSe este orçamento está em vigor no momento. |
| endDate | string (ISO-8601) | opcionalParar de acompanhar depois desta data. |
| name | string | opcionalRótulo. Máx. 200. |
| categoryId | string | opcionalCategoria a acompanhar. Omita para orçar todos os gastos. |
| groupId | string | opcionalGrupo com quem compartilhar. Omita para deixar pessoal. |
/api/v1/budgets/{id}
budgets:write
Substitui um orçamento.
/api/v1/budgets/{id}
budgets:write
Exclui um orçamento de forma reversível.
Grupos
Os grupos são registros financeiros compartilhados — uma casa, uma viagem, um apartamento dividido. Todos os membros veem as mesmas transações; a propriedade continua pessoal. Participação e convites são gerenciados no app iOS; o que a API expõe aqui é o recurso em si.
/api/v1/groups
groups:read
Lista os grupos que você possui ou dos quais é membro.
/api/v1/groups/{id}
groups:read
Busca um grupo.
/api/v1/groups
groups:write
Cria um grupo. Você se torna o dono; convide membros pelo app iOS.
| Campo | Tipo | Descrição |
|---|---|---|
| name | string | obrigatórioNome de exibição. Máx. 100. |
| description | string | opcionalTexto livre. Máx. 500. |
| icon | string | opcionalIdentificador de ícone. |
| color | string | opcionalCor em hexadecimal. |
/api/v1/groups/{id}
groups:write
Substitui os metadados de um grupo.
/api/v1/groups/{id}
groups:write
Exclui um grupo de forma reversível. Os membros perdem a visibilidade; as transações subjacentes voltam a ser pessoais.
Transações
As transações são os verbos do registro financeiro. Elas vêm em quatro formatos: income, expense, transfer (de conta para conta) e adjustment (reajuste pontual). O endpoint base cria income/expense; as transferências têm o próprio endpoint; existem variantes em lote para importadores de alto volume.
/api/v1/transactions
transactions:read
Lista transações com paginação por cursor e filtros.
| Campo | Tipo | Descrição |
|---|---|---|
| limit | integer | opcionalTamanho da página. 1..200. Padrão: 50. |
| cursor | string | opcionalToken opaco de continuação, vindo da resposta anterior. |
| type | string | opcional"income", "expense", "transfer" ou "adjustment". |
| dateFrom | string (ISO-8601) | opcionalLimite inferior, inclusivo. |
| dateTo | string (ISO-8601) | opcionalLimite superior, inclusivo. |
| categoryId | string | opcionalFiltra por uma categoria. |
| accountId | string | opcionalFiltra por uma conta. |
| groupId | string | opcionalFiltra por um grupo compartilhado. |
{
"items": [ /* TransactionDto[] */ ],
"totalCount": 317,
"nextCursor": "eyJrIjoiMjAyNi0wNS0xM1QxMDoz…"
}
/api/v1/transactions/{id}
transactions:read
Busca uma transação.
/api/v1/transactions
transactions:write
Cria uma única transação de receita ou despesa. Para transferências, use /transfer.
| Campo | Tipo | Descrição |
|---|---|---|
| type | string | obrigatório"income" ou "expense". |
| amount | number | obrigatórioValor positivo em currencyCode. |
| currencyCode | string | obrigatórioISO-4217. |
| date | string (ISO-8601) | obrigatórioQuando a transação ocorreu (UTC). |
| accountId | string | opcionalConta de origem/destino. |
| categoryId | string | opcionalRótulo de categoria. |
| payee | string | opcionalEstabelecimento ou contraparte. Máx. 200. |
| note | string | opcionalObservação livre. Máx. 2000. |
| groupId | string | opcionalCompartilhar com um grupo. |
| exchangeRate | number | opcionalTaxa de câmbio quando currencyCode ≠ moeda principal do usuário. |
| convertedAmount | number | opcionalValor na moeda principal do usuário. |
POST /api/v1/transactions
{
"type": "expense",
"amount": 8.50,
"currencyCode": "EUR",
"date": "2026-05-12T09:14:00Z",
"accountId": "acc_01HK8V…",
"categoryId": "cat_food_drinks",
"payee": "Pret",
"note": "Flat white"
}
/api/v1/transactions/{id}
transactions:write
Substitui uma transação. O corpo é idêntico ao de Criar.
/api/v1/transactions/{id}
transactions:write
Exclui uma transação de forma reversível.
/api/v1/transactions/transfer
transactions:write
Cria uma transferência entre duas contas. Sem categoria. Para transferências entre moedas diferentes, informe exchangeRate e convertedAmount na moeda de destino.
| Campo | Tipo | Descrição |
|---|---|---|
| fromAccountId | string | obrigatórioConta de origem. |
| toAccountId | string | obrigatórioConta de destino. Precisa ser diferente da de origem. |
| amount | number | obrigatórioValor enviado, em currencyCode. |
| currencyCode | string | obrigatórioMoeda de origem, ISO-4217. |
| date | string (ISO-8601) | obrigatórioData da transferência. |
| exchangeRate | number | opcionalObrigatório quando as moedas de origem e destino são diferentes. |
| convertedAmount | number | opcionalValor creditado no destino, na moeda dele. |
| note | string | opcionalMáx. 2000. |
Operações em lote
Feitas para importadores. Cada lote é limitado a 100 itens e roda em modo best-effort: uma única linha inválida não desfaz as outras. Os itens bem-sucedidos e os erros por linha são reportados separadamente, para você repetir apenas as falhas.
/api/v1/transactions/bulk
transactions:write
Cria até 100 transações em uma chamada.
{
"items": [ /* successful TransactionDto[] */ ],
"errors": [
{ "index": 3, "error": "Invalid currency code" }
]
}
/api/v1/transactions/bulk
transactions:write
Atualiza até 100 transações em uma chamada. Cada item precisa incluir o seu id junto com o corpo completo da transação.
/api/v1/transactions/bulk-delete
transactions:write
Exclui de forma reversível até 100 transações em uma chamada. Usa POST em vez de DELETE para que o corpo da requisição seja aceito por todos os clientes HTTP.
| Campo | Tipo | Descrição |
|---|---|---|
| ids | string[] | obrigatórioDe 1 a 100 ids de transação. |
{
"deleted": 97,
"notFound": [ "tx_old1", "tx_old2", "tx_old3" ]
}
O objeto de transação
| Campo | Tipo | Descrição |
|---|---|---|
| id | string | Identificador opaco. |
| type | string | income · expense · transfer · adjustment. |
| amount | number | Em currencyCode. |
| currencyCode | string | ISO-4217. |
| exchangeRate | number | null | Definido em lançamentos entre moedas diferentes. |
| convertedAmount | number | null | O mesmo valor na moeda principal do usuário. |
| date | string | ISO-8601 UTC. |
| accountId | string | null | Em transferências, esta é a conta de origem. |
| toAccountId | string | null | Conta de destino, apenas em transferências. |
| categoryId | string | null | Nulo em transferências. |
| groupId | string | null | Definido se estiver compartilhado com um grupo. |
| payee | string | null | Estabelecimento ou contraparte. |
| note | string | null | Texto livre. |
| receiptImagePath | string | null | Caminho do recibo anexado. Busque pelo endpoint de recibos (separado da v1). |
| recurringTransactionId | string | null | Definido se esta linha foi gerada por uma regra de recorrência. |
| source | string | Etiqueta de origem — api, mobile, web, import, entre outras. |
| createdAt | string | ISO-8601 UTC. |
| updatedAt | string | ISO-8601 UTC. |
Ícones
O Manilo vem com um conjunto curado de ícones e uma paleta de cores usados em tudo — contas, categorias e grupos. Busque o catálogo uma vez, guarde em cache e reutilize os identificadores ao criar recursos.
/api/v1/icons
Retorna a biblioteca completa de ícones, agrupada em categorias, junto com a paleta de cores suportada. É versionada — pode ser cacheada com segurança pelo campo version.
{
"version": "2026.05.10",
"library": "font-awesome-6",
"categories": [
{
"id": "finance",
"name": "Finance",
"icons": [ "wallet", "credit-card", "piggy-bank" ]
}
],
"colors": [
{ "name": "Blue", "hex": "#4A90E2" },
{ "name": "Green", "hex": "#22C55E" }
]
}
Versionamento
- Sem mudanças incompatíveis dentro da v1. Vamos apenas acrescentar novos endpoints, novos campos opcionais e novos valores de enum. O tipo, a nulabilidade ou a obrigatoriedade de um campo não vão mudar.
- Novos valores de enum não são mudanças incompatíveis. Trate valores desconhecidos de
type,sourceouactioncomo “não renderizar” em vez de quebrar — vamos adicioná-los conforme o produto crescer. - Mudanças incompatíveis datadas (se algum dia forem necessárias) virão sob
/api/v2/com pelo menos 6 meses de disponibilidade paralela e um cabeçalho de descontinuação nas respostas da v1.
Suporte
Achou um bug, quer um endpoint ou esbarrou em algo que não está documentado? Abra a central de ajuda ou escreva para support@manilo.app — inclua o id da requisição (devolvido no cabeçalho de resposta X-Request-Id) ao relatar um problema.
Para divulgações sensíveis de segurança (vazamento de token, contorno de permissão, leitura não autorizada), escreva para security@manilo.app.