Pular para o conteúdo
Acessar painel

Webhooks

Webhooks permitem que a API Maestron notifique sua aplicação sobre eventos assim que eles acontecem, sem necessidade de polling. Quando um evento ocorre na empresa ativa, a Maestron envia uma requisição POST para a URL configurada, contendo o payload do evento.

A empresa (tenant) é resolvida automaticamente a partir do token usado para configurar o webhook. Para os fundamentos de autenticação, veja Autenticação; para o formato de erros, veja Erros.

Entrega

Cada evento gera uma requisição POST para a URL do webhook, com o payload em JSON no corpo.

Assinatura

Toda entrega é assinada com HMAC-SHA256 no header X-Maestron-Signature, derivada do secret.

Retentativas

Entregas que falham são reenviadas automaticamente com backoff exponencial.

Histórico

Cada tentativa de entrega fica registrada e pode ser consultada e reenviada manualmente.

Os tipos de evento seguem o padrão dominio.recurso.acao. A lista abaixo é o conjunto inicial, voltado ao módulo CRM. Novos eventos serão adicionados conforme outros módulos forem lançados.

EventoDisparado quando
crm.contact.createdUm contato é criado
crm.contact.updatedUm contato é atualizado
crm.contact.deletedUm contato é removido
crm.company.createdUma empresa CRM é criada
crm.company.updatedUma empresa CRM é atualizada
crm.company.deletedUma empresa CRM é removida
crm.deal.createdUm negócio é criado
crm.deal.updatedUm negócio é atualizado
crm.deal.stage_changedUm negócio muda de estágio
crm.deal.wonUm negócio é marcado como ganho
crm.deal.lostUm negócio é marcado como perdido
crm.activity.createdUma atividade é criada
crm.activity.completedUma atividade é concluída

A lista canônica de eventos sempre pode ser obtida via API:

GET /webhooks/events

Listar eventos disponíveis

Retorna os tipos de eventos que podem ser assinados por um webhook.

curl -X GET https://api.maestron.com.br/v1/webhooks/events \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maestron.com.br/v1/webhooks/events', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.get(
    "https://api.maestron.com.br/v1/webhooks/events",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/v1/webhooks/events", {
  method: "GET",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.GetAsync("https://api.maestron.com.br/v1/webhooks/events");
var data = await response.Content.ReadAsStringAsync();
GET /webhooks/events HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Eventos listados.",
  "data": [
    {
      "event": "crm.contact.created",
      "description": "Um contato é criado."
    },
    {
      "event": "crm.deal.won",
      "description": "Um negócio é marcado como ganho."
    },
    {
      "event": "crm.activity.completed",
      "description": "Uma atividade é concluída."
    }
  ]
}
{
  "message": "Não autenticado."
}

Toda entrega tem o mesmo envelope, independentemente do evento. O campo data carrega o recurso no estado relevante ao evento.

{
"id": "evt_01J9Z3K8",
"event": "crm.deal.won",
"created_at": "2026-06-20T14:30:00Z",
"data": {
"id": "deal_01J9Z3K8",
"title": "Plano Anual - Acme",
"value": 1500000,
"currency": "BRL",
"pipeline_id": "pipe_01J9Z3K8",
"stage_id": "stg_01J9Z3K8",
"contact_id": "cont_01J9Z3K8",
"company_id": "comp_01J9Z3K8",
"won_at": "2026-06-20T14:30:00Z"
}
}
CampoTipoDescrição
idstringIdentificador do evento (prefixo evt_). Único por entrega de evento.
eventstringTipo do evento (ex.: crm.deal.won).
created_atstringMomento em que o evento ocorreu, em ISO-8601.
dataobjectO recurso relacionado ao evento. A forma de data segue o recurso do domínio.

Valores monetários são inteiros em centavos e datas seguem ISO-8601, como em toda a API.

Cada requisição enviada ao endpoint do webhook inclui os headers abaixo:

HeaderDescrição
Content-Typeapplication/json
User-AgentMaestron-Webhooks/1.0
X-Maestron-EventTipo do evento (ex.: crm.deal.won)
X-Maestron-DeliveryIdentificador da entrega (prefixo whd_)
X-Maestron-SignatureAssinatura HMAC-SHA256 da entrega (ver abaixo)
X-Maestron-TimestampTimestamp Unix (segundos) usado na assinatura

Cada entrega é assinada com HMAC-SHA256 usando o secret do webhook. O endpoint receptor deve recalcular a assinatura e compará-la com o header X-Maestron-Signature antes de confiar no payload.

