Why mail() fails you
mail() looks free. It hands your message to whatever the server's sendmail is, unauthenticated, and reports success the moment it leaves PHP, not when it reaches an inbox. No SPF alignment, no DKIM signature, no bounce handling. Mailbox providers treat that kind of mail accordingly.
The usual next step is PHPMailer over SMTP, which fixes authentication and adds a dependency, credentials in config, and a connection to manage. The step after that is the one worth taking.
Authentication is also no longer a human chore. My own agent writes the SPF, DKIM, and DMARC records on a subdomain and verifies the alignment itself. The part of email PHP developers dread most is now a prompt.
One POST, and the send is handled
$ch = curl_init("https://api.nitrosend.com/v1/my/messages"); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ["Authorization: Bearer $NITROSEND_API_KEY"], CURLOPT_POSTFIELDS => json_encode([ "from" => "[email protected]", "to" => "[email protected]", "subject" => "Welcome", "html" => "<p>You're in.</p>", ]), ]); curl_exec($ch);
cURL ships with PHP, the token lives in your environment, and delivery, authentication, and events are the platform's job. WordPress, Laravel, or plain PHP, the call is the same.
PHP developers are not a side audience for us. WooCommerce has more installs than any other ecommerce platform, and WooCommerce developers ask us more questions about the API than anyone else. This page exists because of them, and the platform slots into a PHP stack as the MAIL_DRIVER, so every transactional, marketing, and automated send lands in one place instead of scattered across plugins.
Full parameters, responses, and error codes live in the REST API docs and the API reference.
And the part no library gives you
The same account exposes an MCP server, so the agent writing your code can also run your email. Point Claude, Cursor, or Codex at api.nitrosend.com/mcp and it composes, previews, and stages sends, with a human approving every one. The API is for your code. The MCP is for your agent. One platform either way.
Every send comes back with a message ID, and delivery events follow on your webhook: delivered, opened, bounced. No dashboard required to know what happened.