Courier
Datafly Signal delivers events to Courier server-to-server using the Send API. Each delivered Signal event triggers a Courier notification for the recipient, routed across whatever channels your Courier template defines (email, SMS, push, chat, in-app). Signal maps the recipient’s identity into the notification and passes the event properties through as template variables.
Because delivery happens from your own Signal backend, there is no client-side Courier SDK on the page and no browser API key to expose.
Prerequisites
Before configuring Courier in Signal, you need a Courier account, an API key, and a notification template.
Step 1: Create a Courier account
If you don’t already have one, sign up at app.courier.com and complete the onboarding.
Step 2: Create a notification template
- In the Courier dashboard, go to Designer.
- Click Create Notification and design the message for the channels you want (email, SMS, push, etc.).
- Use template variables (e.g.
{order_id},{amount}) where you want event data to appear. These map to the values Signal sends inmessage.data. - Publish the notification and note its template id (the slug you reference in the API).
Step 3: Get your API key
- Go to Settings > API Keys (app.courier.com/settings/api-keys).
- Copy a production API key.
This key is a server-side credential. Signal stores it encrypted and sends it only from your backend. Never place a Courier API key in client-side code.
Configure in Signal
Configuration Fields
| Field | Required | Description |
|---|---|---|
api_key | Yes | Your Courier server-side API key. Sent as a Bearer token. Found under Settings > API Keys. |
template_id | No | The Courier template id to trigger. Set this in the blueprint’s message.template mapping. Leave blank if your blueprint supplies inline message.content instead. |
Management UI Setup
Add the integration
Go to Integrations > Add Integration > Courier and choose the Default preset.
Enter credentials
Paste your Courier api_key.
Set the template id
Open the integration’s Field Mappings and set the message.template value to your Courier template id (the Default preset ships a YOUR_TEMPLATE_ID placeholder you must replace). Alternatively, map inline content via message.content.
Select consent categories
Choose the consent categories that gate this integration (typically marketing). Courier has no consent field of its own, so Signal enforces consent upstream — unconsented events are dropped before they reach Courier.
Save
Click Save. Signal will begin triggering notifications for matching events.
API Endpoint
POST https://api.courier.com/send
Authorization: Bearer {api_key}
Content-Type: application/jsonA successful request returns HTTP 202 with a requestId you can use to track delivery in the Courier dashboard.
Identity Signals
Courier delivers to a recipient, so identity is about who to notify — not probabilistic ad matching. Signal maps the following into message.to:
| Signal source | Courier field | Notes |
|---|---|---|
user_id / anonymous_id | to.user_id | Stable recipient id. Used to look up and merge the Courier profile. |
email (from identify) | to.email | Plaintext. Courier must deliver to the real address, so this is not hashed. Trimmed and lowercased. |
phone (from identify) | to.phone_number | Plaintext, normalised to E.164. Required for SMS delivery. |
locale | to.locale | Used for localised templates. |
first_name / last_name | to.data.first_name / to.data.last_name | Stored as recipient profile attributes, usable in templates. |
Unlike advertising connectors, Courier email and phone values are sent unhashed — a notification platform cannot deliver to a hashed address. Make sure this data flow is acceptable under your privacy review. Email/phone are still only sent for users who have been identified and who have granted the configured consent.
How to send recipient data
Call datafly.identify() when a user logs in, registers, or submits a form:
datafly.identify("user-123", {
email: "jane.doe@example.com",
phone: "+44 7700 900123",
first_name: "Jane",
last_name: "Doe"
});Signal forwards these into message.to so Courier knows who to notify and how.
Event Mapping
The Default preset maps these Signal events. Event properties land in message.data, where they become template variables. Unmapped events are dropped.
| Signal event | Courier data fields |
|---|---|
page | page_url, page_title, referrer |
Signed Up | method, plan |
Order Completed | order_id, amount, currency, items |
Order Refunded | order_id, amount, currency |
To customise, edit the integration’s Field Mappings in the Management UI.
Example: Order Completed event
Datafly.js call:
datafly.identify("user-123", { email: "jane.doe@example.com" });
datafly.track("Order Completed", {
order_id: "ORD-001",
revenue: 129.99,
currency: "USD",
products: [
{ product_id: "SKU-A", name: "Widget", price: 49.99, quantity: 2 },
{ product_id: "SKU-B", name: "Gadget", price: 30.01, quantity: 1 }
]
});Courier Send API payload sent by Signal:
{
"message": {
"to": {
"user_id": "user-123",
"email": "jane.doe@example.com"
},
"template": "order_confirmation",
"data": {
"order_id": "ORD-001",
"amount": 129.99,
"currency": "USD",
"items": [
{ "product_id": "SKU-A", "name": "Widget", "price": 49.99, "quantity": 2 },
{ "product_id": "SKU-B", "name": "Gadget", "price": 30.01, "quantity": 1 }
]
}
}
}In your Courier template, reference these as {order_id}, {amount}, {currency}, and loop over {items}.
Testing Your Integration
Trigger an event
On a page running Datafly.js, identify a recipient and fire a mapped event (for example, complete a test checkout to fire Order Completed).
Check the Signal event debugger
Open the integration’s Event Debugger in the Management UI and confirm the message payload was built with the expected to and data, and that the request returned 202.
Check Courier logs
In the Courier dashboard, go to Logs. You should see the notification with a matching requestId, the resolved recipient, and the per-channel delivery status.
Troubleshooting
| Problem | Solution |
|---|---|
401 Unauthorized | The API key is wrong or revoked. Copy a fresh production key from Settings > API Keys. |
400 Bad Request | Usually a missing recipient or an unknown template. Confirm message.to has at least one of user_id / email / phone_number, and that message.template is a real, published template id. |
404 Not Found | The referenced template id does not exist or is not published in this Courier account. |
| Notification not delivered to a channel | The recipient is missing the identifier that channel needs (e.g. no email for the email channel, no phone_number for SMS). Send it via datafly.identify(). |
| Events not reaching Courier at all | The event is unmapped (dropped by default) or the user has not granted the configured consent. Check the Field Mappings and the integration’s consent categories. |
402 Payment Required | Your Courier plan’s send quota is exhausted. Upgrade the plan or wait for the quota to reset. |
Rate Limits
Courier rate-limits the API per plan. Signal applies a conservative client-side limit (10 requests/second sustained, burst 20) to stay within typical ceilings; adjust this for your Courier plan if you send at higher volume.