O header tem o formato:

X-Maestron-Signature: t=1718894400,v1=5257a869e7 ... 9d2f
  • t: o timestamp Unix da entrega (idêntico a X-Maestron-Timestamp).
  • v1: a assinatura HMAC-SHA256 em hexadecimal.

A string assinada (signed payload) é a concatenação do timestamp, um ponto e o corpo bruto da requisição:

signed_payload = t + "." + corpo_bruto_da_requisição

A assinatura esperada é HMAC_SHA256(signed_payload, secret), em hexadecimal.

A comparação deve usar uma função de comparação em tempo constante (timingSafeEqual ou equivalente) para evitar ataques de timing.

import crypto from 'node:crypto';
function isValidSignature(rawBody, signatureHeader, secret) {
const parts = Object.fromEntries(
signatureHeader.split(',').map((kv) => kv.split('=')),
);
const timestamp = parts.t;
const received = parts.v1;
const signedPayload = `${timestamp}.${rawBody}`;
const expected = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
const a = Buffer.from(received, 'hex');
const b = Buffer.from(expected, 'hex');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}

O secret é a chave usada para assinar as entregas. Ele é retornado apenas na criação do webhook (e ao rotacionar) — a API nunca o reenvia em leituras subsequentes. Se for perdido, gere um novo com a rotação de secret.

GET /webhooks

Listar webhooks

Lista os webhooks configurados na empresa ativa. Suporta paginação.

Parâmetros de query

CampoTipoObrigatórioDescrição
page integer Página atual (padrão: 1).
per_page integer Itens por página (padrão: 20, máx: 100).
curl -X GET https://api.maestron.com.br/v1/webhooks \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maestron.com.br/v1/webhooks', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.get(
    "https://api.maestron.com.br/v1/webhooks",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/v1/webhooks", {
  method: "GET",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.GetAsync("https://api.maestron.com.br/v1/webhooks");
var data = await response.Content.ReadAsStringAsync();
GET /webhooks HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Webhooks listados.",
  "data": [
    {
      "id": "whk_01J9Z3K8",
      "url": "https://app.exemplo.com/webhooks/maestron",
      "events": [
        "crm.deal.won",
        "crm.deal.lost"
      ],
      "is_active": true,
      "created_at": "2026-06-20T14:30:00Z",
      "updated_at": "2026-06-20T14:30:00Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "per_page": 20,
    "total": 1,
    "last_page": 1
  }
}
{
  "message": "Não autenticado."
}

O secret é opcional no corpo. Se omitido, a API gera um automaticamente. Em ambos os casos, o valor final é retornado apenas nesta resposta.

POST /webhooks

Criar webhook

Cria um webhook na empresa ativa. O secret é retornado somente nesta resposta.

Corpo (body)

