Skip to main content

Action Flow API

The Action Flow API can be used to:

A credential role of events is required to utilize the Action Flow API.

You can interact with the Action Flow API using Insomnia (follow the Insomnia instructions) or curl. When using curl, you'll need to set up your Authentication first.

Detailed specs and examples can be found in the Atomic API spec for the Action Flows endpoint.

Sending cards using the API

Sending cards via the API is done by sending requests to the /start, /test, csv-task/test or csv-task endpoints.
The /csv-task and /csv-task/test endpoints enables you to target users in a csv file.

Invoke an Action Flow

The start API for an Action Flow can be found in the workbench. Navigate to the card you want to send. Make sure it is published before trying to send it using the API. The Action Flow API only works for cards that are published.

Select the trigger tab. You can copy the API start trigger for sending this card. It contains the flowConfigId.

Example Action Flow requests

Using the test endpoint

As mentioned earlier, a credential role of events is required to use the test endpoint of the Action Flow API.

Triggering an Action Flow in test mode means only test users can be targeted and draft Action Flows are allowed to be sent.

# set Action Flow test API
TEST_API="https://${orgId}.customer-api.atomic.io/v1/${envId}/action-flow/${flowConfigId}/test"

# request payload
PAYLOAD =
{
"flows": [
{
"payload": {
"cardOptions": {
# card delivery options, all are optional, the Action Flow config overrides these options.
"priority": 2, # 1-10, controls the position of the card in the stream
"expires": "2021-11-18T23:42:14.383Z", # ISO8601 timestamp
"expiresInterval": "PT30M", # ISO8601 interval
"embargo": "2021-11-18T23:42:14.383Z", # ISO8601 timestamp
"targetStreamIds": ["BqWL1sT"],
"targetPlatforms": {"Web": true}
},
"metadata": {
# arbitrary data that will be passed through to analytic events
},
"notificationDetail": {
# arbitrary data provided to the host app with push notification data
},
"variables": {
# values used to personalize cards
"age": "42"
}
},

"target": {
# Targets can be users, segments, tags, allTestUsers or filters
"type": "tag",
"tag": "test"
}
},
# You can start multiple of a flow in one API request
# The only required input is "target"
# Example segment
{
"target": {
type: "segment",
"targetSegmentId": "4nBDF0qG"
}
},
# Example tag
{
"target": {
type: "tag",
"tagName": "myTag"
}
},
# Example allTestUsers
{
"target": {
"type": "allTestUsers"
}
}
],
"options": {
"strictVariables": true # fail the request if it contains variables (in payload) that aren't present in the target Action Flow
}
}

# send request to Atomic
curl -X POST "$TEST_API" \
--header "Content-Type:application/json" \
--header "Authorization: Bearer $TOKEN" \
--data "$PAYLOAD"

# response format
{
"triggeredFlows": [
{
"flowInvocationId": "bade1bb1-b708-424d-bec0-7a3eed3948a1"
}
]
}

Error

  • 401: No permission to environment
  • 404: Flow version not found
  • 409: Flow was invoked with a previously used flowInvocationId using different payload or target inputs.
  • 422: Flow was invoked with a previously used flowInvocationId using different Config ID or Test/Live Mode.

Using the start endpoint

As mentioned earlier, a credential role of events is required to use the start endpoint of the Action Flow API.

Triggering an Action Flow in using the start endpoint, means cards need to be in a published state to be sent and can target both test and live users.

# set Action Flow start API
START_API="https://${orgId}.customer-api.atomic.io/v1/${envId}/action-flow/${flowConfigId}/start"

