API REST
Os SDKs são camadas finas sobre esta API. Use direto de qualquer linguagem.
| Item | Valor |
|---|---|
| URL base | https://api.notific.me (a tela SDKs do app.notific.me mostra o endereço da sua conta) |
| Versão | Toda rota começa com /v0 |
| Autenticação | Authorization: Bearer nm_svc_… (token de serviço) |
| Formato | JSON na entrada e na saída, UTF-8, campos em snake_case, datas RFC 3339 |
| Id da requisição | Envie X-Request-Id para correlacionar; toda resposta devolve um |
Todo erro tem o mesmo envelope, com um code estável em que você pode confiar:
{ "error": { "code": "validation_failed", "message": "evento inválido", "details": { "schema": "event", "errors": [{ "path": "/severity", "message": "…" }] } }, "request_id": "019a…"}| Status | Códigos comuns |
|---|---|
| 400 | bad_request |
| 401 | unauthorized (token ausente, inválido, revogado ou vencido; serviço desativado) |
| 403 | forbidden (falta escopo), approval_required |
| 404 | not_found, hook_not_found |
| 409 | idempotency_conflict, conflict |
| 413 | payload_too_large |
| 422 | validation_failed (com details), idempotency_key_reused |
| 429 | rate_limited (com Retry-After) |
| 503 | unavailable |
A message é para logs; mostre aos seus usuários um texto baseado no code.
Eventos
Seção intitulada “Eventos”POST /v0/events
Seção intitulada “POST /v0/events”Escopo events:write. Corpo: um evento.
POST /v0/events HTTP/1.1Authorization: Bearer nm_svc_...Content-Type: application/json
{ "id": "inv-42-failed", "source": "billing", "type": "invoice.failed", "severity": "high", "occurred_at": "2026-11-05T12:00:00Z", "to": ["jimmy"], "payload": { "invoice": 42 }, "content": { "summary": "Invoice #42 failed" }}HTTP/1.1 202 AcceptedContent-Type: application/json
{ "id": "019a4f2e-…", "status": "queued", "sender_id": "inv-42-failed", "received_at": "2026-11-05T12:00:00.120Z"}statuséqueued, ouduplicate(comduplicate_of) quando juntado pelodedup_key.- Enviar o mesmo
idde novo devolve a resposta guardada comIdempotent-Replayed: true. O mesmoidcom outro corpo devolve409 idempotency_conflict. - Destinatário desconhecido no
todevolve422. - Limites: 1 MiB por corpo; 600 eventos por minuto por token (rajada de 100).
Perguntas (asks)
Seção intitulada “Perguntas (asks)”POST /v0/asks
Seção intitulada “POST /v0/asks”Escopo asks:write. Corpo: um grupo de perguntas. Envie o cabeçalho Idempotency-Key (até 200 caracteres) para que uma nova tentativa nunca crie dois grupos.
POST /v0/asks HTTP/1.1Authorization: Bearer nm_svc_...Content-Type: application/jsonIdempotency-Key: refund-881
{ "to": ["jimmy"], "title": "Refund order #881 (USD 240)?", "context": "The customer reported a duplicate charge.", "questions": [ { "id": "decision", "type": "single", "text": "What should we do?", "options": ["Refund", "Partial refund", "Deny"] }, { "id": "note", "type": "text", "text": "Note for the customer", "optional": true } ], "level": 2, "timeout": "30m", "on_timeout": { "decision": "Deny" }, "callback_url": "https://crm.example.com/hooks/notificme"}HTTP/1.1 201 CreatedContent-Type: application/json
{ "id": "019a4f30-…", "status": "open", "version": 1, "level": 2, "title": "Refund order #881 (USD 240)?", "created_at": "2026-11-05T12:00:00Z", "timeout_at": "2026-11-05T12:30:00Z", "notification_id": "019a4f30-…", "content_hash": "…", "poll_url": "/v0/asks/019a4f30-…"}- Corpo de até 256 KiB. Grupo inválido:
422 validation_failed. - A mesma
Idempotency-Keycom outro corpo:422 idempotency_key_reused. Requisição simultânea com a mesma chave:409 conflict.
GET /v0/asks/{id}?wait=60
Seção intitulada “GET /v0/asks/{id}?wait=60”Escopo asks:read. Devolve a mesma visão. Com wait (segundos, ou duração como 30s, até 60), a chamada faz long-poll: volta assim que o grupo sai de open, ou quando a espera acaba.
HTTP/1.1 200 OKContent-Type: application/json
{ "id": "019a4f30-…", "status": "answered", "version": 1, "level": 2, "title": "Refund order #881 (USD 240)?", "created_at": "2026-11-05T12:00:00Z", "timeout_at": "2026-11-05T12:30:00Z", "content_hash": "…", "poll_url": "/v0/asks/019a4f30-…", "reply": { "question_set_id": "019a4f30-…", "version": 1, "status": "answered", "answers": [ { "question_id": "decision", "question_text": "What should we do?", "value": "Refund" }, { "question_id": "note", "question_text": "Note for the customer", "free_text": "Sorry for the trouble!" } ], "as_text": "…", "answered_by": { "identity": "[email protected]", "device_id": "019a…", "level_used": 2, "auth_method": "totp" }, "answered_at": "2026-11-05T12:03:10Z", "content_hash": "…", "signature": { "alg": "Ed25519", "key_id": "…", "value": "…" } }}status é open, answered, timeout, expired ou cancelled. O reply aparece em answered e timeout.
POST /v0/hooks/{slug}
Seção intitulada “POST /v0/hooks/{slug}”Escopo events:write. Qualquer corpo (JSON, formulário ou texto) vindo de outro sistema, transformado em evento pelo mapeamento do hook. O token pode ir em ?token= para sistemas que só aceitam uma URL.
curl -sS -X POST "https://api.notific.me/v0/hooks/dokploy?token=$NOTIFICME_TOKEN" \ -H "Content-Type: application/json" \ -d '{"type": "build-success", "applicationName": "api", "projectName": "idie"}'{ "status": "queued", "rule": "deploy-ok", "event": { "id": "019a…", "status": "queued", "received_at": "2026-11-05T12:00:00Z" }}statuséqueued,duplicateouignored(nenhuma regra casou,200).?dry_run=1devolve{"status": "dry_run", "rule", "event"}com o evento gerado, sem gravar.- Assinatura HMAC errada:
401 invalid_signature. Sem mapeamento nem preset para o slug:404 hook_not_found.
Gerenciando mapeamentos
Seção intitulada “Gerenciando mapeamentos”Com um token (events:write):
| Rota | Descrição |
|---|---|
GET /v0/hooks |
Lista os hooks do workspace (gravados e presets). |
GET /v0/hooks/{slug}/mapping |
O mapeamento YAML, com o segredo HMAC mascarado. |
PUT /v0/hooks/{slug}/mapping |
Grava um mapeamento (YAML ou JSON). |
DELETE /v0/hooks/{slug}/mapping |
Apaga; um preset com o mesmo slug volta a valer. |
O app usa as rotas do workspace (/v0/workspaces/{handle}/hooks…, inclusive um dry-run com corpo, cabeçalhos e query de exemplo); elas também aceitam tokens com workspace:read e hooks:write.
Chaves de webhook
Seção intitulada “Chaves de webhook”GET /.well-known/notificme-keys.json
Seção intitulada “GET /.well-known/notificme-keys.json”Pública. As chaves Ed25519 (JWKS) que assinam webhooks e respostas. O SDK baixa e guarda em cache.
curl -sS "https://api.notific.me/.well-known/notificme-keys.json"Aprovações (agentes de IA)
Seção intitulada “Aprovações (agentes de IA)”| Rota | Descrição |
|---|---|
POST /v0/approvals |
Pede a uma pessoa que aprove uma escrita travada (method, path, body, reason). |
GET /v0/approvals/{id}?wait=60 |
Estado da aprovação (long-poll até 60 s). |
Depois repita a requisição original com Notificme-Approval: <id>. Veja Agentes de IA e MCP.
Administração do workspace
Seção intitulada “Administração do workspace”Tudo o que o app faz também é API em /v0/workspaces/{handle}/…: serviços, tokens, regras e o simulador, hooks, webhooks (listar e reenviar), eventos, notificações, perguntas, uso, membros e auditoria. Essas rotas aceitam a sessão de uma pessoa ou um token com o escopo correspondente (workspace:read, services:write, tokens:write, rules:write, hooks:write, webhooks:write, audit:read). O jeito mais fácil de usá-las a partir de um agente de IA é o servidor MCP.