Nesta página
Authorization: Bearer e já pode ler e criar lançamentos e tarefas. Para ser avisado quando algo acontece, cadastre um webhook assinado.Versão v1. Endereço base: https://southamerica-east1-app-theros.cloudfunctions.net/apiV1. Formato JSON em UTF-8; datas em ISO 8601 (UTC); valores em reais com até 2 casas. Mudanças que quebram contrato só entram numa /v2; ignore campos que você não conhece.
| Rota | O que faz | Chave |
|---|---|---|
GET /v1/transactions | Lista lançamentos | leitura |
POST /v1/transactions | Cria um lançamento | escrita |
GET /v1/tasks | Lista tarefas | leitura |
POST /v1/tasks | Cria uma tarefa | escrita |
POST /v1/tasks/{id}/complete | Conclui uma tarefa | escrita |
GET /v1/summary | Receitas, despesas e saldo de um mês | leitura |
Autenticação
Crie a chave no app: Perfil > Integrações > API e webhooks > Criar chave. A chave aparece uma única vez (thr_live_ + 43 caracteres, gerada com 256 bits aleatórios). O Theros guarda só um resumo (hash SHA-256): se você perder a chave, revogue e crie outra. Dá para escolher uma validade (30 dias, 90 dias, 6 meses ou 1 ano; o padrão do app é 1 ano). O app mostra, em cada chave, quando foi criada e o último uso.
Envie a chave no cabeçalho Authorization:
curl https://southamerica-east1-app-theros.cloudfunctions.net/apiV1/v1/summary \
-H "Authorization: Bearer thr_live_SUA_CHAVE"
- Nunca ponha a chave na URL (
?api_key=...): a API ignora e responde 401. URLs ficam em logs e históricos. - Trate a chave como senha: não publique em repositório, planilha compartilhada ou captura de tela.
- Cada chave tem um escopo: leitura (
GET) ou leitura e escrita (GETePOST). Use a menor que resolve. - Revogou no app? A chave deixa de valer na chamada seguinte (401), sem cache. Chave vencida também dá 401.
- A resposta 401 é idêntica para chave ausente, malformada, desconhecida, revogada e vencida (mesmo corpo, mesmos cabeçalhos): a API não diz se uma chave existiu.
- Quem erra a chave muitas vezes é freado: mais de 30 chaves inválidas por minuto a partir do mesmo endereço recebem
429(comRetry-After) sem que o Theros consulte a chave. Isso não bloqueia a sua chave válida usada de outro endereço. - O plano é conferido em toda chamada. Se o plano for rebaixado, a API responde 403
plan_requiredaté voltar para Pro/Premium. - Contas compartilhadas (household) ainda não são atendidas: a API responde 409
household_not_supported. - A API não aceita chamadas feitas por JavaScript de página web (CORS fechado: nenhuma resposta traz
Access-Control-*e o preflightOPTIONSé recusado). Use um servidor, uma automação ou um script. - Só
GETePOSTexistem.HEAD,OPTIONS,PUT,PATCH,DELETEeTRACErespondem405; cabeçalhos de troca de método (X-HTTP-Method-Override) são ignorados. - Todo corpo de escrita precisa ser exatamente
application/json(charsetopcional); outro tipo dá415. - Toda resposta traz
Cache-Control: no-store,X-Content-Type-Options: nosniff,Strict-Transport-SecurityeContent-Security-Policy: default-src 'none'. Só HTTPS.
Convenções
Sucesso
{"data": [ ... ], "next_cursor": "eyJ2IjoxLC4uLn0"} // listas
{"data": { ... }} // um objeto
Erro
{"error": {"code": "invalid_amount", "message": "amount deve ser um número (ex.: 12.5), não texto."}}
O code é estável (use no código); a message é para leitura humana e pode mudar.
Paginação. limit de 1 a 100 (padrão 50). Quando next_cursor não é null, repita a chamada com ?cursor=<next_cursor> e os mesmos filtros. O cursor é opaco; não monte nem interprete.
Datas e fuso. from e to são dias (AAAA-MM-DD) no fuso do seu perfil e incluem o dia inteiro. Cada lançamento traz date (instante em UTC) e local_date (o dia no seu fuso).
Limites
Valores provisórios (podem mudar com aviso):
| Limite | Valor |
|---|---|
| Chamadas por chave | 60 por minuto e 5.000 por dia (UTC) |
Escritas (POST) da conta, somando TODAS as chaves | 30 por minuto, 1.000 por hora e 3.000 por dia (UTC) |
| Chaves inválidas por endereço de origem | 30 por minuto (acima disso, 429 sem consulta) |
| Tamanho do corpo | 64 KB |
limit de listas | 1 a 100 |
| Chaves ativas por conta | 5 |
| Endpoints de webhook por conta | 5 |
Estourou? A resposta é 429 com o cabeçalho Retry-After (segundos até poder tentar de novo). Se o contador de limites estiver indisponível, a API não libera: responde 503 (unavailable) com Retry-After:
HTTP/1.1 429 Too Many Requests
Retry-After: 23
{"error":{"code":"rate_limited","message":"Limite de requisições atingido (60/min, 5000/dia por chave). Tente de novo em 23 s."}}
Lançamentos
GET /v1/transactions
Filtros (todos opcionais): from, to (AAAA-MM-DD), type (expense ou income), limit, cursor. Ordem: do mais recente para o mais antigo.
curl "$BASE/v1/transactions?from=2026-10-01&to=2026-10-31&type=expense&limit=50" \
-H "Authorization: Bearer $THEROS_KEY"
{
"data": [
{
"id": "api_3f9c0a...",
"type": "expense",
"amount": 42.5,
"description": "Almoço",
"category": "food",
"category_id": "cat_food",
"subcategory": null,
"date": "2026-10-04T15:00:00.000Z",
"local_date": "2026-10-04",
"notes": null,
"tags": [],
"payment_method": "pix",
"bank_account_id": null,
"credit_card_id": null,
"installment": null,
"created_at": "2026-10-05T14:02:11.000Z",
"origin": "api"
}
],
"next_cursor": null
}
category é a chave da categoria do sistema (food, transport...) ou o nome de uma categoria sua. origin é "api" para o que foi criado por esta API e null para o resto. installment traz {number, total, group_id} nos lançamentos parcelados.
POST /v1/transactions
Exige chave com escrita e o cabeçalho Idempotency-Key (ver seção 6).
| Campo | Obrigatório | Regra |
|---|---|---|
type | sim | "expense" ou "income" |
amount | sim | número maior que 0, até 2 casas decimais (não envie texto) |
description | sim | 1 a 200 caracteres |
category | não | chave do sistema (food, transport, health, education, entertainment, housing, shopping, utilities, taxes, investments, others, salary, plr, investments_return, freelance, bonus, rental, gift), apelido em português já usado no app ("alimentação", "lazer") ou nome/id de categoria sua. Sem category: others (despesa) ou salary (receita). Nome que não existe dá erro: a API nunca cria categoria sozinha. |
date | não | AAAA-MM-DD (vale meio-dia no seu fuso) ou ISO 8601 com fuso (2026-10-04T23:30:00-03:00). Padrão: agora. Aceita de 2000 até 1 ano à frente. |
notes | não | até 1.000 caracteres |
tags | não | até 10 textos de até 30 caracteres |
payment_method | não | pix, credit, debit ou cash |
Campos desconhecidos dão erro (unknown_field): um erro de digitação não vira dado perdido.
curl -X POST "$BASE/v1/transactions" \
-H "Authorization: Bearer $THEROS_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: fatura-2026-10-linha-17" \
-d '{"type":"expense","amount":42.5,"description":"Almoço","category":"alimentação","date":"2026-10-04","payment_method":"pix"}'
Resposta 201 com o lançamento criado (mesmo formato do GET). Repetir a chamada com o mesmo Idempotency-Key e o mesmo conteúdo responde 200 com Idempotent-Replayed: true e não duplica.
Tarefas
GET /v1/tasks
Filtros opcionais: status (todo, inProgress, done, cancelled), limit, cursor. Mais novas primeiro.
{
"data": [
{
"id": "api_81b2...",
"title": "Pagar o DAS",
"description": "MEI",
"status": "todo",
"priority": "high",
"category": "finance",
"due_date": "2026-10-20T15:00:00.000Z",
"reminder_time": "2026-10-20T12:30:00.000Z",
"completed_at": null,
"created_at": "2026-10-05T14:02:11.000Z",
"origin": "api"
}
],
"next_cursor": null
}
POST /v1/tasks
Chave com escrita e Idempotency-Key.
| Campo | Obrigatório | Regra |
|---|---|---|
title | sim | 1 a 200 caracteres |
description | não | até 2.000 caracteres |
due_date | não | AAAA-MM-DD (meio-dia no seu fuso) |
priority | não | low, medium (padrão), high, urgent |
category | não | personal (padrão), work, finance, health, shopping, other |
reminder_time | não | HH:MM (24 h, no seu fuso). Exige due_date. O Theros agenda o aviso sozinho. |
Tarefa com due_date também aparece no calendário do app, como as criadas pelo app.
curl -X POST "$BASE/v1/tasks" \
-H "Authorization: Bearer $THEROS_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: das-2026-10" \
-d '{"title":"Pagar o DAS","due_date":"2026-10-20","reminder_time":"09:30","priority":"high","category":"finance"}'
POST /v1/tasks/{id}/complete
Conclui a tarefa (chave com escrita; não precisa de Idempotency-Key: concluir de novo devolve 200 sem mudar nada). Tarefa recorrente gera a próxima ocorrência, e a resposta traz meta.next_task_id. Tarefa cancelada devolve 409 task_cancelled; id que não é seu devolve 404.
curl -X POST "$BASE/v1/tasks/api_81b2.../complete" -H "Authorization: Bearer $THEROS_KEY"
Idempotência
Redes falham e automações repetem. Em todo POST de criação envie Idempotency-Key (1 a 128 caracteres: letras, números, ., _, :, -). Regras:
- mesma chave de API + mesmo
Idempotency-Key+ mesmo conteúdo: devolve o item já criado (200,Idempotent-Replayed: true); - mesmo
Idempotency-Keycom outro conteúdo:422 idempotency_key_reuse; - o
Idempotency-Keyvale por chave de API (duas chaves podem usar o mesmo texto sem se atrapalhar); - use um valor que identifique o fato (id da linha da planilha, id do pedido), não um aleatório novo a cada tentativa.
Resumo do mês
GET /v1/summary?month=2026-10 (padrão: mês corrente no seu fuso).
{"data": {"month": "2026-10", "from": "2026-10-01", "to": "2026-10-31",
"income": 5000, "expense": 1306.99, "balance": 3693.01, "transactions": 4}}
É a soma simples de receitas e despesas lançadas no mês. Não aplica as regras de poupança/investimento que o app mostra nas telas de estatística.
Erros
| HTTP | code | Quando |
|---|---|---|
| 400 | invalid_json, invalid_type, invalid_amount, invalid_description, invalid_category, invalid_date, invalid_notes, invalid_tags, invalid_payment_method, invalid_title, invalid_priority, invalid_reminder_time, invalid_status, invalid_month, invalid_limit, invalid_cursor, invalid_query, unknown_field | Entrada inválida (a mensagem diz o campo) |
| 400 | idempotency_key_required, invalid_idempotency_key | Falta ou está mal formado o Idempotency-Key |
| 401 | invalid_api_key | Chave ausente, malformada, desconhecida, revogada ou vencida (a resposta é igual em todos os casos) |
| 403 | plan_required | O plano atual não inclui a API |
| 403 | insufficient_scope | Chave só de leitura tentando escrever |
| 404 | not_found | Rota ou tarefa inexistente |
| 405 | method_not_allowed | Método errado (o cabeçalho Allow diz os aceitos) |
| 409 | task_cancelled, household_not_supported, idempotency_conflict | Estado que não permite a ação |
| 413 | payload_too_large | Corpo acima de 64 KB |
| 415 | unsupported_media_type | Corpo que não é application/json |
| 422 | idempotency_key_reuse | Mesmo Idempotency-Key com outro conteúdo |
| 429 | rate_limited | Limite de taxa por chave, de escritas da conta ou de tentativas com chave inválida (veja Retry-After) |
| 500 / 503 | internal_error, unavailable | Erro nosso ou instabilidade momentânea: tente de novo (503 traz Retry-After) |
Webhooks
Um webhook é um endereço https seu que o Theros chama (POST, HTTP/1.1) quando algo acontece. Cadastre em Perfil > Integrações > API e webhooks > Webhooks. O app mostra o segredo de assinatura (whsec_...) uma vez; você precisa dele para conferir que a chamada veio do Theros. Dá para testar, pausar, girar o segredo e ver as últimas 20 entregas.
Eventos
| Evento | Quando |
|---|---|
transaction.created | Um lançamento foi criado (app, WhatsApp, recorrência...). |
task.created | Uma tarefa foi criada. |
task.completed | Uma tarefa passou a concluída. |
transactions.imported | Uma importação de extrato/planilha terminou: um evento com a contagem. |
webhook.test | Só do botão "Testar". |
O que não gera evento (de propósito):
- o que foi criado ou concluído por esta API (evita laço: o Make recebe um aviso, chama a API, e o aviso volta);
- cada lançamento de uma importação em lote (vem um
transactions.importedsó); - as parcelas 2 em diante de uma compra parcelada (a parcela 1 já traz
installment.total); - exclusões e edições (por enquanto).
Corpo
{
"id": "evt_9f1c2a7b3d4e5f6a7b8c9d0e",
"type": "transaction.created",
"created": 1759680131,
"data": { "id": "...", "type": "expense", "amount": 42.5, "description": "Almoço", "category": "food", "date": "2026-10-05T15:00:00.000Z", "local_date": "2026-10-05", "...": "..." }
}
id: identifica o fato. O mesmo fato sempre tem o mesmoid: use-o para ignorar repetição (a entrega é "pelo menos uma vez").created: segundos desde 1970 (UTC).datadetransaction.createdtem o mesmo formato doGET /v1/transactions; o detask.*, o doGET /v1/tasks.datadetransactions.imported:{"batch_id", "source", "count", "period_start", "period_end", "bank_account_id"}.
Cabeçalhos
| Cabeçalho | Conteúdo |
|---|---|
X-Theros-Event | tipo do evento |
X-Theros-Delivery | identificador da entrega (igual nas retentativas) |
X-Theros-Attempt | número da tentativa (1, 2, ...) |
X-Theros-Signature | t=<unix>,v1=<hex> |
User-Agent | Theros-Webhooks/1.0 |
Como verificar a assinatura
v1 é HMAC-SHA256 com chave igual ao segredo (texto whsec_... em UTF-8) sobre a mensagem "<t>.<corpo bruto>", em hexadecimal minúsculo. Use o corpo exatamente como chegou (bytes), antes de qualquer JSON.parse. Recuse se t estiver a mais de 5 minutos do relógio do seu servidor (proteção contra reenvio). Compare em tempo constante.
Node.js (Express)
const crypto = require("crypto");
const express = require("express");
const SECRET = process.env.THEROS_WEBHOOK_SECRET; // whsec_...
const TOLERANCE_SECONDS = 300;
function verify(secret, header, rawBody, nowSec = Math.floor(Date.now() / 1000)) {
let t = null;
const candidates = [];
for (const part of String(header || "").split(",")) {
const i = part.indexOf("=");
if (i < 0) continue;
const k = part.slice(0, i).trim();
const v = part.slice(i + 1).trim();
if (k === "t" && /^\d{1,12}$/.test(v)) t = Number(v);
if (k === "v1" && /^[0-9a-f]{64}$/.test(v)) candidates.push(v);
}
if (t === null || candidates.length === 0) return false;
if (Math.abs(nowSec - t) > TOLERANCE_SECONDS) return false;
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`, "utf8").digest();
return candidates.some((c) => {
const got = Buffer.from(c, "hex");
return got.length === expected.length && crypto.timingSafeEqual(got, expected);
});
}
const app = express();
// raw: precisamos do corpo em bytes para a assinatura
app.post("/theros", express.raw({type: "application/json", limit: "128kb"}), (req, res) => {
const body = req.body.toString("utf8");
if (!verify(SECRET, req.get("X-Theros-Signature"), body)) return res.status(401).send("assinatura inválida");
const event = JSON.parse(body);
// ignore repetição: guarde event.id (ex.: tabela com chave única) e pule se já viu
console.log(event.type, event.id);
res.sendStatus(200); // responda rápido (até 8 s) com 2xx
});
app.listen(3000);
Python (Flask)
import hashlib, hmac, os, re, time
from flask import Flask, request, abort
SECRET = os.environ["THEROS_WEBHOOK_SECRET"] # whsec_...
TOLERANCE_SECONDS = 300
def verify(secret: str, header: str, raw_body: bytes, now: float | None = None) -> bool:
now = time.time() if now is None else now
t, candidates = None, []
for part in (header or "").split(","):
k, _, v = part.partition("=")
k, v = k.strip(), v.strip()
if k == "t" and re.fullmatch(r"\d{1,12}", v):
t = int(v)
if k == "v1" and re.fullmatch(r"[0-9a-f]{64}", v):
candidates.append(v)
if t is None or not candidates:
return False
if abs(now - t) > TOLERANCE_SECONDS:
return False
expected = hmac.new(secret.encode("utf-8"), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
return any(hmac.compare_digest(c, expected) for c in candidates)
app = Flask(__name__)
@app.post("/theros")
def theros():
raw = request.get_data() # bytes exatos
if not verify(SECRET, request.headers.get("X-Theros-Signature", ""), raw):
abort(401)
event = request.get_json(force=True)
print(event["type"], event["id"])
return "", 200
Vetor de teste (confira sua implementação): segredo whsec_test_secret_123, t = 1700000000, corpo {"id":"evt_abc","type":"task.created","created":1700000000,"data":{"id":"t1","title":"Pagar o DAS"}} dão v1 = 7a3efdfa14ecb19c09225c50fd06aff06ec89435ec2f66c9f8dfe4b4ea6c645f.
Entrega, retentativas e desativação
- Seu endpoint deve responder
2xxem até 8 segundos. Redirecionamentos não são seguidos (3xx conta como falha). - Se falhar, o Theros tenta de novo: 1 envio + até 5 retentativas, depois de 1 min, 5 min, 30 min, 2 h e 12 h. O corpo é idêntico em todas as tentativas; a assinatura (
t) é nova a cada uma e usa o segredo atual do endpoint. - Fila e limites de envio. Até 60 eventos por minuto (1.500 por hora) por conta saem na hora. Acima disso a entrega vai para a fila e chega em alguns minutos; acima de 6.000 por dia o excedente é descartado. Um endpoint cuja última tentativa falhou recebe pela fila (o envio imediato volta quando uma entrega dá certo). Cada conta guarda no máximo 100 entregas pendentes; passando disso, as novas são descartadas.
- Uma entrega que esgota as 6 tentativas fica "falhou". Com 20 entregas seguidas nessa situação o endpoint é desativado e o app mostra o motivo; corrija o endereço e toque em Reativar. Uma entrega bem-sucedida zera a contagem.
- A ordem de chegada não é garantida (uma retentativa pode chegar depois de um evento mais novo). Use
createdeid. - O log mostra, por entrega: tipo, tentativas, código HTTP e erro. Guardamos no máximo 200 caracteres da sua resposta, por 14 dias.
Restrições do endereço
Só https; porta 443 (padrão) ou 8443; sem usuário/senha na URL; o nome precisa resolver para um endereço público. São recusados localhost, redes privadas (10.x, 172.16-31.x, 192.168.x), 169.254.x.x (inclui o metadata de nuvem), nomes internos (.local, .internal) e qualquer nome cujo DNS aponte para esses endereços, conferido a cada tentativa. Também são recusados nomes de uma palavra só, .home.arpa, .onion, .svc e as demais zonas que só existem em rede interna, endereços IPv6 que embutem IPv4 privado (::ffff:, NAT64, 6to4, Teredo) IPv4 escrito em decimal, octal ou hexadecimal e os endereços do próprio Theros (therosapp.com, *-app-theros.cloudfunctions.net). A conexão usa o endereço que foi validado (sem nova resolução, contra DNS rebinding), não segue redirecionamentos e lê no máximo 200 caracteres da sua resposta. Para testar em casa, use um túnel com endereço público (ngrok, Cloudflare Tunnel).
Girar o segredo
"Girar segredo" gera um novo e invalida o antigo na hora: não há período em que os dois valham. Entregas pendentes (retentativas) passam a ser assinadas com o segredo novo. Troque o segredo no seu receptor logo em seguida. O cabeçalho traz um v1; o código de exemplo aceita vários só para o caso de você montar uma troca em duas etapas. O segredo é gerado com 256 bits aleatórios, guardado cifrado (AES-256-GCM, amarrado ao seu usuário e ao endpoint) e só aparece na criação e ao girar.
Exemplos de integração
Make / n8n / Zapier (leitura). Use um módulo HTTP com GET https://southamerica-east1-app-theros.cloudfunctions.net/apiV1/v1/transactions?from=... e o cabeçalho Authorization: Bearer <chave>. Para ser avisado em vez de consultar, crie um webhook (Custom Webhook no Make, Webhook no n8n, Catch Hook no Zapier) e cole a URL no app.
Make / n8n / Zapier (escrita). Módulo HTTP POST /v1/transactions com chave de escrita, corpo JSON e Idempotency-Key com o id do registro de origem (assim reexecutar o cenário não duplica).
Google Planilhas (Apps Script).
function importarLancamentos() {
const KEY = PropertiesService.getScriptProperties().getProperty("THEROS_KEY");
const url = "https://southamerica-east1-app-theros.cloudfunctions.net/apiV1/v1/transactions?limit=100";
const res = UrlFetchApp.fetch(url, {headers: {Authorization: "Bearer " + KEY}, muteHttpExceptions: true});
if (res.getResponseCode() !== 200) throw new Error(res.getContentText());
const sheet = SpreadsheetApp.getActiveSheet();
JSON.parse(res.getContentText()).data.forEach((t) =>
sheet.appendRow([t.local_date, t.type, t.amount, t.category, t.description]));
}
Guarde a chave em Propriedades do script, nunca dentro da planilha.
Script de linha de comando.
export BASE=https://southamerica-east1-app-theros.cloudfunctions.net/apiV1
export THEROS_KEY=thr_live_...
curl -s "$BASE/v1/summary?month=$(date +%Y-%m)" -H "Authorization: Bearer $THEROS_KEY" | jq .data
Limitações da v1
- Só a conta pessoal (contas compartilhadas respondem 409).
- Não há
PATCH/DELETEnem leitura de contas, cartões, metas e demais módulos. - Eventos de edição e exclusão não existem ainda.
- Um segundo sistema não "ouve" o que o primeiro escreveu pela API (regra anti-laço, seção 9).
- Limites de plano e de taxa são provisórios.
Segurança: o que o Theros faz e o que fica com você
Segurança "absoluta" não existe; esta seção diz o que está fechado e o que depende de você.
O que o Theros faz. A chave tem 256 bits aleatórios e só o hash fica guardado; o servidor lê e grava só os dados de quem é dono da chave; as coleções de chaves, endpoints, entregas e estado ficam fechadas ao app (a tela usa só o servidor). Revogar vale na chamada seguinte, o plano é conferido a cada chamada, a escrita tem orçamento por conta, tentativas com chave inválida são freadas por endereço e contador indisponível nunca libera. O app mostra a atividade recente: quem criou ou revogou uma chave, criou, excluiu ou mudou o endereço de um webhook e girou um segredo, com data e o endereço de origem truncado. Nos webhooks: segredo cifrado e amarrado ao endpoint, assinatura HMAC-SHA256, bloqueio de SSRF (todos os endereços do DNS são validados e a conexão usa o endereço validado), sem redirecionamento, tempo total de 8 s, no máximo 200 caracteres lidos da sua resposta. O texto que você envia é saneado (sem controle, direção de texto nem invisíveis; descrição, título e tags em uma linha) e, quando o Theros fala com a IA, entra como dado, não como instrução.
O que fica com você.
- Quem tem a chave age como você dentro do escopo dela. Use a menor que resolve (leitura), dê validade e guarde em cofre de senhas ou variável secreta da automação, nunca em planilha compartilhada, repositório, captura de tela ou URL.
- Se a sua conta for comprometida, o invasor pode criar chaves. Ative a verificação em duas etapas, confira a atividade recente e revogue o que não reconhece. Trocar a senha não revoga chaves de API.
- Verifique a assinatura em todo webhook, recuse
tcom mais de 5 minutos e ignore repetições peloiddo evento. - Dados de terceiros que a sua automação grava (assunto de e-mail, nome de formulário) podem tentar enganar a IA ou outras pessoas: filtre antes de gravar.
- Achou uma falha de segurança? Escreva para rafaelfurlan@lunanexgen.com. Não teste contra contas de outras pessoas.
Perguntas frequentes
Quem pode usar a API do Theros?
Os planos Pro e Premium. Você cria a chave no app, em Perfil > Integrações > API e webhooks. Se o plano for rebaixado, a API responde 403 até voltar para Pro ou Premium.
A minha chave é segura?
O Theros guarda só um resumo da chave (hash) e a mostra uma única vez, na criação. Ela tem validade opcional, o app mostra o último uso e a atividade recente da conta, e você revoga a qualquer momento: a chave deixa de valer na chamada seguinte. Trate como senha, use a chave de leitura quando não precisar escrever e nunca a coloque em planilha compartilhada, repositório ou URL. Quem tiver a chave age como você dentro do escopo dela.
Existe limite de chamadas?
Sim, valores provisórios: 60 chamadas por minuto e 5.000 por dia por chave, escritas da conta limitadas a 30 por minuto e 3.000 por dia (somando todas as chaves), corpo de até 64 KB, 5 chaves e 5 webhooks por conta. Estourou o limite? A resposta é 429 com o cabeçalho Retry-After. Chave inválida repetida a partir do mesmo endereço também é freada.
Funciona com o Zapier, o Make e o n8n?
Sim, pelo módulo HTTP (para consultar e criar) e pelos webhooks (para ser avisado). No Zapier use Webhooks by Zapier (Catch Hook); no Make, Custom Webhook; no n8n, o nó Webhook. Ainda não existe um app oficial do Theros no Zapier.
Posso editar ou apagar lançamentos pela API?
Ainda não. A v1 lê e cria lançamentos e tarefas e conclui tarefas. Edição, exclusão e contas compartilhadas ficam para versões futuras.
Posso chamar a API direto do navegador, com JavaScript de uma página?
Não. O CORS é fechado de propósito para a chave não ficar exposta numa página. Chame a partir de um servidor, de uma automação ou de um script.