Saltar al contenido
Docs

Tutorial

Envía emails desde cualquier aplicación PHP con el SDK emailit/emailit-php, con cURL sin más o con PHPMailer por SMTP, y verifica las firmas de los webhooks de Emailit.

Actualizado el 1 oct 2026

En esta guía se explica cómo enviar emails desde una aplicación PHP sin framework: con el SDK oficial emailit/emailit-php, con cURL sin más o por SMTP con PHPMailer. También se incluye un endpoint de webhook que verifica las firmas. ¿Usas Laravel? Sigue en su lugar la guía de Laravel.

Requisitos previos

  • PHP 8.1 o posterior y Composer.
  • Un dominio de envío verificado, por ejemplo acme.com.
  • Una clave de API. Basta con una clave Sending Only limitada a tu dominio.
  • Hasta que tu espacio de trabajo tenga acceso de producción, solo puedes enviar a las direcciones de email de las cuentas de los miembros del espacio de trabajo.

Instalar el SDK

Terminal
composer require emailit/emailit-php

El SDK usa Guzzle para HTTP, que Composer instala por ti.

Configurar la clave de API

Define la clave como variable de entorno en tu servidor web, en el pool de PHP-FPM o en el panel de tu hosting, y léela en tiempo de ejecución:

Terminal
export EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••
PHP
$apiKey = getenv('EMAILIT_API_KEY');

Si cargas un archivo .env con un paquete como vlucas/phpdotenv, guarda ese archivo fuera de la raíz web y fuera del control de versiones.

Enviar un email

send.php
require __DIR__.'/vendor/autoload.php';

$emailit = Emailit::client(getenv('EMAILIT_API_KEY'));

$email = $emailit->emails()->send([
    'from'    => 'Acme <hello@acme.com>',
    'to'      => 'ada@example.com',
    'subject' => 'Your receipt from Acme',
    'html'    => '<p>Thanks for your order.</p>',
    'text'    => 'Thanks for your order.',
]);

echo $email->id; // em_…

La misma llamada acepta cc, bcc, reply_to, attachments, template con variables, scheduled_at y tracking. Para adjuntar un archivo, codifícalo en base64:

PHP
$email = $emailit->emails()->send([
    'from'        => 'Acme Billing <billing@acme.com>',
    'to'          => 'ada@example.com',
    'subject'     => 'Invoice INV-1042',
    'html'        => '<p>Your invoice is attached.</p>',
    'attachments' => [[
        'filename'     => 'INV-1042.pdf',
        'content'      => base64_encode(file_get_contents(__DIR__.'/INV-1042.pdf')),
        'content_type' => 'application/pdf',
    ]],
]);

Para ver todos los campos, consulta Enviar un email, y para los límites, Adjuntos.

Gestionar los errores

PHP
use Emailit\Exceptions\ApiErrorException;
use Emailit\Exceptions\AuthenticationException;
use Emailit\Exceptions\RateLimitException;
use Emailit\Exceptions\UnprocessableEntityException;

try {
    $emailit->emails()->send($message);
} catch (AuthenticationException $e) {
    // 401: the API key is missing or invalid
} catch (RateLimitException $e) {
    // 429: wait and retry
} catch (UnprocessableEntityException $e) {
    // 422: for example, the from domain isn't verified
} catch (ApiErrorException $e) {
    error_log('Emailit error '.$e->getHttpStatus().': '.$e->getMessage());
}

Enviar sin el SDK

Si no puedes usar Composer, llama a la API con cURL:

send-curl.php
$ch = curl_init('https://api.emailit.com/v2/emails');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer '.getenv('EMAILIT_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS     => json_encode([
        'from'    => 'Acme <hello@acme.com>',
        'to'      => 'ada@example.com',
        'subject' => 'Your receipt from Acme',
        'html'    => '<p>Thanks for your order.</p>',
    ]),
]);

$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

if ($status >= 400) {
    throw new RuntimeException("Emailit returned $status: $body");
}

$email = json_decode($body, true); // $email['id'] is the em_ ID

Enviar por SMTP

Funciona cualquier biblioteca de correo de PHP que admita SMTP. Con PHPMailer (composer require phpmailer/phpmailer):

send-smtp.php
use PHPMailer\PHPMailer\PHPMailer;

require __DIR__.'/vendor/autoload.php';

$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host       = 'smtp.emailit.com';
$mail->Port       = 587;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->SMTPAuth   = true;
$mail->Username   = 'emailit';
$mail->Password   = getenv('EMAILIT_API_KEY');

$mail->setFrom('hello@acme.com', 'Acme');
$mail->addAddress('ada@example.com');
$mail->Subject = 'Your receipt from Acme';
$mail->isHTML(true);
$mail->Body    = '<p>Thanks for your order.</p>';
$mail->AltBody = 'Thanks for your order.';

$mail->send();

Con Symfony Mailer, usa el DSN smtp://emailit:API_KEY@smtp.emailit.com:587. Para TLS implícito, usa el puerto 465 (PHPMailer::ENCRYPTION_SMTPS); si tu proveedor de hosting bloquea el 587, prueba con el 2525 o el 2587. Consulta Configuración SMTP.

Recibir webhooks

Crea un webhook que apunte a tu endpoint y guarda su secreto de firma en EMAILIT_WEBHOOK_SECRET. Lee el cuerpo en bruto de php://input y verifícalo antes de fiarte de él:

webhook.php
$payload   = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_EMAILIT_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_EMAILIT_TIMESTAMP'] ?? '';
$secret    = getenv('EMAILIT_WEBHOOK_SECRET');

$expected = hash_hmac('sha256', $timestamp.'.'.$payload, $secret);

if (abs(time() - (int) $timestamp) > 300 || ! hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Invalid signature');
}

// The body is a JSON array of up to 100 events.
foreach (json_decode($payload, true) as $event) {
    if ($event['type'] === 'email.bounced') {
        $address = $event['data']['object']['to'];
        // Stop emailing $address.
    }
}

http_response_code(200);

Responde en menos de 30 segundos con un 2xx; cualquier otra respuesta se reintenta. Consulta Firma de las peticiones.

Consejos para producción

  • Reutiliza un único cliente por petición o por worker en lugar de crear uno por email.
  • Envía en segundo plano. Para los envíos masivos, pon los mensajes en una cola y envíalos desde un worker, para que las páginas sigan siendo rápidas y no superes tus límites de envío (2 emails por segundo por defecto).
  • Haz que los reintentos sean seguros. Si reintentas después de que se agote el tiempo de espera, envía una cabecera Idempotency-Key con cURL para que el email no se envíe dos veces. Consulta Idempotencia.
  • Mantén las claves fuera de la raíz web. No subas nunca claves ni archivos .env al repositorio, y usa una clave distinta para cada aplicación.

Próximos pasos

Transporte de correo y facade para aplicaciones Laravel.
Envía el correo de WordPress a través del SMTP de Emailit.
Plantillas, programación y seguimiento.
Todos los eventos y su payload.

¿Te ha resultado útil esta página?

Gracias por tu opinión.

Gracias. Leemos todos los mensajes.