Courier
Sync user profiles and trigger multi-channel notifications through Courier — a notification orchestration platform that unifies email, push, SMS, chat, and in-app messaging behind a single API. Zeotap keeps Courier user profiles in sync with your warehouse data and can fan out notification events driven by audience changes.
Prerequisites
- A Courier account with an active workspace
- A Courier Auth Token (API key) with write access to profiles and send
- If sending notifications, a published notification template (event) in Courier
Authentication
Courier uses API Key authentication. The key is sent in an Authorization: Bearer <token> header on every request.
- Sign in to Courier .
- Open Settings → API Keys.
- Copy the Auth Token (choose a Published key for production syncs).
- Paste it into the API Key field in Zeotap.
Configuration
Courier requires no workspace-level configuration beyond the API key.
Target Settings
| Field | Type | Required | Description |
|---|---|---|---|
| Object Type | Select | Yes | What to sync to Courier. Options: User Profiles (default), Send Notifications. |
| Notification Template ID | Text | Conditional | The Courier notification template (event) to trigger for each user. Required when Object Type is Send Notifications. |
Supported Operations
Sync Modes
| Mode | Supported |
|---|---|
| Upsert | Yes |
| Insert | — |
| Update | Yes |
| Mirror | — |
Audience Sync Modes
| Mode | Supported |
|---|---|
| Add | Yes |
| Remove | Yes |
| Mirror | Yes |
| Upsert | Yes |
Features
- Field Mapping: Yes
- Schema Introspection: No
Required Mapping Fields
| Field | Description |
|---|---|
| user_id | Primary user identifier for Courier. Used both as the profile key and as the to.user_id on notification sends. |
Default Destination Fields
user_id, email, phone_number, first_name, last_name, locale
Any additional mapped fields are written through to the Courier profile as custom attributes.
How It Works
User Profiles
When Object Type is User Profiles, Zeotap mirrors warehouse rows onto Courier profiles at /profiles/{user_id}.
- Upsert / Update / Add:
POST /profiles/{user_id}with a{"profile": {...}}body. Courier merges the supplied fields into the existing profile, so fields that are not present in the current row are preserved. - Remove:
DELETE /profiles/{user_id}— the profile record is removed entirely. - Mirror: added/changed rows are merged via POST; rows marked as removed are deleted.
Zeotap uses POST (merge) rather than PUT (replace) so that partial-column syncs do not wipe other attributes on the profile.
Send Notifications
When Object Type is Send Notifications, each row triggers the configured Courier notification template:
- Zeotap posts to
/sendwith amessageobject containingto.user_id,template(the template ID), anddata(all non-identity mapped fields passed as template variables). - Courier resolves the recipient’s channels (email, push, SMS, …) from the user’s profile and routing preferences.
Because notifications are append-only events, audience Remove and the removed half of Mirror are treated as no-ops — a notification that has already been dispatched cannot be un-sent.
Request Details
- Base URL:
https://api.courier.com - Authentication:
Authorization: Bearer <api_key> - Content-Type:
application/json - Retries: Zeotap automatically retries transient failures (5xx and 429) with exponential backoff.
Rate Limits
Courier enforces workspace-level rate limits that vary by plan. Zeotap respects HTTP 429 responses and retries with backoff; for very large audiences consider scheduling syncs outside peak traffic windows.
Best Practices
- Use stable user IDs: Map a durable, unique identifier from your warehouse to
user_id. Courier keys profiles on this value, and it is also the routing handle for sends. - Normalize email and phone: Courier routes to the channels present on the profile. Keep
emailandphone_numberin canonical form (lowercased email, E.164 phone). - Use profile syncs to power templates: Keep profile attributes fresh with a User Profiles sync, then reference them in Courier templates rather than re-sending them on every notification.
- Avoid sending notifications on full historical backfills: Notification sends fan out real user messages. Gate notification syncs on incremental audiences or freshly changed rows.
- Test with a Test API key first: Courier supports separate Test and Production keys — use Test keys while iterating on templates to avoid real deliveries.
Troubleshooting
Authentication failed: invalid API key
Confirm that the key you pasted is an Auth Token from Settings → API Keys, not a Tenant token or webhook secret. Make sure you copied the Published (or Test) variant matching your environment.
Profile not found or fields missing after sync
Courier merges fields on POST — it does not return the merged state in the response. Inspect the profile directly via GET /profiles/{user_id} in the Courier dashboard or API to confirm the fields landed. If unexpected fields are missing, check that they are included in your field mapping.
Notifications are not being delivered
Verify that (1) the Notification Template ID matches a published template in Courier, (2) the target user’s profile has a valid channel (email, push token, phone number) for the channels configured in the template, and (3) the user has not opted out of the notification category.
Template variables are empty in the delivered message
Data passed on /send arrives under data.* in the template. Make sure your template references {data.first_name} (not {first_name}). Only non-identity mapped fields are forwarded as data.
429 Too Many Requests
Zeotap retries 429 responses automatically, but sustained throttling indicates you are exceeding your plan’s rate limit. Contact Courier support to raise limits or split the audience into smaller scheduled syncs.
Remove / Mirror has no effect on notifications
Notifications are one-shot send events; a delivered notification cannot be recalled. For the Send Notifications object type, rows flagged for removal are intentionally skipped. Use the User Profiles object type if you want removals to translate into profile deletions.