# request payload
PAYLOAD =
{
"flows": [
{
# optional, used to interact with the triggered flow/card instances
# created by Atomic if not supplied
"flowInvocationId": "...",

"payload": {
"cardOptions": {
# card delivery options, all are optional, the Action Flow config overrides these options.
"priority": 5, # 1-10, controls the position of the card in the stream
"expires": "2021-11-18T23:42:14.383Z", # ISO8601 timestamp
"expiresInterval": "PT30M", # ISO8601 interval
"embargo": "2021-11-18T23:42:14.383Z", # ISO8601 timestamp
"targetStreamIds": ["3MgBE0qK"],
"targetPlatforms": {"Android": true}
},
"metadata": {
# arbitrary data that will be passed through to analytic events
"foo": "bar"
},
"notificationDetail": {
# arbitrary data provided to the host app with push notification data
"foo": "bar"
},
"variables": {
# values used to personalize cards
"name": "John Smith"
}
},

"target": {
# Targets can be users, segments, tags, allTestUsers or filters
"type": "user",
"targetUserIds": ["userA", "userB"]
}
},
# You can start multiple of a flow in one API request
# The only required input is "target"
# Example segment
{
"target": {
type: "segment",
"targetSegmentId": "4nBDF0qG"
}
},
# Example tag
{
"target": {
type: "tag",
"tagName": "myTag"
}
},
# Example allTestUsers
{
"target": {
"type": "allTestUsers"
}
}
]
}

# send request to Atomic
curl -X POST "$START_API" \
--header "Content-Type:application/json" \
--header "Authorization: Bearer $TOKEN" \
--data "$PAYLOAD"

# response format
{
"triggeredFlows": [
{
"flowInvocationId": "ccb23280-79a7-4224-86d3-2ece85e3832a"
}
]
}

Request properties

Flows

The following properties can be sent in an Action Flow start or test request under the flows parameter:

  • target (required): Can be any combination of users, segments, tags, allTestUsers and filters. You need to send one flow object for each target. The User guide describes how to create segments, tags and filters.
  • payload (optional): an object that can contain any one or more of the following:
    • variables: variables that are used in cards.
      • Note that any variables marked as "required" in the workbench must be included here in order for the Action Flow start request to be successful. Read more about required variables in the creating Action Flows article.
      • It is not possible to pass script variables as part of the request; if your card contains script variables, the default script you used in the template will be used when sending the card instance.
    • cardOptions: delivery options for the cards in an Action Flow. An overview can be found in creating Action Flows article. The request to trigger an Action Flow will fail and return an error if any of these options are invalid. These options are overridden if set in the Action Flow configuration.
    • notificationDetail: arbitrary data that is passed through to push notifications.
    • metadata: arbitrary data that is passed through to Atomic events.
    • flowInvocationId: an optional field in the request but will always be present in the response. If none is provided in the request, a new, unique value will be provided in the response. It will be present in all analytics events associated with the created card, so it can be used to track the card’s life cycle.
Important Note about Invocation IDs

For Action Flows, the Invocation ID is used as the idempotency key of the request. If the same Invocation ID is used with different inputs you will get a validation error. If, when using the same Invocation ID with the same inputs, you get an HTTP 200 response. It will not impact the execution of the flow.

For Cards (and Action Flows migrated from an existing Card that have not been edited) the Invocation ID can be used to update the card variables of an existing card. This behavior is not supported in Action Flows. In this case Runtime Variables should be considered where it is desirable to change card content after it has been sent.

Target streams are optional and can either be provided via the API call via targetStreamIds, or can be configured in the workbench using a custom Action Flow. If no target stream is defined, cards will be delivered to the default “All cards” stream only. The request to trigger an Action Flow will fail and return an error if the target streams are invalid for the given environment.

Target platforms are optional and can either be provided via the API call via targetPlatforms, or can be configured in the workbench delivery options. If no platforms are defined, cards will be delivered to all platforms (Web, iOS & Android).

Options

The following properties can be sent in an Action Flow start request under the options parameter, the options parameter is optional:

  • strictVariables - When enabled the API request will fail if it contains variables not associated with the Action Flow.

Bulk targeting

Cards can also be created in bulk using segments, tags and filters - this creates a separate card instance per user associated with the segment, tag or filter.

Get Action Flow configuration

Fetch a specific or latest version of an Action Flow configuration.

Request properties

  • flowConfigId - the target ID of the Action Flow.
  • environmentId - the environment id.
  • flowConfigVersion - the version of the target Action Flow. This can be the version number or 'latest' for the most recent.

As mentioned before, a credential role of events is required to utilize the Action Flow API.

