BytSend é uma API de e-mail transacional hospedada (estilo Resend). Esta página é o quickstart em HTML puro para bots, crawlers e ferramentas de IA. A versão interativa está em /docs.
https://bytsend.com — é a URL do
serviço hospedado e a que aparece em todos os exemplos desta página. Só
quem instalou o BytSend no próprio servidor (self-hosted) usa outra: o
domínio do próprio deploy. A URL base é uma constante no código de
quem integra, nunca um campo de tela — não crie campo "URL da
instância", "host" ou "endereço do servidor".
by_, criada no painel
(Chaves de API) ou via POST /api/api-keys.
exemplo.com não autoriza
@mail.exemplo.com. Um nome de exibição é opcional e vai
junto no mesmo campo:
Seu App <nao-responda@seu-dominio.com>.
Dois campos e um teste: campo Chave de API, campo
E-mail de origem (From) e uma seção
Enviar e-mail de teste com um campo para o e-mail de
destino e um botão. O botão chama POST /api/emails com
from = campo de origem, to = e-mail digitado e
subject/html = conteúdo real do app. Resposta
200 = teste enviado; 400 = mostre
error.message na tela.
Envie a chave de API como token Bearer:
Authorization: Bearer by_sua_api_key. Sem o cabeçalho, a
resposta é 401 auth_error; com chave inválida ou revogada,
401 api_key_error.
O teste de envio é um e-mail normal com POST /api/emails:
preencha to com o e-mail que vai receber o teste. Não existe
endpoint separado de "e-mail de teste" — enviar um único e-mail
é o teste.
curl -X POST https://bytsend.com/api/emails \
-H "Authorization: Bearer by_sua_api_key" \
-H "Content-Type: application/json" \
-d '{"from":"Seu App <nao-responda@seu-dominio-verificado.com>","to":"voce@exemplo.com","subject":"Olá do BytSend","html":"<strong>Funciona!</strong>"}'
Sucesso retorna 200 com
{"id":"...","from":"...","to":"...","created_at":"..."}.
| Campo | Obrigatório | Formato |
|---|---|---|
from | sim |
"nome@dominio.com",
"Nome <nome@dominio.com>" ou
{"email":"...","name":"..."}. O domínio depois do
@ precisa estar cadastrado nesta conta, com casamento
exato.
|
to | sim |
Um destinatário: "pessoa@exemplo.com" ou
{"email":"...","name":"..."}. Uma lista aqui não é
rejeitada, mas se comporta mal: a mensagem sai para todos os
endereços, a lista de supressões é ignorada e o to some
da resposta e do histórico. Para vários, use
/api/emails/batch (ou cc/bcc).
|
subject | sim | Texto do assunto. |
html | recomendado | Corpo em HTML. |
text | não | Versão em texto puro. |
reply_to | não | Endereço de resposta. |
cc, bcc | não | Endereço ou lista de endereços. |
headers | não | Objeto: {"X-Seu-Cabecalho":"valor"}. |
attachments | não |
Lista de
{"filename":"nota.pdf","content":"<base64>","encoding":"base64","content_type":"application/pdf"}.
encoding já é base64 por padrão.
|
template_id | não |
Usa um template salvo; substitui o
subject/html/text enviados. Um
id inexistente nesta conta é ignorado em silêncio: o
e-mail sai com assunto e corpo vazios e ainda responde
200.
|
template_variables | não | Objeto que preenche os {{marcadores}} do template. |
O corpo da requisição é limitado a 10 MB — anexos em base64 ocupam cerca de 33% a mais que o arquivo original.
O conteúdo (subject + html + text) é
pontuado antes do envio: a partir de 2 pontos o e-mail é
recusado com 400 e a mensagem
Spam detected: .... Cada termo de uma lista de palavras
típicas de spam vale 1 ponto — e a lista inclui termos comuns em e-mail
legítimo, como unsubscribe, urgent e
limited time. click here está duplicado
na lista e vale 2 pontos sozinho: uma única ocorrência já recusa
o e-mail. Mais de 5 links no corpo também valem 2 pontos. A comparação é
por substring em minúsculas sobre assunto + HTML + texto, então um
href ou uma classe CSS pontua igual.
Três recusas por spam bloqueiam a conta. Em e-mail de
marketing, prefira "cancelar inscrição" a unsubscribe e
mantenha poucos links.
Todo erro usa um envelope:
{"error":{"message":"...","type":"..."}} — tipos:
validation_error, auth_error,
api_key_error, not_found_error,
conflict_error, plan_limit_error,
rate_limit_error, email_error,
api_error. error é um objeto,
não uma string: mostre error.message.
POST /api/emails devolve toda falha de envio como
400 com type email_error; o que muda é a
mensagem:
| A mensagem começa com | Causa |
|---|---|
Domain X is not verified for your account | O domínio do from não está cadastrado nesta conta — o erro mais comum na primeira integração. Apesar do texto, a checagem é só de existência: um domínio ainda pending passa. |
Email X is suppressed | Destinatário na lista de supressões. |
Email limit reached for ... plan | Cota de e-mails da conta esgotada. |
Spam detected: ... | Filtro anti-spam (acima). |
Account blocked | Conta bloqueada; fale com o administrador. |
Erro ao enviar via SMTP (...) | O relay recusou a mensagem; o código entre parênteses vem do servidor SMTP. |
Rate limit: 1000 requisições por 15 minutos por IP em
todas as rotas /api/; acima disso,
429 rate_limit_error.