PHP code example of postilio / postilio-php

1. Go to this page and download the library: Download postilio/postilio-php library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

postilio / postilio-php example snippets


use Postilio\Enum\EmailStatus;
use Postilio\Model\SendEmailRequest;
use Postilio\PostilioClient;

$postilio = new PostilioClient(getenv('POSTILIO_API_KEY') ?: throw new RuntimeException('Set POSTILIO_API_KEY.'));

$sent = $postilio->sendEmail(new SendEmailRequest(
    from: 'Acme <[email protected]>',
    to: ['[email protected]'],
    subject: 'Welcome to Acme',
    text: 'Hi Ada, your account is ready.',
    html: '<p>Hi Ada, your account is ready.</p>',
    tag: 'welcome',
));

$email = $postilio->getEmail($sent->ids[0]);
var_dump($email->status === EmailStatus::Delivered); // true: a test key simulates it at once

$postilio = new PostilioClient($key, timeout: 15.0, connectTimeout: 5.0);

$factory = new Nyholm\Psr7\Factory\Psr17Factory();
$postilio = new PostilioClient($key, $psr18Client, $factory, $factory);

new SendEmailRequest(
    from: 'Acme Support <[email protected]>',
    to: ['[email protected]'],          // each recipient gets a message of its own
    subject: 'Your ticket 4711',
    text: 'Solved: the export works again.',
    html: null,
    tag: 'support',
    replyTo: '[email protected]',
    attachments: [new EmailAttachment('report.pdf', 'application/pdf', file_get_contents('report.pdf'))],
    cc: ['[email protected]'],       // cc and bcc only with exactly one `to`
    bcc: ['[email protected]'],
    headers: [
        'List-Unsubscribe' => '<https://example.com/unsubscribe/3f9a1c7e>',
        'List-Unsubscribe-Post' => 'List-Unsubscribe=One-Click',
    ],
    sendAt: new DateTimeImmutable('+1 hour'),  // scheduled; cancel it with cancelEmail()
);

$postilio->sendEmail($receipt, "order-{$order->id}-receipt");

use Postilio\Enum\ErrorCode;
use Postilio\Exception\RateLimitException;
use Postilio\Exception\UnprocessableException;

try {
    $postilio->sendEmail($message);
} catch (UnprocessableException $e) {
    if ($e->error() === ErrorCode::UnverifiedSenderDomain) {
        // the sender's domain is not verified (yet)
    }
} catch (RateLimitException $e) {
    // e.g. the sandbox's daily limit: try again after $e->retryAfter seconds
}

$postilio = new PostilioClient($key, maxRetries: 2, maxRetryDelay: 30.0);

if ($email->status === EmailStatus::Bounced) { /* … */ }

$domain = $postilio->createDomain(new CreateDomainRequest('mail.example.com'));
foreach ($domain->records as $record) {
    echo "{$record->type} {$record->name} → {$record->value}\n";
}
$domain = $postilio->checkDomain($domain->id); // once DNS is in place; $domain->dmarc holds the DMARC check
// Postilio publishes the record your DKIM CNAME points to itself; a pending domain whose own records are found waits for it
if ($domain->platformKey?->status === PlatformKeyStatus::Failed) { /* Postilio's team is on it; nothing to do on your side */ }

$page = $postilio->listSuppressions(reason: SuppressionReason::HardBounce, limit: 100);
while ($page->next !== null) {
    $page = $postilio->listSuppressions(reason: SuppressionReason::HardBounce, before: $page->next, limit: 100);
}

$created = $postilio->createWebhookEndpoint(new CreateWebhookEndpointRequest(
    'https://api.example.com/hooks/postilio',
    [WebhookEventType::Delivered, WebhookEventType::Bounced, WebhookEventType::Complained],
));
// $created->secret (whsec_…) is shown this once: store it in your secret store now.

$usage = $postilio->getUsage('2026-10');
echo "{$usage->project->billable} billable\n";

use Postilio\Webhook\WebhookEvent;
use Postilio\Webhook\WebhookVerifier;

$verifier = new WebhookVerifier(getenv('POSTILIO_WEBHOOK_SECRET') ?: throw new RuntimeException('Set POSTILIO_WEBHOOK_SECRET.'));

$body = file_get_contents('php://input');
if (!$verifier->verify($_SERVER['HTTP_WEBHOOK_ID'] ?? null, $_SERVER['HTTP_WEBHOOK_TIMESTAMP'] ?? null,
    $_SERVER['HTTP_WEBHOOK_SIGNATURE'] ?? null, $body)) {
    http_response_code(401);
    exit;
}
$event = WebhookEvent::parse($body);
// Deliveries are at least once and in no particular order: drop a webhook-id you handled before,
// order by $event->data->occurredAt, and queue the work so you answer within 10 seconds.
http_response_code(204);