
Iterable's Frequently Asked Questions page is a central hub where its customers can always go to with their most common questions. These are the 287 most popular questions Iterable receives.
Use snippets to reuse the same content across multiple templates. For
example, a snippet might contain a repeatedly used header, call-to-action
block, or footer. Editing a snippet causes all templates that reference it to receive the
updated content. This is a more efficient workflow than manually editing the
same content multiple times in multiple templates.
# Table of contents
Creating or editing a snippet Example snippet
Using a snippet in a template
# Creating or editing a snippet To create or edit a snippet, follow these steps:
Navigate to Content > Snippets to bring up the Manage Snippets
screen. #
To create a new snippet, click Create New Snippet; to edit an existing
snippet, click its name.
The Create a Snippet screen appears.
Provide a Snippet Name. This name will be used to include the snippet in a template. It can
contain letters, numbers, spaces, dashes, and underscores.
WARNING Changing the name of an existing snippet breaks any template that
references it by its old name. If you change a snippet's name, be sure to
update all templates that rely on it.
To pass data to a snippet, use Positional Parameters. A snippet's content might need to change based on the value of a user
profile or event field. For example, a snippet might select a product image based on a user
profile's favoriteColor field. It's possible, though, that one template might want to consider the
recipient's favoriteColor, while another needs to look at the
lastPurchasedColor. If the snippet is hard-coded to look at a
particular field, it can't be re-used in both of these scenarios. To solve this problem, don't reference specific user profile or event
fields in snippets. Instead, pass data to snippets as positional
parameters: variables sent from the template to the snippet. Snippets
that make use of positional parameters aren't tied to specific user
profile or event fields and can be reused more broadly. To add positional parameters to a snippet:
Click Add New Positional Parameter.
In the Key input, specify the parameter's name. For example, specifying a Key of firstName allows the snippet
to access any value passed to that parameter as {{firstName}}.
Add as many positional parameters as needed.
Enter a Description that clarifies what the snippet is and where it
should be used.
In the Markup input, specify the content of the snippet. As you create or update a snippet's content, keep in mind the following:
The specific editor available for modifying snippet content depends on
the Use WYSIWYG Template Editor setting in
Settings > Project Settings. For snippets that will be used in SMS messages, push notifications,
or web push notifications, only use plain text (no HTML). Changing an existing snippet impacts all templates that reference it
(including those tied to live campaigns).
To reference a user profile field, event field, or positional parameter,
use a Handlebars expression
such as {{userProfileField}} or {{#if parameterName}}.
To reference a field from a data feed:
Use double curly braces to reference data feed data. For example:
{{fieldInDataFeed}}. In the template that references the snippet, open the
Advanced Options tab. On this tab, check Enable Template Generation Using Data Feeds
and Merge the Data feed and User Contexts.
Typical CSS precedence rules apply to any CSS contained in a snippet:
Inline CSS (with the HTML style attribute) overrides CSS rules
in a style tag. A more-specific selector takes precedence over a less-specific one. If two CSS rules have the same specifity, the one that appears
later in the code takes precedence. A CSSrule with!importantalways takes precedence.
Close all HTML tags (unless you're intentionally leaving a tag open so
that the template can close it). Templates can make use of CSS styles defined in a snippet.
After editing the snippet, click Save. This creates (or updates) the
snippet and allows templates to reference it.
# Example snippet The following properties describe a snippet that displays either a greyscale
or color version of some social media icons, depending on the value of a
passed-in positional parameter:
Snippet Name socialMediaIcons
Positional Parameters useColor
Description Displays a greyscale or color collection of social media icons, depending
on the boolean value passed to the useColor parameter.
Markup {{#if useColor}}
<br />
<img alt="Icons" src=".../socialMediaColor.png" />
<br />
{{else}}
<br />
<img alt="Icons" src=".../socialMediaGreyscale.png" />
<br />
{{/if}
(source view)
Using a snippet in a template To insert a snippet in a template, follow these steps:
Navigate to Content > Templates and create a new template or open an
existing one.
On the Edit Template screen, click Insert Snippet.
In the Insert a Snippet window, select the snippet you'd like to
insert.
If the snippet contains HTML, toggle on the Render HTML switch. Enabling this option changes the Handlebars for inserting the snippet
so that it uses triple curly braces rather than double curly braces.
Triple curly braces cue Iterable to render the HTML in the template as
HTML rather than as plain text.
If the snippet requires any positional parameter values, specify them
in the Handlebars input, after the name of the snippet.
NOTE When passing values to a snippet's positional parameters, templates can
specify user profile fields, event fields, or literal valuesall of which
can have different types (numbers, strings, boolean values, etc.). Make
sure to pass parameter values that make sense; for example, don't provide
a string (such as a name) for a positional parameter that the snippet
uses in a numeric comparison.
Click the Copy button.
In the appropriate place in your template, paste the text copied from the
Insert a Snippet window.
To preview the template, including its snippet content, choose
Preview > Preview With Data or Preview > Preview on Devices. On the Preview on Devices screen, click Regenerate Previews to
make sure you see up-to-date content.
View Article
Universal merge parameters are parameters that are available for all
clients regardless of setup. Below is a list of all universal parameters that
can be used in your templates.
# List of available merge parameters
View in browser URL: {{viewInBrowserUrl}}
Unsubscribe URL : {{unsubscribeUrl}}
Hosted unsubscribe URL: {{hostedUnsubscribeUrl}}
Unsubscribe message type URL: {{unsubscribeMessageTypeUrl}}
Campaign name: {{campaignName}}
Campaign ID: {{campaignId}}
Recurring campaign ID: {{recurringCampaignId}}
Template ID: {{templateId}}
Client Template ID: {{clientTemplateId}}
Channel ID: {{channelId}}
Message type ID: {{messageTypeId}}
Recipient email: {{email}}
Company name: {{companyName}}
Company address: {{physicalAddress}}
Current date: {{now}} For example, "Oct 5, 2018"
Current date: {{now format='MMMM dd, yyyy'}} For example, "October 5, 2018"
Current date: {{now format='MM/dd/yy'}} For example, "10/05/2018"
Current year: {{now format='yyyy'}} For example, "2018"
Date, full format: {{now format='full'}} For example, "Monday, December 12, 2016"
Date, custom format:{{now format='E, MMMM dd, yyyy'}} Sample output for this custom format: "Mon, December 10, 2018"
Date five days from today: {{dateMath "now" "+5d"}}
# Example usage
# viewInBrowserUrl
{{viewInBrowserUrl}} provides a link to a web version of your email. The following example shows {{viewInBrowserUrl}} being used in the
WYSIWYG editor: # The following example shows {{viewInBrowserUrl}} being used in source code: <a href="{{viewInBrowserUrl}}" target="_blank">View this email in your browser</a>
NOTE Clicking this link in an email proof will show an error message.
# unsubscribeUrl
{{unsubscribeUrl}} inserts a link to unsubscribe from the channel associated
with the message. By default, Iterable auto-appends the unsubscribe
block. If this feature is disabled, you must include {{unsubscribeUrl}},
{{unsubscribeMessageTypeUrl}} or {{hostedUnsubscribeUrl}} in emails sent
through a marketing channel. To learn more, read
Message Channels and Message Types Overview. The following example shows {{unsubscribeUrl}} being used in the WYSIWYG
editor: The following example shows {{unsubscribeUrl}} being used in source code: <a href="{{unsubscribeUrl}}">unsubscribe</a>
# hostedUnsubscribeUrl
{{hostedUnsubscribeUrl}} inserts the link to your hosted unsubscribe page
or email preferences center. Set this up in your Iterable
project settings. The following example shows {{hostedUnsubscribeUrl}} being used in the
WYSIWYG editor: The following example shows {{hostedUnsubscribeUrl}} being used in source
code: <a href="{{hostedUnsubscribeUrl}}">Update subscription preferences</a>
NOTE If you wish to add parameters to the end of the hosted unsubscribe URL, it is
best to type them in on the project settings
page instead of in the template body. However, if you do add the parameters
to the template body, use & as the first character of your parameter
string instead of ?.
# unsubscribeMessageTypeUrl {{unsubscribeMessageTypeUrl}} inserts the link to unsubscribe from the
message type associated with the message. By default, Iterable will
auto-appends the unsubscribe block. If this feature is disabled,
you must include {{unsubscribeUrl}}, {{unsubscribeMessageTypeUrl}}
or {{hostedUnsubscribeUrl}} in emails sent through a marketing channel.
To learn more, read Message Channels and Message Types Overview.
The following example shows {{unsubscribeMessageTypeUrl}} being used
in the WYSIWYG editor: The following screenshot shows {{unsubscribeMessageTypeUrl}} being used
in source code: <a href="{{unsubscribedMessageTypeUrl}}">Unsubscribe from Iterable's Newsletter Messages</a>
# campaignId
{{campaignId}} inserts the numerical ID of the campaign into the template. The following example shows {{campaignId}} being used in a template: This example would render text similar to the following:
# recurringCampaignId {{recurringCampaignId}} inserts the campaign ID of the recurring (parent)
campaign. This could be useful in a case where you want to include the parent
campaign ID in a custom link parameter for attribution purposes (for example,
if you want to attribute user engagement related to entire series of
newsletters instead of to a single month's).
{{email}} inserts the recipient's email address into the template. The following example shows {{email}} in the template editor: In an email, this would appear as follows:
# companyName {{companyName}} inserts your company's name, which you set as the project
name in your project settings.
# physicalAddress
{{physicalAddress}} inserts your company's physical mailing address, which you set in your project
settings.
You must include the address in your emails to comply with CAN SPAM laws. By
default, Iterable auto-appends your unsubscribe block, which will include the
address you have entered in project settings. If you have turned off this
feature, then you can use {{physicalAddress}} in your emails when coding your
unsubscribe block. The following example shows {{physicalAddress}} in the template editor: In an email, this would appear as follows:
now
{{now}} will give you current time at time of send. You can then format this
date according to your needs: {{now format='YYYY-MM-dd'}}`
NOTE If you are using the WYSIWYG editor, be sure to use single quotes. If you use
double quotes around the format, it won't save properly.
The following example shows {{now}} in the template editor: In an email, this would appear as follows:
View Article
Iterable projects provide two levels of metrics:
Campaign-level (specific to a campaign; covered in this article) Aggregate-level (across multiple campaigns; covered in
Viewing Aggregate Campaign Metrics )
NOTE Read Metrics Definitions,
SMS Campaign Metrics,
and Push Campaign Metrics
to learn more about different metrics in Iterable.
# Table of contents
Campaign-level metrics
Email template
Heatmaps
Exporting data
Displaying metrics
# Campaign-level metrics
NOTE This guide describes how to view standalone campaign metrics. To learn how to
view metrics for campaigns associated with workflows, read
Workflow Analytics.
To view the metrics for a specific campaign, open the campaign in Iterable.
Metrics are visible for campaigns that are running or finished. At the top of the campaign's page, you will see the overall campaign details
like launch time, the list used, the status of the campaign, which template
was used and the experiment details. The list size at send time is equal to the total number of
subscribers on the list minus the number of subscribers who have unsubscribed
from the message channel delivering the message. Therefore, the list
size may differ from the actual send size. #
TIP To learn more about message channels and types, read
Message Channels and Message Types Overview.
# Email template Click the View Email button to navigate to the template used in the
campaign:
# Heatmaps Click the View Heatmap button to navigate to a heatmap that describes
where users are clicking in a message: View different heatmaps for each of the variations of a campaign experiment
by clicking on the dropdown on the left-hand side above the heatmap table: Use the search bar to filter for specific links or text. You can also view
the raw link data by toggling on the "Show raw link data," which is useful
for showing link stats for highly dynamic content.
# Exporting data Click the Export Data button to export a variety of different reports as
a CSV file. You can drill down to the specific individuals who opened,
clicked, or purchased from your campaigns. Export data such as email clicks, purchase, email unsubscribes, hosted
unsubscibe clicks, email or spam complaints, custom events, bounces,
opens, subscibes, sends, and uninstalls.
# Displaying metrics At the bottom of the page, select metrics,
date ranges, and experiment variations.
TIP Remember to select which metrics you want to view from the dropdown on the
right - none of them will be selected by default.
# Events over time The following graph displays open, click, unsubscribe, bounce, and other
events over time:
# Segment analysis The segment analysis grid shows various metrics by user segment:
# Opens breakdown The opens breakdown pie chart shows statics for Unique opens and
Not yet opened:
# Device type breakdown The device type breakdown shows the devices that have been used to open a
campaign. Some of the slices on this pie chart might include:
iPhone: Apple's Mail app on an iPhone
iPad: Apple Mail app on an iPad
Gmail: Gmail app or website
Android: Non-Gmail app opens on Android
: Unknown user agent and device
NOTES
A Gmail slice on the pie chart includes users who used a Gmail app or
the Gmail website, since Iterable is not able to distinguish between the two. If a user used a non-Gmail email client to open an email sent to a Gmail
account, the open is counted in a non-Gmail bucket. For example, if a user
opened such an email using the Mail app on the iPhone, the open would be
counted by Iterable as an iPhone open.
Map The world map shows locations where users have engaged with your campaigns:
View ArticleIterable can create and send push notification campaigns to iOS and Android
devices, all from a single message template. Push notifications can be customized with sounds, images, videos, and action
buttons (iOS and Android support different options)all the elements needed
to create engaging and valuable content for your users. Iterable's push
notification editor provides live previews as you edit, validates errors, and
can be used to integrate data stored on a user's Iterable profile into a
message. This guide describes how to use Iterable to set up your mobile apps to send
push notifications, create a push notification template, send a push
notification campaign, and use workflows to send push notifications.
# Table of contents
Setting up your mobile apps
Creating a push notification template
Using the push notification template editor
Basic push notification information
Expert mode
Deprecated push notification fields
Saving the push notification template
Creating a push notification campaign
Using a workflow to send a push notification
Further reading
# Setting up your mobile apps Before sending push notifications, work with your mobile engineers to
configure your iOS and Android apps. For more information, take a look at the
following resources:
iOS:
Setting Up iOS Push Notifications Iterable's iOS SDK
iOS SDK Release Notes
Android:
Setting up Android Push Notifications Iterable's Android SDK
Android SDK Release Notes
# Creating a push notification template To send push notifications with Iterable, first create a push notification
template and provide basic details about its name, message type, title, text,
push open action, and any associated rich media. Then use expert mode to
further customize the template's configuration as necessary. To create a push notification template, navigate to Content > Templates
click Create New Template, and select Push. This brings up the push
notification template editor. Snippets Overview
# Using the push notification template editor As you edit the fields in the push template:
The preview updates as you type. Use the Apple and Android icons to switch the preview between platforms. Use Handlebars expressions to reference data contained in a user profile or
triggering event. For example, entering {{messageTitle}} in the Title
field references a messageTitle field on the triggering event or user
profile (if both the user profile and the triggering event have a field with
this name, the field on the triggering event takes precedence). Use the Insert Snippet buttons to find a snippet
to enter into a field Use the Send Proof and Preview with Data buttons to send a test
notification or preview your notification with data from a user's Iterable
profile. Be sure to save the template before using these options.
# Basic push notification information When building a push notification template, provide the following basic
information:
Template Name: The template's internal-facing name. Use this to find
the right template when building a campaign. Message Type: The message type associated with the campaign.
Message types categorize messages, allowing users to receive only the content
they're most interested in. For more information, read
Messages Channels and Types Overview. Title: The title text that should appear at the top of the push
notification. Push Message: The text that should appear in the body of the
push notification.
Push Open Action: The action that should occur when the user taps on
the push notification.
Open App: Opens the app associated with the push notification. Open URL: Passes a URL to the mobile appliction's URL handler. This
URL can deep link to specific content in the app or point to external
content to open in a web browser. When this option is selected, the
template editor will prompt you to provide a URL.
Rich Push: An image or video (Android push notifications do not support
video) and action button to associate with the push notification. Action
buttons sit below push notifications and allow users to take immediate action
on their content. Use them to encourage users to make a purchase, write a
review, visit a website, share content on social media, unsubscribe from a
list, or take some other relevant action. Options specified in this section apply to both iOS and Android push
notifications. To configure platform-specific settings or use more than
one action button, use expert mode.
NOTES
In the push notification preview, click an image to expand it. The action button shows when the push notification is expanded; if you
don't see it, click on the preview. This section allows you to configure a single action button; to use
multiple action buttons, see expert mode. To include images, videos, or action buttons with iOS push
notifications, have your mobile engineers add a Notification Service
Extension to your iOS application. For more information, read about
Iterable's iOS SDK.
# Expert mode To further configure the push notification, enable Expert Mode (using the
toggle at the top of the template editor). Then, adjust the following
settings as necessary:
Custom Action: The name of a custom action to pass to your mobile
application's custom action handler. Work with your team's mobile engineers
to decide on a list of custom actions to support. This option is only
available when Expert Mode is toggled on.
Action Buttons: Buttons that display below push notifications, allowing
users to take immediate action on their content. Use them to encourage users
to make a purchase, write a review, visit a website, share content on social
media, unsubscribe from a list, or take some other relevant action. A push
notification can have up to three action buttons. Example action buttons on iOS and Android:
NOTES
Action buttons show when the push notification is expanded; if you
don't see them, click on the preview. To include images, videos, or action buttons with iOS push
notifications, have your mobile engineers add a Notification Service
Extension to your iOS application. For more information, read about
Iterable's iOS SDK.
Options for action buttons:
Button Text: The text that should on the button. For example, Buy now!. Identifier: A value to include on the Track Push Open event sent
from the mobile app to Iterable after the user taps the button. Useful
for segmenting on users that have tapped a particular push notification
button.
Button Type: The button's type impacts its appearance and the
actions available to it (see below). Iterable supports three different
types of action buttons:
Normal Button: A button with black text. Destructive Button: A button with red text. Text Input Button: A button that displays a text input after
being tapped. When selected, this type of button provides a
Placeholder input for specifying placeholder text for the push
notification's text input, and a Submit Button Text input for
specifying the text to use on the input's submit button.
Button Action: The action to trigger when tapping on the button. There
are four types of button actions:
Open App: Opens the app associated with the push notification. Open URL: Opens an external URL or a deep link to content within
the app.
Custom Action: Passes the provided value to the application's
custom action handler, which is defined in the app's code. Decide in
advance with your team's mobile engineers on a list of supported custom
actions. The Open App option nested under Custom Action causes
the app to come to the foreground to execute the action.
Unchecking this option executes the action with the app in the
background.
Track Only: Sends Iterable a Track Push Open event with the
associated button identifierwithout opening the app or redirecting the
user. This option is useful for buttons that dismiss the push
notification. This button action is available for destructive buttons
and text input buttons.
# iOS-only settings
Rich Media URL: The URL of an image, video, audio file, or animated
GIF. Iterable validates the URL to make sure it can be rendered.
NOTES
In the push notification preview, click an image to expand it. To include images, videos, or action buttons with iOS push
notifications, have your mobile engineers add a Notification Service
Extension to your iOS application. For more information, read about
Iterable's iOS SDK.
Badge Count The badge count the app should show after receiving this
push notification. This field can contain a Handlebars expression that
references a badge count stored on the user's Iterable profile. For example,
{{badgeCount}}.
Wake App: Causes the app to wake up in the background to perform a
background update. Un-checking this setting ensures that the user doesn't
wake the application and cause it to ping your system's servers.
# Android-only settings
Rich Media URL: The URL of a hosted image. Iterable validates the URL
to make sure it can be rendered. Google recommends using an aspect ratio of
2:1 for rich media push messages.
NOTES In the push notification preview, click an image to expand it.
# Advanced Options
Custom Sound: The name of the sound file to play when the push
notification arrives. For the sound file to play, your mobile engineers must
bundle it in your mobile application. For more information, read
Setting Up iOS Push Notifications
and Setting up Android Push Notifications. Enable Template Generation Using Data Feeds: Data feeds query external
web services at send time, providing the results to Iterable so it can
customize the messages sent by a campaign. This option enables data feeds in
the push notification template. For more information about using data feeds
in Iterable, read Rendering Templates with Data Feeds.
# Custom Metadata Additional JSON data to send with the push notification. This data will be
available for your apps to process as necessary. This data can be used to control the state of your application. For example,
if a user reaches VIP status and a push message is congratulating them for
this achievement, the notification might contain custom data telling the app
that the user is now a VIP. The app could process this custom metadata and
accordingly change the home screen or app colors.
# Deprecated push notification fields The following fields have been deprecated and are no longer available for new
templates. Instead, use the Rich Push, Push Open Action, and
Action Buttons options discussed above.
iOS Deep Link Android Deep Link iOS Category
Templates that already use these fields will continue to display
them and work as expected
# Saving the push notification template After configuring the push notification template, save and view a preview:
Save the template by clicking Save Template.
Preview the template by clicking Send Proof or Preview With Data. On the Preview with Data screen, enter an email address and click
Load User Data to view how that user's profile data impacts the
rendering of the push notification.
Back in the template editor, make changes as necessary.
# Creating a push notification campaign After configuring your mobile apps to work with push notifications and
creating a push notification template, you can send a push notification
campaign. Follow these steps:
Navigate to Messaging > Campaigns and click Create New Campaign.
Fill in the necessary details for the campaign (name, custom converstion
metric, labels), and choose a campaign type: Blast or Triggered. For Message Medium, select Push.
Enable Selective Push, if necessary. If you have multiple mobile apps only a subset should receive the push
notification campaign, enable Selective Push and select the mobile
apps to include. If you do not enable selective push, Iterable sends the push notification
campaign to all push integrations defined in the project, regardless
of whether or not they are assigned to mobile apps.
NOTE Define mobile apps in Settings > Mobile Apps. For more details,
see Setting Up iOS Push Notifications
and Setting Up Android Push Notifications.
Select send and suppression lists. In order for users to receive ush notification campaigns from Iterable,
their user profiles must have a device token associated with your mobile
app. Iterable's mobile SDKs ( iOS,
Android ) populate
these tokens when the app is run.
Click Continue to Templates. Select and edit a template, or create a new one. Read
Creating a push notification template
for more information. After editing, saving, and previewing the template, click
Save & Continue To Review. To activate a triggered campaign, click Activate Campaign. To send a
blast campaign, click Send Campaign Right Now or
Schedule Campaign for Later. After launching the campaign, you'll see its
Campaign Analytics screen, where you can view statistics about the
campaign. For more information about these analytics, read
Push Campaign Metrics.
# Using a workflow to send a push notification To use an Iterable workflow
to send push notifications, follow these steps:
Navigate to Messaging > Workflows.
Select an existing workflow or click Create New Workflow to create
a new one. Set up up the workflow as necessary.
At the point in the workflow where you'd like to send a push notification,
drag a Send Push node onto the workflow canvas and connect it to another
node.
Configure the new Send Mobile Push node by double-clicking on it.
Provide a Campaign Name, select a custom conversion metric if
necessary, and add Labels.
Select a template and click Update Node. Alternatively, edit an existing template before selecting it:
Right-click the name of a template and open it in a new browser tab.
Edit the push notification template
as necessary. Click Save Template. Back in the original browser tab, close the workflow node. Double-click the Send Mobile Push node to re-open it. Select the edited template and click Update Node.
Back on the workflow canvas, click Save. Enable the workflow with the toggle in the upper-left corner of the
workflow canvas.
TIP To learn more about testing workflows, read Testing a Workflow.
# Further reading
Iterable's iOS SDK iOS SDK Release Notes Setting Up iOS Push Notifications
Advanced iOS Push Notifications. Iterable's Android SDK Android SDK Release Notes Setting up Android Push Notifications
Rendering Templates with Data Feeds.
Testing a Workflow.
Messages Channels and Types Overview.
View Article
SSO allows automatic, fine-grained management of your organization's Iterable
accounts:
Users login through your Identity Provider (IdP) rather than create their own
username and password You can disable logins from your IdP after a user leaves your organization
SSO is configured through the open standard
Security Assertion Markup Language (SAML). Iterable supports any SAML-compatible IdP. For example:
Okta ADFS OneLogin
# Table of contents
Pre-existing users
Configuring your identity provider (IdP)
SAML settings
Attribute statements
Roles
Okta example
Configure Roles Via Okta Groups
Configuring Iterable Okta IdP metadata
# Pre-existing users After a user logs in to Iterable using your organization's IdP, their
previous Iterable credentials will no longer work. Depending on your
configuration, their assigned projects and roles may also be modified.
# Configuring your identity provider (IdP) The following sections describe how to configure your IdP to work with
Iterable.
# SAML settings In your IdP, use the following SAML settings for the Iterable integration:
Single sign-on URL: https://app.iterable.com/authenticate/saml?orgId=ORG_ID Replace ORG_ID with the your organization's ID (found by navigating
to Settings > Project)
Audience URI (SP entity ID): https://app.iterable.com/authenticate/saml
Name ID format: EmailAddress
Application username: Email
# Attribute statements Configure your IdP to include the following attribute statements
when authenticating with Iterable:
firstName: the user's first name
lastName: the user's last name
email: the user's email address
roles: see the Roles section below
# Roles The roles property designates the role assigned to an Iterable user. Its
value has two possible formats, you may only use one:
OrgAdmin: use for organization admins, grants the user access to all
projects and roles
42:Contributor, 93:Publisher: A comma-separated mapping of project IDs to
roles, allowing you to set per-project roles. The user is granted limited
access to only the projects and roles specified.
The Iterable project ID can be found by switching to that project in
Iterable and navigating to Settings > Accounts
The possible role values are Reader, Contributor, Publisher, AccountManager, and
Admin
For more details on these roles, see Account Roles and Permissions.
# Okta example In Okta, an Iterable configuration should look similar to the following: #
# Configure Roles Via Okta Groups Rather than using a static value for the roles property, Okta allows
administrators to define this property on a group basis. This enables them to
define different roles for different users within their organization. From the Okta Admin Console, go to Directory > Profile Editor then click the
Profile button next to the Iterable app From there click Add Attribute and fill it in how you like, but make sure you
set the following:
Variable name: roles Attribute required: checked
Return to the Assignments tab in the Iterable application. Assign a group,
then click the Edit button. Set the roles property as desired for this group (don't use my example
values!) Switch back to the General tab and click Edit on SAML Settings. Click Next to
get to the Configure SAML step. Set the value of the roles User Attribute to `appuser.roles'
# Configuring Iterable For Iterable to recognize requests from your IdP, it must be aware of your
IdP metadata. IdP metadata is a block of XML that contains a certificate and
application information. It should look similar to the following: <?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://www.okta.com/blahblah">
<md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>
SEqwY8cFuVvOjUuZJ/bhzIAW8W/oZZJkL3qD96uJzlhf1dZN3MnttFhMahKAahlNU2Kd9/Qznz2+
kdljGHs/x7AEfFbe4mEpKi52aZAFD8gcZv4s3wnCMgzndTqEn7dx+4kVtGEh6NAzJfMVgLk50ybb
l6otY3x6m72Jk6zhTKYZHMM9k99sWWs+T3ewq6mbVGMNNk54JdmUtzf42MxT/b9bIvLhVYDqzswy
CFVP7oNN8VmjaI+c6BC89WYthX8gflknlC2PFQa+G4LddERIPLxTDEfQWVONoKHJhxotRvb1HLp2
Jzlhf1dZN3MnttFhMahKAahlNU2Kd9/Qznz2+SEqwY8cFuVvOjUuZJ/bhzIAW8W/oZZJkL3qD96u
CMgzndTqEn7dx+4kVtGEh6NAzJfMVgLk50ybbkdljGHs/x7AEfFbe4mEpKi52aZAFD8gcZv4s3wn
bVGMNNk54JdmUtzf42MxT/b9bIvLhVYDqzswyl6otY3x6m72Jk6zhTKYZHMM9k99sWWs+T3ewq6m
UuZJ/bhzIAW8W/oZZJkL3qD96uJzlhf1dSEqwY8cFuVvOjZN3MnttFhMahKAahlNU2Kd9/Qznz2+
Fbe4mEpKi52aZAFD8gcZv4s3wnCMgzndTkdljGHs/x7AEfqEn7dx+4kVtGEh6NAzJfMVgLk50ybb
6zhTKYZHMM9k99sWWs+T3ewq6mbVGMNNkl6otY3x6m72Jk54JdmUtzf42MxT/b9bIvLhVYDqzswy
I+c6BC89WYthX8gflknlC2PFQa+G4LddECFVP7oNN8VmjaRIPLxTDEfQWVONoKHJhxotRvb1HLp2
tFhMahKAahlNU2Kd9/Qznz2+SEqwY8cFuJzlhf1dZN3MntVvOjUuZJ/bhzIAW8W/oZZJkL3qD96u
+4kVtGEh6NAzJfMVgLk50ybbkdljGHs/xCMgzndTqEn7dx7AEfFbe4mEpKi52aZAFD8gcZv4s3wn
tzf42MxT/b9bIvLhVYDqzswyl6otY3x6mbVGMNNk54JdmU72Jk6zhTKYZHMM9k99sWWs+T3ewq6m
+G4LddERIPLxTDEfQWVONoKHJhxotRvb1HLp2CFVP7oNN8VmjaI+c6BC89WYthX8gflknlC2PFQa
hDsLV9h/c5As5qx7/zSOLmoG3W+LoABOHiXo==
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://some.url/sso/samle"/>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://some.url/sso/samle"/>
</md:IDPSSODescriptor>
</md:EntityDescriptor>
Iterable does not currently provide a user interface for specifying IdP
metadata. Instead, please send it to your Iterable CSM and request that they
add it to your account.
Okta IdP metadata In Okta, IdP metadata can be found in the admin interface on your
application configuration page, on the Sign On tab. Click
Identity Provider Metadata.
View Article
New and improved features:
Added support for send time experiments
Drag-and-Drop Editor now supports video
Miscellaneous/bug fixes:
Field Data Type mismatch errors are now flagged as 4XX error responses to the user update, user bulk update, and event track API calls
View ArticleThis teardown evaluates the user engagement strategies of two leaders in grocery delivery, Safeway and Instacart. Who delivers a fresher experience with their email and mobile marketing?
To view all User Engagement Teardowns, view iterable.com/teardown.
View ArticleIterable allows you to send campaigns at a specific local time depending on
the user. For example, a campaign can be delivered at exactly 9am Pacific,
Eastern or Samoan time.
# Instructions You can enable this feature if you provide either a timeZone or ip field
for users. These fields are case and space-sensitive. For timeZone, the time zone will need to be formatted as described
by Wikipedia's List of tz database time zones.
Here's an example of how it would look in CSV: # For ip, you will need to include the user's ip address. Here's the CSV
example:
WARNING If you provide the ip field in an import and have the
Enable User IP to Location Lookup
setting enabled, Iterable will automatically do a geoLookup and fill in the
city, country, region, state, and timeZone fields on the user
profile if this information is returned by the geo lookup. You can send blast campaigns and workflow campaigns at a specific local time.
In blast campaigns, you can choose this option in the final launch step of
the campaign creation process.
# Starting and fallback time zones for blast campaigns When scheduling a blast campaign, you have the option to choose both a
starting and fallback time zone (see below). The starting time zone is used to determine when the campaign will start
sending. No messages will be sent before the selected time in this time zone.
Anyone with a timeZone value that is east of the starting time zone (up
until the international date line) will receive the email at this starting
time. The fallback time zone will dictate when users who do not have the
timeZone field set will be sent the campaign. Say you set your email to send today at 3:00pm, with a starting time zone of
America/Chicago and a fallback time zone of `America/Honolulu``:
User Location
timeZone field Send time Note
Bob San Francisco, CA America/Los_Angeles 3pm PST/5pm CST
Sally New York, NY America/New_York 4pm EST/3pm CST Sally is east of the starting time zone, so she is sent the email immediately at 3pm CT.
Wendy San Francisco,CA 6pm PST/3pm HST Wendy doesn't have a timeZone on her user profile, so she is sentthe emailwith the fallback time zone.
Delaying a workflow until a specific time In workflows, you can send at a specific local time by adding a delay prior
to a message send node that will delay until a specific time:
View ArticleIterable uses data feeds to populate campaign messages with data pulled from
web services. Since Iterable can pass parameters to these services, each data
feed query can fetch data relevant to a specific user. This makes it possible
to use dynamically-queried data to send personalized, relevant messages. In Iterable, a single template can reference one or many data feeds, which
means that data from multiple sources can be used to customize a single
message. Iterable data feeds support web services that return JSON, XML, RSS,
or Atom data. This document describes how to use data feeds in an Iterable campaign.
# Set up a web service A data feed defined in Iterable retrieves its data by querying a web service. For example, the JSON data below might come from a web service that returns
product recommendations based on a user's prior purchases. The data includes:
Information about a user's past purchase Three recommended products, each of which includes a name, description,
price, and image URL.
{
"pastPurchase": "Hot Dog Halloween Outfit for Cats",
"suggestedProduct": [
{
"name": "Deluxe Cat Tree",
"description": "A jungle for your favorite feline buddy",
"price": 160,
"imageUrl": "http://img-cache.cdn.gaiaonline.com/0b4be3af7262e023cce39cffa697d4cd/http://i324.photobucket.com/albums/k331/michellepaints/CC_Cat_Tree.jpg"
},
{
"name": "Catnip Mouse Toy",
"description": "Cats go absolutely crazy for this realistic mouse toy!",
"price": 4,
"imageUrl": "http://www.crystalclearpet.com/shop/treats/images/catnip-large-mouse-11077a.jpg"
},
{
"name": "Set of 3 Furry Sticks",
"description": "Dangle this enticing toy in front of your kitty!",
"price": 5,
"imageUrl": "http://i01.i.aliimg.com/wsphoto/v1/1944996867/Freeshipping-font-b-Rabbit-b-font-font-b-Fur-b-font-Strip-Funny-Cat-Stick-Cat.jpg"
}
]
}
A sample web service for this data exists here: http://static.iterable.com/sample-data-feeds/sample_data_feed.json.
Click the URL to see the JSON it returns.
NOTE The web service queried by a data feed should use a response charset of
UTF-8.
# Customize the response for each user To personalize the data returned by a data feed for each of a campaign's
recipients, pass user-specific merge parameters to the data feed's URL. A
data feed URL that uses merge parameters might look something like the
following: http://host/sample_data_feed.json?{{#urlEncode}}email={{email}}{{/urlEncode}}
Here, the recipient's email is passed in double curly braces (Handlebars),
and it is URL-encoded by the #urlEncode helper. The web service hosted at
this URL must expect the passed-in URL parameters and use them to look up
personalized data. Before making a data feed query, Iterable replaces any parameters found in
its URL with values from a user's profile or with data included on the event
that triggered the campaign (using the POST /events/track
API endpoint). This makes it possible to use fields other than email
(such as userId).
NOTE Certain merge parameters related to the campaign itself, like
{{campaignId}} and {{campaignName}}, are generated at campaign send time.
These fields may appear blank when previewing the template with data.
# Data feed HTTP response codes When querying a data feed URL, Iterable interprets the resulting HTTP
response code as follows:
HTTP response code Meaning Iterable behavior
200 OK (Success) Data feed content will be used to customize a message template as necessary before sending
429 Too many requests Retry data feed call every three minutes, up to 20 times
4XX Invalid parameters or invalid feed URL Will not send
5XX Server error Retry data feed call every three minutes, up to 20 times
Other Unrecoverable error Will not send
Wikipedia provides more detail
about HTTP status codes.
# Data feed response times Iterable expects a data feed to return a complete response within ten
seconds; otherwise, it will retry the query three minutes later. After five
unsuccessful query attempts, Iterable will skip sending the message to the
user in question.
# Create a data feed to query the web service To use data feeds in a campaign, first define the data feeds in Iterable:
Navigate to Content > Data Feeds
For each necessary data feed, click the Create New Feed button and
provide the required information: #
Name: The name of the data feed. Used to select it when using it in
a campaign.
Format: The type of data the data feed will query from a web
service.
Template Handlebars Alias: An alias that can be used by a template
to reference data from this data feed.
For example, if the data feed returns a field1.field2 property,
setting an alias of my_alias allows a template to reference this data
as [[my_alias.field1.field2]]. Otherwise, the data would be
available as [[field1.field2]]. Data field aliases clarify which data feed an expression
references, especially in situations where a single template uses
multiple data feeds.
Authorization Token: An authorization token to include with the
data feed request. Click Add New Custom HTTP Header to add custom HTTP headers
required by the URL (as necessary).
# Reference data feeds in a template To reference a data feed in a template:
Create a template by navigating to Content > Templates and clicking
Create New Template. Alternatively, do this while creating a campaign. When entering text for the template's content, reference a data feed with
either:
Double square brackets
Double square brackets are the default way to access data feed
data. For example, the following expression references the price of the
first item in the suggestedProduct array of the data feed defined
above: [[suggestedProduct.[0].price]].
Double curly braces
Double curly braces are the default way to reference user profile
data.
However, if Advanced Options > Enable Template Generation Using Data Feeds > Merge the Data Feed and User Contexts
is enabled for the template, double curly braces can reference both
user profile data and data feed data.
For example, the following code references the price of the first item
in the suggestedProduct array of the data feed defined above:
{{suggestedProduct.[0].price}}. If the expression contained in double curly braces can reference either
a value from the user's profile or a data feed, Iterable will use the
user profile data.
Because of this, it's possible to write a single Handlebars
expression that pulls user profile data when it's available, but
otherwise uses data feed data.
# Using aliases to reference data feed data Templates can use aliases to reference data feed data, so long as:
The data feeds in question have aliases defined in Integrations > Data
Feeds. In the template,
Advanced Options > Enable Template Generation Using Data Feeds > Use Data Feed Alias is enabled.
For example, a template might reference a data feed having alias my_alias
by using syntax such as: [[my_alias.suggestedProduct.[1].price]].
# Example template Here is an example of a template that uses data from both a data feed and a
user profile:
# Integrate data feeds into a campaign Iterable can query data feeds at campaign send time (once per recipient, to
maximize personalization) or at campaign design time (only one time,
minimizing load on the server that hosts the web service). These two options
are described in more detail below.
# Querying data feeds at campaign send time (once per recipient) The most common way to fetch a data feed is at campaign send time, once per
recipient. With this approach, data from the feed is both up-to-date and
customized for the recipient (assuming user-specific merge parameters are
included in the data feed's URL). To have a campaign query data feeds at send time for each recipient:
When creating a campaign, on the Select Template step, select the
template whose contents reference the data feeds in question. Scroll to the bottom of the screen and click Continue to Design. Navigate to the Advanced options tab.
Select data feeds:
Check Enable Template Generation Using Data Feeds. Click the text input below the checkbox to view a list of the data
feeds available to the project. Select all necessary data feeds (select one or many, as necessary).
Set other data feed options on the Advanced options tab:
Aliases
If the template's contents use aliases (as defined for each data
feed in Content > Data Feeds) to reference data feeds,
select the Use Data Feed Alias checkbox. For example, a data feed might have an alias such as my_alias.
With Use Data Feed Alias enabled, the template can access the
data feed's data as follows: [[my_alias.field1.field2]]. Otherwise,
this data would be available as [[field1.field2]]. Aliases can make templates more readable and provide a way to
disambiguate between two similar data feeds.
Merging data feed and user contexts If the selected template uses curly braces to reference data feeds,
enable Merge the Data Feed and User Contexts.
Caching
To cache the template's data feeds (to reduce load on the servers
that host them), select the Cache Data Feed Response checkbox. For each recipient, Iterable will determine the data feed URL to
query by substituting parameters from the user's profile into the
data feed's pre-defined URL (as necessary). If that URL has been
cached within the past hour, the cached response will be used;
otherwise, Iterable will query the URL.
NOTE Iterable will re-cache the data feeds for a template every hour while
sending the campaign.
Save the template by scrolling to the bottom of the page and clicking
Save Template.
Preview how the template will render with data feed data:
Click Preview and select Preview with Data. On the Preview with Data screen, in the Load User Data text
input, enter an email address associated with a user profile. Click
Load User Data.
Under Load Data Feed data, select the data feed to use while
previewing the template. Click Load Feed, and the data feed will
load.
NOTES
It is only possible to preview one data feed at a time. If your
template relies on multiple data feeds, preview each one
sequentially.
If your template uses an alias to reference a data feed, for the
Preview With Data screen to work properly you must manually edit
the feed's loaded data and wrap it in a top-level element with the
same name as its alias. For example, for a data feed having alias
my_alias, wrap the data as follows: { "my_alias": { "field1": { "field2": "testing" } } }
Examine the preview to make sure it looks as expected. Remember, if the
data feed changes prior to the campaign being sent, the actual campaign
will differ from the preview.
# Querying data feeds at campaign creation time Alternatively, Iterable can query a data feed one time during campaign setup,
immediately integrating that data into the campaign's copy of the template.
This minimizes load on the server that hosts the data feed, since the HTTP
request is made only one time. However, with this approach it is not possible
to personalize the data feed request for a specific user. To query a data feed during campaign creation:
When creating a campaign, on the Select Template step, click on the
template whose contents reference the data feed in question. Scroll to the bottom of the screen and click Use Template with Data Feed.
In the Select Data Feed to Merge Into Template modal window that
appears, select the data feed from which data should be queried. Click
Use This Data Feed.
NOTE When querying a data feed at campaign creation time (as opposed to send
time), it is only possible to use reference one data feed in a template.
To preview the template:
Click the Preview button and choose Preview with Data. Verify that the template renders as expected.
Finish setting up the campaign On the bottom of the Edit Template screen (part of campaign setup), click
Save & Continue to Review to finish setting up the campaign.
View ArticleUsing Kickdynamic with Iterable enables you to streamline email template
creation and populate your emails with dynamic content that renders at the
time of open.
NOTE This integration requires an Iterable account and
a Kickdynamic account. If youre not already an Iterable client,
request a demo
to discuss the how the Iterable and Kickdynamic integration can work for you.
# Image tag integration into template HTML The Kickdynamic image tag integration into Iterable is extremely light
weight. Once a campaign has been set up in Kickdynamic, a dynamic tag will be
displayed similar to the tag below. The image tag can include merge
parameters, which will be populated by Iterable at the time of send based on
Iterable CRM data.
This screenshot shows an example image tag produced by Kickdynamic: #
Login to your Iterable account and navigate to the email template where
you would like to insert the Kickdynamic content and paste it here:
Thats it. Your emails will now render Kickdynamic content upon send.
NOTE You can also pre-render this content using the Preview function
located at the bottom of the page shown above.
Other ways to integrate Kickdynamic Kickdynamic also supports the following integration methods. Please contact
your Kickdynamic CSM to set them up if the image tag integration does not
suit your needs.
API (JSON) CSV XML
View Article
Iterable partners with
Stitch Data to enable
clients to export and replicate all their Iterable data in the data warehouse
of their choice.
NOTE This integration requires an Iterable account and a
Stitch Data account. If youre not already an Iterable client,
request a demo
to discuss how the Iterable and Stitch Data integration can work for you.
# Table of contents
Add Iterable as a Stitch Data Source
Generate an Iterable webhook URL
Set up webhooks in Iterable
Replication
Webhooks and historical data
Method
Query for the latest data
Schema
Webhook URLs & security
# Add Iterable as a Stitch Data Source
Sign in to your Stitch account. On the Stitch Dashboard page, click the Add Integration button. Click the Iterable icon.
Enter a name for the integration. This is the name that will display on the Stitch Dashboard for the
integration; itll also be used to create the schema in your destination.
For example, the name Stitch Iterable would create a schema called
stitch_iterable in the destination.
WARNING Schema names cannot be changed after you save the integration.
Click Save Integration.
# Generate an Iterable webhook URL
Once Stitch has successfully saved and created the Iterable integration,
youll be redirected to a page that displays your Iterable webhook URL and
token (which is blurred in the image below): set up webhooks in Iterable
Click the Copy button to copy it. Note that this particular URLwon'tdisplay in Stitch again once you click
Continue. Think of this URL like you would your login or API credentials:
keep it secret, keep it safe. You can, however, generate another URL
should you need it. Onceyou'vecopied your webhook URL, click Continue to wrap things up
in Stitch.
# Set up webhooks in Iterable The last step is to set up webhooks in your Iterable account.
Sign into your Iterable account. Click Integrations > System Webhooks. In the Endpoint field, paste your Stitch-generated webhook URL. Click Create Webhook. After the webhook is saved, click the Edit button on the far right to
select the events you want to track.
Check the events you want to track:
Your changes will save automatically. Youre good to go.
# Replication Afteryou'vesuccessfully connected your Iterable integration, Stitch will
continuously replicate your webhook data into your data warehouse.
# Webhooks and historical data Because Iterable data is sent to Stitch in real-time, this means that only
new records are replicated to your data warehouse. Most webhook-based
integrationsdon'tretain historical data due to this as-it-happens approach. In the event that our webhook service experiences downtime, you may notice
some lag between an event occurring and the data appearing in your data
warehouse.
# Method This version of Stitchs Iterable integration uses append-only replication.
Append-only replication is a type of incremental replication where newly
replicated data is appended to the end of a table. Existing rows are not
updated; updates are added to the end of the table as new rows. Data stored
this way can provide insights and historical details about how those rows
have changed over time.
# Query for the latest data If you simply want the latest version of the objector objects, if you
elected to track more than one during the setupin the integrations table
(data), youll have to adjust your querying strategy to account for the
append-only method of replication. This is a little different than querying
records that are updated using updated_at incremental replication. To do this, you can use the _sdc_sequence column and the tables primary key.
The _sdc_sequence is a Unix epoch (down to the millisecond) attached to the
record during replication and can help determine the order of all the
versions of a row.
NOTE If you didnt define a primary key while setting up the integration,
the primary key for the table will be _sdc_primary_key.
If you want to create a snapshot of the latest version of this table, you
could run a query like this: SELECT * FROM [stitch-redshift:stitch-iterable.data] o
INNER JOIN (
SELECT
MAX(_sdc_sequence) AS seq,
[primary-key]
FROM [stitch-redshift:stitch-iterable.data]
GROUP BY [primary-key]) oo
ON o.[primary-key] = oo.[primary-key]
AND o._sdc_sequence = oo.seq
This approach uses a subquery to get a single list of every rows primary key
and maximum sequence number. It then joins the original table to both the
primary key and maximum sequence, which makes all other column values
available for querying.
# Schema In v1 of the stitch incoming webhooks integration, Stitch will create a
single tablecalled datain the webhook integration schema (this will be
the name you enter in the Integration Schema field when you set up Iterable)
of your data warehouse. The schema of this table will contain two types of columns:
Columns used by Stitch (prepended with _sdc) Columns sent by the providers webhook API
Aside from the Stitch columns, the schema of this table will depend entirely
on Iterables webhook API. With the exception of the _sdc fields, Stitch does
not augment incoming webhooks data nor does it have any control over the
fields sent by the webhook provider.
# Webhook URLs & security Stitch allows you to generate up to two Iterable webhook URLs at a time. These
URLs contain security access tokens and as such, have access to your Iterable
account. If you ever need to change your webhook URL, you can do so in the
Integration Settings page after the integration has been created:
Click into the integration from the Stitch Dashboard page. Click the Settings button. In the Webhook URLs section, click the Generate Webhook URL button. A new webhook URL will display. Press the clipboard icon to copy it. Follow the steps in the
section to update the webhook URL in Iterable.
Afteryou'veupdated the webhook URL in Iterable, click the Revoke button
next to the oldest webhook URL in Stitch. This will invalidate the token and
revoke access.
View Article
Iterable can ingest Zendesk
webhooks to enable the automation of user profile updates and messaging
campaigns based on user actions taken and tickets filed in Zendesk.
NOTE This integration requires an Iterable account and a
Zendesk account. If youre not already an Iterable client,
request a demo
to discuss how the Iterable and Zendesk integration can work for you.
# Instructions You must have Zendesk admin access to set up this integration. Reference
this Zendesk support doc
for further help setting up the webhook in Zendesk.
# Create an API key in Iterable
Sign in to Iterable account at https://app.iterable.com/login/.
Navigate to Integrations > API Keys. /events/track
Click Create New API Key.
For the key type, select JavaScriptSDK. Click Create. Copy the API key from the Key column of the Existing API Keys table.
# Create a webhook in Zendesk
NOTE This example demonstrates how to create a Zendesk webhook that will post an event to
Iterable's /events/track
endpoint. You can also use this method to update information on the user
profile simply by mapping the webhook (or Notify Target, as Zendesk refers
to it) to the /users/update
endpoint.
In Zendesk Support, click the Admin icon
()
in the left sidebar. Then, select Settings > Extensions. Click the Targets tab and click Add Target.
Select HTTP Target. You will be taken to a page similar to this
screenshot:
For the URL, enter the following: https://api.iterable.com/api/events/track?apiKey=[YOUR_API_KEY]
For Method, choose POST. For Content type, choose JSON.
Click Submit. You will be taken to a page where you can test a call to Iterables
endpoint with your proposed JSON body. Please note that you need to
structure the JSON body in accordance with the Iterable endpoint the
Zendesk Webhook is pointing at. Please refer to Iterable's
API docs
for examples.
In a new browser tab, open Business Rules > Triggers.
Click Create New Trigger and set up your logic. It should look something like this:
In the Actions section, map the trigger to the webhook you just
created.
For the first dropdown, select Notify Target. For the second dropdown, select Title of the webhook defined in
step 3.
Provide a JSON body.
Format the JSON payload as specified by Iterable's
API. The JSON body should look similar to the screenshot above, and
must contain an email and eventName parameter.
Add merge parameters (placeholders) directly in the JSON body as
necessary. For a list of available placeholders, click on the
View Available Placeholders link, which will bring up a list
similar to the following:
Example JSON body: {
"email": "{{current_user.email}}",
"eventName": "New Zendesk Ticket Created",
"dataFields": {
"Ticket_Id": "{{ticket.id}}",
"Ticket_Description": "{{ticket.description}}",
"Ticket_Priority": "{{ticket.priority}}"
}
}
Copy the JSON body into the webhook configuration in the previous
browser tab.
Click Submit. If youdon'tget an error code, login to your Iterable account and check
the event under the test users email you used. Onceyou'veconfirmed Iterable ingested the test event, confirm that the
trigger is active.
Your automated webhook from Zendesk to Iterable is now set up and you can use
events ingested from Zendesk to trigger messaging campaigns.
View Article
This document describes metadata stores, a way to save data in Iterable
and use it to personalize message campaigns.
IMPORTANT
Iterable will sunset metadata store APIs and the #metadata Handlebars
helper in favor of Catalog
on March 10, 2020. Contact your Iterable CSM to discuss adding Catalog to
your plan. For information about differences between Catalog and metadata stores,
see Using Catalog.
# Table of contents
What is a metadata store?
Do I need a metadata store?
How do I set up a metadata store?
How do I edit an existing metadata store?
How do I use my metadata in an email template?
What is the maximum size for a metadata store entry?
Can I use a metadata store to store and insert HTML snippets?
Further reading
# What is a metadata store? A metadata store is a database of data fields that are common across your
project. By using it, you can insert common fields into your messages
without having to send them with event tracking API calls. For example, consider a food delivery service with a central list of
restaurant information. This company might use the metadata store to
look up and insert an individual restaurant's information into its
emails, without having to pass along lots of data on event tracking
API calls.
# Do I need a metadata store? If you have a large amount of data that is common to all your users, and
you're commonly referencing that data in your emails, you might want to
consider setting up a metadata store. If you're unsure, feel free to
email [email protected] for more information.
# How do I set up a metadata store? Use the PUT /metadata/{table}/{key}
API endpoint to add entries to a metadata store. Metadata stores save
entries as key-value pairs (the keys being used to look up the
data again in the future). When calling this API, the request body must have a value key
associated with an object containing the item's details: {
"value": {
"field1": "ABC",
"field2": "DEF"
}
}
For example, the following API calls store data in a restaurants
metadata store:
Korean Restaurant
URL: PUT /metadata/restaurants/koreanrestaurant
Request body:{
"value": {
"name":"Korean Restaurant",
"hours":"10am-2pm",
"bestitem":"Galbi"
}
}
Boba Place
URL: PUT /metadata/restaurants/ilyasbobaplace
Request body:{
"value": {
"name":"Ilya's Boba Place",
"hours":"3pm-5am",
"bestitem":"Green Tea Latte"
}
}
Fancy Restaurant
URL: PUT /metadata/restaurants/fancyrestaurant
Request body:{
"value": {
"name":"Fancy Restaurant",
"hours":"12pm-10pm",
"bestitem":"Prix fixe"
}
}
# How do I edit an existing metadata store? Update an existing metadata store using the
PUT /metadata/{table}/{key}
API endpoint. Include the entire object to ensure that all the unchanged
fields are preserved. For example, to edit the hours of the Korean Restaurant defined
above, include all of the restaurant's data fields, even though name
and bestitem have not changed:
URL: PUT /metadata/restaurants/koreanrestaurant
Request body: {
"value": {
"name":"Korean Restaurant",
"hours":"9am-3pm",
"bestitem":"Galbi"
}
}
```
# How do I use my metadata in an email template? Use Handlebars to insert data from a metadata store in a message template. For example, you might use a favRestaurant user profile field to look up
a user's favorite restaurant in a restaurants metadata store, and then
reference its bestItem: {{#metadata "restaurants" favRestaurant as |restaurantInfo|}}
The restaurant's best item is {{restaurantInfo.bestitem}}
{{else}}
The restaurant's best item could not be found!
{{/metadata}}
Using the example data from above, a user whose favRestaurant is
bobaPlace would see a message mentioning its Green Tea Latte. If the user profile doesn't have a favRestaurant value, or if the
restaurants metadata store doesn't have a match for the profile's
favRestaurant value, the message would instead display "The restaurant's
best item could not be found!" To suppress the message instead of displaying alternative text, use the
required=true attribute: {{#metadata "restaurants" favRestaurant required=true as |restaurantInfo|}}
The restaurant's best item is {{restaurantInfo.bestitem}}
{{/metadata}}
# What is the maximum size for a metadata store entry? Each entry must be 30KB or less.
# Can I use a metadata store to store and insert HTML snippets? Yes, with the caveat that each HTML snippet must be 30KB or less. Use the PUT /metadata/{table}/{key}
to store the HTML snippet in the metadata store. Insert the snippet in
the snippet into an email template using Handlebars logic.
# Further reading
Catalog Overview Using Catalog Catalog Items Defining Data Types for Catalog Item Fields Collections Using Collections in Messages Catalog Issues and Limitations Catalog APIs API Overview and Sample Payloads Metadata Store APIs
View Article
support site Welcome to Iterable, your agile and user-friendly growth marketing platform
that allows you to send the right message, to the right device, at the right
time! We've created a list of useful shortcuts that will show you how to carry out
your most important tasks.
# What is your role at your company?
Email Marketer Email Designer Integration Engineer Mobile Engineer Data Analyst
# Common tasks
# Setting up Iterable for the first time?
Setting up a new Iterable project Set up user roles and permissions Add a new project Delete a project
# Managing your customers?
Import user lists Create a new list View a user profile
# Creating or modifying an email campaign?
Create a new blast campaign Schedule a recurring blast campaign Create a new triggered campaign Clone an existing campaign Archive an existing campaign Cancel, reschedule, or abort an existing campaign View the results of a completed campaign Create a new email template from scratch (no HTML experience)
# Trying to set up more advanced campaign logic using workflows?
Create a new workflow Troubleshoot a workflow Setup custom events in workflow
# Creating a new template?
Upload HTML file for email template (from PC/from website) Create a new email template from scratch (HTML experience) Sending push notifications Create a new SMS template Personalize a template with user data or event fields Personalize a template with data feed Create templates with multi-language support Preview a template with real user data or a data feed
# Managing existing templates?
Revert back to a previous version of a template View the history of changes for a template Clone an existing template
# Setting up your tools to work with Iterable's API?
View API documentation Create, edit, or delete API keys Create, edit, or delete webhooks Create, edit, or delete data feeds Setup custom event API calls Import user lists via API Add JS snippet to call Iterable API
# Integrating Iterable with one of your existing platforms?
Set up Mixpanel integration Set up Segment integration Set up mParticle integration Set up Magento integration Set up Zapier/SurveyMonkey integration Integrate with other services
# Setting up mobile integrations?
Set up iOS push notifications Set up Android push notifications Disable push notifications View API documentation Frequently Asked Questions Setup in-app messages
# Performing data analysis?
Set up an A/B experiment View the metrics of a completed campaign Understand email campaign metrics Understand SMS campaign metrics Understand push notification campaign metrics Understand A/B experiment analytics View the aggregated metrics for multiple campaigns Export campaign results Setup custom conversion tracking Track purchases and revenue
# Other questions? Have more questions that aren't covered in the handbook? Check out our or contact our
wonderful Customer Success team!
View Article
This section will cover best practices around testing and troubleshooting
your deep links. #
# Table of contents
Testing deep links
Troubleshooting deep links
Mail Domain is not verified
Links are not rewritten
Links are rewritten as /u instead of /a
Universal links are not launching app
# Testing deep links
If the email deep link is clicked but it does not take you directly into
the app (and instead you are directed to a mobile-web browser), please:
Ensure the AASA file is properly formatted. This Branch tool should help. Ensure the AASA file is available at the end of your domain under: https://yourdomain/apple-app-site-association.
Ensure Your file is served over HTTPS (not HTTP).
Ensure the mobile app is configure to deep link in Xcode Capabilities. Re-download your provisioning profiles in Xcode.
If the email deep link opens the app directly but not to the content you
expected, please:
Review your URL handing methods. Review your deep links schema
# Troubleshooting deep links Below is an end-to-end schematic for Troubleshooting Deep Linking
# Mail Domain is not verified Make sure you have secure protocol set up to comply with HSTS. Make sure you
have added following while creating SSL certificate:
Origin SSL Protocols: check only TLS1.2 Origin Protocol Policy: HTTPS Only
Also Make sure you have added CNAME and A record to your domain's DNS Settings.
# Links are not rewritten HTTPS is required for deep linking. Make sure you have enabled HTTPS in
Project Settings > Main Domain > Tracking Domain.
# Links are rewritten as /u instead of /a Enable Deep Link Rewriting in the Mobile Deep Linking section of
project settings.
Universal links are not launching app Make sure your app has associated domain set to launch the app. For iOS, add an associated whitelabel domain in Xcode, under
Capabilities > Associated Domain. For Android, add <intent-filter> with <host> and <scheme>. <intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="links.iterable.com" android:pathPrefix="/a/" android:scheme="http"/>
<data android:host="links.iterable.com" android:pathPrefix="/a/" android:scheme="https"/>
<data android:host="demo-app.iterable.com" android:pathPrefix="/" android:scheme="https"/>
</intent-filter>
View Article
This section covers out integrations with partners to execute third-party
deep linking within Iterable. This will enable you to track deep links within
Iterable and with attribution partners.
WARNING You must set up iOS and Android deep linking before these integrations
will work. To do so, please read iOS Universal Links Setup and
Android App Links Setup.
Universal links allows you to automatically convert your email links into
multi-platform deep links that take users directly to content in the app on
mobile devices, while still maintaining the same web experience for desktop
and mobile users without the app.
# Table of contents
Branch integration overview
Set up your click tracking domain
Branch installation
Branch contact
AppsFlyer integration overview
AppsFlyer mobile setup
Set up your click tracking domain
AppsFlyer contact
# Branch integration overview [email protected] Branch provides one of the leading cross-platform linking and
attribution platform with solutions that unify user aquisition and
measurement across different devices, operating systems, and channels.
# Set up your click tracking domain Within Iterable, you must set up a custom click tracking domain. Add and verify a custom click tracking domain in the [Mail Domains] page of
your Iterable account: After you added and verified a click tracking domain you have to update DNS
CNAME for it and point it to thirdparty.bnc.lt. Once the CNAME record is
added, please allow up to an hour for Branch to generate SSL and AASA files
for your click tracking domain.
# Branch installation Please review Branch Documentation
to see the rest of the integration.
# Branch contact [email protected]
# AppsFlyer integration overview AppsFlyer is one of the leading attribution platforms and
include a deep-linking solutions that measures attribution and acquisition
across different devices, operating systems, and channels.
# AppsFlyer mobile setup Please follow the guide on the AppsFlyer site
and confirm your deep linking is working within their system before trying to
integrate with Iterable.
# Set up your click tracking domain Within Iterable, you must set up a custom click tracking domain. Add and verify a custom click tracking domain in the [Mail Domains] page of
your Iterable account: After you added and verified a click tracking domain you have to update DNS
CNAME for it and point it to *.onelink.com/ Once the CNAME record is added.
# AppsFlyer contact
View Article
Deferred deep linking allows a user to click on a link, install an app
associated with the link, and then visit the content associated with that
link in the newly installed app.
WARNING To enable this feature, contact your Iterable CSM.
#
# Table of contents
Overview
iOS deferred deep linking
Android deferred deep linking
# Overview Deferred deep linking
allows a user who does not have a specific app installed to:
Click on a deep link that would normally open content in that app. Install the app from the App Store. Open the app and immediately see the content referenced by the link.
As the name implies, the deep link is deferred until the app has been
installed. After tapping a deep link in an email from an Iterable campaign, users
without the associated app will be directed to the App Store to install it.
If the app uses the Iterable iOS SDK and has deferred deep linking enabled,
the content associated with the deep link will load on first launch.
# iOS deferred deep linking Set IterableConfig.checkForDeferredDeeplink to true to enable deferred
deep linking with the Iterable iOS SDK. This should be added to the
beginning of your
application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?)
method. Swift let config = IterableConfig()
config.checkForDeferredDeeplink = true
Android deferred deep linking In the Android SDK, call the setter method
IterableApi.getInstance.setDDLChecked passing in true to enable deferred
deep linking. This should be added to your Application class within the
onCreate() method along with the other IterableApi initializations. Java IterableApi.getInstance().setDDLChecked(true);
View Article
When you use iOS Universal Links in your messages, users who are using iOS 9
and up can tap a link to your website and get seamlessly redirected to your
installed app without going through a browser, all while having the links
tracked within Iterable. #
WARNING You must set up HTTPS link tracking before following the steps in
this guide.
# Table of contents
Setup
Example file
FAQ
What happens if a user doesn't have my app installed but clicks on a Universal Link?
Will this work on Android too?
Will this work for users on iOS versions lower than 9?
Can I have more than one apple-app-site-association for my domain?
Will this work for subdomains (cats.example.com) or only the top level domain (example.com)?
What should an apple-app-site-association file look like? How does all this work?
Can you illustrate the flow in a more graphical form?
Can I use wildcards in my apple-app-site-association file?
Do I need to include the Iterable appID section in my app-app-site-association file?
# Setup
Determine which links you want to redirect to your iOS application. Identify the target pages and their corresponding URLs that you want to
send users to via Universal Links. For example, if you are a home browsing app, you may want /homes/
schema to securely redirect all your users to the home browsing section.
Create an apple-app-site-association file. Once you have determined which URLs to link to, create an
apple-app-site-association file that will contain the redirect rules
to the URLs you have identified in step 1. This file is a JSON object
that determines which links to rewrite into Universal Links. Below is a sample one you can use. The file name does not matter but it
must be a JSON file. You can read more about creating apple-app-site-association files in
Apple's developer documentation. Iterable will use your apple-app-site-association file to determine
which links in your messages to rewrite into iOS Universal Links.
NOTE After the links have been rewritten by Iterable, they will appear in this
format:
Normal track and redirect URLs:
mydomain.com/u/samplepath
iOS Universal Links:
mydomain.com/a/samplepath
# Example file {
"applinks": {
"apps": [],
"details": [
{
// The App Id is found on the apple developer account
// the bundle ID is found in Xcode General section
"appID": "appID.bundleID",
"paths": [
//The /a/* is all you need here
"/a/*"
]
},
{
"appID": "iterable",
"paths": [
//PATHS TO BE REDIRECTED GO HERE
//For Example: This is your path to show a product
"/product/*",
//This maybe to show your credentials page
"/credentials/*"
//This would prevent a deep link to a certain section
"NOT /email-confirmation/*",
]
}
]
}
}
Email your apple-app-site-association file to [email protected]. After we process the file, you can view it on the bottom of the
project settings screen (Settings > Project Settings).
Set up your iOS application to handle Universal Links
Add your whitelabeled domain (for example,
links.YOUR_COMPANY_NAME.com) to the Associated Domain in your Xcode
Capabilities. You can read more about it in
Apple's developer documentation.
You also need to whitelabel your account by updating your CNAME record
to point to Iterable, under Settings > DNS Setup. For more
information on updating your DNS records, read
Sending Your First Campaign.
Next, From your application's restorationHandler,
call the getAndTrack on IterableApi, along with a callback to handle
the returned original URL to deep link to the appropriate page.
IterableSDK (4.3.0+):
Swift: func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
guard let url = userActivity.webpageURL else {
return false
}
// This will track the click, retrieve the original URL and call `handleIterableURL:context:` with the original URL
return IterableAPI.handle(universalLink: url)
}
Objective-C: - (BOOL)application:(UIApplication *)application continueUserActivity(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
// This will track the click, retrieve the original URL and call `handleIterableURL:context:` with the original URL
return [IterableAPI handleUniversalLink:userActivity.webpageURL];
}
Without the SDK: Add this code snippet
to your continueUserActivity instead of calling the SDK's built-in
getAndTrackDeeplink function.
NOTE The apple-app-site-association file is obtained when the app is
installed or updated, so you'll need to release a new version of the
app before all your existing users see the new path.
Here is some sample code that shows how you can handle Universal
Links within your app: func application(_ application: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
print("Clicked on link: \(userActivity.webpageURL?.absoluteString)")
IterableAPI.getAndTrackDeeplink(userActivity.webpageURL!, callbackBlock: {
(url) in
print("Handle Original URL deep link: \(url)");
});
return true
}
Set up HTTPS for your links domain Follow the instructions here
to set up HTTPS for your domain so that your AASA file is correctly read.
Set up your website to handle Universal Links Ensure that your website is set up to handle Universal Links, so that
users who do not have an app set up for Universal Links will get
gracefully redirected to the corresponding link on your website. We recommend that you mirror your iOS and website paths in order to
improve maintainability of the redirection logic over time.
Congratulations, you are now ready to test your iOS Universal Links!
# FAQ
# What happens if a user doesn't have my app installed but clicks on a Universal Link? The user will get directed to your website in his/her browser like a normal
link, as long as your website has been set up to handle Universal Links (see
step 5 above).
# Will this work on Android too? Yes! Please go to the next section titled Android App Links Setup.
# Will this work for users on iOS versions lower than 9? Unfortunately, iOS 9 is the minimum requirement for Universal Links to work
on the user's device.
# Can I have more than one apple-app-site-association for my domain? Each domain can only have a single apple-app-site-association file.
# Will this work for subdomains (cats.example.com) or only the top level domain (example.com)? We now rewrite URLs for subdomains as well as top-level domains.
# What should an apple-app-site-association file look like? How does all this work? Here's a sample apple-app-site-association file that we will use to walk
through the entire process: {
"applinks": {
"apps": [],
"details": [
{
"appID": "appID.bundleID", <-- Add Your AppId from Itunes Connect and Bundle ID from Apple developer site
"paths": [
"/a/*" <-- [RULE 1] Mandatory rule required in all Iterable association files
]
},
{
"appID": "iterable", <-- Add Your AppId from Itunes Connect
"paths": [
"NOT /samplepath/toignore", <-- [RULE 2] Tells Iterable to write as regular (non-Universal) link
"/samplepath/*" <-- [RULE 3] Tells Iterable to rewrite into Universal Path
]
}
]
}
}
WARNING Only edit the content with notes next to it.
When you send that file to Iterable, we store a copy of it on our servers.
When you send a message, the following happens:
Iterable goes through each link in the message and compares it to the list
of rules in the apple-app-site-association file to see if there is a
match. For this example, let's assume that one of your links is
yourdomain.com/samplepath/hello.html. If there is a match, Iterable will rewrite the link before sending it out
in your message. In this example, yourdomain.com/samplepath/hello.html
matches RULE 3 above and will be rewritten into
yourdomain.com/a/ABCD1234, where ABCD1234 is a unique identifier for that
link (you don't have to worry about this unique identifier). At this point, Iterable also stores a mapping of /a/ABCD1234 to
/samplepath/hello.html on the Iterable servers. When a user clicks on the rewritten link /a/ABCD1234, the user's device
will detect it based on RULE 1 in the apple-app-site-association file (a
copy of the file is stored on device) and opens your app based on the appID
in the file. Your app then uses the Iterable SDK to make a call to Iterable's servers
to track the click and get the actual destination /samplepath/hello.html. Your app receives /samplepath/hello.html from the Iterable server and
opens the destination within your app.
# Can you illustrate the flow in a more graphical form? Sure thing! Here's a similar example for iOS Universal Links to the
snapface.com domain.
# Can I use wildcards in my apple-app-site-association file? Yes, you can use * to specify an entire section (matches all substrings) or ?
to match any single character. You can combine both wildcards in a single
path, such as /foo/*/bar/201?/mypage which would match
/foo/abc/bar/2015/mypage and /foo/def/bar/2019/mypage. For more details, check out Apple's documentation here.
Do I need to include the Iterable appID section in my app-app-site-association file? Yes. The purpose of the Iterable appID section is to provide more control
over which paths get rewritten by Iterable. If you want a subset of paths to
be opened in Iterable but not the others, then placing those paths under the
Iterable appID section will limit rewriting to those paths. If you want all paths to be rewritten, use: {
"appID": "iterable",
"paths": ["*"]
}
View Article
# Table of contents
Overview
Testing
1. Navigate to Contact Lookup
2. Look up your specific user
Troubleshooting
User profile not found in iterable
Update user profile is failing
dataTypeMismatch while updating user profile
Invalid API key
Error:4XX email already exists
Duplicate users in Iterable
# Overview Typically it is fairly easy to troubleshoot the User Profile within Iterable.
You will just want to ensure that the correct userId or email has the
most up to date information from your testing. You can view individual user
profiles in Iterable by going to Audiences > Contact Lookup Section as
shown below.
NOTES
You can store a soft limit of 1,000 user parameters on your user profiles If you are only identifying the user on the IterableAPI.userId call, then
Iterable assumes you do not know the email of the user yet and will create a
placeholder email called [email protected]. We will
discuss in the next section how we can update the email of an unkown user.
You will also want to confirm:
You are using the correct userId or email. You do not have any duplicate IterableAPI.email = "[email protected]" calls. You have the correct API key for that project. That API key has userUpdate priviledges.
# Testing To verify is the user profile is being generated and set with relevant
information, go to Audience > Contact Lookup > Enter Test Email Address
and search. This should return a user profile with email address and userId
(if set).
# 1. Navigate to Contact Lookup #
# 2. Look up your specific user
# Troubleshooting
# User profile not found in iterable
Make sure you are looking in the correct project, user profiles created
and updated with sandbox project won't appear in productions and vice versa. Make sure you are setting an email after Iterable SDK is initiated.
# Update user profile is failing We recommend using email id as primary key when updating user's profile. If
you use userId as a primary key to update user'r profile, you may run into
duplicate record error.
# dataTypeMismatch while updating user profile This error occurs when you pass a differnt data format for an existing field.
Make sure all your data formats match when making update user profile call.
# Invalid API key Verify your API key is valid. Make sure you are using a mobile API key or
standard API key in the app.
# Error:4XX email already exists If you are updating existing user with new known email address, make sure you
are using 'merge': true in the request. This will merge new data with
existing user without trying to create or override existing user fields.
Duplicate users in Iterable This can happen when apps aren't synchronized with updated user profile. When
a user updates their email address on web app, this will update a current
user with with an updated email address. If user's mobile app is not
sychronized to get updated user profile, when user accesses mobile app later,
register device token can create a new user with old email address. Make sure you are not calling register device token method on outdated email
address.
View Article
Below are some recommended (but optional) additions to your user update
mobile code.
# Table of contents
Attribution on user profile
User logout and endpointEnabled
endpointEnabled Why will a token be set as invalid?
Session counter best practices
Hiding user properties
NOTES Don't feel like you need to integrate this section unless these use cases are
relevant to your business.
# Attribution on user profile You can attach third-party attribution data to the user profile to leverage
in your own campaign. For example, if you know a user came from an
advertisement campaign for benefits over your competitors, you may want to
leverage those features in a push campaign. Each mobile attribution provider has their client-side methods for returning
attribution data at time of the app launch. Below are some top mobile
attribution and links to their documentation for returning attribution data.
AppsFlyer Branch Adjust
You can attach the response of these methods to the Iterable User Profile and
leverage those results in your owned media.
# User logout and endpointEnabled When the user logs out of your app, you also want to make sure you disable
the user from receiving push notifications for the previous user. You will
want to call the method below when your user logs out. Swift disableDeviceForCurrentUser()
Java IterableApi.getInstance().disablePush();
# endpointEnabled Device tokens are required to communicate with specific devices. When a
mobile platform (such as APNS or GCM) informs that token is invalid, we set
endpointEnabled to false.
# Why will a token be set as invalid? A token can be set invalid by any of the following:
When disableRegistrationToken has been called explicitly. While using SDK, if app doesnt set autoPushRegistration to false. When
autoPushRegistration is set to true SDK automatically enables and
disables the token. When app is uninstalled.
# Session counter best practices The best methodology for tracking sessions is to add a counter client-side
and then update the user profile on each subsequent app launch.
NOTES You will likely not want to include Sessions as an Iterable Track Call
because sessions typically occur 20x-40x more than any other event! This
flooding of events will create a lot of noise and make it difficult to
navigate towards signaling events.
Navigate to the AppDelegate file in your Xcode and add this code to your applicationDidBecomeActive: Swift func applicationDidBecomeActive(_ application: UIApplication) {
// get current number of times app has been launched
let currentCount = UserDefaults.standard.integer(forKey: "launchCount")
// increment received number by one
UserDefaults.standard.set(currentCount+1, forKey:"launchCount")
// return counter
let iter_session_counter = UserDefaults.standard.integer(forKey: "launchCount")
IterableAPI.updateUser(["iter_current_app_session_counter":iter_session_counter], mergeNestedObjects: false, onSuccess: myUserUpdateSuccessHandler, onFailure: myUserUpdateFailureHandler)
}
# Hiding user properties Sometimes people make mistakes and you may accidentally record a user
property wrong within your Iterable production instance (yikes!). There is
however an easy fix to hide unnecessary data. Navigate to the
Project Settings of your Iterable project and scroll down to the
User Properties listings. You can select which User Properties you'd like to view in your project,
which will hopefully save your team a lot time and effort. For more
information, please checkout our Project Settings documentation.
View Article
Updating the User Profile reflects the most recent information about a user.
User Profile data enables you to:
Populate any Iterable channel (Email, Inapp, Push, SMS, etc..) with
personalized information later with Handlebars
Flag users for A/B testing, cohorting and Segmentation Start a user journey
A user profile value can be a value like first name, or a dynamic value that
changes, such as the date of last login or the number of times the user
purchases a food.
# Table of contents
How to make the updateUser call
When to make the updateUser call
NOTES
You can store a soft limit of 1,000 user parameters on your user
profiles. If you feel you may go over this, please reach out to your Iterable
point of contact and request it to be raised. Again, if you are only identifying the user on the IterableAPI.userId
call, then Iterable assumes you do not know the email of the user yet and
will create a placeholder email called [email protected].
We will discuss in the next section how we can update the email of an unkown
user.
# How to make the updateUser call Iterable can handle multi-level deep nested objects. You will want to add
that object to the dataField arguement in the IterableAPI.updateUser()
user call. Swift // The IterableAPI.updateUser() can be added any method within your code. myFunc() is just an example
myFunc(){
// Example data fields
let dataField : [String: Any] = [
"Address":[
"Street1": "123 Main St",
"Street2": "Apt 1",
"City": "Iter-a-ville",
"State": "Ca",
"Zip": "90210"
]
]
// Most important code
IterableAPI.updateUser(dataField, mergeNestedObjects: false, onSuccess: myUserUpdateSuccessHandler, onFailure: myUserUpdateFailureHandler)
}
func myUserUpdateSuccessHandler(data:[AnyHashable:Any]?) -> () {
// success
print("sent to Iterable success")
}
func myUserUpdateFailureHandler(reason:String?, data:Data?) -> () {
// failure
print("sent to Iterable failure")
}
Java JSONObject address = new JSONObject();
JSONObject datafields = new JSONObject();
try {
address.put("Street1", "123 Main St");
address.put("Street2", "Apt 1");
address.put("City", "Iter-a-ville");
address.put("State", "CA");
address.put("Zip", "90210");
datafields.put("dataFields", address);
} catch (JSONException e) {
e.printStackTrace();
}
IterableApi.getInstance().updateUser(datafields);
Now you will be able to personalize the user's City (or any user profile)
later with Handlebars
in any of your channels by writing this code within the Iterable platform: {{Address.City}}
NOTES
mergeNestedObjects default is set to false
mergeNestedObjects set to true means that if the user profile has data:
{mySettings:{mobile:true}} and your code changes the contact field to:
{mySettings:{email:true}}, the resulting profile will be:
{mySettings:{mobile:true,email:true}} and merge the two results.
# When to make the updateUser call Typically you want to make the updateUser() call when:
Your user has changed or added their personal information Completed a key step in your onboarding, sales or retargeting process. For
example, you may want to add "completedOnboarding":true or
"testGroup":"A" to the user profile for later segmentation, splitting the
users down different journeys or analyzing later for test comparisons.
# Tracking anonymous users Iterable can track anonymous users by utilizing the userId. This will
automatically create a placeholder email. You can use a variety of client
side libraries to generate a unique ID on demand and pass it to the Iterable
userId parameter.
# Taking a user from anonymous to known Iterable can handle anonymous to known users. The function below will update
the current user email and userId. You will likely want to call the code
below when your user logs in or identifies themselve via a signup. Swift // The IterableAPI.updateUser() can be added any method within your code. yourUserIsNowKnownFunction() is just an example
let email = "[email protected]"
//Call
yourUserIsNowKnownFunction() {
IterableAPI.updateEmail(email, onSuccess: myUserUpdateSuccessHandler, onFailure: myUserUpdateFailureHandler)
}
func myUserUpdateSuccessHandler(data:[AnyHashable:Any]?) -> () {
// success
print("sent to Iterable success")
}
func myUserUpdateFailureHandler(reason:String?, data:Data?) -> () {
// failure
print("sent to Iterable failure")
IterableAPI.email = email
//This assumes your saving your user profile fields in the datafield object locally
IterableAPI.updateUser(dataField, mergeNestedObjects: false)
}
Java final String email = "[email protected]";
IterableApi.getInstance().updateEmail(email, new IterableHelper.SuccessHandler() {
@Override
public void onSuccess(JSONObject data) {
System.out.println("sent to Iterable success");
}
}, new IterableHelper.FailureHandler() {
@Override
public void onFailure(String reason, JSONObject data) {
System.out.println("sent to Iterable failure");
IterableApi.getInstance().setEmail(email);
//This assumes your saving your user profile fields in the datafield object locally
IterableApi.getInstance().updateUser(datafields);
}
});
There is a chance the updateEmail() call will fail. The most likely reason
is that the user already exists so we should now update the user call
directly in the onFailure handler.
View Article
The Iterable Android SDK is a Java implementation of an Android client for Iterable. Identifying the User
SDK Support The Iterable Android SDK supports Android API versions 15 and higher
( Android version history ).
# Table of contents
Installing the SDK
Initialize the SDK Configure
Troubleshooting
Next Steps
# Installing the SDK
Add Iterable Android SDK in your project Add Firebase Messaging Service support for your project
To add Iterable SDK and Firebase messaging in your project, add the following
dependencies to your application's build.gradle in dependencies block:
dependencies{
implementation 'com.iterable:iterableapi:3.1.3'
implementation 'com.google.firebase:firebase-messaging:X.X.X' // Min version 17.4.0 this is required for push notifications and in-app messaging features
}
See Bintray for the
latest version of the Iterable Android SDK.
# Initialize the SDK
# Configure In the onCreate method of the Application, initialize the Iterable SDK: IterableConfig config = new IterableConfig.Builder()
.setPushIntegrationName("myPushIntegration")
.build();
IterableApi.initialize(context, "<your-api-key>", config);
The apiKey should correspond to the API key of your project in Iterable. If
you'd like, you can specify a different apiKey depending on whether you're
building in DEBUG or PRODUCTION, and point the SDK to the relevant
Iterable project.
NOTES
Don't call IterableApi.initialize from Activity#onCreate; it is
necessary for Iterable SDK to be initialized when the application is
starting, to make sure everything is set up regardless of whether the app is
launched to open an activity or is woken up in background as a result of an
incoming push message. You add your push notification integration in this step but we'll complete
this in a later section which can be found here
Once you know the email (Preferred) or userId of the user, call setEmail or setUserId
EMAIL: IterableApi.getInstance().setEmail("[email protected]");
USERID: IterableApi.getInstance().setUserId("userId");
NOTE Don't specify both email and userId in the same session, as
they will be treated as different users by the SDK. Only use one type of
identifier, email or userId, to identify the user.
# Multiple push providers To learn how to work with multiple push notification providers, read
Setting up Android Push Notifications.
# Troubleshooting If you're having trouble installing or initializing the SDK, read
Testing and Troubleshooting the Iterable SDK.
# Next Steps After the SDK has been installed, read .
View Article
Apple and FCM require quite a few steps to set up push notifications. Below
are some best practices on testing and troubleshooting Iterable push
notifications. #
# Table of contents
Testing iOS push notifications
Sending a test iOS push notification
Getting the push notification token
Troubleshooting
Test push on Iterable is not working on iOS
Invalid Token
Invalid Sandbox .p12
Invalid Production .p12
Invalid bundle identifier
Iterable sends the push notification, but the iOS device doesn't receive it
Rich push is not working
Push sent from a template is failing
iOS 10 push notifications not registering
Testing Android push notifications Sending a test Android push notification
Android Troubleshooting
Unable to create mobile push integration
Test notification is not working on Android
Iterable sends the push notification, but the Android device doesn't receive it
# Testing iOS push notifications It is difficult to know exactly what is wrong and occasionally, you will have
to repeat the steps from the beginning to know exactly what is wrong. Below
are some steps and milestones for setting up push notifications.
# Sending a test iOS push notification Once your certificate has been exported from Apple and uploaded to Iterable,
you will want to send a test push via our Test Push Integration. To send a test
push, go to Mobile Apps > Integrations > Test Push. Use the Apple Sandbox Certificates for Xcode and the
Apple Production Certificates when testing from TestFlight.
# Getting the push notification token You can get the push notification token directly from Xcode. To do so, use
the code below to grab the printed deviceTokenString from the
didRegisterForRemoteNotificationsWithDeviceToken. Then add that token to
the above screenshot to send a Test Push to your device.
NOTES It may take a little time for the certificate to propogate through the system
so the first push may take a few minutes but then it should work as expected.
Swift import Foundation
//put outside class
extension Data {
var hexString: String {
let hexString = map { String(format: "%02.2hhx", $0) }.joined()
return hexString
}
}
//usage
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let deviceTokenString = deviceToken.hexString
print(deviceTokenString)
}
# Troubleshooting
# Test push on Iterable is not working on iOS If push on Iterable is not set up correctly, you would see one of the
following errors on 'Test Push'.
# Invalid Token Make sure the token you are using to test push set up belongs to correct
bundle id configured for the setting. For APNS_SANDBOX testing, please use a
token generated by sandbox app. Similarly, for production use the token
generated with production push certificate.
NOTE If you deploy your sandbox app to TestFlight, it uses production certificate
and hence it should be tested using production set up instead on sandbox/dev
set up.
# Invalid Sandbox .p12 This error means you are uploading production .p12 file into a sandbox
congifuration. Verify the .p12 file. If it is still failing, regerate the
certificate and upload a newely exported dev .p12
# Invalid Production .p12 This error means you are uploading sandbox .p12 file into a production
configuration. Verify the .p12 file. If it is still failing, regerate the
certificate and upload a newely exported production .p12 Apple now has an option of creating one certificate with production and
sandbox extension. In your Apple Developer Account, while creating
certificates, look for the Apple Push Notification service SSL (Sandbox & Production)
option. This will make token management easier.
# Invalid bundle identifier While uploading .p12 into Iterable platform, make sure you are uploading a
relevant file for the bundle id specified. You may recieve an error shown
above if the bundle identifier on .p12 doesn't match the bundle identifier
mentioned in the set up.
# Iterable sends the push notification, but the iOS device doesn't receive it Make sure your app has the user's permission to send a push notification. If you do not receive a test push, then unfortunately your certificates will
likely need to be re-exported (Apple occasionally has this problem). Please
follow the steps from the beginning.
NOTE To test iOS push notifications, you must use a real device. You cannot use
the iOS simulator.
Before you start testing with push templates, verify if your device is
registered under user's profile. Push template can be tested using user's
email address. This will fetch device from devices array on user's profile
and use the valid device token to send push to a user. Now test send a test push notification. Navigate to
Templates > Push > Send Proof and click the Send Proof button, found
in the lower-right corner. Send the message to the test email that you've set
in the app. If the device receives your message, you are ready to send campaigns. If you do not receive the message but are receiving test pushes in step 2,
check that the code in your app is identifying the email address that you
sent the proof to. IterableAPI.email = "[email protected]"
# Rich push is not working
Make sure your system notifications are working, if not, please follow
troubleshooting steps above. For rich push notification to work, you will need to make sure you have
added IterableNotificationExtension to your Xcode project. Please follow this
document on how to add extension.
# Push sent from a template is failing There are multiple reasons why your push template proof is not working when
test push is working.
Make sure email address you are testing with has a devices array on their
user's profile. If you are having trouble registering device on user's
profile, please refer to user registration troubleshooting guide. Check if notificationsEnabled is set to true. notificationsEnabled is set
to false when user disables permission to receive push notification. Check if endpointEnabled is set to true. endpointEnabled is set to false,
if user uninstalls the app, making device token no longer valid for push.
# iOS 10 push notifications not registering With the introduction of iOS 10 and Xcode 8, and there are a number of
changes made to push notifications. In particular, note the following change to the aps-environment
entitlement: Scenario: If you upgrade to iOS 10 and Xcode 8, and push notifications don't
work, check to see if there are errors from didFailToRegisterForRemoteNotificationsWithError.
If you get the following error on iOS 10 but not iOS 9, you will need to
enable push entitlements locally. fail to register with error Error Domain=NSCocoaErrorDomain Code=3000 "no
valid 'aps-environment' entitlement string found for application"
UserInfo={NSLocalizedDescription=no valid 'aps-environment' entitlement
string found for application}
With Xcode 8, the entitlements are set from your local entitlements file,
rather than from the provisioning profile you created on the Apple Developer
Portal. The entitlements will now need to be added to your Xcode build under
Capabilities, in addition to in your provisioning profile.
# Testing Android push notifications To verify Android set up, go to Firebase Console.
Send a test message from Cloud Messaging in Firebase to test your set up.
# Sending a test Android push notification After you have verified the Firebase setup:
Open the Iterable App
Open up your your project. Click on Settings and open Mobile Apps. Click on the Android App and make sure the Firebase API key has been
configured. Click on Test Push and enter the device token for your test device. Add a test payload and send the test.
# Android Troubleshooting
# Unable to create mobile push integration Make sure you have a correct API Key from Firebase. You can locate this key
by opening your Firebase project and navigating to
Settings > Project Settings > Cloud Messaging and looking in the
Project Credentials section.
# Test notification is not working on Android
Make sure you have followed Firebase Set up and test from Firebase works.
Check Firebase Setup
for details. Verify the device token you are entering is correct
Iterable sends the push notification, but the Android device doesn't receive it All push from Iterable platform are received as data messages in the app.
Iterable SDK renders the notification. Thus, make sure you do NOT have 'OS
Notifications' enabled when using Iterable SDK integration. Also make sure
your app has user's permission to send push.
View Article
Iterable System Webhook Iterable campaigns can send iOS push notifications. Push notifications are
remotely triggered notifications that appear on a user's device even when
the application is closed (depending on whether or not the user allows them). Users can then tap on these notifications to open the associated application
to specific, relevant content or instant Action Buttons. If you are a marketer, work with your mobile engineers to implement the steps
discussed in this article. If you have already completed the technical setup,
learn more about setting up a push notification campaign by reading
Creating a Push Notification Campaign. The Iterable SDK will facilitate:
Passing of device tokens between Iterable and the App Passing images and gifs through as part of the push template Creating Action Buttons
for your users to take instant actions from the push message. Tracking of:
Push Bounce Push Open Push Send Push Send Skip Push Uninstall
NOTES All the analytic data is available for free via the Iterable Export API
or the
features.
View Article
Iterable can send push notifications to iOS and Android devices. Push
notifications display content such as text and images, and can alert users by
playing a sound. Depending on a user's device settings, push notifications can appear even
when an application is closed. Upon receipt, users can tap these
notifications to open the associated application or perform another action
associated with the notification. Read Google's Notifications Overview
document for technical information about push notifications on Android. This guide describes the technical setup necessary to send Android push
notifications with Iterable. Work with your organization's mobile engineers
to complete the steps below.
# Table of contents
Overview
Instructions
1. Set up Firebase for your Android app
2. Create a mobile app in Iterable
3. Assign a push integration to the mobile app
4. Install Iterable's Android SDK in your mobile app
5. Configure the SDK
6. Use Iterable to send a test Android push notification
Upgrading from Google Cloud Messaging (GCM) to Firebase Cloud Messaging (FCM)
Customizing Android push notifications
Adding sounds to Android push notifications
Adding deep links to Android push notifications
Setting the background color of a push notification
Add custom icons to your push notifications
Further reading
# Overview To use Iterable to send push notifications to an Android app, the following
things must happen:
Your users must install your mobile app. Your mobile app must store a unique Firebase token on the user's
Iterable profile. Iterable must contact Firebase, telling it what content to send and which
devices to send it to.
The Iterable Android SDK
automatically tracks push notification opens. Alternatively, you can track
push notification opens with Iterable's POST /api/events/trackPushOpen
API.
# Instructions Follow the steps below to set up Iterable to send Android push notifications:
# 1. Set up Firebase for your Android app For Iterable to send Android push notifications, it must communicate
with Firebase Cloud Messaging. To learn how to set up Firebase for your Android app, read Google's
Add Firebase to your Android project
document.
# 2. Create a mobile app in Iterable Iterable uses mobile apps to store the details about your app's name,
identifier, platform, and store URL.
TIPS
It's best to use separate Iterable projects for sandbox and production
data. An Iterable push notification campaign can target as many (or few) of your
mobile apps as necessary.
To create a mobile app in Iterable:
Navigate to Settings > Mobile Apps.
Click Add a New Mobile App to bring up the Create New Mobile App
form: Iterable Android SDK docs
For Name, enter the name of your app. For example, Iterable Docs Push.
For Platform, select Android.
For Package Name, enter your application ID. For example, com.iterable.docspush.
(Optional) For Store URL, enter your app's Play Store URL.
Click Create App. This brings up a screen showing the app's details:
# 3. Assign a push integration to the mobile app A push integration stores the API key Iterable uses to authenticate with
Firebase when sending push notifications on your behalf. A push integration
is stored as part of a mobile app. You can either associate an
existing push integration or a
new push integration with a mobile app.
# Existing push integration To associate an already-existing push integration with the newly created
mobile app:
Navigate to Settings > Mobile Apps.
Find the existing push integration in the Unassigned Integrations
interface at the bottom of the screen.
Click that push integration's Assign App button.
In the Assign Push Integration window, select the mobile app you just
created.
Click Assign.
# New push integration To create a new push integration for the mobile app:
With the new mobile app still open in Iterable, click the Configure
button next to Firebase, bringing up a window similar to the following:
Select whether or not to Use OS Notifications.
Enabling this option causes Android (instead of Iterable's SDK) to
render push notifications for the app. Disabling this option causes the Iterable SDK to render push
notifications for the app.
WARNING It's usually best to leave this option disabled unless you are not using
the Iterable Android SDK
(or have another compelling reason to enable it).
For API Key, enter your Firebase Server Key. Locate this key by opening your Firebase project and navigating to
Settings > Project Settings > Cloud Messaging and looking in the
Project Credentials section.
Click Update to save the push integration.
# 4. Install Iterable's Android SDK in your mobile app To install Iterable's Android SDK, follow the
Installing the SDK
instructions (on GitHub).
NOTE You can receive Iterable push notifications without setting up the Android
SDK. To do so:
Set up your Android app as described in Google's
Set up a Firebase Cloud Messaging client app on Android document. Call POST /api/users/registerDeviceToken
each time the app opens. Call POST /api/users/disableDevice
each time the user signs out of the app Track push notification opens by calling POST /api/events/trackPushOpen.
# 5. Configure the SDK
# Handling Firebase push messages and tokens The SDK adds a FirebaseMessagingService to the app manifest automatically,
so you don't have to do any extra setup to handle incoming push messages. If your application implements its own FirebaseMessagingService, make sure
you forward onMessageReceived and onNewToken calls to
IterableFirebaseMessagingService.handleMessageReceived and
IterableFirebaseMessagingService.handleTokenRefresh, respectively: public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
IterableFirebaseMessagingService.handleMessageReceived(this, remoteMessage);
}
@Override
public void onNewToken(String s) {
IterableFirebaseMessagingService.handleTokenRefresh();
}
}
IMPORTANT The step above is mandatory for handling multiple push providers.
Note that FirebaseInstanceIdService is deprecated and replaced with
onNewToken in recent versions of Firebase.
# Push notifications
In the onCreate method of the Application, initialize the Iterable SDK: IterableConfig config = new IterableConfig.Builder()
.setPushIntegrationName("myPushIntegration")
.build();
IterableApi.initialize(context, "<your-api-key>", config);
The apiKey should correspond to the API key of your project in
Iterable. If you'd like, you can specify a different apiKey depending
on whether you're building in DEBUG or PRODUCTION, and point the SDK
to the relevant Iterable project.
IMPORTANT Don't call IterableApi.initialize from Activity#onCreate; it is
necessary for Iterable SDK to be initialized when the application is
starting, to make sure everything is set up regardless of whether the app
is launched to open an activity or is woken up in background as a result
of an incoming push message.
Once you know the email (Preferred) or userId of the user, call
setEmail or setUserId
EMAIL: IterableApi.getInstance().setEmail("[email protected]");
USERID: IterableApi.getInstance().setUserId("userId");
IMPORTANT Don't specify both email and userId in the same session, as they will be
treated as different users by the SDK. Only use one type of identifier,
email or userId, to identify the user.
Register for remote notifications On application launch (or whenever you want to register the token), call
registerForPush: IterableApi.getInstance().registerForPush();
This will take care of retrieving the token and registering it with
Iterable.
IMPORTANT Device registration will fail if user email or userId is not set. If
you're calling setEmail or setUserId after the app is launched (i.e.
when the user logs in), make sure you call registerForPush() again to
register the device with the logged in user.
You can now send remote push notifications to your device from Iterable.
# Disabling push notifications to a device When a user logs out, you typically want to disable push notifications to
that user/device. This can be accomplished by calling disablePush(). Please
note that it will only attempt to disable the device if you have previously
called registerForPush(). In order to re-enable push notifcations to that device, simply call
registerForPush() as usual when the user logs back in.
# 6. Use Iterable to send a test Android push notification To send a test Android push notification, first look up the device token for
a test user who has installed and run the app:
In Iterable, navigate to Audience > Contact Lookup and enter the user's
email address. In the devices array, examine the appPackageName field to find the
object that corresponds to your app. Copy the token, since you'll need this to send the test push
notification.
Then, send a test push notification to that user:
Navigate to Settings > Mobile Apps. Click the mobile app for which you'd like to send a push notification.
In the Integrations section, click Test Push to bring up the
Send Test Push window:
For Device Token, enter the token you located above. For Message, enter a message to display in the push notification. Click Send Notification. Monitor the recipient's device (or emulator) to verify that the push
notification arrives.
# Upgrading from Google Cloud Messaging (GCM) to Firebase Cloud Messaging (FCM) Google has deprecated Google Cloud Messaging (GCM) in favor of Firebase Cloud
Messaging (FCM). GCM APIs will soon be removed. Refer to Google's Firebase migration guide
for information about migrating your app from GCM to FCM.
NOTE If you previously had a GCM integration, we suggest upgrading your existing
GCM project to Firebase. This will allow you to:
Keep your Sender ID Keep your existing push integration in Iterable Update your Iterable push integration with a new Firebase server key
With this approach, old GCM tokens remain valid and the migration will
be almost transparent.
# Customizing Android push notifications The following sections describe the technical setup necessary for various
Android push notification customizations in Iterable. For marketer-specific information about how to configure these features in
Iterable when sending a campaign, read Creating a Push Notification Campaign.
# Adding sounds to Android push notifications To add sound to Android push notifications sent with Iterable, follow these
instructions:
Place the necessary sound files in the Android project's res/raw folder.
IMPORTANT
Sound file names should be lowercase and should not have any special
characters. Take a look at Android's documentation about supported media formats. This documentation is not
specific about which formats work for push notifications, so it's best to
test as necessary.
When setting up an Iterable push notification template, put the name of the
sound file in the Sound field.
NOTES
To use the default push notification sound, set this field to default. Whether or not a device plays the sound or vibrates depends on the
user's device settings.
# Adding deep links to Android push notifications Iterable push notification templates make it possible to set deep link
URLs for iOS and Android. To learn more about using Iterable's Android SDK to handle deep links,
take a look at the Iterable Android SDK documentation
on GitHub. If your app is not using Iterable's Android SDK, it can still handle a deep
link contained in an Iterable push notification. Iterable provides the deep
link URL in the defaultAction object included in the notification's
payload. When this object's type field is set to openUrl, the data
field will contain the deep link URL. After a user has opened a tapped on a push notification to open the app,
use the getPayloadData() method on IterableApi to access the notification
payload.
# Setting the background color of a push notification To set the background color of a push notification, update the
AndroidManifest.xml file: <meta-data android:name="iterable_notification_color" android:value="#FFFFFF"></meta-data>
#FFFFFF can be replaced with any hex color. In stock Android, the
notification icon and action buttons will be tinted with this color. Alternatively, you can also use a color resource: <meta-data android:name="iterable_notification_color" android:resource="@color/notification_color"/>
# Add custom icons to your push notifications By default, push notifications display the application icon. To use a
different icon, place the image resource inside your app's res/drawable
directory. Then, edit AndroidManifest.xml, adding the following line: <meta-data android:name="iterable_notification_icon" android:resource="@drawable/ic_notification_icon"/>
In this case, ic_notification_icon is the name of the notification icon. Alternatively, call setNotificationIcon(String iconName) to use the custom
icon, referencing the image asset by name and without a file extension.
# Further reading For more information about push notifications in Iterable, read:
Push Notification Setup FAQ. Creating a Push Notification Campaign
View Article
This document describes how to implement an image carousel in an iOS
push notification sent by Iterable. Apple Rich Push Notifications
IMPORTANT Carousels are not an officially support feature of Iterable push
notifications.
# Table of contents
Add a Notification Content Extension to your Xcode targets
Add code to the AppDelegate
Add pre-written code to your app
Adding images
Test a push
Further reading
# Add a Notification Content Extension to your Xcode targets Go to File > New > Target and create a Notification Extension: This will create some new files in Xcode.
# Add code to the AppDelegate Add some code to the bottom of your AppDelegate file to reference the new
Content Extension. //In didFinishLaunchingWithOptions
NotificationHelper.registerNotification()
UNUserNotificationCenter.current().delegate = self
//Below main Class in extension
extension AppDelegate : UNUserNotificationCenterDelegate {
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
completionHandler();
}
}
# Add pre-written code to your app You can then add the files from this GitHub repository:
https://github.com/BFMarks/CarouselPush. When using Iterable to send the push notification that has a carousel, set
the iOS Category to the UNNotificationExtension value from the
Info.plist file. In the examples below, the value is
myNotificationCategory:
Info.plist value:
iOS Category in Iterable:
# Adding images At the time of this writing, the Iterable UI does not support multiple
images. Work around this limitation by adding the parameters as one string
with comma-separated values in the payload dictionary. {
"title": "Title 1,Title 3,Title 3",
"deep_link": "://deeplink1,://deeplink2,://deeplink3",
"images": "https://iterable.com/wp-content/uploads/2016/12/Iterable_Logo_transparent-tight.png,https://dudodiprj2sv7.cloudfront.net/product-logos/dX/qp/NIJXVXZVD189-180x180.PNG,https://dudodiprj2sv7.cloudfront.net/product-logos/dX/qp/NIJXVXZVD189-180x180.PNG"
}
The Notification Content Extension code will parse out these values.
# Test a push Send a test push to make sure the carousel works as anticipated.
# Further reading For more information about push notifications in Iterable, read:
View Article
# Within Iterables In-App Template Editor, you can create in-app animations
using simple CSS! There are a variety of ways of presenting the in-app and in
this example, we will use an elliptic pop-up.
# Table of contents
Creating the template
Adding animations
Full code example
# Creating the template In order to use custom CSS inside of an Iterable in-app, you must create a
template via the WYSIWYG editor. If you are very uncomfortable with HTML,
then you can build your in-app in the Bee Free editor and export it to HTML
for upload.
# Adding animations You will need to add two parts of code to the template in order to achieve
the animations.
The keyframe reference: @keyframes slide-in-elliptic-bottom-fwd {
0% {
-webkit-transform: translateY(600px) rotateX(30deg) scale(0);
transform: translateY(600px) rotateX(30deg) scale(0);
-webkit-transform-origin: 50% 100%;
transform-origin: 50% 100%;
opacity: 0;
}
100% {
-webkit-transform: translateY(0) rotateX(0) scale(1);
transform: translateY(0) rotateX(0) scale(1);
-webkit-transform-origin: 50% -200px;
transform-origin: 50% -200px;
opacity: 1;
}
}
The animation code: .modal-content {
background-color: #ffffff;
margin: auto;
border: 0;
width: 85%;
border-radius: 8px;
max-width: 320px;
position: relative;
animation: slide-in-elliptic-bottom-fwd 1.0s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation-iteration-count: 1;
animation-delay: 0.5s;
}
Full code example If you are having trouble getting your in-app to animate, try adding the
pop-up below, customizing it as necessary: <!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"><!-- <link href="style.css" rel="stylesheet" type="text/css" /> -->
<style type="text/css">body {
font-family: Arial, sans-serif;
}
h1{
color:#232323;
}
h2{
color:#232323;
}
p{
color: #4a4a4a;
margin-top:-12px;
}
.modal {
display: yes;
position: fixed;
z-index: 1;
padding-top: 10%;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0, 0.7);
}
/* ----------------------------------------------
* Generated by Animista on 2019-6-19 17:23:47
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-in-elliptic-bottom-fwd
* ----------------------------------------
*/
@keyframes slide-in-elliptic-bottom-fwd {
0% {
-webkit-transform: translateY(600px) rotateX(30deg) scale(0);
transform: translateY(600px) rotateX(30deg) scale(0);
-webkit-transform-origin: 50% 100%;
transform-origin: 50% 100%;
opacity: 0;
}
100% {
-webkit-transform: translateY(0) rotateX(0) scale(1);
transform: translateY(0) rotateX(0) scale(1);
-webkit-transform-origin: 50% -200px;
transform-origin: 50% -200px;
opacity: 1;
}
}
/* Modal Content */
.modal-content {
background-color: #ffffff;
margin: auto;
border: 0;
width: 85%;
border-radius: 8px;
max-width: 320px;
position: relative;
animation: slide-in-elliptic-bottom-fwd 1.0s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation-iteration-count: 1;
animation-delay: 0.5s;
}
.image-container {
position: relative;
width: 100%;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
/* The Close Button */
.image-container .close {
color: #9f9f9f;
position: absolute;
right: 12px;
top: 12px;
font-size: 40px;
font-weight: light;
background-color: transparent;
border:none;
text-decoration:none;
}
.contenttext{
padding-left:7.5%;
padding-right:7.5%;
padding-top: 0px;
text-align: center;
}
.cta{
width:100%;
text-align: center;
padding-top: 8px;
padding-bottom: 24px;
}
.cta .btn{
height:40px;
background-color: #ed8623;
border:0;
border-radius: 40px;
text-align: center;
min-width: 120px;
color: #ffffff;
font-size: 0.875em;
font-family: Arial, sans-serif;
}
.outside{
margin-top: 24px;
font-size:.875em;
text-align: center
}
.outside .dismiss{
color: #ffffff;
background-color: transparent;
border:none;
}
</style>
</head>
<body>
<div class="modal" id="myModal"><!-- Modal content -->
<div class="modal-content">
<div class="image-container">
<br />
<br />
&nbsp;
<div style="text-align:center"><img alt="BGimage" style="max-width:180px;" width="240" src="https://iterable.com/wp-content/uploads/2016/12/Iterable_Logo_transparent-tight.png" />
</div>
<a class="close" href="itbl://"></a>
</div>
<div class="btn">
<div class="contenttext">
<h1><span style="color:#003e7d;">INTRODUCING
<br />
ANIMATIONS</span>
</h1>
<p>{{firstName}}, tracking your in-app
<br />
is as easy as adding this code.
</p>
</div>
<div class="cta">
<button class="btn">Try It Now!
</button>
<br />
&nbsp;
</div>
</div>
</div>
</div>
</body>
</html>
View Article
Within Iterable's in-app message template editor, you can create in-app
carousels. #
# Table of contents
Creating the template
Adding a carousel
# Creating the template In order to use custom CSS inside of an Iterable in-app, you must create a
template via the WYSIWYG editor. If you are very uncomfortable with HTML,
then you can build your in-app in the Bee Free editor and export it to HTML
for upload.
Notes You must use full screen view to render this in-app carousel.
Adding a carousel Example code: <!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<style type="text/css">body {
font-family: Arial, sans-serif;
}
h1{
color:#232323;
}
h2 {
color:#232323;
}
p {
color: #4a4a4a;
margin-top:-12px;
}
/* The Modal (background) */
.modal {
display: yes;
/* Hidden by default */
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
/* padding-top: 10%;
padding-bottom: 10%;*/
/* Location of the box */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(0,0,0);
/* Fallback color */
background-color: rgba(0,0,0,0.7);
/* Black w/ opacity */
}
/* Modal Content */
.modal-content {
background-color: #ffffff;
border: 0;
width: 85%;
border-radius: 8px;
max-width: 320px;
/*max-height: calc(100% - 1em);*/
max-height: 90vh;
margin: 0 auto;
position: relative;
animation-duration: 1.5s;
animation-name: slide-up;
animation-iteration-count: 1
}
@media screen and (orientation:portrait) {
.modal-content {
top: 25%;
}
@keyframes slide-up {
from {
top: 100%
}
to {
top: 25%
}
}
}
@media screen and (orientation:landscape) {
.modal-content {
top: 5vh;
}
@keyframes slide-up {
from {
top: 100%
}
to {
top: 5vh;
}
}
}
.image-container {
position: relative;
width: 100%;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
/* The Close Button */
.image-container .close {
color: #9f9f9f;
position: absolute;
right: 12px;
top: 12px;
font-size: 40px;
font-weight: light;
background-color: transparent;
border:none;
text-decoration:none;
}
.contenttext{
padding-left:7.5%;
padding-right:7.5%;
padding-top: 0px;
text-align: center;
}
.cta{
width:100%;
text-align: center;
padding-top: 8px;
padding-bottom: 24px;
}
.cta .btn{
height:40px;
background-color: #ed8623;
border:0;
border-radius: 40px;
text-align: center;
min-width: 120px;
color: #ffffff;
font-size: 0.875em;
font-family: Arial, sans-serif;
}
.outside{
margin-top: 24px;
font-size:.875em;
text-align: center
}
.outside .dismiss{
color: #ffffff;
background-color: transparent;
border:none;
}
.carousel {
position: relative;
width:200px;
border:10px solid white;
margin:20px auto 40px auto;
box-shadow:0px 0px 40px #000;
}
.carousel > img {
display:none;
width:100%;
}
.carousel > input {
position:absolute;
left:-9999px;
}
.carousel > input:checked + label + img {
display:block;
}
.carousel > label,
.carousel > input:checked ~ label ~ label ~ label ~ label {
display:none;
}
.carousel > input:checked + label {
display:block;
left:0;
}
.carousel > input:checked ~ label ~ label ~ label {
display:block;
right:0;
}
.carousel > label {
position:absolute;
top:0;
width:25%;
height:100%;
visibility:hidden;
}
.carousel > label:before {
content:'';
display:block;
position:absolute;
width:100%;
height:100%;
visibility:visible;
}
.carousel > label:after {
display:block;
position:absolute;
top:50%;
width:25px;
height:25px;
line-height:22px;
margin:-15px 10px 0 10px;
background-color:black;
color:white;
font-family:'Arial';
font-weight:bold;
font-size:18px;
text-align:center;
visibility:hidden;
border:2px solid white;
border-radius:20px;
box-shadow:0 3px 4px black;
}
.carousel > label:after {
visibility:visible;
}
.carousel > input:checked + label:after {
left:0;
content:'\00AB';
}
.carousel > input:checked ~ label ~ label ~ label:after {
right:0;
content:'\00BB';
}
</style>
</head>
<body>
<div id="myModal" class="modal"><!-- Modal content -->
<div class="modal-content" style="padding-bottom: 10px;">
<div class="image-container">
<br />
&nbsp;
<div style="text-align:center"><img alt="BGimage" style="max-width:180px;" width="172" src="https://static.iterable.com/f2111070fa144bf9b92868933306b744/19-08-08-iterable-logo-navy (1).png" />
</div>
<a class="close" href="itbl://"></a>
</div>
<div class="btn">
<div class="contenttext">
<h1><span style="color:#00185c;">The latest styles!</span>
</h1>
</div>
</div>
<div class="carousel">
<input id="image1" type="radio" checked="checked" name="image-selector" /> <label for="image4">View image 4</label> <img alt="" width="200" height="133" src="https://www.dropbox.com/s/6pzu0i8xe5vnuiw/mens-watch-and-ring_925x.jpg?dl=1" />
<input id="image2" type="radio" name="image-selector" /> <label for="image1">View image 1</label> <img alt="" width="200" height="133" src="https://www.dropbox.com/s/6hidqmdjngze1gg/man-using-smartphone_925x.jpg?dl=1" />
<input id="image3" type="radio" name="image-selector" /> <label for="image2">View image 2</label> <img alt="" width="200" src="https://www.dropbox.com/s/sh74vw612sqi3o9/mens-leather-dress-shoes_925x.jpg?dl=1" />
<input id="image4" type="radio" name="image-selector" /> <label for="image3">View image 3</label> <img alt="" width="200" height="133" src="https://www.dropbox.com/s/i3hqrqude82vxqd/white-faced-watch_925x.jpg?dl=1" /> <label for="image4">View image 4</label> <label for="image1">View image 1</label>
</div>
</div>
</div>
</body>
</html>
View Article
#
# Table of contents
Overview
How an app receives in-app messages Example in-app workflow
Custom payload
# Overview In-app messages are custom messages that appear while a mobile app is in
the foreground. Unlike push notifications, they do not appear when the app is
in the background or closed. In-app messages can:
Be created with raw HTML or a drag-and-drop editor. Contain buttons for closing the message or navigating to specific content. Be sent as part of blast, triggered, or workflow-based campaigns. Be displayed in any order, or prevented from displaying at all. Contain metadata that the associated mobile app can inspect. Point to new content or functionality in your app, promotions, and other
important information.
# How an app receives in-app messages Iterable in-app works by sending a silent push
to your app to notify the client side that there is an in-app message in the
queue, ready for our user to view.
# Example in-app workflow
A marketer sets up an Iterable in-app or Mobile Inbox in the Iterable
dashboard. The Iterable system sends a silent push notification to the mobile app. The mobile app receives the silent push and pulls down (does a GET
request) the most recent in-app messages. Remote messages on the server are added to the local storage for increase
performance and speed. The user is presented the in-app(s) messages with little workload on
client-side performance.
Custom payload A custom payload enbales developers to include:
Prioritization around which in-app messages to show first Determine which view should present the in-app message Apply additional personalization with Handlebars
View Article
#
# Table of contents
Default behavior
Overriding whether to show or skip a particular in-app message
Getting the local queue of in-app messages
Handling in-app message buttons and links
Changing the display interval between in-app messages
# Default behavior By default, when an in-app message arrives from the server, the SDK
automatically shows it if the app is in the foreground. If an in-app message
is already showing when the new message arrives, the new message will be
shown 30 seconds after the currently displayed in-app message closes
( see how to change this default value below ).
Once an in-app message is shown, it will be "consumed" from the server queue
and removed from the local queue as well. There is no need to write any code
to get this default behavior.
# Overriding whether to show or skip a particular in-app message An incoming in-app message triggers a call to the onNewInApp method of
IterableConfig.inAppHandler (an IterableInAppHandler object). To override
the default behavior, set inAppHandler in IterableConfig to a custom
class that overrides the onNewInApp method. onNewInApp should return
InAppResponse.SHOW to show the incoming in-app message or
InAppResponse.SKIP to skip showing it. class MyInAppHandler implements IterableInAppHandler {
@Override
public InAppResponse onNewInApp(IterableInAppMessage message) {
if (/* add conditions here */) {
return InAppResponse.SHOW;
} else {
return InAppResponse.SKIP;
}
}
}
// ...
IterableConfig config = new IterableConfig.Builder()
.setPushIntegrationName("myPushIntegration")
.setInAppHandler(new MyInAppHandler())
.build();
IterableApi.initialize(context, "<your-api-key>", config);
# Getting the local queue of in-app messages The SDK keeps the local in-app message queue in sync by checking the server
queue every time the app goes into foreground, and via silent push messages
that arrive from Iterable servers to notify the app whenever a new in-app
message is added to the queue. To access the in-app message queue, call
IterableApi.getInstance().getInAppManager().getMessages(). To show a
message, call IterableApi.getInstance().getInAppManager().showMessage(message). // Get the in-app messages list
IterableInAppManager inAppManager = IterableApi.getInstance().getInAppManager();
List<IterableInAppMessage> messages = inAppManager.getMessages();
// Show an in-app message
inAppManager.showMessage(message);
// Show an in-app message without consuming (not removing it from the queue)
inAppManager.showMessage(message, false)
# Handling in-app message buttons and links The SDK handles in-app message buttons and links as follows:
If the URL of the button or link uses the action:// URL scheme, the SDK
passes the action to IterableConfig.customActionHandler.handleIterableCustomAction(). If
customActionHandler (an IterableCustomActionHandler object) has not been
set, the action will not be handled. For the time being, the SDK will treat itbl:// URLs the same way as
action:// URLs. However, this behavior will eventually be deprecated
(timeline TBD), so it's best to migrate to the action:// URL scheme
as it's possible to do so.
The iterable:// URL scheme is reserved for action names predefined by
the SDK. If the URL of the button or link uses an iterable:// URL known
to the SDK, it will be handled automatically and will not be passed to the
custom action handler. The SDK does not yet recognize any iterable:// actions, but may
do so in the future.
The SDK passes all other URLs to IterableConfig.urlHandler.handleIterableURL().
If urlHandler (an IterableUrlHandler object) has not been set, or if it
returns false for the provided URL, the URL will be opened by the system
(using a web browser or other application, as applicable).
Changing the display interval between in-app messages To customize the time delay between successive in-app messages, set
inAppDisplayInterval on IterableConfig to an appropriate value in
seconds. The default value is 30 seconds.
View Article
#
# Table of contents
In-app messages
Default behavior
Overriding whether to show or skip a particular in-app message
Getting the local queue of in-app messages
Handling in-app message buttons and links
Changing the display interval between in-app messages
# In-app messages In-app messages are handled via silent push messages from the server. When
your application receives a silent push, call the Iterable iOS SDK in your
app delegate, as follows: Swift // In AppDelegate.swift
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
IterableAppIntegration.application(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler)
}
Objective-C - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[IterableAppIntegration application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
# Default behavior By default, when an in-app message arrives from the server, the SDK
automatically shows it if the app is in the foreground. If an in-app message
is already showing when the new message arrives, the new in-app message will
be shown 30 seconds after the currently displayed in-app message closes (see
how to change this default value ).
Once an in-app message is shown, it will be "consumed" from the server queue
and removed from the local queue as well. There is no need to write any code
to get this default behavior.
# Overriding whether to show or skip a particular in-app message An incoming in-app message triggers a call to the onNew method of
IterableConfig.inAppDelegate (an object of type IterableInAppDelegate).
To override the default behavior, set IterableConfig.inAppDelegate to a
custom class that overrides the onNew method. onNew should return .show
to show the incoming in-app message or .skip to skip showing it. Swift class YourCustomInAppDelegate : IterableInAppDelegate {
func onNew(message: IterableInAppMessage) -> InAppShowResponse {
// perform custom processing
// ...
return .show // or .skip
}
}
Objective-C // Implement this method in your custom class that implements IterableInAppDelegate
// This will most likely be the global AppDelegate class.
- (enum InAppShowResponse)onNewMessage:(IterableInAppMessage * _Nonnull)message {
// perform custom processing
// ...
return InAppShowResponseShow; // or InAppShowResponseSkip
}
// ...
// Now set this custom class in IterableConfig
IterableConfig *config = [[IterableConfig alloc] init];
config.inAppDelegate = self; // or other class implementing the protocol
[IterableAPI initializeWithApiKey:@"YOUR API KEY" launchOptions:launchOptions config:config];
# Getting the local queue of in-app messages Until they are consumed by the app, all in-app messages that arrive from the
server are stored in a local queue. To access this local queue, use the
read-only IterableAPI.inAppManager property (an object which conforms to
the InAppManager protocol). By default, all in-app messages in the local
queue will be consumed and removed from this queue. To keep in-app messages
around after they are shown, override the default behavior (as described
above). Swift // Get the in-app messages list
let messages = IterableAPI.inAppManager.getMessages()
if messages.count == 0 {
print("Don't present 0")
} else {
print("presents the first message")
IterableAPI.inAppManager.show(message: messages[0])
}
// How to override the consume:
// Show an in-app message without consuming, i.e., not removing it from the queue
IterableAPI.inAppManager.show(message: message, consume: false)
Objective-C // Get the in-app messages list
NSArray *messages = [IterableAPI.inAppManager getMessages];
// Show an in-app message
[IterableAPI.inAppManager showMessage:message];
// Show an in-app message without consuming, i.e., not removing it from the queue
[IterableAPI.inAppManager showMessage:message consume:NO callbackBlock:nil];
# Handling in-app message buttons and links The SDK handles in-app message buttons and links as follows:
If the URL of the button or link uses the action:// URL scheme, the SDK
passes the action to IterableConfig.customActionDelegate.handle(). If
customActionDelegate (an IterableCustomActionDelegate object) has not
been set, the action will not be handled. For the time being, the SDK will treat itbl:// URLs the same way as
action:// URLs. However, this behavior will eventually be deprecated
(timeline TBD), so it's best to migrate to the action:// URL scheme
as it's possible to do so.
The iterable:// URL scheme is reserved for action names predefined by
the SDK. If the URL of the button or link uses an iterable:// URL known
to the SDK, it will be handled automatically and will not be passed to the
custom action handler. The SDK does not yet recognize any iterable:// actions, but may
do so in the future.
The SDK passes all other URLs to IterableConfig.urlDelegate.handle(). If
urlDelegate (an IterableUrlDelegate object) has not been set, or if it
returns false for the provided URL, the URL will be opened by the system
(using a web browser or other application, as applicable).
Take a look at this sample code
for a demonstration of how to implement and use the IterableURLDelegate and
IterableCustomActionDelegate protocols. The following code demonstrates how to assign a urlDelegate and
customActionDelegate to an IterableConfig object: Swift let config = IterableConfig()
config.urlDelegate = YourCustomUrlDelegate()
config.customActionDelegate = YourCustomActionDelegate()
Changing the display interval between in-app messages To customize the time delay between successive in-app messages (default value
of 30 seconds), set inAppDisplayInterval to an appropriate value (in
seconds). Swift let config = IterableConfig()
// ten second delay between in-app presentations
config.inAppDisplayInterval = 10.0
View Article
This document lists comprehensive sets of Iterable track events for
several verticals. Each vertical listed below contains carefully selected
track events that we recommend recording. #
# Table of contents
E-commerce
Travel
Gaming
Entertainment & Streaming
Fintech - P2P lending
# E-commerce
NOTES If you are using Shopify, please check out our Shopify Integration.
Signup Login Add_to_cart Abondan_cart Add_to_wishlist Initiated_checkout Purchase Share Churn Subscription
# Travel
NOTES Iterable maintains all you events in perpituity which is ideal for travel
apps.
Signup Login Started_booking Abondan_booking Purchase Share Churn Subscription
# Gaming
NOTES Gaming apps include games such as arcade, strategy, educational games and
even gambling. The events that we recommend recording in gaming apps are
in-app purchases, sharing on social media and inviting friends.
Login Signup Purchase Level_achieved Tutorial_completion Share Invite Bonus_claimed
# Entertainment & Streaming
NOTES Iterable events are as close to real-time as possible, so you can rely on
time sensitive event triggers.
Login Signup Start_trial Purchase Media_play Share Invite Media_save
Fintech - P2P lending
NOTES Please do not include any personal identifiable financial information within
your Iterable events.
Registration_submitted Signup Fill_Loan_form Submit_loan_application Loan_accepted Loan_rejected Payment Payment_completed
View Article
Iterable Custom Conversion Tracking The Iterable SDK provides easy code to track user events enabling your team
to record a specific action at a given time. Iterable will also collect user
track calls from your website, mobile-app, tablet or offline events to ensure
all of your events aggregate back to the same user across multiple devices.
# Table of contents
Event tracking specifications
Attribution definition
Attribution methodologies
# Event tracking specifications Before you start adding Iterable event tracking SDK code to your app, you will
want to spec-out which events to track. At a high level, you will want to
think about each of the milestones within your user journey (sign up, viewed
product, add to cart, purchase, share). Your Iterable Implementation Manager
can assist on this section but we also have some recommended events in the
following sections.
NOTES It is not recommended to add a session event or app launch event to your
app because it happens far more frequently than other events. This creates a
noise and can distract from the main signal coming from your data.
# Attribution definition Campaign Attribution is the idea of attributing (or giving credit) a
particular conversion event (or user action) to a given campaign. For example, if you are testing different content in three push notification
campaigns, you will want to track and attribute your conversion event to
ensure your team knows which push notification is most effective for your
given user base. Some common custom conversion events could be:
Started_Trial, Shared_Item_With_Friend, Added_Item_to_Cart.
# Attribution methodologies Iterable uses two common methodologies for attributing events back to
particular campaigns. By default, the majority of the mobile attribution
tracking will be automatically handled by the SDK. Here are the two options for attribution when creating a campaign within
Iterable:
Campaign ID explicitly set Only conversion events with a campaignId field set to this campaign will
be attributed to the campaign.
Attribution window When the Attribution Window is chosen, all Custom Conversions Events in
the given time frame will be automatically attributed to the that
particular campaign.
Read more about
View Article
This document describes various API endpoints that can be used to manage
users and devices in Iterable, without using the mobile SDK.
# Table of contents
Creating and updating users User profile update
Managing devices
Register device token
Disable device
# Creating and updating users Users can be created and updated in Iterable with the API when a user logs
into the mobile app, updates their profile, or uses a feature within the app.
Anonymous users can also be created in Iterable via a userId if an email
address is not known yet.
# User profile update To add a user or update a user profile, ake a POST call to
/users/update.
This call will add new fields and update existing fields as necessary.
Data is merged; fields missing from the call to the API are not deleted
from the user profile. To identify the user, you must pass either email or
userId. If you provide both, email takes precedence. Sample request body: {
"email": "[email protected]",
"dataFields": {
"catName": "Jimmy"
},
"userId": "1",
"mergeNestedObjects": true
}
Optional fields in this sample request include: email, userId,
mergeNestedObjects
# Creating a user without an email address To create a user profile for a user that does not have a known email
address, make a POST call to /users/update.
In the request body, set preferUserId to true and supply a value for
userId.
# mergeNestedObjects When calling the /users/update
API endpoint, if mergeNestedObjects is set to true, then Iterable will
merge top-level object data (as opposed to single fields), instead of
overwriting it. mergeNestedObjects defaults to false. For example, if a user profile has data such as: { "mySettings": { "mobile": true } }
And the API request contains the following data: { "mySettings": { "email": true } }
With mergedNestedObjects set to true, the resulting merged profile
would be: { "mySettings": { "mobile": true, "email": true } }
With mergeNestedObjects set to false, the resulting merged profile
would be: { "mySettings": { "email": true } }
# Managing devices Devices can be registered and disabled by calling Iterable's API with the
platform, token, and applicationName for the messaging service set up
in Iterable. By default, endpointEnabled will be set to true on a
user profile when the devie token/regID is successfully added. /users/disableDevice
# Register device token To register a mobile device token, which enables push notifications, make a
POST call to /users/registerDeviceToken.
To identify the user, you must pass either email or userId. If you provide
both, email takes precedence.
NOTE To learn more about push notifications, read
Push notification setup (iOS and Android).
Sample request body: {
"email": "[email protected]",
"device": {
"token": "sampleToken123",
"platform": "APNS",
"applicationName": "Pizza Tracker",
"dataFields": {
"phoneType": "iPhone 6 plus"
}
},
"userId": "2"
}
Optional fields in this sample request include: email, dataFields, and
userId. If a user disables push notifications for the app after the device has been
added, it is up to the app developer to call the /users/disableDevice
API endpoint to mark that device's endpointEnabled property to false in
Iterable. Otherwise, if that user is included in future push sends, they will
still be included in the send number, although they will not receive the
message. It is important to regularly disable devices for users who have
opted out of push in order to have accurate campaign metrics.
# Disable device To disable a device, and prevent it from receiving further push notifications,
make a POST call to . You must include the device token when making
this call. If the token exists on multiple user profiles, including email will
disable the token for that one email address only. If email is not
included, the token will be disabled from all user profiles. The same is
true for including or omitting userId. Sample request body: {
"token": "sampleToken123",
"email": "[email protected]",
"userId": "2"
}
Optional fields in this sample request include: email, userId
View Article
To engage users on mobile devices, Iterable's API can be used for things such
as event tracking, purchase tracking, and the sending of messages. It is not
necessary to use Iterable's mobile SDKs to call these endpoints. This document describes various mobile-related API endpoints.
# Table of contents
Custom event tracking POST /api/events/track
Push notifications POST /api/events/trackPushOpen
In-app messages
POST /api/events/trackInAppOpen
POST /api/events/trackInAppClick
Tracking Purchases POST /api/commerce/trackPurchase
# Custom event tracking Actions taken by users within a mobile app can be sent to Iterable using the
POST /api/events/track endpoint.
# POST /api/events/track Use this to send custom events, such as user logins, signups and app opens to
Iterable. These events can then be used to trigger
workflows
or for custom conversion tracking
in campaigns. Data fields in custom event calls can be used to populate merge
parameters in templates. You can also segment on these events in the user
profile. If createdAt field is not included, event will be sent
immediately. Either email or userId must be passed in to identify the user.
If both are passed in, email takes precedence. An optional string id parameter may be passed as one of the top-level
parameters. If an event exists with that id, the event will be updated. If no
id is specified, a new id will automatically be generated and returned.
NOTE An id value must:
Contain only alphanumeric characters and hyphens. Be no longer than 512 bytes in length. Be unique across all custom events in the project.
Sample JSON request body: {
"email": "[email protected]",
"eventName": "startedMembership",
"id": "12345",
"dataFields": {
"source": "facebook",
"membershipType": "monthly"
},
"userId": "1",
"campaignId": 123,
"templateId": 123
}
Optional fields: email, id, dataFields, userId, campaignId, and
templateId.
# Push notifications
# POST /api/events/trackPushOpen When a push notification is sent to a device, either by publishing a push
campaign or adding a push action to a workflow, Iterable will automatically
track successful sends under the push campaign metrics. When the push notification is opened on the device, the app will need to call
the POST /api/events/trackPushOpen
endpoint. Either email or userId must be passed in to identify the user.
If both are passed in, email takes precedence. Include the campaignId in
the call, and Iterable will attribute the open to the campaign that sent the
notification. Read Sending Push Notifications
to learn more. Sample JSON request body: {
"email": "[email protected]",
"userId": "2",
"campaignId": 12345,
"templateId": 67890,
"messageId": "01234567890",
"dataFields": {
"openedMostRecentPush": true
}
}
Optional fields: email, userId, campaignId, templateId, messageId,
dataFields
# In-app messages Iterable can track in-app engagement from the app from through the
POST /api/events/trackInAppOpen
endpoint and the POST /api/events/trackInAppClick
endpoints. To learn more about receiving, rendering, and tracking in-app
messages, read Setting up in-app messages (without the SDK).
# POST /api/events/trackInAppOpen Use this endpoint to track an in-app notification opens. Either
email or userId must be passed in to identify the user. If both are
passed in, email takes precedence. To learn more, read
In-app message overview. Sample JSON request body: {
"email": "[email protected]",
"userId": "123",
"messageId": "01234567890"
}
Optional fields: email, userId
# POST /api/events/trackInAppClick Use this endpoint to track an in-app notification clicks. Either email or
userId must be passed in to identify the user. If both are passed in,
email takes precedence. To learn more, read
In-app message overview. {
"email": "[email protected]",
"userId": "123",
"messageId": "01234567890"
}
Optional fields: email, userId
# Tracking Purchases
# POST /api/commerce/trackPurchase Track in-app purchases by calling Iterable's POST /api/commerce/trackPurchase
endpoint. Tracking purchases allows marketers to segment based on purchase history,
trigger workflows, and attribute revenue to campaigns. When a purchase event for a user is tracked, it will also clear the
shoppingCartItems on the user's profile. Adding in the campaignId will
attribute the purchase to specific Iterable campaign.
NOTE We recommend casting the required price and total fields as doubles
instead of longs. To do that, you will need to include a number with a
decimal in the first call that you use to cast that field. Use a non-zero
decimal value to cast the field as a double (example: 5.55). Otherwise, the
field will be cast as a long.
An optional string id parameter may be passed as one of the top-level
parameters. If a purchase event exists with that id, the event will be
updated. If no id is specified, a new id will will automatically be
generated and returned.
NOTE An id value must:
Contain only alphanumeric characters and hyphens. Be no longer than 512 bytes in length. Be unique across all purchase events in the project.
Sample JSON request body: {
"user": {
"email": "[email protected]",
"dataFields": {
"totalPurchases": 5
},
"userId": "1"
},
"items": [
{
"id": "1",
"sku": "1",
"name": "Iterable Stickers",
"description": "Put these stickers anywhere and everywhere!",
"categories": [
"stickers",
"novelty"
],
"price": 5.50,
"quantity": 2,
"imageUrl": "http://static.iterable.com/iterable-demo-v1/15-03-04-Iterable_stickers.jpg",
"url": "iterable.com"
}
],
"campaignId": 14348,
"templateId": 29592,
"total": 11,
"dataFields": {
"shippingAddress1": "360 3rd Street",
"shippingAddress2": "Suite 675",
"city": "San Francisco",
"state": "CA",
"zip": 94107
}
}
Required fields: user, items, items.id, items.name, items.price,
items.quantity, total
View Article
While Iterable's iOS and
Android SDKs simplify the
process of working with in-app messages, Iterable's API makes it possible to
manually check for, render, and consume in-app messagesand to track events
such as inAppClick, inAppOpen, and inAppConsume. This document
describes API endpoints relevant to these tasks.
NOTE When rendering in-app messages without the SDK, pay attention to scaling,
positioning, scrolling, etc.
# Table of contents
Overview
API calls
Get in-app messages for a user
Consume an in-app message
Track an in-app open
Track an in-app click
# Overview When in-app campaigns are published or a contact in Iterable enters a
Send in app action in a workflow, the in-app message is
delivered to an in-app message queue for the contact (these messages are
automatically removed after 24 hours). To display the in-app message, poll
the message queue and display and consume in-app messages as necessary. After
displaying a message, the mobile app should track an inAppOpen event. If a
user clicks on a message's call to action, the app should track an
inAppClick event. The diagram below displays how these calls work together to send, display,
and track in-app messages through Iterable's API. /events/trackInAppClick
NOTE To learn more about in-app messages, read the
In-app messages overview.
# API calls
# Get in-app messages for a user To fetch in-app messages for a specific user, make a GET request to the
/inApp/getMessages
API endpoint. Sample request URL: https://api.iterable.com:443/api/inApp/getMessages?email=chris%40iterable.com&userId=1234&count=123&api_key=[API_KEY]
# Consume an in-app message To consume an in-app message, make a POST request to the
/events/inAppConsume
API endpoint. Sample request body: {
"email": "[email protected]",
"userId": "123",
"messageId": "01234567890"
}
To identify the user, you must pass either email or user. If you provide
both, email takes precedence.
# Track an in-app open To track when a user opens an in-app message, make a POST request to the
/events/trackInAppOpen
API endpoint. Sample request body: {
"email": "[email protected]",
"userId": "123",
"messageId": "01234567890"
}
To identify the user, you must pass either email or user. If you provide
both, email takes precedence.
# Track an in-app click To track when a user clicks on an in-app message, make a POST request to the
API endpoint. Sample request body: {
"email": "[email protected]",
"userId": "123",
"messageId": "01234567890"
}
To identify the user, you must pass either email or user. If you provide
both, email takes precedence.
View Article
While Iterable's SDK contains all of the functionality out of the box to
set up deep links, some teams might choose to avoid including additional SDKs
in their apps. To take full advantage of Iterable's deep linking without the
SDK, add the following code snippetwhich automatically handles the click
track and redirect within the app.
# iOS #define ITBL_DEEPLINK_IDENTIFIER @"/a/[a-zA-Z0-9]+"
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler {
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:ITBL_DEEPLINK_IDENTIFIER options:0 error:NULL];
NSString *urlString = userActivity.webpageURL.absoluteString;
NSTextCheckingResult *match = [regex firstMatchInString:urlString options:0 range:NSMakeRange(0, [urlString length])];
void (^customRouteCallback)(NSString *) = ^(NSString * routeURL) {
//<MAKE A CUSTOM CALL TO YOUR APP'S ROUTES HERE WITH THE 'routeURL'>
};
if (match == NULL) {
customRouteCallback(urlString);
} else {
NSURLSessionDataTask *trackAndRedirectTask =
[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:urlString]
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
customRouteCallback(response.URL.absoluteString);
}];
[trackAndRedirectTask resume];
}
return YES;
}
View Article
In this section we will discuss migrating from another push provider over to
Iterable. #
# Table of contents
Migrating push notifications to iterable
1. Install the Iterable SDK
2. Configure your app to support push notifications from Iterable
Transfering tokens
Migrating channel preferences
Slow migration Selectively targeting users
# Migrating push notifications to iterable To migrate to Iterable you will need to simply have your app developers
install the Iterable SDK and add historical user device token to over to
Iterable's system.
# 1. Install the Iterable SDK You can find documentation for iOS here
and Android here.
NOTES
Integrating Iterable push notifications will not cause any issues with
other push notification services in your app. All push notifications are handled by Apple and Google frameworks and
multiple providers can be in the same app at the same time.
# 2. Configure your app to support push notifications from Iterable You can find push notification documentation for iOS here
and Android here. Then all new data will start to flow into iterable. The operating system will
maintain whether you have valid permissions from the user to engage in that
channel. If the user has not given permissions on push notifications, then
Iterable will mark them as unsubscribed from mobile push.
# Transfering tokens You can transfer all of your user device tokens from your previous provider
to Iterable. This is accomplished with the /registerDeviceToken API. Loop through all active tokens and add it to the /registerDeviceToken
Iterable API. If this is a new user, you will also need to call
/users/update in order to set any user fields.
NOTES Transfering tokens is not mandatory as you can simply wait till your users
update the app to include the Iterable SDK.
# Migrating channel preferences Your users may have push channel preferences from your historical push
provider and ypu may want to move those preferences over to Iterable! To do
so, you will want to use the /bulkUpdateSubscriptions API to migrate over
historical preferences.
# Slow migration Another very common approach is to slowly migrate off of the other provider.
This is accomplished by updating your app with the Iterable SDK and slowly
transition your campaigns over to Iterable. You will be able to see which
users have updated to the newest version of your app within the
Iterable Segmentation tool.
Selectively targeting users Within Iterable you can also selectively target your users based on their app
versions and only send pushes to users with the Iterable SDK. Once a
sufficient number of your users have updated, you can remove the competitor's
SDK.
View Article
When you use Android App Links in your messages, users can tap a link to your
website and get seamlessly redirected to your installed app without going
through a browser, all while having the links tracked within Iterable. Deep Link FAQs
WARNING You must set up iOS deep linking
before implementing Android deep linking (they rely on similar architecture).
# Table of contents
Setup
1. Enable App Links
2. Upload assetlinks.json
3. Determine which links to rewrite
4. Set up the track and get redirect call
FAQ
# Setup
# 1. Enable App Links
Set up your application to enable App Links via the instructions
here. Create Intent Handlers for URIs Generate the assetlinks.json file
# 2. Upload assetlinks.json
After you generate the assetlinks.json file with your app's
fingerprint, the .well-known/assetlinks.json file will need to be
hosted by Iterable, so you can send it to us by email. Once the assetlinks.json file has been uploaded, you can test it out via the
Statement List Generator and Tester.
# 3. Determine which links to rewrite Iterable re-writes links defined by your uploaded
apple-app-site-association file. See iOS Universal Links Setup
to learn how to set up that file.
# 4. Set up the track and get redirect call For App Links to work with link rewriting in emails, you need to set up an
assetlinks.json file in the Iterable project. If you already have a urlHandler, you can use the same handler can be used
for email deep links by calling handleAppLink in the activity that handles
all app links in your app: // MainActivity.java
@Override
public void onCreate() {
super.onCreate();
...
handleIntent(getIntent());
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null) {
handleIntent(intent);
}
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() != null) {
IterableApi.handleAppLink(intent.getDataString());
// Overwrite the intent to make sure we don't open the deep link
// again when the user opens our app later from the task manager
setIntent(new Intent(Intent.ACTION_MAIN));
}
}
Alternatively, call getAndTrackDeeplink along with a callback to handle the
original deep link URL. You can use this method for any incoming URLs, as it
will execute the callback without changing the URL for non-Iterable URLs. IterableApi.getAndTrackDeeplink(uri, new IterableHelper.IterableActionHandler() {
@Override
public void execute(String result) {
Log.d("HandleDeeplink", "Redirected to: "+ result);
// Handle the original deep link URL here
}
});
# FAQ For answers to common questions about deep links, read the .
View Article
Below you can find how to confirm whether your events are working or how to
fix a setup that doesn't seem to work.
# Table of contents
Testing
Troubleshooting
Push opens are not tracked
Custom events tracking
# Testing Navigate to Audience > Contact Lookup to view a user's tracked events: # Sample events: Click on the Event History section of your test user to confirm that your
events are being tracked to the correct user. When inspecting the events,
verify that the dataFields object contains any passed-in data.
NOTES
By default, Iterable will track some information on the user (like image or
IP address) from third party systems. If you would like this tracking turned
off, please notify your customer success manager or contact
[email protected]. Custom events are starred. System events are represented with a checkbox.
# Troubleshooting
Double-check the API key Check the correct user based on whether you initiated the SDK with an Email
or UserId identify call.
# Push opens are not tracked Make sure you are on the latest version of SDK. Iterable Android SDK can be
found here and iOS can be
found here.
Custom events tracking Make sure you are using a call to track event when trying to track custom
events. You can either use API events/track or use following code to add
custom event tracking to your app Swift IterableAPI.track(event: "Custom_event", dataFields: ["key": "value"])
Java IterableApi.getInstance().track("Custom_event", datafields);
View Article
The Iterable mobile SDK can track user events as a way to record a specific
action at a given time.
NOTES Iterable does not currently charge for track calls but we still encourage our
customers to only track relevant and actionable events within the platform in
order to reduce noise and focus on important milestones for your user.
# Table of contents
Custom event names
Tracking custom events
Tracking purchase events
Tracking purchase event metadata
# Custom event names It is better not to include spaces in your custom event names, because it
requires extra handlebar logic within the plaform. For example, when a user
signs up, you will likely want to define it as signUp or signs_up but not
Signs Up.
# Tracking custom events Most events tracked within Iterable will be unique to your business and
distinct use case. Below are some examples of how to structure your custom
events. Swift IterableAPI.track(event: "Custom_event", dataFields: ["key": "value"])
Java IterableApi.getInstance().track("Custom_event", datafields);
# Tracking purchase events Iterable has a dedicated endpoint for tracking purchases. It is recommended
to use this call to enable Iterable to better track purchase analytics and
attribution. There are 2 ways to track purchases in the Iterable SDK.
NOTES The SDK by default will track campaign ID and Template ID. For more
information on setting up attribution from email, please visit our deep
linking section.
Swift // Example price field
let price_from_app: NSNumber = 4.99
//Create an array of commerce Items
let items_from_app = [CommerceItem(id: "String", name: "String", price: 4.99, quantity: 1)]
// Iterable Track Call
IterableAPI.track(purchase: price_from_app, items: items_from_app)
Java Double total = new Double(4.99);
List<CommerceItem> items = new ArrayList<CommerceItem>();
items.add(new CommerceItem("String", "String", 4.99, 1));
IterableApi.getInstance().trackPurchase(total, items);
# Tracking purchase event metadata You can include datafields (also known as metadata) in the track purchase
call as well. This can be any data that you would like to leverage in future
campaigns. Swift // Example data fields
let dataField : [String: Any] = [
"Store_Address":[
"Street1": "123 Main St",
"Street2": "Apt 1",
"City": "Iter-a-ville",
"State": "Ca",
"Zip": "90210"
]
]
// Example price field
let price_from_app: NSNumber = 4.99
//Create an array of commerce Items
let items_from_app = [CommerceItem(id: "String", name: "String", price: 4.99, quantity: 1)]
// Iterable Track Call
trackPurchase(price_from_app, items: items_from_app, dataFields: dataField)
Java JSONObject store_address = new JSONObject();
final JSONObject datafields = new JSONObject();
try {
store_address.put("Street1", "123 Main St");
store_address.put("Street2", "Apt 1");
store_address.put("City", "Iter-a-ville");
store_address.put("State", "CA");
store_address.put("Zip", "90210");
datafields.put("dataFields", address);
} catch (JSONException e) {
e.printStackTrace();
}
Double total = new Double(4.99);
List<CommerceItem> items = new ArrayList<CommerceItem>();
items.add(new CommerceItem("String", "String", 4.99, 1));
IterableApi.getInstance().trackPurchase(total, items, datafields);
View Article
#
# Table of contents
Push notification setup FAQs
What does OS Notifications toggle do?
What is the difference between endpointEnabled and notificationsEnabled?
When using Segment, is it possible to use the Segment Identify call to add device tokens to user profiles?
Is it possible to send push notifications to apps that do not incorporate Iterable's mobile SDKs?
Is it possible to export push tokens for my users from our existing push provider and add them into Iterable using the POST /users/registerDeviceToken API?
Will users of old app versions (in which Iterable's SDK is installed) receive Iterable push notifications, assuming they have valid push tokens on their Iterable user profiles?
If users upgrade from old app versions (without Iterable's SDK installed) to new app versions (with Iterable's SDK installed), will they receive push notifications from Iterable before opening the new version of the app?
If users opted in to push notifications when using older versions of an app, will they continue to receive push notifications after installing new versions of that same app (even if they aren't asked to opt in to push notifications again)?
Is it possible to track custom events and properties?
Is there a maximum length or size for push notifications?
What is the payload that is received on device?
In-app message FAQs
What kind of devices can display in-app messages?
Are in-app messages available for all types of campaigns?
Can in-app messages be associated with Iterable message channels?
Is it possible to receive in-app messages in apps not configured to use push notifications?
How can in-app messages be customized?
When can mobile apps display in-app messages?
How is it possible to control in-app message rendering?
How does a mobile app know when new in-app messages are available?
Will users see the same in-app messages more than once?
What versions of Iterable's mobile SDK support in-app messages?
Is it possible to receive and display in-app messages without using Iterable's mobile SDKs?
Is it possible to create a close button that looks like an X?
What happens when a user receives multiple in-app messages?
What is the difference between POST /api/events/inAppConsume and POST /api/inApp/cancel?
Deep Link FAQs
What happens if a user clicks on a Universal Link associated with an app they do not have installed?
Is it possible to have more than one apple-app-site-association file for my domain?
Will this work for subdomains (cats.example.com) or only the top level domain (example.com)?
What should an apple-app-site-association file look like? How does all this work?
Can you illustrate the flow in a more graphical form?
Is it possible to use wildcards in an apple-app-site-association file?
Must the apple-app-site-association file include the Iterable appId section?
What does an apple-app-site-association file look like?
# Push notification setup FAQs
# What does OS Notifications toggle do? OS Notifications toggle on Android, when enabled, let's OS render the
notification message by sending a push of type "notification message". If you
are using SDK, you don't need to enable the toggle. OS notifications when
disabled send data message to Android. SDKs render data message type.
# What is the difference between endpointEnabled and notificationsEnabled?
endpointEnabled is a flag set on the server based on token validity.
notificationsEnabled is a flag indicating device settings.
# When using Segment, is it possible to use the Segment Identify call to add device tokens to user profiles? Unfortunately, you cannot use this method. You must call the Iterable
POST /api/users/registerDeviceToken
API endpoint to add push tokens.
# Is it possible to send push notifications to apps that do not incorporate Iterable's mobile SDKs? Yes, this is possible. Add valid device tokens to user profiles via the
POST /api/users/registerDeviceToken
API endpoint. We still recommend implementing the Iterable SDK ( iOS,
Android ) since it does
make it easier to send the token to Iterable for new versions of your app.
Additional benefits include automatic tracking of push opens, simple
implementation of rich content in push notifications, and support for deep
linking.
# Is it possible to export push tokens for my users from our existing push provider and add them into Iterable using the POST /users/registerDeviceToken API? Yes, these push tokens should work. On Android, a push token is associated with the device, app, and the
project/API key you request it for. On iOS, the push token is associated with the device, app, and
certificate/provisioning profile the app is running under when requesting the
token.
# Will users of old app versions (in which Iterable's SDK is installed) receive Iterable push notifications, assuming they have valid push tokens on their Iterable user profiles? As long as the push token is still valid and the user has opted in to push
notifications, the push notification will work.
# If users upgrade from old app versions (without Iterable's SDK installed) to new app versions (with Iterable's SDK installed), will they receive push notifications from Iterable before opening the new version of the app? Depends. If APNS/GCM decides the push token remains the same with the new
app, then it should work fine. However, the push tokens are subject to
change. Various factors such as OS upgrades, app upgrades, wiping your
device, etc. may or may not change the token (depending on OS and other
factors). This Stack Overflow post
provides more details.
# If users opted in to push notifications when using older versions of an app, will they continue to receive push notifications after installing new versions of that same app (even if they aren't asked to opt in to push notifications again)? This will work. Each time the app is opened, the
POST /api/users/registerDeviceToken
API call will pass the token to Iterable. If the token has changed, it will
update the user's profile in Iterable with the new token. Since the user has
already opted in to receive push from your app in the past, the user will
receive push notifications.
# Is it possible to track custom events and properties? You can track custom events via the track function call on the track SDK. You
can also update user contact fields via the updateUser function call on the
SDK.
# Is there a maximum length or size for push notifications? There are best practices for the size of your push notifications to ensure
deliverability and high engagement rates. Here are some key numbers to keep in mind:
Limit the size of a push notification to 2KB, including the entire
message and its payload. 48 lines or 140280 characters: Depending on what language your team
is using, you might be able to deliver a 2000 character message. However,
remember that your message may be truncated after four to eight lines. Short
and sweet is best. Plus, since we know they are on mobile, some users may be
using expensive cellular data to engage with you instead of WiFi, so be kind
and shrink those message sizes.
# What is the payload that is received on device?
The payload received on device contains a specific iterable section with
the key itbl, which is used by the SDK to track the notification. The notification also contains all of the platform-specific information as
expected (for example, aps for iOS).
The custom payload data is set on the root level of the notification payload.
iOS example: {
"itbl": {
"templateId": 7,
"campaignId": 2,
"messageId": "38e834ad76a149eb918a9d66e8dd9015",
"isGhostPush": false
},
"aps": {
"alert": "test push message"
},
"custom": "",
"fields": "",
"here": ""
}
Android example: Bundle[{itbl={"campaignId":207256,"isGhostPush":false,"messageId":"d3a8a725bdc34f2699272b38de3a08e0","templateId":296434}, google.sent_time=1481139004, body=Android URI deeplink test, from=668868396390, custom-key=custom-value, uri=itblTest://testingDeeplink, google.message_id=0:1512675342843879%694c27b9f9fd7ece}]
# In-app message FAQs
# What kind of devices can display in-app messages? iOS and Android devices can display in-app messages.
# Are in-app messages available for all types of campaigns? Yes. Iterable supports in-app messages for blast, triggered, and
workflow-related campaigns.
# Can in-app messages be associated with Iterable message channels? Yes, in-app messages can be tied to different
message channels and types.
# Is it possible to receive in-app messages in apps not configured to use push notifications? Iterable uses silent push to notify device that in-app messages are
available. We use silent pushes so client doesnt have to continuously poll
the server to check if in-apps are available. If you do not have push set up,
you will still be able to receive in-app messages on app launch and when app
is in foreground.
# How can in-app messages be customized? Customization of the in-app can be done from in-app templates. SDK fetches
the HTML from server and displays.
# When can mobile apps display in-app messages? In-app messages display when an app is in the foreground. In addition to listening for silent push notifications, Iterable's mobile SDK
checks for new in-app messages at strategic timessuch as when the app comes
to the foreground.
# How is it possible to control in-app message rendering? You can call getMessages and render in-app at a specific location in your
app.
# How does a mobile app know when new in-app messages are available? Iterable alerts mobile apps to the existence of new in-app messages by
sending silent push notifications. After receiving a silent push notification
and downloading its associated in-app messages, an app can decide whether or
not to display them, and in what order. Silent push notifications aren't visible or audible to the user. Instead,
they're background notifications that serve as a communication mechanism
between Iterable and the app.
# Will users see the same in-app messages more than once? No, in-app messages will not be shown to users who have already seen them.
# What versions of Iterable's mobile SDK support in-app messages? In-app messages have been supported since version 4.4.0
of the iOS SDK and version 2.2.0
of the Android SDK. However, it's always best to use the most recent version of Iterable's mobile
SDKs. For information about the deprecation and end-of-life schedule for older
SDK versions, read the iOS SDK Deprecation and End-of-Life Schedule
and the Android SDK Deprecation and End-of-Life Schedule.
# Is it possible to receive and display in-app messages without using Iterable's mobile SDKs? Yes. For instructions, read Setting up In-App Messages (Without the SDK).
However, Iterable strongly recommends using the mobile SDKs.
# Is it possible to create a close button that looks like an X? One way to create an X-style close button is to use the Bee Free editor with
a configuration similar to the following:
Add a button to the message template Set the button's text to X
Set the button's URL to action://, which will close the in-app
message when tapped Choose a Background Color for the button Choose a Text Color for the button For Align, choose right Specify a Border Radius of 20
For Content Padding, specify:
0 for Top and Bottom
10 for Left and Right
Specify a Solid, 1-pixel border of any desired color.
# What happens when a user receives multiple in-app messages? Unless the mobile app has been customized to selectively display in-app
messages, it will show all in-app messages in the order that you send them.
# What is the difference between POST /api/events/inAppConsume and POST /api/inApp/cancel?
POST /api/events/inAppConsume Indicates that a user has viewed or deleted an in-app message and remove
the message from the server's message queue. It's only necessary to call
this endpoint if you're not using one of Iterable's mobile SDKs.
POST /api/campaigns/cancel Indicates that an in-app message should not be delivered to a user and
remove it from the server's queue.
# Deep Link FAQs
# What happens if a user clicks on a Universal Link associated with an app they do not have installed? The user will get directed to your website in his/her browser, like a normal
link, as long as your website has been set up to handle Universal Links. On iOS, this works for users running iOS 9 or higher. This also works for Android App Links.
# Is it possible to have more than one apple-app-site-association file for my domain? Each domain can only have a single apple-app-site-association file.
# Will this work for subdomains (cats.example.com) or only the top level domain (example.com)? We now rewrite URLs for subdomains as well as top-level domains.
# What should an apple-app-site-association file look like? How does all this work? Here's a sample apple-app-site-association file that we will use to walk
through the entire process: {
"applinks": {
"apps": [],
"details": [
{
"appID": "appID.bundleID",
"paths": [
"/a/*" <-- [RULE 1] Mandatory rule required in all Iterable association files
]
},
{
"appID": "iterable",
"paths": [
"NOT /samplepath/toignore", <-- [RULE 2] Tells Iterable to write as regular (non-Universal) link
"/samplepath/*" <-- [RULE 3] Tells Iterable to rewrite into Universal Path
]
}
]
}
}
WARNING Only edit the fields displayed in red above.
When you send that file to Iterable, we store a copy of it on our servers.
When you send a message, the following happens:
Iterable goes through each link in the message and compares it to the list
of rules in the apple-app-site-association file to see if there is a
match. For this example, let's assume that one of your links is
yourdomain.com/samplepath/hello.html. If there is a match, Iterable will rewrite the link before sending it out
in your message. In this example, yourdomain.com/samplepath/hello.html
matches RULE 3 above and will be rewritten into
yourdomain.com/a/ABCD1234, where ABCD1234 is a unique identifier for that
link (you don't have to worry about this unique identifier). At this point, Iterable also stores a mapping of /a/ABCD1234 to
/samplepath/hello.html on the Iterable servers. When a user clicks on the rewritten link /a/ABCD1234, the user's device
will detect it based on RULE 1 in the apple-app-site-association file (a
copy of the file is stored on device) and opens your app based on the appID
in the file. Your app then uses the Iterable SDK to make a call to Iterable's servers
to track the click and get the actual destination /samplepath/hello.html. Your app receives /samplepath/hello.html from the Iterable server and
opens the destination within your app.
# Can you illustrate the flow in a more graphical form? Sure thing! Here's a similar example for iOS Universal Links to the
snapface.com domain.
# Is it possible to use wildcards in an apple-app-site-association file? Yes, you can use * to specify an entire section (matches all substrings) or ?
to match any single character. You can combine both wildcards in a single
path, such as /foo/*/bar/201?/mypage which would match
/foo/abc/bar/2015/mypage and /foo/def/bar/2019/mypage. For more details, check out Apple's documentation here.
# Must the apple-app-site-association file include the Iterable appId section? Yes. The purpose of the Iterable appID section is to provide more control
over which paths get rewritten by Iterable. If you want a subset of paths to
be opened in Iterable but not the others, then placing those paths under the
Iterable appID section will limit rewriting to those paths. If you want all paths to be rewritten, use: {
"appID": "iterable",
"paths": ["*"]
}
What does an apple-app-site-association file look like? Use this template to get started: {
"applinks": {
"apps": [],
"details": [
{
"appID": "appID.bundleID",
"paths": [
"/a/*"
]
},
{
"appID": "iterable",
"paths": [
"PATHS TO BE REDIRECTED GO HERE"
]
}
]
}
}
View Article
this guide
# Table of contents
Troubleshooting
iOS in-app message is not shown
Android in-app message is not shown
No messages received
# Troubleshooting By default, when an in-app message is sent, it sits on server queue. It gets
pulled by SDK when App is in the foreground. You can see which in-app
messages are in the queue by sending a test campaign and then by going to our
API docs for In-app_getMessages,
add your API key and email of your test user. The GET request will then return all the messages in the queue and you can
determine if you sent the message to the right location.
# iOS in-app message is not shown Make sure you call IterableAppIntegration from didReceiveRemoteNotification: // In AppDelegate.swift
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
IterableAppIntegration.application(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler)
}
# Android in-app message is not shown If you are implementing your own onMessageReceived() and onNewToken()
methods, make sure you forward onMessageReceived() and onNewToken() calls
to IterableFirebaseMessagingService.handleMessageReceived and
IterableFirebaseMessagingService.handleTokenRefresh respectively. @Override
public void onMessageReceived(RemoteMessage remoteMessage) {
IterableFirebaseMessagingService.handleMessageReceived(this, remoteMessage);
}
# No messages received If you do not see messages received during troubleshooting, verify your
notification setup. Iterable uses silent push to alert the app when in-app
is available. Follow
to see if you have push notifications set up correctly. In iOS, make sure you have Background Fetch enabled for your app:
View Article
This document describes how to set up and test the Iterable SDK. You can add
the SDK via Cocoapods,
Carthage, or direct import of the libraries. They
should all have the same result.
NOTES The Iterable iOS SDK is a Swift implementation of an iOS client for Iterable,
for iOS versions 9.0 and higher.
# Table Of Contents
Table Of Contents
CocoaPods
Carthage
Installing manually
Initializing
1. Import the IterableSDK module
2. Create mobile API Key
3. Set the API and initialize the SDK
4. Add code to your app delegate
5. Create a test user
Next steps
# CocoaPods To use CocoaPods to install Iterable's iOS SDK, first
install CocoaPods. sudo gem install cocoapods
Then, follow these steps:
If your project does not yet have a Podfile, create one.
In the terminal, navigate to the directory containing your project's
.xcodeproj file
Run the following command: pod init
Edit your project's Podfile.
Add the Iterable-iOS-SDK pod to your project's app target. If your app will receive push notifications containing media
attachments (images, etc.), add the YOUR-APP-notification-extension
pod to your project's Notification Service Extension target.
Identifying the User After these changes, your Podfile should look similar to the
following: platform :ios, '11.0'
use_frameworks!
target 'swift-sample-app' do
pod 'Iterable-iOS-SDK'
end
target 'swift-sample-app-notification-extension' do
pod 'Iterable-iOS-AppExtensions'
end
You must include use_frameworks! in your Podfile, no matter if
your app is based on Swift or Objective-C. If your project cannot use
this option, install the SDK manually.
In the terminal, run the following command to install the SDK (and app
extensions, if necessary): pod install
This will create an .xcworkspace file. To open your project in Xcode,
use this file instead of the .xcodeproj file.
For more information, take a look at the CocoaPods
documentation.
# Carthage To use Carthage to install Iterable's iOS SDK, first install Carthage.
Then, follow these steps:
If it does not yet exist, create a file named Cartfile in the same
directory as your Xcode project.
Edit Cartfile, adding the following line: github "Iterable/swift-sdk"
In the terminal, in the same directory as your Cartfile, run the
following command: carthage update
In Xcode, navigate to the Build Phases section for your app's target.
Click the + icon and select New Run Script Phase. A Run Script
section will appear.
In the Run Script section, below the Shell input, add the
following command: /usr/local/bin/carthage copy-frameworks
In the Input Files section, click + and add the following path: $(SRCROOT)/Carthage/Build/iOS/IterableSDK.framework
In the Output Files section, add the path to the copied framework: $(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/IterableSDK.framework
Add <Xcode project directory>/Carthage/Build/iOS/IterableSDK.framework
to your Xcode project by dragging it into the Xcode Project Navigator.
When prompted by Xcode, add the framework to your app's target. If your app will be using push notifications that contain media
attachments (images, etc.), repeat steps 6 through 8, substituting
IterableAppExtensions.framework for IterableSDK.framework. In step 8,
add IterableAppExtensions.framework to your project's Notification
Service Extension target (instead of the app target).
For more information, take a look at the Carthage
documentation.
# Installing manually Attached to the release, you will find two framework bundles:
IterableSDK.framework and IterableAppExtensions.framework.
In Xcode, choose the target for your app. Now, add the
IterableSDK.framework to the Embedded Binaries section. If you want
to use an Iterable Rich Notification Extension, you will have to add
IterableAppExtensions.framework to the embedded binaries section as well.
If you want to use an Iterable Rich Notifiation Extension, you will need
to add IterableAppExtension.framework to Linked Frameworks and
Libraries section of your app extension target (not app target). Please
note that you will have to add the IterableAppExtension.framework bundle
to both the app target (step 1) and app extension target (step 2) of your
project. In the app target, it goes in the Embedded Binaries section and
in app extension target it goes in the Linked Frameworks and Libraries
section.
In build settings, set Always Embed Swift Standard Libraries setting
to Yes. This is necessary for both Swift and Objective-C projects.
# Initializing Now that the SDK library is referencable by the app, it must be initialized:
Import the IterableSDK module Set the API and Configuring the SDK Initialize
# 1. Import the IterableSDK module To use the IterableSDK module, import it at the top of your Objective-C
or Swift files: Swift // In AppDelegate.swift file
// and any other file where you are using IterableSDK
import IterableSDK
Objective-C // In AppDelegate.m file
// and any other file where you are using IterableSDK
@import IterableSDK;
NOTES If you have errors please see our troubleshooting at the end of this section
# 2. Create mobile API Key Go to Integrations > API Keys and create a mobile specific API for your
app, as shown below: Screenshot of selection choice.
# 3. Set the API and initialize the SDK In the application:didFinishLaunchingWithOptions: method of your app
delegate, call initialize(apiKey:launchOptions:config:), passing in your
Iterable API key: Swift let config = IterableConfig()
config.customActionDelegate = self
config.urlDelegate = self
//We will add our push integration names later
config.sandboxPushIntegrationName = "<your-bundle-app-ID>"
config.pushIntegrationName = "<your-bundle-app-ID>"
IterableAPI.initialize(apiKey: "<your-api-key>", launchOptions: launchOptions, config: config)
Objective-C IterableConfig *config = [[IterableConfig alloc] init];
config.sandboxPushIntegrationName = @"<your-bundle-app-ID>";
config.pushIntegrationName = @"<your-bundle-app-ID>";
[IterableAPI initializeWithApiKey:@"<your-api-key>" launchOptions:launchOptions config:config]
NOTES Iterable config() provides configuration and customization options for the
Iterable SDK. We will use it later for setting up push and in-app.
# 4. Add code to your app delegate We will cover this code in more detail in each section later but for now,
please add this code to your AppDelegate file.
# Code for push notifications Swift func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
IterableAPI.register(token: deviceToken)
}
Objective-C - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[IterableAPI registerToken:deviceToken];
}
# Code for push tracking From this method, call the userNotificationCenter(_:didReceive:withCompletionHandler:)
method on IterableAppIntegration. This tracks a push open event and
performs the associated action. Swift public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
IterableAppIntegration.userNotificationCenter(center, didReceive: response, withCompletionHandler: completionHandler)
}
Objective-C - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
[IterableAppIntegration userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
# Code for in-app messages In-app messages are handled via silent push messages from the server. When
your application receives a silent push, call the Iterable iOS SDK in your
app delegate, as follows: Swift // In AppDelegate.swift
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
IterableAppIntegration.application(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler)
}
Objective-C - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[IterableAppIntegration application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
Turn on Remote Notifications under Signing and Capabilities in Your
Xcode Target.
# 5. Create a test user Register a test email right after the config file and you should now see a
test user within the Contact Lookup section of the platform. Swift IterableAPI.email = "[email protected]"
IterableAPI.updateUser(["init_test":"test"], mergeNestedObjects: false)
Objective-C IterableAPI.email = @"[email protected]";
Go to Iterable, select Audiences > Segmentation and click refresh to see
your test user! If you do not see your test user, read
Testing and Troubleshooting the Iterable SDK.
# Next steps After the SDK has been installed, read about .
View Article
Iterable's Android SDK Release Notes Iterable's iOS and Android mobile SDKs help you to:
# Send and track push notifications
The Iterable SDK will automatically track push notification sends, opens,
and bounces Automatically track device uninstalls Maintain the most up-to-date device tokens
# Send and track in-app messages
Reduce load on your system by sending a silent push to the device to
efficiently pull in-apps to the device Store in-apps on the device for faster load time Use a mobile inbox
# Save implementation time
Provide error handling to ensure accuracy Minimize the amount of code needed to deploy your mobile app with Iterable Provide tested and proven code for new Apple / Android OS updates Easily update user profile and event data
# Automatically track and attribute engagement events
Update user profile and event data for enriched triggered campaigns Automatically attribute to conversion events to specific campaigns Help measure effectiveness of your campaigns
NOTES Itegrating the Iterable SDK will save your team time and effort. However,
it is possible to connect your mobile app to Iterable without using the SDK.
# Without the Iterable SDK Without the Iterable SDK you will lose some benefits of the platform and it
will require significantly more effort, especially around:
Push action buttons In-app modals Automatic tracking of attribution data Mobile Inbox
# iOS Next Steps
iOS SDK Initialization and Setup User Identity Tracking events iOS Push Notifications iOS Deep Linking iOS In-app Messages Mobile Inbox
# iOS Sample projects and Github For sample projects, look at the following repositories:
Swift sample project Objective-C sample project Swift Github Objective-C Github Iterable's iOS SDK Release Notes
# Android Next Steps
Android SDK Initialization and Setup User Identity Tracking events Android Push Notifications Android Deep Linking Android In-app Messages Mobile Inbox
# Android Github
Android Github
View Article
Here are some common issues with troubleshooting your SDK initialization. Identifying the User
# Table of contents
iOS SDK initialization testing
iOS SDK troubleshooting
CocoaPods troubleshooting
Carthage troubleshooting
Manual import troubleshooting
Android SDK initialization testing
Android SDK initialization troubleshooting
Gradle sync failed
Multiple push providers
Next steps
# iOS SDK initialization testing
Can you add the import the library without an error: import IterableSDK
Double check your API credentials
# iOS SDK troubleshooting
# CocoaPods troubleshooting
Update your pods Check the syntax of your podfile Ensure you're opening the Xcode .xcworkspace, not the .xcodeproject file
Make sure you have uncommented use_frameworks!. You must include
use_frameworks! in your Podfile, no matter if your app is based on Swift or
Objective-C. If your project cannot use this option, install the SDK
manually. If you see this error: [!] CocoaPods could not find compatible versions for pod "Iterable-iOS-AppExtensions":
In Podfile:
Iterable-iOS-AppExtensions
There are only pre-release versions available satisfying the following requirements:
'Iterable-iOS-AppExtensions', '>= 0'
You should explicitly specify the version in order to install a pre-release version
Make sure you are using verified latest release of
CocoaPods. To update CocoaPods run following command in the terminal: sudo gem install cocoapods
Make sure you add the Iterable-iOS-AppExtensions pod, without a specific
version (or =>0).
# Carthage troubleshooting
Update to the latest released version of the SDK Update Carthage
# Manual import troubleshooting
Ensure you manually linked the libraries Check that the libraries are listed in your Linked Frameworks and Library
section under the General tab
# Android SDK initialization testing To make sure SDK is successfully integrated, perform a gradle sync.
# Android SDK initialization troubleshooting
# Gradle sync failed
Gradle sync failed with ERROR: Failed to resolve: com.iterable:iterableapi:3.1.3
Ensure you have jcenter() in project level gradle file:
allprojects {
repositories {
google()
jcenter()
}
}
# Multiple push providers To learn how to work with multiple push providers, please read
Setting up Android Push Notifications.
# Next steps After installing the SDK, please read .
View Article
Update User Optional Recommendations The Iterable SDK can identify users by email or user ID.
# Table of contents
Overview
Identifying the user by email
Identifying the user by user ID
Identifying the device of the user
Auto push registration
Send the device token to Iterable
Updating the user email and a customer userId
Next steps
# Overview To identify a user, you'll need to do two things: specify an email address
or user ID, and then call updateUser to send that value to Iterable.
# Identifying the user by email Email is typically used as the key identify within Iterable because it tracks
across devices to aggregate data between a user's phones, tablet, web-site
activity or even IoT (Internet-of-Things) device. Iterable also allows for multi-dimensional nested data types, meaning you can
organize your data based on relevant key values. Once you have an email address or user ID for your app's current user, set
IterableAPI.email or IterableAPI.userId. For example:
WARNING
Don't specify both email and userId in the same call, as they will be
treated as different users by the SDK. Only use one type of identifier, email
or userId, to identify the user. Your app will not be able to receive push notifications until you set one
of these values
Add this line of code as soon as you know the user's email: Swift IterableAPI.email = "[email protected]"
Objective-C IterableAPI.email = @"[email protected]";
Java IterableApi.getInstance().setEmail("[email protected]");
NOTES Please see Iterable-Specific User Specific Profile Fields
to ensure you don't add data that is specific to set fields in Iterable.
# Identifying the user by user ID Iterable can also identify user by user ID. However, all things being equal,
it is recommended to use email as the key identifier. Swift IterableAPI.userId = "user123"
Objective-C IterableAPI.userId = @"user123";
Java IterableApi.getInstance.setUserId("user123");
You can add the userId identifier at any point after the IterableConfig()
call.
NOTES
When creating a user with a userId, Iterable also assigns that user a
fake email adress (using the placeholder.email domain). For example,
setting a userId of user123 gives that user anemail similar to
[email protected]. We will discuss in the next section
how we can update the email of an unkown user. A user ID can be up to 52 characters long.
# Identifying the device of the user For Iterable to send push notifications to an iOS device, it must know the
unique token assigned to that device by Apple or Android. Iterable uses silent push notifications to tell iOS apps when to fetch new
in-app messages from the server. Because of this, your app must register for
remote notifications with Apple even if you do not plan to send it any push
notifications.
# Auto push registration IterableConfig.autoPushRegistration determines whether or not the SDK will: Automatically register for a device token when the the SDK is given a new
email address or user ID. Disable the device token for the previous user when
a new user logs in. If IterableConfig.autoPushRegistration is true (the default value): Setting IterableAPI.email or IterableAPI.userId causes the SDK to
automatically call the registerForRemoteNotifications() method on
UIApplication and pass the resulting device token to the
application(_:didRegisterForRemoteNotificationsWithDeviceToken:) method on
the app delegate. If IterableConfig.autoPushRegistration is false: After setting IterableAPI.email or IterableAPI.userId, you must
manually call the registerForRemoteNotifications() method on
UIApplication. This will fetch the device token from Apple and pass it to
the application(_:didRegisterForRemoteNotificationsWithDeviceToken:) method
on the app delegate.
# Send the device token to Iterable
NOTES
Iterable users the device token to send push notifications and in-app
messages. Users do not need to opt in to Apple push notifications for Iterable to get
the device token.
To send the device token to Iterable and save it on the current user's
profile, call IterableAPI.register(token:) from the
application(_:didRegisterForRemoteNotificationsWithDeviceToken:) method on
UIApplicationDelegate. For example: Swift func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
IterableAPI.register(token: deviceToken)
}
Objective-C - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[IterableAPI registerToken:deviceToken];
}
Java
// Iterable SDK automatically registers the push token with Iterable
// whenever setEmail or setUserId is called.
// If you want to trigger token registration manually, first disable automatic
// registration by calling setAutoPushRegistration(false) on IterableConfig.Builder when initializing the SDK.
// Than call registerForPush whenever you want to register the token:
// Only use this line if you want to register push manually.
// IterableApi.getInstance().registerForPush();
Once you register for push, you should see the device on the user profile,
which can be accessed by going to the Iterable dashboard, clicking
Audiences > Contact Lookup. Now you'll always have the most up to date device token and can export Device
Identifier (IDFA) for future marketing campaigns.
# Updating the user email and a customer userId This code body is used to identify users when you have both the email and
UserID. You need to add the new user ID in two places. Swift IterableAPI.updateEmail("[email protected]", onSuccess: { (_) in
IterableAPI.updateUser([AnyHashable.ITBL_KEY_USER_ID : "new_user_id"], mergeNestedObjects: false, onSuccess: { (_) in
IterableAPI.userId = "new_user_id" // note this needs to be set after both calls have finished successfully
}, onFailure: { (_, _) in
ITBError()
})
}) { (_, _) in
ITBError()
}
Java IterableApi.getInstance().updateEmail("[email protected]", new IterableHelper.SuccessHandler() {
@Override
public void onSuccess(JSONObject data) {
JSONObject userIDobj = new JSONObject();
try {
userIDobj.put("userId", "newUserId");
} catch (JSONException e) {
e.printStackTrace();
}
IterableApi.getInstance().updateUser(userIDobj);
}
}, new IterableHelper.FailureHandler() {
@Override
public void onFailure(String reason, JSONObject data) {
Log.e(TAG, reason)
}
});
# Next steps To troubleshoot user identification, read User Testing and Troubleshooting. If you have successfully identified the user for your use case, please read
Updating User Profile
and . If you are seeing your user incorrectly identified, please read
View Article
Iterable can customize your push notifications with action buttons, animated
GIFs, images, sounds, and deep linking. Setting up Android Push Notifications
# Table of contents
Adding a push extension
Configure support for rich push notifications
Adding sounds to iOS push notifications
Adding deep links to iOS push notifications
Further reading
# Adding a push extension Follow these instructions:
First, create a push extension in the target settings of Xcode. This is
will enable your extension to reference the pre-built libraries of code. Edit your project's Podfile. Add the Iterable-iOS-SDK pod to your projec's app target. If your app will receive push notifications containing media
attachments (images, etc.), add the Iterable-iOS-AppExtensions pod to
your project's Notification Service Extension target.
After these changes, your Podfile should look similar to the
following: platform :ios, '11.0'
use_frameworks!
target 'swift-sample-app' do
pod 'Iterable-iOS-SDK'
end
target 'swift-sample-app-notification-extension' do
pod 'Iterable-iOS-AppExtensions'
end
You must include use_frameworks! in your Podfile, no matter if
your app is based on Swift or Objective-C. If your project cannot use
this option, install the SDK manually. The following sections describe the technical setup necessary for various
iOS push notification customizations in Iterable. For marketer-specific information about how to configure these features in
Iterable when sending a campaign, read
Creating a Push Notification Campaign.
# Configure support for rich push notifications For push notifications to contain images, animated GIFs, video, or action
buttons, you must create a Notification Service Extension. The Iterable iOS SDK provides a Notification Service Extension implementation
that handles media attachments and action buttons. To use it:
Include Iterable-iOS-AppExtensions in your Podfile, as explained
above. Create a new target of type Notification Service Extension in your
Xcode project. If you are calling Iterable SDK from Swift, edit the NotificationService
class (auto-generated by Xcode) so that it extends
ITBNotificationServiceExtension. If you are using Objective-C, use delegation instead of inheritance.
Swift import UserNotifications
import IterableAppExtensions
class NotificationService: ITBNotificationServiceExtension {
}
Objective-C // File: NotificationService.m
#import "NotificationService.h"
@import IterableAppExtensions;
@interface NotificationService ()
@property (nonatomic, strong) ITBNotificationServiceExtension *baseExtension;
@end
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.baseExtension = [[ITBNotificationServiceExtension alloc] init];
[self.baseExtension didReceiveNotificationRequest:request withContentHandler:contentHandler];
}
- (void)serviceExtensionTimeWillExpire {
[self.baseExtension serviceExtensionTimeWillExpire];
}
@end
# Adding sounds to iOS push notifications To add sound to iOS push notifications, follow these instructions:
Place the necessary sound files in the iOS project's Library/Sound
folder, or in the top-level directory of the Xcode project.
NOTE See Apple's UNNotificationSound documentation
for a list of supported sound formats.
When creating a push notification template in Iterable, put the name of the
sound file in the Sound field:
NOTES
To use the default push notification sound, set this field to default. Whether or not a device plays the sound or vibrates depends on the
user's device settings.
# Adding deep links to iOS push notifications Iterable push notification templates make it possible to set deep link
URLs for iOS and Android. To learn more about using Iterable's iOS SDK to handle deep links,
take a look at the Iterable iOS SDK documentation
on GitHub. If your app is not using Iterable's iOS SDK, it can still handle a deep link
contained in an Iterable push notification. Iterable provides the deep link
URL in the defaultAction object included in the notification's payload.
When this object's type field is set to openUrl, the data field will
contain the deep link URL. When using the SDK, code executing after an app has opened in response to a
user's interaction with a push notification can use
IterableApi.lastPushPayload to access the push notification's payload.
# Further reading For more information about push notifications in Iterable, read:
Frequently Asked Questions Creating a Push Notification Campaign Push Notification Testing and Troubleshooting Iterable iOS SDK docs Apple's UserNotifications framework documentation
.
View Article
A deep link is a URI that links to a specific location within your mobile
app. The following sections describe how to work with deep links using
Iterable's iOS SDK. Android App Links Setup
NOTES You should be able to use the same schema (pre-defined paths for presenting
deep linking to a user) as your email or third party deep links.
# Table of contents
iOS deep links
Android deep links
Handling links from push notifications
Handling email links
# iOS deep links Push notifications and action buttons may have openUrl actions attached to
them. When a URL is specified, the SDK first calls the urlDelegate object
specified on your IterableConfig object. You can use this delegate to
handle openUrl actions the same way as you handle normal deep links. If the
delegate is not set or if it returns false (the default), the SDK will open
the URL with Safari. If, upon receiving a deep link, you want to navigate to
a specific view controller in your app, do so in the urlDelegate. In the code below, DeepLinkHandler is a custom handler which is reponsible
for deep link navigation. You have to provide an implementation for deep link
navigation. Please see the sample
application
for a reference implementation for DeeplinkHandler. Swift func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// ...
// Initialize Iterable API
let config = IterableConfig()
// ...
config.urlDelegate = self
IterableAPI.initialize(apiKey: apiKey, launchOptions:launchOptions, config: config)
// ...
}
// Iterable URL Delegate. It will be called when you receive
// an `openUrl` event from push notification.
func handle(iterableURL url: URL, inContext context: IterableActionContext) -> Bool {
return DeeplinkHandler.handle(url: url)
}
Objective-C - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// ...
// Initialize Iterable SDK
IterableConfig *config = [[IterableConfig alloc] init];
// ...
config.urlDelegate = self;
[IterableAPI initializeWithApiKey:@"YOUR API KEY" launchOptions:launchOptions config:config];
// ...
}
- (BOOL)handleIterableURL:(NSURL *)url context:(IterableActionContext *)context {
// Assuming you have a DeeplinkHandler class that handles all deep link URLs and navigates to the right place in the app
return [DeeplinkHandler handleUrl:url];
}
# Android deep links
# Handling links from push notifications Push notifications and action buttons may have openUrl actions attached to
them. When a URL is specified, the SDK first calls the urlHandler specified
in your IterableConfig object. You can use this class to handle openUrl
actions the same way as you handle normal deep links. If the handler is not
set or returns NO, the SDK will open a browser with that URL. // MyApplication.java
@Override
public void onCreate() {
super.onCreate();
// ...
IterableConfig config = new IterableConfig.Builder()
.setPushIntegrationName("myPushIntegration")
.setUrlHandler(this)
.build();
IterableApi.initialize(context, "YOUR API KEY", config);
}
@Override
public boolean handleIterableURL(Uri uri, IterableActionContext actionContext) {
// Assuming you have a DeeplinkHandler class that handles all deep link URLs and navigates to the right place in the app
return DeeplinkHandler.handle(this, uri);
}
# Handling email links For App Links to work with link rewriting in emails, you need to set up an
assetlinks.json file in the Iterable project. For more information, read
. If you already have a urlHandler, the same handler can be used for email
deep links by calling handleAppLink in the activity that handles all app
links in your app: // MainActivity.java
@Override
public void onCreate() {
super.onCreate();
// ...
handleIntent(getIntent());
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null) {
handleIntent(intent);
}
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() != null) {
IterableApi.handleAppLink(intent.getDataString());
// Overwrite the intent to make sure we don't open the deep link
// again when the user opens our app later from the task manager
setIntent(new Intent(Intent.ACTION_MAIN));
}
}
Alternatively, call getAndTrackDeeplink along with a callback to handle the
original deep link URL. You can use this method for any incoming URLs, as it
will execute the callback without changing the URL for non-Iterable URLs. IterableApi.getAndTrackDeeplink(uri, new IterableHelper.IterableActionHandler() {
@Override
public void execute(String result) {
Log.d("HandleDeeplink", "Redirected to: "+ result);
// Handle the original deep link URL here
}
});
View Article
This document describes various best practices to consider when working with
push notifications. FCM
# Table of contents
Tracking uninstalls
Migrating GCM to FCM for Android
Renewing push certificates in Iterable
# Tracking uninstalls Iterable will automatically track app uninstalls. The methodology is as
follows:
A push campaign is sent to the end user. 12 hours later a "ghost push" is sent the user (a ghost push being a
silent push that will not alert the user). If the ghost push is failed to be delivered to the device due to the app
being uninstalled, the app uninstall is then tracked in Iterable.
# Migrating GCM to FCM for Android For Android push notification, Google Cloud Manager (GCM) has been deprecated
in favor of FireBase Cloud Messages (FCM). If you are on GCM, you must
migrate to the new system. You can migrate an existing GCM client app on
Android to Firebase Cloud Messaging (FCM) using the instructions in this
guide. Before getting started, keep in mind the following:
GCM and FCM SDKs cannot co-exist within an application. GCM tokens retrieved via GoogleCloudMessaging.register() or
InstanceID.getToken() will continue to work in FCM without any modification
or renewal.
Please follow this Google documentation
to complete the migration.
# Renewing push certificates in Iterable Your push notifications certificates are generally only valid for one year.
Once they expire, you must renew them by creating new certificates and
uploading them to Iterable.
NOTES
Apple should send you an email when your push notification certificate is
close to expiring. It is worth adding a calendar reminder to ensure you know exactly when the
certificates will expire. The Iterable dashboard will also note your certificates expiration date in
the Mobile Apps section.
Please follow the steps in the previous section around creating certificates.
Once you have new valid certificates, you can upload them to Iterable and
continue to receive push in your app.
Apple Docs
View Article