# send request to Atomic
curl -X GET "https://${orgId}.customer-api.atomic.io/v1/${environmentId}/action-flow/${flowConfigId}/config/${flowConfigVersion}" \
--header "Authorization: Bearer $TOKEN"

Responses

The full Action Flow config for the requested version.

Sample Response
{
"data": {
"status": "PUBLISHED",
"config": {
"type": "card",
"steps": {
"create-card": {
"id": "create-card",
"next": [],
"type": "create-card",
"properties": {
"output": {
"type": "default"
},
"cardTemplateId": "3"
}
}
},
"version": "2",
"variables": {
"age": {
"type": "number",
"source": "event",
"default": 42
},
"name": {
"type": "string",
"source": "static",
"default": "John Smith"
},
"birthday": {
"type": "date",
"source": "event",
"default": "1980-01-01T08:00",
"defaultFormatter": "date",
"defaultFormatterOption": "dd/MM/Y h:mma"
}
},
"initialSteps": [
"create-card"
],
"cardTemplates": {
"3": {
"metadata": {
"cardName": "Published card",
"delivery": {
"priority": 5
},
"cardDescription": "Test card"
},
"subviews": {},
"variables": {
"age": {
"type": "number",
"source": "event",
"default": 42
},
"name": {
"type": "string",
"source": "static",
"default": "John Smith"
},
"birthday": {
"type": "date",
"source": "event",
"default": "1980-01-01T08:00",
"defaultFormatter": "date",
"defaultFormatterOption": "dd/MM/Y h:mma"
}
},
"defaultView": {
"actions": [
{
"key": "t3Mn4ltPGuA3la0bECKYC",
"type": "submitButton",
"attributes": {
"text": "Submit",
"values": {},
"responseDefinition": ""
}
}
],
"content": [
{
"key": "E1g1Bzxvw8cf3OK9ojq0k",
"type": "headline",
"attributes": {
"text": "Hello %{name}"
}
},
{
"key": "TgUT6rqy54ERErqG5D8Fm",
"type": "image",
"attributes": {
"src": "%{assetv1:atomic.png}",
"label": "Test image",
"format": "inline",
"thumbnailSrc": "%{assetv1:atomic.png}"
}
},
{
"key": "TmJdg3jiViCRHNdeBrABC",
"type": "text",
"attributes": {
"text": "Your birthday is %{birthday} "
}
}
]
},
"notification": {
"attributes": {
"body": "A card has arrived for %{name}"
}
}
}
}
},
"created": "2023-02-21T02:17:32.216Z",
"updated": "2023-02-21T02:17:32.216Z",
"version": 1
}
}

Error

  • 401: No permission to environment
  • 404: Flow version not found
  • 409: Flow was invoked with a previously used flowInvocationId using different payload or target inputs.
  • 422: Flow was invoked with a previously used flowInvocationId using different Config ID or Test/Live Mode.

Update Action Flow metadata

Updates the name and/or description of an Action Flow.

Request properties

  • flowConfigId - the target ID of the Action Flow.
  • environmentId - the environment id.

As mentioned before, a credential role of events is required to utilize the Action Flow API.

PAYLOAD='{"actionFlow": {"name": "My First Action Flow"}}'

# send request to Atomic
curl -X PUT "https://${orgId}.customer-api.atomic.io/v1/${environmentId}/action-flow/${flowConfigId}" \
--data "$PAYLOAD" \
--header "Authorization: Bearer $TOKEN"

Responses

On success, the updated Action Flow details are returned

Sample Response
{
"data": {
"id": "rkEdVXl5",
"name": "My First Action Flow",
"description": "Default action flow for card template 3",
"status": "active",
"created": "2023-02-21T02:17:32.216Z",
"updated": "2023-02-23T23:02:39.487Z",
"variables": {
"age": {
"type": "number",
"source": "event",
"default": 42
},
"name": {
"type": "string",
"source": "static",
"default": "John Smith"
},
"birthday": {
"type": "date",
"source": "event",
"default": "1980-01-01T08:00",
"defaultFormatter": "date",
"defaultFormatterOption": "dd/MM/Y h:mma"
}
},
"invocationUrl": "http://localhost:6005/v1/4dkLrv/action-flow/rkEdVXl5/start"
}
}

