Pular para o conteúdo
couryo

Guia do desenvolvedorIntegrações

SDKs oficiais

SDKs oficiais do Couryo para Node.js, PHP (com Laravel) e Python (com Django), com Idempotency-Key automático, novas tentativas, erros tipados e verificação de webhook.

Ver em Markdown

Os três SDKs oficiais fazem a mesma coisa do mesmo jeito. Qualquer um deles poupa o trabalho repetitivo de falar com a API REST:

  • Idempotency-Key automático em todo POST, repetido nas novas tentativas: um envio que deu tempo esgotado mas passou nunca sai duplicado.
  • Novas tentativas com espera crescente para erro de rede, 5xx e rate_limited, respeitando o Retry-After. Erros que falhariam de novo (domain_not_verified, daily_limit_reached...) voltam na hora.
  • Erros tipados com o code estável da API, a message no idioma escolhido (pt-BR por padrão) e o request_id para o suporte.
  • Verificação de webhook (Standard Webhooks, segredo whsec_) numa chamada.
  • E-mails, lote, templates, domínios, contatos, eventos, campanhas, supressões e webhooks.
Linguagem Pacote Instalar Integração pronta
Node.js 20.3+ @couryo/node npm install @couryo/node Next.js e Express (guia)
PHP 8.1+ couryo/couryo-php composer require couryo/couryo-php transporte de e-mail do Laravel (guia)
Python 3.9+ couryo pip install couryo backend de e-mail do Django (guia)

Não usa nenhuma dessas linguagens? A API é REST com JSON: qualquer cliente HTTP funciona, e o SMTP serve para qualquer ferramenta que já envia e-mail.

Enviar um e-mail#

Todos leem a chave da variável COURYO_API_KEY quando você não passa nenhuma. Use uma chave ck_test_ enquanto testa: nada é entregue e o e-mail aparece no painel (modo de teste).

Node.js
import { Couryo } from "@couryo/node";

const couryo = new Couryo(); // lê COURYO_API_KEY

const { id } = await couryo.emails.send({
  from: "Loja Exemplo <pedidos@exemplo.com.br>",
  to: "ana@exemplo.com.br",
  subject: "Pedido 1042 confirmado",
  html: "<p>Obrigado pela compra!</p>",
  text: "Obrigado pela compra!",
});
PHP
<?php
require 'vendor/autoload.php';

$couryo = new Couryo\Couryo(getenv('COURYO_API_KEY'));

$email = $couryo->emails->send([
    'from' => 'Loja Exemplo <pedidos@exemplo.com.br>',
    'to' => 'ana@exemplo.com.br',
    'subject' => 'Pedido 1042 confirmado',
    'html' => '<p>Obrigado pela compra!</p>',
    'text' => 'Obrigado pela compra!',
]);
echo $email['id']; // msg_...
Python
from couryo import Couryo

couryo = Couryo()  # lê COURYO_API_KEY

email = couryo.emails.send({
    "from": "Loja Exemplo <pedidos@exemplo.com.br>",
    "to": "ana@exemplo.com.br",
    "subject": "Pedido 1042 confirmado",
    "html": "<p>Obrigado pela compra!</p>",
    "text": "Obrigado pela compra!",
})
print(email["id"])  # msg_...

Sua própria chave de idempotência#

Quando o mesmo evento do seu sistema pode disparar duas vezes (um webhook de pagamento repetido, um job que roda de novo), passe uma chave que identifica o evento. A segunda chamada recebe a mesma resposta, sem enviar de novo.

Node.js
await couryo.emails.send(corpo, { idempotencyKey: "pedido-1042-confirmacao" });
PHP
$couryo->emails->send($corpo, ['idempotency_key' => 'pedido-1042-confirmacao']);
Python
couryo.emails.send(corpo, idempotency_key="pedido-1042-confirmacao")

Tratar erros#

Node.js
import { CouryoError } from "@couryo/node";

try {
  await couryo.emails.send(corpo);
} catch (e) {
  if (e instanceof CouryoError && e.code === "domain_not_verified") {
    // e.status, e.message (em português), e.param, e.requestId
  }
}
PHP
use Couryo\Exception\CouryoException;

try {
    $couryo->emails->send($corpo);
} catch (CouryoException $e) {
    if ($e->getErrorCode() === 'domain_not_verified') {
        // $e->getStatus(), $e->getMessage(), $e->getParam(), $e->getRequestId()
    }
}
Python
from couryo import CouryoError

try:
    couryo.emails.send(corpo)
except CouryoError as e:
    if e.code == "domain_not_verified":
        ...  # e.status, e.message, e.param, e.request_id

A lista de códigos, com causa e correção, está em Erros.

Verificar um webhook#

Passe o corpo cru, exatamente como chegou. O SDK confere a assinatura e o horário (até 5 minutos) e devolve o evento.

Node.js
import { verifyWebhook } from "@couryo/node";

const evento = verifyWebhook({ secret: process.env.COURYO_WEBHOOK_SECRET!, headers: req.headers, body: corpoCru });
PHP
$evento = Couryo\Webhook::verify(getenv('COURYO_WEBHOOK_SECRET'), getallheaders(), file_get_contents('php://input'));
Python
from couryo import verify_webhook

evento = verify_webhook(os.environ["COURYO_WEBHOOK_SECRET"], request.headers, corpo_cru)

Detalhes do formato em Webhooks.

Contatos, eventos e campanhas#

Node.js
await couryo.contacts.create({ email: "ana@exemplo.com.br", attributes: { nome: "Ana", plano: "pro" }, tags: ["cliente"] });
await couryo.events.track({ contact: { email: "ana@exemplo.com.br" }, name: "user.signed_up" });

const campanha = await couryo.campaigns.create({ name: "Novidades de outubro", audience: { type: "all" }, template_id: "novidades" });
await couryo.campaigns.preflight(campanha.id); // contagem real e revisão antes de disparar

Os eventos iniciam as sequências com esse gatilho; as campanhas passam por uma checagem antes do disparo. Os mesmos métodos existem no PHP e no Python, com os nomes no estilo de cada linguagem.

Código aberto#

Os SDKs têm licença MIT. Os modelos de e-mail brasileiros (Pix, boleto, recuperação de senha e outros) também saem como um pacote React Email independente, que funciona com qualquer provedor.