CampoTipoObrigatórioDescrição
url string Sim URL HTTPS que receberá as entregas.
events string[] Sim Lista de tipos de evento a assinar.
secret string Secret de assinatura. Se omitido, é gerado automaticamente.
is_active boolean Define se o webhook está ativo (padrão: true).
curl -X POST https://api.maestron.com.br/v1/webhooks \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://app.exemplo.com/webhooks/maestron",
    "events": [
      "crm.deal.won",
      "crm.deal.lost"
    ],
    "is_active": true
  }'
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.maestron.com.br/v1/webhooks', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
    'json' => [
        'url' => 'https://app.exemplo.com/webhooks/maestron',
        'events' => crm.deal.won,crm.deal.lost,
        'is_active' => true,
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
payload = {
    "url": "https://app.exemplo.com/webhooks/maestron",
    "events": crm.deal.won,crm.deal.lost,
    "is_active": True,
}
response = requests.post(
    "https://api.maestron.com.br/v1/webhooks",
    headers=headers,
    json=payload,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/v1/webhooks", {
  method: "POST",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "url": "https://app.exemplo.com/webhooks/maestron",
    "events": [
      "crm.deal.won",
      "crm.deal.lost"
    ],
    "is_active": true
  }),
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var payload = new StringContent(
    "{\"url\":\"https://app.exemplo.com/webhooks/maestron\",\"events\":[\"crm.deal.won\",\"crm.deal.lost\"],\"is_active\":true}",
    System.Text.Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://api.maestron.com.br/v1/webhooks", payload);
var data = await response.Content.ReadAsStringAsync();
POST /webhooks HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN
Content-Type: application/json

{
  "url": "https://app.exemplo.com/webhooks/maestron",
  "events": [
    "crm.deal.won",
    "crm.deal.lost"
  ],
  "is_active": true
}

Respostas

{
  "message": "Webhook criado.",
  "data": {
    "id": "whk_01J9Z3K8",
    "url": "https://app.exemplo.com/webhooks/maestron",
    "events": [
      "crm.deal.won",
      "crm.deal.lost"
    ],
    "secret": "whsec_2b7f1c9a4d8e6f0a3c5b9d2e7f1a4c8b",
    "is_active": true,
    "created_at": "2026-06-20T14:30:00Z",
    "updated_at": "2026-06-20T14:30:00Z"
  }
}
{
  "message": "Não autenticado."
}
{
  "message": "Os dados informados são inválidos.",
  "errors": {
    "url": [
      "O campo url deve ser uma URL válida."
    ],
    "events": [
      "O campo events é obrigatório."
    ]
  }
}
GET /webhooks/{id}

Retornar webhook

Retorna um webhook pelo identificador. O secret não é incluído.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim Identificador do webhook (prefixo whk_).
curl -X GET https://api.maestron.com.br/v1/webhooks/{id} \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maestron.com.br/v1/webhooks/{id}', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.get(
    "https://api.maestron.com.br/v1/webhooks/{id}",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/v1/webhooks/{id}", {
  method: "GET",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.GetAsync("https://api.maestron.com.br/v1/webhooks/{id}");
var data = await response.Content.ReadAsStringAsync();
GET /webhooks/{id} HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Webhook retornado.",
  "data": {
    "id": "whk_01J9Z3K8",
    "url": "https://app.exemplo.com/webhooks/maestron",
    "events": [
      "crm.deal.won",
      "crm.deal.lost"
    ],
    "is_active": true,
    "created_at": "2026-06-20T14:30:00Z",
    "updated_at": "2026-06-20T14:30:00Z"
  }
}
{
  "message": "Não autenticado."
}
{
  "message": "Registro não encontrado."
}
PATCH /webhooks/{id}

Atualizar webhook

Atualiza url, eventos, secret ou status de um webhook. Campos omitidos permanecem inalterados.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim Identificador do webhook (prefixo whk_).

Corpo (body)

CampoTipoObrigatórioDescrição
url string Nova URL HTTPS de destino.
events string[] Nova lista de tipos de evento a assinar.
secret string Novo secret de assinatura.
is_active boolean Ativa ou desativa o webhook.
curl -X PATCH https://api.maestron.com.br/v1/webhooks/{id} \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      "crm.deal.won",
      "crm.deal.lost",
      "crm.deal.stage_changed"
    ],
    "is_active": false
  }'
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('PATCH', 'https://api.maestron.com.br/v1/webhooks/{id}', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
    'json' => [
        'events' => crm.deal.won,crm.deal.lost,crm.deal.stage_changed,
        'is_active' => false,
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
payload = {
    "events": crm.deal.won,crm.deal.lost,crm.deal.stage_changed,
    "is_active": False,
}
response = requests.patch(
    "https://api.maestron.com.br/v1/webhooks/{id}",
    headers=headers,
    json=payload,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/v1/webhooks/{id}", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "events": [
      "crm.deal.won",
      "crm.deal.lost",
      "crm.deal.stage_changed"
    ],
    "is_active": false
  }),
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var payload = new StringContent(
    "{\"events\":[\"crm.deal.won\",\"crm.deal.lost\",\"crm.deal.stage_changed\"],\"is_active\":false}",
    System.Text.Encoding.UTF8, "application/json");
var response = await client.SendAsync(new HttpRequestMessage(
    new HttpMethod("PATCH"), "https://api.maestron.com.br/v1/webhooks/{id}") { Content = payload });
var data = await response.Content.ReadAsStringAsync();
PATCH /webhooks/{id} HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN
Content-Type: application/json

{
  "events": [
    "crm.deal.won",
    "crm.deal.lost",
    "crm.deal.stage_changed"
  ],
  "is_active": false
}

Respostas

{
  "message": "Webhook atualizado.",
  "data": {
    "id": "whk_01J9Z3K8",
    "url": "https://app.exemplo.com/webhooks/maestron",
    "events": [
      "crm.deal.won",
      "crm.deal.lost",
      "crm.deal.stage_changed"
    ],
    "is_active": false,
    "created_at": "2026-06-20T14:30:00Z",
    "updated_at": "2026-06-20T15:10:00Z"
  }
}
{
  "message": "Não autenticado."
}
{
  "message": "Registro não encontrado."
}
{
  "message": "Os dados informados são inválidos.",
  "errors": {
    "url": [
      "O campo url deve ser uma URL válida."
    ]
  }
}
DELETE /webhooks/{id}

