Skip to main content
Documentation

PHP SDK

Packagist: coffeemail/coffeemail-php v0.1.0

Full reference for the official coffeemail/coffeemail-php package for modern PHP (8.2+). Strict typing, safe data, error returns, tuple destructuring and cryptographic webhook validation.

Looking for Node.js or TypeScript docs? Check the official reference for the @coffeemail/node package.

Node.js SDK
terminal
composer require coffeemail/coffeemail-php

Client Initialization

Laravel • Symfony • WordPress • Vanilla PHP

The API key is automatically resolved from the COFFEEMAIL_API_KEY environment variable if omitted from the constructor.

$client = new CoffeeMail(?string $apiKey = null, string $locale = 'pt-BR', int $timeoutSeconds = 10);
send_email.php
use CoffeeMail\CoffeeMail; // Carrega automaticamente COFFEEMAIL_API_KEY do ambiente ou do construtor:$client = new CoffeeMail(); [$data, $error] = $client->emails->send([    'from' => 'contato@seudominio.com.br',    'to' => 'cliente@gmail.com',    'subject' => 'Bem-vindo ao CoffeeMail!',    'html' => '<h1>Olá!</h1><p>Sua conta está ativa.</p>',]); if ($error !== null) {    echo "Erro ao enviar [{$error->code}]: {$error->message}\n";    exit(1);} echo "E-mail enfileirado com sucesso: {$data['id']}\n";

Tuple Destructuring and Safe Returns

Safe Pattern { data, error }

Operations return a CoffeeMailResponse instance allowing direct [$data, $error] destructuring or calling ->unwrap() to throw typed exceptions.

error_handling.php
use CoffeeMail\CoffeeMail;use CoffeeMail\Exceptions\RateLimitError; $client = new CoffeeMail(); [$data, $error] = $client->emails->send([    'from' => 'contato@seudominio.com.br',    'to' => 'cliente@gmail.com',    'subject' => 'Aviso',    'html' => '<p>Mensagem</p>',]); if ($error instanceof RateLimitError) {    echo "Aguarde {$error->retryAfterSeconds} segundos antes de tentar novamente.\n";    exit(1);} if ($error !== null) {    echo "Falha de envio: {$error->message}\n";    exit(1);} echo "ID: {$data['id']}\n";

Cryptographic Webhook Verification

HMAC SHA-256 (hash_equals)

The Webhooks::verifySignature method validates the HMAC SHA-256 signature in the x-coffeemail-signature header using constant-time comparison against timing attacks.

webhook_controller.php
use CoffeeMail\Resources\Webhooks; // No endpoint de webhook do seu app PHP:$payload = file_get_contents('php://input');$signature = $_SERVER['HTTP_X_COFFEEMAIL_SIGNATURE'] ?? '';$secret = getenv('COFFEEMAIL_WEBHOOK_SECRET'); if (! Webhooks::verifySignature($payload, $signature, $secret)) {    http_response_code(401);    echo "Assinatura inválida";    exit;} $event = json_decode($payload, true);echo "Evento processado com segurança: " . $event['event'];

Methods Catalog

Reference of operations available in the official PHP client.

Emails

.send()— Send transactional email
$client->emails->send(array $payload): CoffeeMailResponse
send.php
use CoffeeMail\CoffeeMail; $client = new CoffeeMail(); [$data, $error] = $client->emails->send([    'from' => 'noreply@seudominio.com.br',    'to' => 'cliente@example.com',    'subject' => 'Confirmação do pedido #123',    'html' => '<h1>Obrigado!</h1><p>Seu pedido está em processamento.</p>',]); if ($error !== null) {    echo "Erro ao enviar [{$error->code}]: {$error->message}\n";    exit(1);} echo "E-mail enfileirado com sucesso: {$data['id']}\n";
.sendBatch()— Send batch emails
$client->emails->sendBatch(array $items): CoffeeMailResponse
sendBatch.php
use CoffeeMail\CoffeeMail; $client = new CoffeeMail(); [$data, $error] = $client->emails->sendBatch([    [        'from' => 'noreply@seudominio.com.br',        'to' => 'cliente1@example.com',        'subject' => 'Notificação 1',        'html' => '<p>Mensagem 1</p>',    ],    [        'from' => 'noreply@seudominio.com.br',        'to' => 'cliente2@example.com',        'subject' => 'Notificação 2',        'html' => '<p>Mensagem 2</p>',    ],]); if ($error !== null) {    throw $error;}
.get()— Retrieve email delivery status
$client->emails->get(string $id): CoffeeMailResponse
get.php
use CoffeeMail\CoffeeMail; $client = new CoffeeMail(); [$data, $error] = $client->emails->get('eml_8f92b7c4'); if ($data !== null) {    echo "Status: {$data['status']}\n";}
.list()— List send history with filters
$client->emails->list(array $query = []): CoffeeMailResponse
list.php
use CoffeeMail\CoffeeMail; $client = new CoffeeMail(); [$data, $error] = $client->emails->list([    'limit' => 20,    'status' => 'delivered',]);

Domains

.create()— Register sender domain
$client->domains->create(array $payload): CoffeeMailResponse
create.php
use CoffeeMail\CoffeeMail; $client = new CoffeeMail(); [$data, $error] = $client->domains->create([    'name' => 'meudominio.com.br',]);
.verify()— Verify domain DNS records
$client->domains->verify(string $id): CoffeeMailResponse
verify.php
use CoffeeMail\CoffeeMail; $client = new CoffeeMail(); [$data, $error] = $client->domains->verify('dom_123');

Templates

.preview()— Preview template with variables
$client->templates->preview(string $id, array $variables = []): CoffeeMailResponse
preview.php
use CoffeeMail\CoffeeMail; $client = new CoffeeMail(); [$data, $error] = $client->templates->preview('tpl_123', [    'nome' => 'João',    'codigo' => '9842',]);

Webhooks

.verifySignature()— Verify webhook HMAC signature
Webhooks::verifySignature(string $payload, string $signature, string $secret): bool
verifySignature.php
use CoffeeMail\Resources\Webhooks; // No controller do seu framework (Laravel, Symfony, etc.):$payload = file_get_contents('php://input');$signature = $_SERVER['HTTP_X_COFFEEMAIL_SIGNATURE'] ?? '';$secret = getenv('COFFEEMAIL_WEBHOOK_SECRET'); $isValid = Webhooks::verifySignature($payload, $signature, $secret); if (! $isValid) {    http_response_code(401);    echo "Assinatura inválida";    exit;}

Metrics

.get()— Query deliverability metrics
$client->stats->get(array $query = []): CoffeeMailResponse
get.php
use CoffeeMail\CoffeeMail; $client = new CoffeeMail(); [$data, $error] = $client->stats->get([    'from' => '2026-01-01',    'to' => '2026-01-31',]);