Guide
How to send email with PHP
Send email from plain PHP with cURL and the REST API.
In short
Create a Sendpository account, verify your domain, put your API key inSENDPOSITORY_API_KEY, and send with the code below - one HTTPS request per email, from server-side code only.1. Verify your sending domain
Add your domain in the dashboard and publish the three DNS records it shows - SPF and a bounce record on an sp. subdomain, and a DKIM key on your apex. Your existing records are never edited. Verification usually lands in a few minutes, and you can set up the code below while you wait.
2. Create a key
Create an API key with the sending permission. It is shown once, so put it straight into your secrets. Set SENDPOSITORY_API_KEY in your server environment and read it with getenv().
3. Send an email
<?php
$ch = curl_init("https://api.sendpository.com/v1/emails");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("SENDPOSITORY_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"from" => "Your App <hello@mail.yourdomain.com>",
"to" => ["customer@example.com"],
"subject" => "Your receipt",
"html" => "<p>Thanks for your order.</p>",
]),
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 300) {
throw new RuntimeException($body["error"]["message"]);
}
echo $body["id"];A success returns { "id": "..." } - the message’s id for looking it up later. A failure returns { "error": { "type", "message" } } with a 4xx or 5xx status.
Where the send belongs
In the request, usually - PHP's process model means there is no long-lived worker to block - but return the response first with `fastcgi_finish_request()` if your server supports it, so the user is not waiting on an upstream call.
Set `CURLOPT_TIMEOUT`. Without it a stalled connection holds a PHP-FPM worker until the pool runs out.
Testing it
- Check `curl_errno()` as well as the HTTP status. A DNS failure or timeout returns no status at all, and code that only reads the status treats it as success.
- Keep the key in the environment, not in a config file inside the web root.
Things to know
- Replaces mail() - which sends unauthenticated mail that most inboxes now reject.
- Using WordPress or Laravel? See the Laravel guide for the framework HTTP client.
Questions
How do I stop a slow send blocking the page?
Call `fastcgi_finish_request()` after you have written the response, then send. The user gets the page immediately and PHP-FPM finishes the work afterwards. Set `CURLOPT_TIMEOUT` as well, or a stalled connection holds the worker.
How do I send email with PHP?
Verify your sending domain, create an API key, put it in an environment variable, and POST the message as JSON to https://api.sendpository.com/v1/emails from server-side PHP code. The example on this page runs as written once the domain is verified.
Can I send email with PHP without SMTP?
Yes. This is plain HTTPS, so PHP needs no mail library and no SMTP port - which matters on hosts that block outbound 25 and 587. Failures come back as a status code on the call instead of as a bounce message hours later.
More guides
Send your first email in minutes
6,000 emails a month (up to 200 a day), free forever. No card needed.