Remover webhook

Remove um webhook. Entregas pendentes deixam de ser tentadas.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim Identificador do webhook (prefixo whk_).
curl -X DELETE https://api.maestron.com.br/v1/webhooks/{id} \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.maestron.com.br/v1/webhooks/{id}', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.delete(
    "https://api.maestron.com.br/v1/webhooks/{id}",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/v1/webhooks/{id}", {
  method: "DELETE",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.DeleteAsync("https://api.maestron.com.br/v1/webhooks/{id}");
var data = await response.Content.ReadAsStringAsync();
DELETE /webhooks/{id} HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Webhook removido."
}
{
  "message": "Não autenticado."
}
{
  "message": "Registro não encontrado."
}

Gera um novo secret de assinatura, invalidando o anterior. O novo valor é retornado apenas nesta resposta.

POST /webhooks/{id}/rotate-secret

Rotacionar secret

Gera um novo secret de assinatura e o retorna. O secret anterior deixa de ser válido.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim Identificador do webhook (prefixo whk_).
curl -X POST https://api.maestron.com.br/v1/webhooks/{id}/rotate-secret \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.maestron.com.br/v1/webhooks/{id}/rotate-secret', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.post(
    "https://api.maestron.com.br/v1/webhooks/{id}/rotate-secret",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/v1/webhooks/{id}/rotate-secret", {
  method: "POST",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.PostAsync("https://api.maestron.com.br/v1/webhooks/{id}/rotate-secret", null);
var data = await response.Content.ReadAsStringAsync();
POST /webhooks/{id}/rotate-secret HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Secret rotacionado.",
  "data": {
    "id": "whk_01J9Z3K8",
    "secret": "whsec_9f3a1d7c2b8e4f6a0c5d9b3e7f1a4c8b"
  }
}
{
  "message": "Não autenticado."
}
{
  "message": "Registro não encontrado."
}

Envia um evento de teste para a URL configurada e registra a entrega no histórico. Útil para validar conectividade e a verificação de assinatura do endpoint receptor.

POST /webhooks/{id}/ping

Testar webhook

Envia um evento de teste para a URL do webhook e registra a entrega.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim Identificador do webhook (prefixo whk_).
curl -X POST https://api.maestron.com.br/v1/webhooks/{id}/ping \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.maestron.com.br/v1/webhooks/{id}/ping', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.post(
    "https://api.maestron.com.br/v1/webhooks/{id}/ping",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/v1/webhooks/{id}/ping", {
  method: "POST",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.PostAsync("https://api.maestron.com.br/v1/webhooks/{id}/ping", null);
var data = await response.Content.ReadAsStringAsync();
POST /webhooks/{id}/ping HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Webhook testado.",
  "data": {
    "delivery_id": "whd_01J9Z3K8",
    "event": "webhook.ping",
    "status": "success",
    "response_code": 200
  }
}
{
  "message": "Não autenticado."
}
{
  "message": "Registro não encontrado."
}

Uma entrega é considerada bem-sucedida quando o endpoint responde com status 2xx. Qualquer outro status, timeout ou erro de conexão marca a tentativa como falha e agenda uma retentativa.

  • As retentativas usam backoff exponencial entre tentativas.
  • O número total de tentativas é limitado; após esgotá-lo, a entrega fica com status failed e não é mais tentada automaticamente.
  • Cada tentativa é registrada como uma entrega consultável no histórico.
  • Entregas que falharam podem ser reenviadas manualmente.
TentativaAtraso aproximado após a falha anterior
1imediata
21 minuto
35 minutos
430 minutos
52 horas
66 horas

Cada tentativa de entrega é registrada com o payload enviado, o código HTTP de resposta, o número de tentativas e os timestamps.

GET /webhooks/{id}/deliveries

Listar entregas

Lista as entregas (tentativas) de um webhook. Suporta paginação e filtros.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim Identificador do webhook (prefixo whk_).

Parâmetros de query

CampoTipoObrigatórioDescrição
status string Filtra por status: pending, success ou failed.
event string Filtra pelo tipo de evento.
page integer Página atual (padrão: 1).
per_page integer Itens por página (padrão: 20, máx: 100).
curl -X GET https://api.maestron.com.br/v1/webhooks/{id}/deliveries \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maestron.com.br/v1/webhooks/{id}/deliveries', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.get(
    "https://api.maestron.com.br/v1/webhooks/{id}/deliveries",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/v1/webhooks/{id}/deliveries", {
  method: "GET",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.GetAsync("https://api.maestron.com.br/v1/webhooks/{id}/deliveries");
