PHP
One POST with cURL or Guzzle, and where to keep the key.
There is no emails.sh PHP package to install: the API is a single JSON POST, and the ext-curl that ships with every PHP build covers it. If your project already has Guzzle, the second example is shorter.
With cURL
<?php
// src/Email.php
// The key comes from https://emails.sh/dashboard/api-keys and is read from the
// environment. Put it in .env and load it however your app already does.
function send_email(string $to, string $subject, string $html): string
{
$payload = json_encode([
'from' => 'Acme <hello@acme.com>',
'to' => [$to],
'subject' => $subject,
'html' => $html,
], JSON_THROW_ON_ERROR);
$ch = curl_init('https://emails.sh/v1/emails');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('EMAILSSH_API_KEY'),
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
if ($body === false) {
throw new RuntimeException('emails.sh unreachable: ' . curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
$result = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if ($status >= 400) {
$refusal = $result['error'];
throw new RuntimeException($refusal['code'] . ': ' . $refusal['message'] . ' ' . ($refusal['next'] ?? ''));
}
return $result['id'];
}<?php
require __DIR__ . '/src/Email.php';
$id = send_email('ada@example.com', 'Your receipt from Acme', '<p>Thanks for your order.</p>');
echo "queued {$id}\n";With Guzzle
composer require guzzlehttp/guzzle<?php
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
$client = new Client(['base_uri' => 'https://emails.sh', 'timeout' => 10]);
try {
$response = $client->post('/v1/emails', [
'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILSSH_API_KEY')],
'json' => [
'from' => 'Acme <hello@acme.com>',
'to' => ['ada@example.com'],
'subject' => 'Your receipt from Acme',
'html' => '<p>Thanks for your order.</p>',
],
]);
$result = json_decode((string) $response->getBody(), true);
echo "queued {$result['id']}\n";
} catch (ClientException $e) {
$refusal = json_decode((string) $e->getResponse()->getBody(), true)['error'];
// next says what to do about it, so log it rather than the class name.
fwrite(STDERR, $refusal['code'] . ': ' . $refusal['message'] . ' ' . ($refusal['next'] ?? '') . "\n");
}