Sign in to fill these examples with your own keys. Sign in Start free trial

Send emails with WordPress

Install the PostShiba plugin and call wp_mail.

What you'll build

A WordPress site where every wp_mail call goes through the PostShiba API. That includes WooCommerce and any other plugin that sends with wp_mail.

Before you start

  • An API key with Send only access. Full access also works. See Create an API key. Support keys cannot send.
  • A verified sending domain. See Add and verify a domain. The from address must be on it.
  • A cluster that is ready to send (sending_ready is true). See Clusters.
  • WordPress 6.0 or later on PHP 8.1 or later.

Install

The plugin is on GitHub, not WordPress.org. Clone it into your plugins folder, then activate PostShiba under Plugins.

install.sh
1git clone https://github.com/postshiba/postshiba-wordpress wp-content/plugins/postshiba

Send your first email

  1. Open Settings → PostShiba. Save your API key and a from address on your verified domain. Or define them in wp-config.php, where constants override the saved settings.
wp-config.php
1define('POSTSHIBA_API_KEY', 'YOUR_API_KEY'); 2define('POSTSHIBA_FROM_EMAIL', 'hello@mail.example.com');
  1. Choose Send test email on the settings page, or call wp_mail from your own code.
send.php
1wp_mail( 2 'you@example.com', 3 'Your receipt', 4 'Thanks for your order.', 5 [ 6 'From: hello@mail.example.com', 7 'Reply-To: support@example.com', 8 'X-Capsule-Unique-Args: {"order_id":"ord_123"}', 9 ] 10);

wp_mail returns true once the message is queued. The message then shows under Events in the dashboard. The plugin hooks pre_wp_mail and posts to POST /api/v1/emails. It sends X-Capsule-Unique-Args as unique_args.

The settings page also takes a from name, a base URL, and a cluster id. The matching constants are POSTSHIBA_FROM_NAME, POSTSHIBA_BASE_URL, and POSTSHIBA_CLUSTER_ID. Without a cluster id, PostShiba uses your first cluster that is ready to send. POSTSHIBA_ENABLED set to false turns the plugin off without removing it.

Attachments and templates

Attach a file

Pass file paths as the fifth wp_mail argument. The plugin base64-encodes each file for the API. Up to 10 files, 18 MB in total. See Attachments for allowed types.

attachment.php
1wp_mail( 2 'you@example.com', 3 'Your invoice', 4 'Your invoice is attached.', 5 [], 6 [WP_CONTENT_DIR . '/uploads/invoice.pdf'] 7);

Hosted PostShiba templates are not available through wp_mail.

Keep the key safe

Use a Send only key on your site. It can send email and call GET /api/v1/users/me. Every other request returns 403 forbidden.

If this key leaks Send only Full access
Send mail from your verified domains Yes Yes
Read events, recipients, templates, and sent messages No Yes
See SMTP passwords and webhook secrets No Yes
Change clusters, domains, credentials, webhooks, and suppressions No Yes
  • Keep Full access keys for setup scripts, the CLI, and MCP. Don't paste one into WordPress.
  • The settings page stores the key in your WordPress database, where any administrator, database backup, or plugin with database access can read it. Prefer the POSTSHIBA_API_KEY constant in wp-config.php, or read it from an environment variable there. Don't commit wp-config.php, and limit who has administrator, file, and database access.
  • The plugin sends from your server. Never put a key, even a Send only key, in theme JavaScript or page content.
  • Create one key per site and environment, such as production and staging. If a key leaks, delete it on API keys and create a new one. Deleting stops it straight away.

Troubleshooting

A failed send makes wp_mail return false, and Send test email shows "Test email failed." The plugin does not surface the API error. Send the same message with curl to see the error string.

Status error What to do
401 Invalid token or no user signed in The API key is missing, mistyped, or deleted. Save it again in Settings → PostShiba.
403 forbidden Support keys cannot send. Use a Send only or Full access key. A Send only key gets this on any call other than sending.
403 domain_unverified The from address is not on a verified domain.
403 kyc_required Your team is pending production approval. Until then, send only to team members, live inbox addresses, and inbox forward-to addresses.
422 invalid A required field is missing or an attachment was rejected.
429 throttled The cluster hit its hourly throttle or 24-hour cap. Retrying right away hits the same cap. See What happens at your cap.
429 rate_limited More than 300 send requests in one minute on one API key.

Every other status is on Errors.

Next steps