Docs / Use cases / Password reset
Use case

Reset password email

Deliver secure, expiring password reset links on demand with one Mailbot API call.

Answer first: to send a reset email, POST https://api.mailbot.id/v1/send with your Bearer key and a JSON body whose html/text contains a single-use, expiring reset link pointing to your app. Your backend creates and stores the reset token; Mailbot delivers the message.

Use case

When a user can't sign in, they request a reset. Your backend generates a single-use, short-lived token, stores it, and emails a link like https://yourapp.com/reset?token=...; the user sets a new password, and the token is invalidated. Mailbot delivers the message.

Your backend owns the security logic: generate the token, store it with an expiry, validate it when the user opens the link, and invalidate it on use and on password change. Mailbot accepts the email payload and returns a message id for your reset log.

When to send

  • A user clicks "forgot password" and requests a reset.
  • An admin forces a reset on an account.
  • A security event requires re-credentialing.
Avoid account enumeration. For security, respond the same way in your UI whether or not the email matches an account, and keep reset links single-use and short-lived.

API call

cURL
curl https://api.mailbot.id/v1/send \
  -H "Authorization: Bearer $MAILBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "noreply@yourdomain.com",
    "to": "user@example.com",
    "subject": "Reset your password",
    "text": "Reset your password: https://yourapp.com/reset?token=abc123. This link expires in 60 minutes.",
    "idempotency_key": "pwreset-user-142-1718000000"
  }'
PHP / Laravel (HTTP client)
use Illuminate\Support\Facades\Http;

$token = createResetToken($user->id);       // single-use, short expiry
$link = "https://yourapp.com/reset?token={$token}";

$response = Http::withToken(env('MAILBOT_API_KEY'))
    ->acceptJson()
    ->post('https://api.mailbot.id/v1/send', [
        'from' => 'noreply@yourdomain.com',
        'to' => $user->email,
        'subject' => 'Reset your password',
        'text' => "Reset your password: {$link}. This link expires in 60 minutes.",
        'idempotency_key' => "pwreset-user-{$user->id}-{$requestId}",
    ]);

$response->throw();
$data = $response->json();
// $data['id'], $data['status']

Required fields

FieldRequiredNotes
toYesThe user's email address.
subjectYesState the purpose, for example "Reset your password".
text or htmlYesThe body must contain the reset link and its expiry.
fromNoVerified sender; defaults to the configured sender if omitted.
idempotency_keyRecommendedTie to the reset request so retries don't double-send.

Example payload

JSON request
{
  "from": "noreply@yourdomain.com",
  "to": "user@example.com",
  "subject": "Reset your password",
  "text": "Reset your password: https://yourapp.com/reset?token=abc123. This link expires in 60 minutes. If you didn't request this, ignore this email.",
  "html": "<p>Reset your password by clicking the link below.</p><p><a href=\"https://yourapp.com/reset?token=abc123\">Reset password</a></p><p>This link expires in 60 minutes.</p>",
  "idempotency_key": "pwreset-user-142-1718000000"
}

Example response

202 · queued
{
  "ok": true,
  "id": "msg_3f8c1a...",
  "status": "queued"
}

For delivered messages, the response can include status: "sent" and a delivery_id. See the API reference for every response shape.

Errors

StatusMeaningWhat to do
400Invalid payload (bad to, missing subject/body).Fix the request; read details.
401Bad or missing API key.Check the Bearer header.
429Send limit reached.Back off; surface a "try again later" message to the user.
502 / 503Mailbot is temporarily unable to accept the send.Retry with backoff using the same idempotency_key.

Full error handling guidance is in the integration guide.

Testing

For safe setup, use the standard test endpoint to confirm delivery reaches an address you control:

cURL · test email
curl https://api.mailbot.id/v1/test-email \
  -H "Authorization: Bearer $MAILBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "to": "safe@yourdomain.com", "label": "Password reset test" }'

Production checklist

  • Single-use reset tokens with a short expiry, invalidated on use and on password change.
  • Return a neutral response in your app whether or not the account exists (avoid account enumeration).
  • Verified sender domain; from set to a verified address.
  • API key kept server-side; never sent to the browser or mobile client.
  • 429/5xx handled with backoff and a clear user message.
  • idempotency_key tied to the reset request.