Notificações
Um agente avisa o seu humano por e-mail, webhook assinado ou ntfy, com canais, prioridade e histórico de envios.
Envie um aviso curto (título, mensagem e prioridade) para quem opera a conta: por e-mail, por um webhook assinado ou por um tópico do ntfy. Pensado para agentes de IA que terminam uma tarefa longa ou precisam de uma decisão, e também útil em qualquer automação.
- Base path
/v1/tools/notify- Escopos
tools:notify:sendtools:notify:managetools:manage
Como funciona
Uma notificação tem title, message e priority (normal ou high), e opcionalmente uma url para o humano abrir. Ela sai por um canal:
- Canal escolhido: o
channeldo pedido, pelo nome do canal. - Canal padrão: o canal marcado com
is_default, quando o pedido não trazchannel. - E-mail da conta: sem canal nenhum configurado, a notificação vai para o e-mail da conta.
Também está disponível no MCP como a tool notify (toolset notify): o agente avisa que terminou uma tarefa longa ou que precisa de uma decisão.
| Operação | Rota |
|---|---|
| Enviar notificação | POST/ |
| Histórico de envios | GET/messages |
| Listar canais | GET/channels |
| Criar canal | POST/channels |
| Consultar canal | GET/channels/{id} |
| Alterar canal | PATCH/channels/{id} |
| Excluir canal | DELETE/channels/{id} |
| Testar canal | POST/channels/{id}/test |
Canais
Cada canal tem um name único na conta e um kind:
kind | Campos | Como entrega |
|---|---|---|
email | nenhum | Envia só para o e-mail da conta. Não é possível escolher outro destinatário. |
webhook | url, secret | Faz um POST na URL, assinado como no Webhook Relay. |
ntfy | server, topic | Publica no tópico do ntfy, no servidor informado. |
is_default marca o canal usado quando o pedido não indica um, e enabled: false desativa o canal sem apagá-lo. O secret do webhook nunca volta nas respostas: guarde-o ao criar o canal.
O tópico do ntfy é a senha
Em servidores públicos do ntfy, quem souber o tópico lê as notificações. Use um nome longo e imprevisível, ou um servidor seu.
Limites, retry e histórico
- Rate limit: há um limite de notificações por período; acima dele o envio falha com
notify.rate_limited. - Retry do webhook: uma entrega que falha é tentada de novo algumas vezes antes de virar
notify.delivery_failed. O receptor deve tratar repetições e conferir a assinatura. - Histórico:
GET /messageslista os envios (canal, prioridade, status e data), paginado compageepage_size(até 100). O histórico não guarda o título nem o corpo da mensagem.
Custos
Cada envio pela API é cobrado conforme o valor indicado no endpoint. Canais e histórico são grátis, e a falha na entrega não é cobrada.
Endpoints
Enviar notificação
/v1/tools/notify- Custo
- Franquia diária, depois 0,03 crédito/leitura via API
- Dry-run
- Suportado (
X-Dry-Run: true) - Autenticação
- qualquer um de
tools:notify:sendtools:manage
title e message são obrigatórios; priority é normal ou high; url e channel são opcionais. Sem channel, usa o canal padrão e, sem nenhum canal, o e-mail da conta.
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/notify' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "title": "Deploy concluído", "message": "A versão 2.4 está no ar.", "priority": "normal" }'const response = await fetch('https://api.respawntech.dev/v1/tools/notify', {
method: 'POST',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({ "title": "Deploy concluído", "message": "A versão 2.4 está no ar.", "priority": "normal" }),
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.respawntech.dev/v1/tools/notify",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
json={ "title": "Deploy concluído", "message": "A versão 2.4 está no ar.", "priority": "normal" },
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/notify');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{ "title": "Deploy concluído", "message": "A versão 2.4 está no ar.", "priority": "normal" }
JSON,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/notify", strings.NewReader(`{ "title": "Deploy concluído", "message": "A versão 2.4 está no ar.", "priority": "normal" }`))
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"channel": "celular",
"kind": "ntfy",
"status": "delivered"
}
}Histórico de envios
/v1/tools/notify/messages- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:notify:managetools:manage
Paginado por page e page_size (até 100). Não traz o corpo das mensagens.
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/notify/messages?page=1&page_size=20' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/notify/messages?page=1&page_size=20', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/notify/messages?page=1&page_size=20",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/notify/messages?page=1&page_size=20');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/notify/messages?page=1&page_size=20", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"channel": "celular",
"kind": "ntfy",
"priority": "high",
"status": "delivered",
"created_at": "2026-10-06T12:00:00Z"
}
],
"page": 1,
"page_size": 20,
"total": 1
}
}Listar canais
/v1/tools/notify/channels- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:notify:managetools:manage
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/notify/channels' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/notify/channels', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/notify/channels",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/notify/channels');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/notify/channels", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "celular",
"kind": "ntfy",
"server": "https://ntfy.sh",
"topic": "meu-topico-secreto",
"is_default": true,
"enabled": true,
"created_at": "2026-10-06T12:00:00Z"
}
]
}
}Criar canal
/v1/tools/notify/channels- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:notify:managetools:manage
name e kind são obrigatórios. url e secret valem para webhook; server e topic, para ntfy. Campos que não combinam com o kind respondem notify.invalid_channel.
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/notify/channels' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "name": "celular", "kind": "ntfy", "server": "https://ntfy.sh", "topic": "meu-topico-secreto", "is_default": true }'const response = await fetch('https://api.respawntech.dev/v1/tools/notify/channels', {
method: 'POST',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({ "name": "celular", "kind": "ntfy", "server": "https://ntfy.sh", "topic": "meu-topico-secreto", "is_default": true }),
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.respawntech.dev/v1/tools/notify/channels",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
json={ "name": "celular", "kind": "ntfy", "server": "https://ntfy.sh", "topic": "meu-topico-secreto", "is_default": True },
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/notify/channels');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{ "name": "celular", "kind": "ntfy", "server": "https://ntfy.sh", "topic": "meu-topico-secreto", "is_default": true }
JSON,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/notify/channels", strings.NewReader(`{ "name": "celular", "kind": "ntfy", "server": "https://ntfy.sh", "topic": "meu-topico-secreto", "is_default": true }`))
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 201
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "celular",
"kind": "ntfy",
"server": "https://ntfy.sh",
"topic": "meu-topico-secreto",
"is_default": true,
"enabled": true,
"created_at": "2026-10-06T12:00:00Z"
}
}Consultar canal
/v1/tools/notify/channels/{id}- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:notify:managetools:manage
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "celular",
"kind": "ntfy",
"server": "https://ntfy.sh",
"topic": "meu-topico-secreto",
"is_default": true,
"enabled": true,
"created_at": "2026-10-06T12:00:00Z"
}
}Alterar canal
/v1/tools/notify/channels/{id}- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:notify:managetools:manage
Envie só os campos que mudam. Um canal desativado responde notify.channel_disabled quando escolhido num envio.
curl -sS -X PATCH 'https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "enabled": false }'const response = await fetch('https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000', {
method: 'PATCH',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({ "enabled": false }),
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.patch(
"https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
json={ "enabled": False },
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{ "enabled": false }
JSON,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
req, err := http.NewRequest("PATCH", "https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000", strings.NewReader(`{ "enabled": false }`))
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "celular",
"kind": "ntfy",
"server": "https://ntfy.sh",
"topic": "meu-topico-secreto",
"is_default": true,
"enabled": true,
"created_at": "2026-10-06T12:00:00Z"
}
}Excluir canal
/v1/tools/notify/channels/{id}- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:notify:managetools:manage
curl -sS -X DELETE 'https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000', {
method: 'DELETE',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.delete(
"https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("DELETE", "https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"deleted": true
}
}Testar canal
/v1/tools/notify/channels/{id}/test- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:notify:managetools:manage
Envia uma notificação de teste pelo canal, para conferir a configuração antes de depender dele.
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000/test' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000/test', {
method: 'POST',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000/test",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000/test');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/notify/channels/550e8400-e29b-41d4-a716-446655440000/test", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"status": "delivered"
}
}Erros
| Código | HTTP | Quando |
|---|---|---|
notify.invalid_channel | 400 | Canal inválido: tipo desconhecido ou campos que não combinam com o tipo (URL do webhook, servidor e tópico do ntfy). |
notify.channel_not_found | 404 | Canal inexistente ou de outra conta. |
notify.channel_name_taken | 409 | Já existe um canal com esse nome na conta. |
notify.channel_disabled | 409 | O canal escolhido está desativado. |
notify.rate_limited | 429 | Limite de notificações por período excedido; tente de novo mais tarde. |
notify.delivery_failed | 502 | Não foi possível entregar a notificação no canal (nada é cobrado). |
notify.unavailable | 503 | O envio de notificações está indisponível no momento; tente de novo em alguns segundos. |
Atualizado em