Pular para o conteúdo

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.

Escopo events:write. Corpo: um evento.

POST /v0/events HTTP/1.1
Authorization: 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 Accepted
Content-Type: application/json
{
"id": "019a4f2e-…",
"status": "queued",
"sender_id": "inv-42-failed",
"received_at": "2026-11-05T12:00:00.120Z"
}
  • status é queued, ou duplicate (com duplicate_of) quando juntado pelo dedup_key.
  • Enviar o mesmo id de novo devolve a resposta guardada com Idempotent-Replayed: true. O mesmo id com outro corpo devolve 409 idempotency_conflict.
  • Destinatário desconhecido no to devolve 422.
  • Limites: 1 MiB por corpo; 600 eventos por minuto por token (rajada de 100).

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.1
Authorization: Bearer nm_svc_...
Content-Type: application/json
Idempotency-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 Created
Content-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",
"recipients": ["[email protected]"],
"notification_id": "019a4f30-…",
"content_hash": "…",
"poll_url": "/v0/asks/019a4f30-…"
}
  • Corpo de até 256 KiB. Grupo inválido: 422 validation_failed.
  • A mesma Idempotency-Key com outro corpo: 422 idempotency_key_reused. Requisição simultânea com a mesma chave: 409 conflict.

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 OK
Content-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.

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.

Janela do terminal
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, duplicate ou ignored (nenhuma regra casou, 200).
  • ?dry_run=1 devolve {"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.

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.

Pública. As chaves Ed25519 (JWKS) que assinam webhooks e respostas. O SDK baixa e guarda em cache.

Janela do terminal
curl -sS "https://api.notific.me/.well-known/notificme-keys.json"
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.

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.