Publish new version of an Action Flow

Publishes a new version of an Action Flow configuration.

Request properties

  • flowConfigId - the target ID of the Action Flow.
  • environmentId - the environment id.

As mentioned before, a credential role of events is required to utilize the Action Flow API.


PAYLOAD='{
"type": "card",
"steps": {
"create-card": {
"id": "create-card",
"next": [],
"type": "create-card",
"properties": {
"output": {
"type": "default"
},
"cardTemplateId": "3"
}
}
},
"version": "2",
"variables": {
"age": {
"type": "number",
"source": "event",
"default": 42
},
"name": {
"type": "string",
"source": "static",
"default": "John Smith"
},
"birthday": {
"type": "date",
"source": "event",
"default": "1980-01-01T08:00",
"defaultFormatter": "date",
"defaultFormatterOption": "dd/MM/Y h:mma"
}
},
"initialSteps": [
"create-card"
],
"cardTemplates": {
"3": {
"metadata": {
"cardName": "Published card",
"delivery": {
"priority": 5
},
"cardDescription": "Test card"
},
"subviews": {},
"variables": {
"age": {
"type": "number",
"source": "event",
"default": 42
},
"name": {
"type": "string",
"source": "static",
"default": "John Smith"
},
"birthday": {
"type": "date",
"source": "event",
"default": "1980-01-01T08:00",
"defaultFormatter": "date",
"defaultFormatterOption": "dd/MM/Y h:mma"
}
},
"defaultView": {
"actions": [
{
"key": "t3Mn4ltPGuA3la0bECKYC",
"type": "submitButton",
"attributes": {
"text": "Submit",
"values": {},
"responseDefinition": ""
}
}
],
"content": [
{
"key": "E1g1Bzxvw8cf3OK9ojq0k",
"type": "headline",
"attributes": {
"text": "Hello %{name}"
}
},
{
"key": "TgUT6rqy54ERErqG5D8Fm",
"type": "image",
"attributes": {
"src": "%{assetv1:atomic.png}",
"label": "Test image",
"format": "inline",
"thumbnailSrc": "%{assetv1:atomic.png}"
}
},
{
"key": "TmJdg3jiViCRHNdeBrABC",
"type": "text",
"attributes": {
"text": "Your birthday is %{birthday} "
}
}
]
},
"notification": {
"attributes": {
"body": "A card has arrived for %{name}"
}
}
}
}
}'

# send request to Atomic
curl -X POST "https://${orgId}.customer-api.atomic.io/v1/${environmentId}/action-flow/${flowConfigId}/config/publish" \
--data '$PAYLOAD'
--header "Authorization: Bearer $TOKEN"

Responses

Success

On success, the response will contain the processed config object. Refer to the Atomic API Spec for full details.

