Coming from Mailchimp
If your platform syncs its customers’ contacts to Mailchimp today, most of that code maps straight across. An audience becomes a workspace, a member becomes a contact, and Mailchimp’s add-or-update becomes our upsert by your own id, so you don’t compute hashes any more. The biggest difference is consent: Mailchimp’s member status is split into marketing consent you assert and suppressions we record.
The Mailchimp side below follows Mailchimp’s Marketing API, version 3.0.91.
The mapping
Section titled “The mapping”| Mailchimp | SendTruss |
|---|---|
| An audience (list), usually one per customer | A workspace per customer, created by API with your own reference for the customer |
A merge field (POST /lists/{list_id}/merge-fields; types text, number, address, phone, date, url, imageurl, radio, dropdown, birthday, zip), per audience |
An attribute definition, per platform and shared by every workspace; types string, number, boolean and date |
subscriber_hash, the MD5 of the lowercased address |
ref: plus your own id for the person, in every contact path; no hash to compute |
Add or update a member (PUT /lists/{list_id}/members/{subscriber_hash}) with status_if_new |
Create or update a contact by reference: PUT …/contacts/ref:<id>, which creates or updates |
Batch subscribe or unsubscribe (POST /lists/{list_id}, up to 500 members) |
Create or update contacts in a batch: POST …/contacts/batch, up to 500, one result per contact |
Tags (POST …/members/{subscriber_hash}/tags, each active or inactive) |
Tags on the contact: the whole set in an upsert, or add and remove one at a time |
Status subscribed, with timestamp_opt |
marketing with state subscribed and at, the time the person agreed, in the upsert |
Status unsubscribed |
marketing with state unsubscribed and at, in the upsert |
Status pending (double opt-in) |
pending: a contact you haven’t sent consent for yet. It gets no marketing until you send subscribed |
Status cleaned |
A suppression we record from a hard bounce. You can’t set it; you hear of it as a contact.suppressed webhook |
Status transactional |
Nothing to set: every contact gets transactional email, and marketing consent governs only marketing (streams) |
language |
locale, such as pt-BR, in the upsert |
Archive a member (DELETE …/members/{subscriber_hash}) |
Delete a contact |
Permanently delete a member (POST …/actions/delete-permanent) |
Erase a person |
| Webhooks, with sources user, admin and api | Webhook endpoints, with a source on every body; changes you make through the API send none |
| Interests (groups) | No equivalent yet. Tags cover most of what groups were used for |
What works differently
Section titled “What works differently”You address people by your own id. Mailchimp keys a member on the hash of their address, so a changed address changes the key you call them by. We key a contact on your reference, so an address change is just an upsert with the new email. An address can belong to only one contact in a workspace; a second is refused with email_taken, naming the contact that has it.
Attributes are defined once for your platform. Merge fields belong to each audience, so a platform with 500 customers keeps 500 copies of the same fields in step. Attribute definitions belong to your platform, so define each one once, before the first sync. A definition’s key and type can’t change later, so map Mailchimp’s types with care: text, phone, url, radio, dropdown and zip become string, number becomes number, date and birthday become date. An address field becomes several string attributes, one per part you use.
Consent carries its time, and a stale one is refused. Mailchimp lets a sync set a member back to subscribed. We refuse a subscribed dated at or before the contact’s latest opt-out, with consent_older_than_opt_out, so a nightly sync carrying an old “yes” can’t undo this morning’s unsubscribe. Send the time the person actually agreed, which is Mailchimp’s timestamp_opt when you’re moving existing members across.
There is no status to set. status on a contact is read-only, and follows from the consent you send. status_if_new has no counterpart: a contact created without marketing is pending, which is what you want for anyone who hasn’t agreed.
Suppressions are ours. Mailchimp’s API lets you set a member’s status to cleaned. Here a suppression is recorded from what the recipient’s mail server told us, and your consent can’t lift it. Your endpoint hears about each one through contact.suppressed.
Tags in an upsert are the whole set. Mailchimp’s tag call marks each tag active or inactive. Our upsert’s tags replaces the contact’s tags, which suits a sync that sends state. For a change of one tag, use the add and remove calls.
Languages use hyphens. Mailchimp’s language codes write a region with an underscore, as in pt_PT. Send it as pt-PT.
Webhooks skip your own changes. A Mailchimp webhook can opt into changes made through its API. Ours never send changes you made yourself, so your sync can’t react to its own echo. Mailchimp’s unsubscribe event becomes contact.left_marketing (and contact.rejoined_marketing if the person undoes it within the undo window), and cleaned becomes contact.suppressed. Its subscribe, profile and upemail events have no counterpart, since in your platform those changes come from you.
Moving a sync across
Section titled “Moving a sync across”Do it in this order, and before your customers send their first campaign:
- Define your attributes. One attribute definition per merge field you use, for your platform.
- Create a workspace per audience. Create a workspace for each customer, with the id your platform already uses for them as the
reference. - Backfill each workspace. Send each audience’s members through the batch upsert, 500 at a time, by your id for each person. Map each member’s status:
subscribed:marketingsubscribed,atset totimestamp_opt;unsubscribed:marketingunsubscribed,atset to the time they left, orlast_changedif that’s all you have;pending: nomarketing;cleaned: leave them out, or send them with nomarketingso they get none.
- Switch your live sync. Where your code called Mailchimp’s add-or-update, call the upsert, sending only what changed.
- Register a webhook endpoint for
contact.left_marketing,contact.rejoined_marketingandcontact.suppressed, so your platform’s own records stay in step with what people do.
Sync your contacts covers steps 3 and 4 in detail.