Notideus
Tutorials

Sending emails with PHP

A complete PHP walkthrough with the official SDK: sending, error handling and retries.

Use the official notideus/notideus-php — PHP 8.2 and later:

composer require notideus/notideus-php

The send function

emails()->send() authenticates with your API key, throws a typed NotideusException on failure, and returns the stored email row:

<?php

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

$notideus = new Notideus\NotideusClient($_ENV['NT_KEY']); // "nt_live_…"

$email = $notideus->emails()->send([
    'from' => 'Notideus <noreply@demo.dev>',
    'to' => ['jane@example.com'],
    'subject' => 'Welcome to Notideus',
    'html' => '<p>Hi Jane,</p><p>Your account is ready.</p>',
    'idempotency_key' => 'docs-quickstart-1',
]);

echo $email['id'] . ' ' . $email['status'] . PHP_EOL;

Expected output

send returns the stored email row (201 Created). Response abbreviated to id, status, from, to and subject:

{
  "id": "01a0a11c-188e-7c9e-9b69-753fcb4c8d0d",
  "status": "queued",
  "from_address": "Notideus <noreply@demo.dev>",
  "to_emails": ["jane@example.com"],
  "subject": "Welcome to Notideus"
}

id uniquely identifies this email; status is queued — it is picked up for delivery from there.

Error handling

The SDK throws NotideusException, which carries the API error code (getErrorCode()), the HTTP status (getStatus()), and getRetryAfter() (seconds) on 429. Catch it and branch on $e->getErrorCode():

use Notideus\NotideusClient;
use Notideus\NotideusException;

$notideus = new NotideusClient($_ENV['NT_KEY']);

try {
    $notideus->emails()->send([
        'from' => 'Notideus <noreply@demo.dev>',
        'to' => ['jane@example.com'],
        'subject' => 'Welcome to Notideus',
        'html' => '<p>Hi Jane,</p><p>Your account is ready.</p>',
    ]);
} catch (NotideusException $e) {
    fprintf(STDERR, '%s %d %s', $e->getErrorCode(), $e->getStatus(), $e->getMessage());
}
StatusCodeWhat to do
401unauthorizedMissing, invalid or revoked key — check NT_KEY.
403insufficient_scopeThe key lacks emails:send — create a key with the right scope.
402quota_exceededMonthly allowance reached — back off and retry later. See Quotas and limits.
422from_domain_not_verifiedThe From domain matches no verified team domain — verify it in the dashboard first.
The SDK retries idempotent sends for you: it re-issues a request on network failure, 5xx or 429 (honoring Retry-After) only when the send carries an idempotency_key — so a retried send never double-sends. Choosing the key is still yours: derive it from your own data (for example order-12345-welcome). See Idempotency for key choice and scope rules.
Copyright © 2026