Skip to content
Skip to content
PGB Learn

Send email from your app

Send transactional email such as receipts and notifications with one API call, and check delivery in the Console.

Updated Nov 12, 2026

Transactional mail is the email your app sends on its own: receipts, notifications, alerts, welcome messages. Each project can send it with one authenticated request. Sign-in emails such as verification codes and password resets are separate and are covered in Customize the emails your users receive.

Before you start

Sending needs your project's secret key (pgb_sec_...), so it must happen on your server, never in a browser or mobile app. See API keys. Your project also needs mail access: see Request approval to send email.

Open Transactional Mail

In the sidebar, under Core Services & Infrastructure, choose Transactional Mail. Once your project is approved you see:

  • Monthly Quota: emails sent this month against the free allowance.
  • Bounce Rate and Complaint Rate, with the quarantine thresholds beside them.
  • Active Mail Provider and the Sender address.
  • Email Event History & Delivery Logs: the latest 50 events, with recipient, subject, status and time.
  • Sending Key & How To Send, with a ready-made example.

Send a test from the Console

  1. Choose Send a Test Email.
  2. Fill in Recipient Email, Subject and Message Body.
  3. Choose Send Live Test Email.

The message appears in Email Event History & Delivery Logs within moments.

Send from your code

curl -X POST https://my-project.pgbhub.app/mail/send \
  -H "Authorization: Bearer pgb_sec_..." -H "Content-Type: application/json" \
  -d '{"to": "[email protected]", "subject": "Welcome!", "text": "Thanks for signing up."}'

The request accepts:

Field Meaning
to One recipient address
subject Required, cannot be empty
text Plain-text body. Required, cannot be empty
html Optional HTML version
from Optional sender. It must be on your verified domain or the default sender, otherwise the default sender is used
reply_to Optional single address for replies. Line breaks, commas and semicolons are refused

The response includes a message_id you can keep for your records.

With the TypeScript SDK:

const sent = await admin.mail.send({
  to: "[email protected]",
  subject: "Your receipt",
  text: "Thanks for your order.",
  html: "<p>Thanks for your order.</p>",
  replyTo: "[email protected]",
});
console.log(sent.message_id);

The Python, Go and Rust SDKs have the same call. See Use the Python SDK and Use the Go and Rust SDKs.

Handle errors

Response What it means
400 Something in the request is invalid, such as a bad address or an empty subject
401 You did not use the project's secret key
402 Your account is paused
403 Mail is not approved, the project is quarantined, a limit was reached, or sending is paused. The message says which
503 with MAIL_PROVIDER_UNAVAILABLE Sending is temporarily unavailable. Retry later

Sends are never retried for you, because a retry could send the email twice. Retry only when you know the first attempt did not go out.

Good to know

  • to takes one address per request. To email many people, send one request per person.
  • Messages go out from the shared sender until you verify your own domain. See Send from your own domain.
  • Keep subjects and content honest and expected by the recipient. High bounce or complaint rates lead to quarantine.

More guides in Console: sending email