Sample Response
{
"data": {
"status": "PUBLISHED",
"config": {
"type": "card",
"steps": {
"create-card": {
"id": "create-card",
"next": [],
"type": "create-card",
"properties": {
"output": {
"type": "default"
},
"cardTemplateId": "3"
}
}
},
"version": "2",
"variables": {
"age": {
"type": "number",
"source": "event",
"default": 42
},
"name": {
"type": "string",
"source": "static",
"default": "John Smith"
},
"birthday": {
"type": "date",
"source": "event",
"default": "1980-01-01T08:00",
"defaultFormatter": "date",
"defaultFormatterOption": "dd/MM/Y h:mma"
}
},
"initialSteps": [
"create-card"
],
"cardTemplates": {
"3": {
"metadata": {
"cardName": "Published card",
"delivery": {
"priority": 5
},
"cardDescription": "Test card"
},
"subviews": {},
"variables": {
"age": {
"type": "number",
"source": "event",
"default": 42
},
"name": {
"type": "string",
"source": "static",
"default": "John Smith"
},
"birthday": {
"type": "date",
"source": "event",
"default": "1980-01-01T08:00",
"defaultFormatter": "date",
"defaultFormatterOption": "dd/MM/Y h:mma"
}
},
"defaultView": {
"actions": [
{
"key": "t3Mn4ltPGuA3la0bECKYC",
"type": "submitButton",
"attributes": {
"text": "Submit",
"values": {},
"responseDefinition": ""
}
}
],
"content": [
{
"key": "E1g1Bzxvw8cf3OK9ojq0k",
"type": "headline",
"attributes": {
"text": "Hello %{name}"
}
},
{
"key": "TgUT6rqy54ERErqG5D8Fm",
"type": "image",
"attributes": {
"src": "%{assetv1:atomic.png}",
"label": "Test image",
"format": "inline",
"thumbnailSrc": "%{assetv1:atomic.png}"
}
},
{
"key": "TmJdg3jiViCRHNdeBrABC",
"type": "text",
"attributes": {
"text": "Your birthday is %{birthday} "
}
}
]
},
"notification": {
"attributes": {
"body": "A card has arrived for %{name}"
}
}
}
}
},
"created": "2023-02-21T02:17:32.216Z",
"updated": "2023-02-21T02:17:32.216Z",
"version": 2
}
}

Error

There are several types of validation errors that can be returned.

  • 400: Validation error with config payload
  • 401: No permission to environment
  • 403: No permission to publish because approvals are enabled for environment
  • 409: Current draft exists for action flow

List Action Flows

List all Actions Flows in an environment.

Request properties

  • environmentId - the environment id.

Query Parameter

  • name: filter Action Flows containing supplied name
  • status: (DRAFT | PUBLISHED | ARCHIVED) filter Action Flows by supplied status

If both parameters are supplied, both parameters will be applied.

As mentioned before, a credential role of events is required to utilize the Action Flow API.

# send request to Atomic
curl -X GET "https://${orgId}.customer-api.atomic.io/v1/${environmentId}/action-flow?name=My%0First" \
--header "Authorization: Bearer $TOKEN"

Response

A list of Action Flows for the environment are returned.

Sample Response
{
"data": [
{
"id": "rkEdVXl5",
"name": "My First Action Flow",
"description": "Default action flow for card template 3",
"status": "active",
"created": "2023-02-21T02:17:32.216Z",
"updated": "2023-02-23T23:02:39.487Z",
"variables": {
"age": {
"type": "number",
"source": "event",
"default": 42
},
"name": {
"type": "string",
"source": "static",
"default": "John Smith"
},
"birthday": {
"type": "date",
"source": "event",
"default": "1980-01-01T08:00",
"defaultFormatter": "date",
"defaultFormatterOption": "dd/MM/Y h:mma"
}
},
"invocationUrl": "http://localhost:6005/v1/4dkLrv/action-flow/rkEdVXl5/start"
}
]
}

Errors

  • 401: No permission to environment

Bulk Start Action Flow

You can start an Action Flow in which you target multiple users and provide input variables, by using a csv file. This can be done via the workbench, as explained in the Action Flow bulk send tool section.

Use the workbench to format your csv while testing

You can find a sample csv file in the tools section in the workbench. The workbench also lists what naming conventions to use in your header columns. You might need a few tries before you have perfected the csv file with all correct column headers, variable names, etc. It is easier to do this in the workbench, since it returns the job status in the UI.

The maximum file size uploadable is 32mb.

You can also bulk start an Action Flow via a sequence of API requests:

  1. Generate a URL to upload the csv by making a request to the "csv-task" or "csv-task/test" endpoint. The return value provides an upload URL to upload the input data for the Action Flow. This upload URL is a type of presigned S3 upload URLs. The upload link is only valid for 5 minutes.
  2. Send a POST request with the csv file to the presigned url.

The "csv-task/test" endpoint is only able to send to test Atomic Workbench users, and can send draft Action Flows. The "csv-task" can send to live customers and can only send published Action Flows.

Generate the upload URL

Request properties

As mentioned before, a credential role of events is required to utilize the Action Flow API.

To generate an upload URL, you need to take note of:

  • orgId - the id of your organization
  • flowConfigId - the target ID of the Action Flow
  • environmentId - the id of the environment