var data = await response.Content.ReadAsStringAsync();
GET /webhooks/{id}/deliveries HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Entregas listadas.",
  "data": [
    {
      "id": "whd_01J9Z3K8",
      "event": "crm.deal.won",
      "status": "failed",
      "response_code": 500,
      "attempts": 3,
      "created_at": "2026-06-20T14:30:00Z",
      "last_attempt_at": "2026-06-20T15:05:00Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "per_page": 20,
    "total": 1,
    "last_page": 1
  }
}
{
  "message": "Não autenticado."
}
{
  "message": "Registro não encontrado."
}
GET /webhooks/{id}/deliveries/{delivery_id}

Retornar entrega

Retorna uma entrega com o payload enviado, código HTTP de resposta, tentativas e timestamps.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim Identificador do webhook (prefixo whk_).
delivery_id string Sim Identificador da entrega (prefixo whd_).
curl -X GET https://api.maestron.com.br/v1/webhooks/{id}/deliveries/{delivery_id} \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maestron.com.br/v1/webhooks/{id}/deliveries/{delivery_id}', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.get(
    "https://api.maestron.com.br/v1/webhooks/{id}/deliveries/{delivery_id}",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/v1/webhooks/{id}/deliveries/{delivery_id}", {
  method: "GET",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.GetAsync("https://api.maestron.com.br/v1/webhooks/{id}/deliveries/{delivery_id}");
var data = await response.Content.ReadAsStringAsync();
GET /webhooks/{id}/deliveries/{delivery_id} HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Entrega retornada.",
  "data": {
    "id": "whd_01J9Z3K8",
    "event": "crm.deal.won",
    "status": "failed",
    "response_code": 500,
    "attempts": 3,
    "payload": {
      "id": "evt_01J9Z3K8",
      "event": "crm.deal.won",
      "created_at": "2026-06-20T14:30:00Z",
      "data": {
        "id": "deal_01J9Z3K8",
        "title": "Plano Anual - Acme",
        "value": 1500000
      }
    },
    "response_body": "Internal Server Error",
    "created_at": "2026-06-20T14:30:00Z",
    "last_attempt_at": "2026-06-20T15:05:00Z"
  }
}
{
  "message": "Não autenticado."
}
{
  "message": "Registro não encontrado."
}

Reenvia manualmente uma entrega que falhou. Só é possível reenviar entregas em estado reenviável (failed); tentar reenviar uma entrega já bem-sucedida ou em andamento retorna 409.

POST /webhooks/{id}/deliveries/{delivery_id}/retry

Reenviar entrega

Reenvia manualmente uma entrega que falhou.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim Identificador do webhook (prefixo whk_).
delivery_id string Sim Identificador da entrega (prefixo whd_).
curl -X POST https://api.maestron.com.br/v1/webhooks/{id}/deliveries/{delivery_id}/retry \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.maestron.com.br/v1/webhooks/{id}/deliveries/{delivery_id}/retry', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.post(
    "https://api.maestron.com.br/v1/webhooks/{id}/deliveries/{delivery_id}/retry",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/v1/webhooks/{id}/deliveries/{delivery_id}/retry", {
  method: "POST",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.PostAsync("https://api.maestron.com.br/v1/webhooks/{id}/deliveries/{delivery_id}/retry", null);
var data = await response.Content.ReadAsStringAsync();
POST /webhooks/{id}/deliveries/{delivery_id}/retry HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Entrega reenviada.",
  "data": {
    "id": "whd_01J9Z3K8",
    "event": "crm.deal.won",
    "status": "success",
    "response_code": 200,
    "attempts": 4,
    "last_attempt_at": "2026-06-20T16:00:00Z"
  }
}
{
  "message": "Não autenticado."
}
{
  "message": "Registro não encontrado."
}
{
  "message": "A entrega não está em um estado reenviável."
}

Endpoints de webhook precisam de uma URL pública acessível pela Maestron. Em desenvolvimento, exponha o servidor local com um túnel HTTP, por exemplo o ngrok.

Terminal window
# Expõe a porta local 3000 com uma URL HTTPS pública
ngrok http 3000

A saída mostra uma URL pública, por exemplo https://a1b2c3d4.ngrok-free.app.