Access is invite-only during beta. Once invited, create a key to personalize these examples. Production sending requires a separate review.

Switching from Mailchimp Transactional

Keep your transactional application flow while you replace Mandrill auth, templates, webhooks, and inbound routes with PostShiba.

Mandrill is now Mailchimp Transactional. This guide covers its API and SMTP service, not Mailchimp Marketing audiences or campaigns.

Run both providers during the migration

Keep Mandrill credentials, webhooks, and DNS through rollback. Both providers can authenticate the same domain when DKIM selectors and return-path hostnames differ. Otherwise, use a separate PostShiba sending subdomain.

Adjust this 30-day example to your volume and risk limits:

  1. Days 1–3. Run controlled tests with team members and hosted inboxes.
  2. Days 4–10. Route about 10% of new traffic to PostShiba.
  3. Days 11–17. Increase to about 25% if checks remain healthy.
  4. Days 18–24. Increase to about 50% if checks remain healthy.
  5. Days 25–30. Route 100% of new traffic to PostShiba if checks remain healthy.

Route a stable recipient cohort or feature-flagged message class. Use exactly one provider per production message. Never dual-send a real message.

PostShiba uses shared IPs. The ramp validates your integration and reputation under steady traffic. It is not dedicated-IP warming.

Inbound mail moves separately because MX records cannot percentage-split traffic. Test with a hosted inbox or new subdomain, then switch MX in a separate change.

Inventory the Mandrill setup

Before changing traffic, record:

  • Every /messages/send, /messages/send-template, and SMTP caller, including secret locations, rotation owners, and X-MC-* headers
  • Subaccounts and their domains, credentials, and traffic
  • Stored templates, merge languages, and merge vars
  • Global metadata, recipient_metadata, tags, and the code that reads them later
  • Outbound webhook URLs, events, authentication keys, and mandrill_events parsers
  • Inbound domains, MX records, TTLs, routes, and webhooks

Keep a recent message and event history as a baseline. You need a PostShiba account, DNS control, and secret storage.

Map the concepts

Mailchimp Transactional PostShiba
Transactional account and API key Team-locked API key
POST /messages/send with JSON key POST /api/v1/emails with a Bearer token
Subaccount or X-MC-Subaccount Tenant with a tenant credential
Metadata, recipient_metadata, tags, X-MC-Metadata, and X-MC-Tags unique_args on each message
Stored template and merge vars Hosted Liquid templates, or text and html rendered by your application
smtp.mandrillapp.com with an API key password smtp.postshiba.com:587 with an issued smtp_… credential
mandrill_events and X-Mandrill-Signature JSON event array with X-Capsule-Timestamp and X-Capsule-Signature
Inbound domain and mailbox route Domain-bound inbox and receiving webhook

Build the PostShiba side

1. Clear the production gate and start a cluster

Create a shared cluster, request production approval, and wait for sending_ready: true. Pending teams may create one cluster and inboxes, but may send only to team members and live inboxes. Wait for KYC approval before production.

2. Issue the token and recreate tenancy

Under API keys, create an API key and confirm it with Create an API key.

Map each Mandrill subaccount to a tenant before creating its domain and credentials. Tenants scope domains, credentials, inboxes, and suppressions. They do not reproduce Mandrill reputation, quotas, reports, or pause behavior. Otherwise, use the default tenant.

3. Verify domains and issue credentials

Add each sending domain to its tenant. Publish the returned DKIM and return-path CNAMEs, then wait until both are verified.

Create a cluster SMTP credential per tenant. REST sends need it but authenticate with the platform token.

4. Bring your suppressions

Import Mandrill rejects and unsubscribes before you send. A missed row is a complaint on the new cluster.

Export /rejects/list and any unsubscribe list you keep in your application. Map subaccount lists to the matching tenant.

Upload the CSV on Suppressions, or post the addresses:

import-suppressions.sh
1 curl -sS -X POST \
2 -H "Authorization: Bearer $POSTSHIBA_API_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "emails": ["unsubscribed@example.net", "bounced@example.net"],
6 "tenant_id": "WbLcFd"
7 }' \
8 https://app.postshiba.com/api/v1/teams/KjkAJW/suppressions/import

Use a column named email, address, or recipient, or one address per line. Existing rows are skipped. Max 10,000 addresses per request. See Suppressions.

5. Render and send one message

Remove the top-level JSON key. Combine message.from_name and message.from_email in from. Split message.to objects by type into to, cc, and bcc, preserving display names. Move headers["Reply-To"] to reply_to.