You can generate an upload URL in Insomnia by using the "queue up Action Flow requests using CSV to provide input data" request, or by using curl. When using curl, you'll need to set up your Authentication first.

 # send request to Atomic
curl -X POST "https://${orgId}.customer-api.atomic.io/v1/${environmentId}/action-flow/${flowConfigId}/csv-task" \
--header "Authorization: Bearer $TOKEN"
Test mode

To use this endpoint in test mode change the URL to be "https://${orgId}.customer-api.atomic.io/v1/${environmentId}/action-flow/${flowConfigId}/csv-task/test"

Responses

Success

On success, the response will contain the task information, including the task id and status url used to check on the task processing. Refer to the Atomic API Spec for full details.

Sample Response
  {"data": {
"task": {
"id": 123,
"status": "pending"
},
"uploadUrl": "https://${bucketName}.s3.amazonaws.com/master/${atomicZone}/customer-csv-uploads/${environmentId}/${fileName}.csv",
"statusUrl": "https://${orgId}.customer-api.atomic.io/v1/${environmentId}/action-flow/${flowConfigId}/csv-task/123/status"
}
}

This response contains data that can be used to monitor the status of the upload, as described in the Bulk Start Action Flow Status section.

Error

  • 400: Input validation
  • 401: No permission to environment
  • 404: Action Flow not found

Upload the csv file to the presigned URL

In this step, you upload your csv file to an Amazon S3 bucket. Because it is a presigned URL, you don't need to provide any of the authentication headers. It is however mandatory to provide the file type, otherwise you'll receive an error message.

A bash script in its simplest form could look something like

#!/bin/sh

CSV_FILE="insert/path/to/csv/file"
S3_LINK="https://insert_upload.url.com"

curl -X PUT -T $CSV_FILE -L --header “Content-type: text/csv” "$S3_LINK"

Bulk Start Action Flow Status

Related to the Bulk Start Action Flow endpoint above, the status endpoint is used to monitor the status of a task. The same endpoint is used for both live and test sends.

The output of the above endpoint provides a status URL. This is the URL to use when checking the Bulk Start Action Flow task.

Request properties

  • flowConfigId - the target ID of the Action Flow.
  • environmentId - the environment id.
  • taskId - the task id, from the initial call of the Bulk Start Action Flow call.

As mentioned before, a credential role of events is required to utilize the Action Flow API.

Success

The response will contain the task information, Refer to the Atomic API Spec for full details

Sample Response

If the job is still in pending state, the upload URL will be returned as well.

{
"data": {
"task": {
"id": 123,
"status": "completed"
},
"statusUrl": "https://${orgId}.customer-api.atomic.io/v1/${environmentId}/action-flow/${flowConfigId}/csv-task/123/status"
}
}

Error

  • 400: Input validation
  • 401: No permission to environment
  • 404: Action Flow not found

Sending custom data in push notification payloads

When sending requests to the Atomic Platform, you can send an optional notificationDetail object as part of the API request payload.

The notificationDetail object allows you to define data to be sent by Atomic in the push notification payload. You use this data to decide which action to take in your host app when a user taps on an Atomic push notification, such as navigating to a particular screen or section.

Size limit

To support both iOS and Android, the push notification payload itself has a size limit of 2KB. This should be considered when determining the data to include in the notificationDetail object.

{
"flows": [
{
"payload": {
"options": {},
"variables": {
"flaggedBy": "Joe Bloggs"
},
"notificationDetail": {
"businessId": "ABCD1234"
},
"target": {...}
}
}
]
}

The Atomic iOS and Android SDKs include a method to detect push notifications originating from Atomic - notificationFromPushPayload. You pass the push notification payload from the host app to this method, and it will return:

  • null or nil if the push notification payload did not originate from Atomic;
  • Otherwise, a structured object, containing:
    • the custom data in the push notification payload (sent in notificationDetail above);
    • the ID of the stream container that triggered the notification;
    • the card instance ID that the notification pertains to.

For more information on using this feature in the SDKs, see the relevant documentation for iOS and Android.