Email & MJML
Email on Inklura has three parts: Mail Designer, the app where you compose newsletters in
MJML, the platform's sending service, and two Platform API
routers: campaigns to manage and send campaigns, and emailAnalytics for reporting.
Mail Designer
Mail Designer (maildesigner.inklura.fr / mail.inklura.fr) composes newsletters in MJML,
which compiles to HTML that mail clients render correctly, and keeps the MJML source for
later editing. An AI assistant helps you draft the message. Mail Designer has its own
newsletter programs and scheduling; you use it from its interface.
Managing and sending campaigns: the campaigns router
The Platform API's campaign lifecycle lives in the campaigns tRPC router, called at
/api/trpc/campaigns.<procedure> using the tRPC conventions. Each
procedure requires the listed permission:
| Procedure | Type | Input | Purpose | Permission |
|---|---|---|---|---|
getCampaigns |
query | page, per_page, search, status |
List campaigns. | campaigns:read |
getCampaignById |
query | id |
Fetch one campaign. | campaigns:read |
createCampaign |
mutation | see below | Create a campaign. | campaigns:create |
createCampaignWizard |
mutation | channelType, details, template, audience, schedule |
Create a campaign with the guided wizard. | campaigns:create |
updateCampaign |
mutation | createCampaign fields + id, status |
Update a campaign. | campaigns:update |
deleteCampaign |
mutation | id |
Delete a campaign. | campaigns:delete |
sendCampaign |
mutation | id |
Send a campaign. | campaigns:send |
pauseCampaign |
mutation | id |
Set the campaign status to paused. |
campaigns:update |
resumeCampaign |
mutation | id |
Set the campaign status back to active. |
campaigns:update |
duplicateCampaign |
mutation | id |
Duplicate a campaign. | campaigns:create |
getCampaignActivity |
query | id, page, per_page |
Read a campaign's activity, paginated. | campaigns:read |
getCampaignTags |
query | none | List campaign tags. | campaigns:read |
createCampaignTag |
mutation | name |
Create a campaign tag. | campaigns:create |
Pagination starts at page: 0, with per_page: 10 by default. getCampaigns matches
search against the name and description, and returns { data, total, page, per_page, totalPages }.
The procedures that look up a campaign by id (except pauseCampaign and resumeCampaign)
return NOT_FOUND for an unknown campaign or one that belongs to another site.
Creating a campaign
createCampaign accepts:
| Field | Type | Notes |
|---|---|---|
name |
string | Required, at least 3 characters. |
type |
string | Required. |
channelType |
string | email or sms. Falls back to type, then email. |
subject, content |
string | Email subject and content. |
templateId |
string | Template to use. |
segmentId |
string | Contact segment to send to. |
marketingCampaignId |
string | Parent marketing campaign. |
scheduled, scheduledDate |
boolean, date | scheduled: true creates the campaign with status scheduled, otherwise draft. |
testMode, testEmail |
boolean, string | Test mode (false by default) and test address. |
The response includes the campaign id.
curl -X POST "https://manage.inklura.fr/api/trpc/campaigns.createCampaign" \
-H "Authorization: Bearer $INKLURA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"json":{"name":"October newsletter","type":"email","subject":"What is new this month","segmentId":"<segment-id>"}}'
Sending
sendCampaign sets the campaign status to active, then sends the message to every contact
in the campaign's segments (minus any excluded segment), skipping unsubscribed addresses. Each send is logged and then
feeds emailAnalytics. An SMS campaign goes out by SMS to the contacts who opted in. You do
not call the sending service directly.
curl -X POST "https://manage.inklura.fr/api/trpc/campaigns.sendCampaign" \
-H "Authorization: Bearer $INKLURA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"json":{"id":"<campaign-id>"}}'
pauseCampaign and resumeCampaign only change the campaign status: they do not interrupt
a send already started by sendCampaign.
Reporting: the emailAnalytics router
Reporting goes through a separate router, emailAnalytics. Every procedure requires a
session that holds the analytics:read permission (see
tRPC Procedures).
| Procedure | Main input | Returns |
|---|---|---|
getDashboardMetrics |
period filters | Sends, unique opens and clicks, bounces, unsubscribes and their rates, compared with the previous period. |
getCampaignAnalytics |
campaignId, includeTimeSeries, timeSeriesInterval |
Analytics for one campaign and its 50 most recent sent emails. |
getCampaignRevenue |
campaignId, period (default 1y) |
Conversions, revenue, cost and ROAS attributed to a campaign. |
getTopCampaigns |
limit (1 to 100, default 10), sortBy, sortOrder, period |
Best-performing campaigns. |
getEngagementTrends |
period filters, granularity (default day) |
Engagement over time. |
getProviderPerformance |
period filters | Delivery performance. |
getUnsubscribeAnalytics |
period filters | Unsubscribe metrics. |
getUnsubscribeFunnel |
period (7d, 30d or 90d), campaignId |
The unsubscribe funnel. |
getHealthStatus |
none | Status of the analytics service. |
The period filters are:
| Field | Values | Default |
|---|---|---|
period |
today, yesterday, 7d, 30d, 90d, 1y, custom |
30d |
startDate, endDate |
dates, for period: "custom" |
|
campaignId |
campaign UUID | |
emailAddress |
a recipient address | |
includeComparison |
boolean | true |
sortBy accepts openRate, clickRate, bounceRate or totalEmails (default openRate);
sortOrder is asc or desc (default desc). timeSeriesInterval accepts hour, day,
week or month (default hour), as does granularity.
curl -G "https://manage.inklura.fr/api/trpc/emailAnalytics.getDashboardMetrics" \
-H "Authorization: Bearer $INKLURA_TOKEN" \
--data-urlencode 'input={"json":{"period":"7d"}}'
On failure, most procedures return an INTERNAL_SERVER_ERROR. Two degrade instead:
getCampaignAnalytics still returns the campaign's sent emails, with analytics: null and an
empty time series when the analytics service is unavailable, and getCampaignRevenue returns
zeros with hasData: false. getHealthStatus reports each component as healthy or
unhealthy, and the whole as healthy, degraded or unhealthy.
Open and click tracking
When tracking is enabled for a send (the sending service's default), the email carries a
tracking pixel and its links go through a redirect. An open is counted when the pixel
loads; a click is counted when the reader passes through the redirect to the destination
page. These events feed emailAnalytics.
Related
- tRPC Procedures: how to call
campaigns.*andemailAnalytics.* - Marketing Journeys: the
EMAILstep, the only journey step that sends - Integrations Overview