PostShiba hosted templates use Liquid, not Mandrill merge tags. Port *|FNAME|* to {{ name }}, publish, and send with template.id plus variables. You can still render text and html in your application. Send one request per recipient when personalization differs.

send-order-confirmation.sh
1 curl -sS -X POST \
2 -H "Authorization: Bearer $POSTSHIBA_API_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "from": "Orders <orders@mail.example.com>",
6 "to": ["customer@example.net"],
7 "subject": "Order ord_123 is confirmed",
8 "text": "Thanks, Sam. We received order ord_123.",
9 "html": "<p>Thanks, Sam. We received order <strong>ord_123</strong>.</p>",
10 "tenant": "acme",
11 "unique_args": {
12 "order_id": "ord_123",
13 "message_type": "order-confirmation"
14 }
15 }' \
16 https://app.postshiba.com/api/v1/emails

Require HTTP 201 with "queued": true, then store message_id. Map tags to scalar fields such as message_type. unique_args allows 32 scalar keys. Never include secrets or message content.

Use only a confirmed tenant ID or slug. An unknown tenant value is 422 {error: invalid, field: tenant}.

POST /api/v1/emails has no idempotency key. For automatic retries, use cluster-specific POST /sends with Idempotency-Key. Otherwise, reconcile before resending.

6. Change SMTP clients when used

Use smtp.postshiba.com:587, STARTTLS, smtp_… credentials, and AUTH PLAIN. AUTH LOGIN fails.

Replace X-MC-Metadata and X-MC-Tags with X-Capsule-Unique-Args. X-SMTPAPI.unique_args also works. Render templates first. The credential selects the tenant, not X-MC-Subaccount.

7. Replace delivery webhooks

Create a delivery webhook and store its secret. Update the receiver before routing traffic. Mandrill can batch mandrill_events. Each PostShiba POST contains one event inside a JSON array signed with HMAC-SHA256 over {timestamp}.{raw_body}.

Follow Verify webhook requests with the raw body and both X-Capsule-* headers. Parse event, email, sg_event_id, sg_message_id, and unique_args. Deduplicate on sg_event_id.

Map delivered to delivered, deferral to deferred, terminal bounce outcomes to bounce, reject to dropped, spam to spamreport, and unsub to unsubscribe. Treat send to processed as an operational approximation: Mandrill means sent, while PostShiba means accepted. PostShiba does not emit opens or clicks.

8. Move inbound mail when used

Replace each Mandrill route with an exact domain-bound inbox or a catch-all. Move other matching into your application.

Choose json or sendgrid_parse. Neither sends inbound mandrill_events. Update the handler and verify requests with webhook_secret.

Lower the old MX TTL first. Domain-bound addresses use local@inbound.{sending_domain}. Publish MX only there. Equal-priority MX records do not split safely. If Mandrill already receives on that exact hostname, replace its MX after testing. Otherwise update Reply-To values or aliases to use the new PostShiba address.

Cut over in stages

  1. Send rendered fixtures to a team member or live inbox. Check bodies, headers, links, and attachments.
  2. Confirm queued: true, then observe processed and delivered with the expected unique_args.
  3. After KYC approval, follow the ramp. Before each increase, compare delivery, bounce, complaint, unsubscribe, webhook, and API error rates.
  4. Finish outbound before switching inbound MX. Confirm a signed inbound webhook.

Roll back

Route new messages back to Mandrill. Keep both webhook handlers active for late events. Do not resend PostShiba-queued messages. Reconcile uncertain attempts by message_id, sg_event_id, and unique_args.

For inbound rollback, restore Mandrill MX and keep both handlers through DNS expiry. Keep PostShiba resources through rollback.

Final checklist

  • KYC is approved, and the shared cluster reports sending_ready: true.
  • Each tenant that sends has a verified domain and a live credential.
  • Old Mandrill templates are ported to Liquid or rendered in the application.
  • API callers use Bearer auth, or SMTP callers use STARTTLS and AUTH PLAIN.
  • Metadata and tags arrive as scalar unique_args.
  • Every REST send uses a confirmed tenant ID or slug.
  • Signed delivery events update the right application record.
  • Inbound MX and signed receiving webhooks work when inbound mail is used.
  • Reject and unsubscribe lists are imported per tenant.
  • The traffic switch sends each production message through one provider, and rollback is ready.

About

PostShiba is the email platform that powers Bento behind the scenes. You can build your own products, like Bento, on top of it.

© 2026 PostShiba by Backpack Internet Pty. Ltd. All rights reserved.

The same policies that govern Bento are applied to PostShiba Privacy | Terms | Security