Rule API Documentation
This is the documentation for the Rule v2 api. If you find anything unclear or incorrect, please let us know by dropping an email to: [email protected]
Overview ¶
Authentication
To be able to use the API you first have to obtain an api key from your accounts settings page.
Once the api key has been generated it can be used in the following ways when making requests.
Passed as a get parameter:
apikey: YOUR-API-KEY-HERE
Passed as part of the request body:
apikey: YOUR-API-KEY-HERE
Passed as an header:
Authorization: Bearer YOUR-API-KEY-HERE
Failed authorization will result in a 401 response:
{
"error": "NotAuthorized"
}
Encryption
Rule enforces https (TLS 1.0-1.3). Incoming http requests will result in a 3XX response, redirecting to https.
Pagination
Actions that requests all items of a resource will be paginated. The pagination can be customized to tour liking by changing the limit parameter to only fetch a desired amount of items. The limit can Not exceed 100 items.
Exceeding the limit limitation will result in a 400 response:
{
"error": "LimitExceed",
"message": "Limit can't exceed 100."
}
Each paginated action will return a meta section in the response. The meta section will consist of a link to get the next page.
The link is populated with all necessary attributes so you can simply follow the link directly to get the next set of items.
Example of meta section:
{
"meta": {
"next": "https://app.rule.io/api/v2/subscribers?page=2&limit=100&apikey=YOUR-API-KEY-HERE"
}
}
Error handling
Each action specifies any given errors that can occur during the request and consists of mostly validation errors.
Sometimes unexpected errors can occur, and when they do a 500 response will be returned.
{
"error": "UnexpectedError",
"message": "An unexpected error occurred. Contact support if the error persists."
}
When this happens send a support request to: [email protected] with a description of how the error occurred.
Rate limit
To prevent accidental over use, the API is rate limited. This means that if you post an unusually big number of requests or generate a vast amount of error responses, any subsequent requests will not be accepted for a limited time.
An example rate limit is 2000 requests / 10 minutes and error limit 49%.
If you exceed the given limit you will receive a 429 response:
Too Many Attempts.
Along with the response some custom headers will be available:
-
X-RateLimit-Limit - Will show the maximum number of attempts
-
X-RateLimit-Remaining - Will show the number of attempts remaining
-
Retry-After - Will show the time until further attempts are allowed again
If you have a use case that exceeds the rate limit please contact [email protected] with a description of the use case, for further recommendation.
Testing
The Rule API is available for testing as a Postman collection:
Subscribers ¶
Create new subscriber ¶
Create subscriberPOST/subscribers
Attributes
-
update_on_duplicate- (optional) defaults to false if omitted. -
automation- (optional) Defaults to false if omitted. -
sync_subscribers- (optional) If omitted, automations are sent if there are less than 20 subscribers in the request. -
fields_clear- (optional) Defaults to false if omitted. Clears all custom field data of subscriber before creating new. -
tags- can consist of both names and/or ID’s of already existing tags (N.B. this means that tags consisting only of integers will be interpreted as IDs and not as text). If a tag does not exist it will be created. -
language- (optional) Needs to be ISO 639-1 formatted. If no language is passed the subscriber will default to the account language. -
phone_number- (required without email) -
email- (required without phone_number)
Field types
-
The “field key” have to formatted as:
GroupName.FieldName. Both the group and the field will be created if they don’t exist. The field name can’t consist ofemail,phone_numberor contain a. -
The field
typeattribute is not required and will default totextif omitted. -
Valid field types are:
textdatedatetimemultiplejson
When using the multiple type you have to pass in the values as an array. E.g ['Item1', 'Item2']
When using the json type you have to pass in the value as json string or json in base64 format.
E.g "[{\"name\":\"Test\",\"quantity\":null,\"price\":\"100\"}]"
To be certain of correct phone number formatting the phone_number attribute should be prefixed with an valid country code. E.g +46
If no prefix is given we will try to parse the number as a Swedish number.
The “field key” not allowed characters:
[] / \ | @ ^ ~ `
Length of fields data within one group should be less then 65000 characters (65 kB) (count sum of existing & new values). Please notice that special scandinavian characters are storing as two symbols.
opt in
An opt in flow can be trigger by passing require_opt_in: true as an attribute. For this to work a sign up flow in Rule have to be created first. One or more tag used to create the subscriber have to be tied to a sign up flow in Rule for the optin to function.
Additionally, require_opt_in: true will only affect new subscriber creation, since existing subscriber are already opted in, or waiting for opt in.
Consult the Rule manual for more information about creating sign up flows.
If no opt in flow can be found the subscriber will be automatically opted in.
automation
By passing automation: reset in the request, automation flows will be reset for all tags and segments based on the tags in the request that matches, even if the subscriber already belongs to provided tags.
For each automation flow that gets reset, previously scheduled messages will be removed.
Passing automation: force in the request, will trigger a new automation flow for all tags and matching segments based on the request tags, even if the subscriber already belongs to provided tags. Previously scheduled messages from the automation flows triggered will not be removed.
NOTE: Automation will be triggered only if there are less than 20 subscribers in the request.
When passing automation: "reset" or automation: "force" for a blocked subscriber, the subscriber will be set to active. Existing suppressions remain unchanged.
sync_subscribers
If omitted, automations are sent if there are less than 20 subscribers in the request.
By passing sync_subscribers: true all subscribers in the request will receive automations. Max sync limit is 100. If there are more than 100 subscribers in request - error is returned.
By passing sync_subscribers: false automations won’t be triggered for subscribers.
Example URI
createHeaders
Content-Type: application/jsonBody
{
"update_on_duplicate": true,
"tags": [
"Test Tag"
],
"subscribers": {
"email": "[email protected]",
"phone_number": "+46123456789",
"language": "sv",
"fields": [
{
"key": "Group.FirstName",
"value": "John",
"type": "text"
},
{
"key": "Group.Items",
"value": [
"Item1",
"Item2"
],
"type": "multiple"
},
{
"key": "Group.Products",
"value": "[{\"name\":\"Product1\",\"price\":\"100\"}]",
"type": "json"
},
{
"key": "Group.Created",
"value": "2016-03-20 12:00:00",
"type": "datetime"
}
]
}
}create multipleCreate multiple subscribers at once.
Creating multiple subscribers can be slow. Therefore this request will be handled asynchronously. If you for some reason don’t want that
behavior, you can pass async: false as part of the request.
Headers
Content-Type: application/jsonBody
{
"update_on_duplicate": true,
"tags": [
"Test Tag"
],
"subscribers": [
{
"email": "[email protected]",
"phone_number": "+46123456789",
"fields": [
{
"key": "Group.FirstName",
"value": "John",
"type": "text"
},
{
"key": "Group.Items",
"value": [
"Item1",
"Item2"
],
"type": "multiple"
},
{
"key": "Group.Created",
"value": "2016-03-20 12:00:00",
"type": "datetime"
}
]
},
{
"email": "[email protected]",
"phone_number": "+46123456987",
"fields": [
{
"key": "Group.FirstName",
"value": "Jane",
"type": "text"
},
{
"key": "Group.Items",
"value": [
"Item1",
"Item2"
],
"type": "multiple"
},
{
"key": "Group.Created",
"value": "2016-03-20 12:00:00",
"type": "datetime"
}
]
}
]
}200Headers
Content-Type: application/jsonBody
{
"message": "Success",
"subscriber": {
"id": "1",
"email": "[email protected]",
"phone_number": "+46123456789",
"language": "sv",
"created_at": "2016-03-20 12:00:00",
"updated_at": "2016-03-20 12:00:00",
"tags": [
{
"id": "1",
"name": "Test tag"
}
]
},
"suppressed": []
}409Headers
Content-Type: application/jsonBody
{
"error": "DuplicateSubscriber",
"message": "Subscriber already exists"
}400Headers
Content-Type: application/jsonBody
{
"error": "BadRequest",
"message": "Some fields could not be validated",
"fields": {
"email": ["The email field is required when phone number is not present."]
}
}
{
"error": "InvalidFieldName",
"message": "Invalid name given. Email & phone_number are reserved keyword."
}
{
"error": "InvalidFieldType",
"message": "Invalid type given. Valid types are: [text, single, multiple, json, datetime, date, time]."
}404Headers
Content-Type: application/jsonBody
{
"error": "TagNotFound",
"message": "Could not find tag with given ID."
}413Headers
Content-Type: application/jsonBody
{
"error": "RequestEntityTooLarge",
"message": "Max 1000 subscribers per call allowed."
}Get subscribers ¶
Get subscribersGET/subscribers{?limit}
Example URI
- limit
number(optional) Example: 20Number of subscribers to fetch. Defaults to 100 and can’t exceed 100.
200Headers
Content-Type: application/jsonBody
{
"subscribers": [
{
"id": 1,
"email": "[email protected]",
"phone_number": "+46123456789",
"language": "sv",
"opted_in": true,
"created_at": "2016-03-22 12:00:00",
"updated_at": "2016-03-22 12:00:00",
"tags": [
{
"id": 1,
"name": "Newsletter"
}
],
"suppressed": []
},
{
"id": 2,
"email": "[email protected]",
"phone_number": "+461234567987",
"language": "sv",
"opted_in": true,
"created_at": "2016-03-22 12:00:00",
"updated_at": "2016-03-22 12:00:00",
"tags": [
{
"id": 1,
"name": "Newsletter"
}
],
"suppressed": []
}
],
"meta": {
"next": "https://app.rule.io/api/v2/subscribers?page=2&limit=3"
}
}Get subscriber ¶
Get subscriberGET/subscribers/{identifier}{?identified_by}
Example URI
- identifier
string(required) Example: [email protected]-
id (number) - ID belonging to a subscriber.
-
email (string) - Email belonging to a subscriber.
-
phone_number (string) - Phone number belonging to a subscriber. Make sure to
urlencodethe input.
-
- identified_by
enum(optional) Example: emailSpecify your identifier, ID, phone number or email (default: email)
200Headers
Content-Type: application/jsonBody
{
"subscriber": {
"id": "1",
"email": "[email protected]",
"phone_number": "+46123456789",
"language": "sv",
"opted_in": true,
"created_at": "2016-03-20 12:00:00",
"updated_at": "2016-03-20 12:00:00",
"tags": [
{
"id": "1",
"name": "Newsletter"
}
],
"suppressed": [],
"syncAtSegments": [
{
"id": 1,
"name": "Customers",
"description": "New customers",
"created_at": "2016-03-20 12:00:00",
"updated_at": "2016-03-20 12:00:00",
"sync_at": "12:00:00"
}
]
}
}404Headers
Content-Type: application/jsonBody
{
"error": "NotFound",
"message": "Could not find subscriber with given identifier."
}Get subscriber fields ¶
Get subscriber fieldsGET/subscriber/{identifier}/fields{?identified_by}
Example URI
- identifier
string(required) Example: [email protected]-
id (number) - ID belonging to a subscriber.
-
email (string) - Email belonging to a subscriber.
-
phone_number (string) - Phone number belonging to a subscriber. Make sure to
urlencodethe input.
-
- identified_by
enum(optional) Example: emailSpecify your identifier, ID, phone number or email (default: email)
200Headers
Content-Type: application/jsonBody
{
"message": "Success",
"groups": [
{
"name": "Member",
"historical": false,
"fields": [
{
"id": 1,
"name": "FirstName",
"value": "John",
"type": "text"
}
]
}
]
}404Headers
Content-Type: application/jsonBody
{
"error": "NotFound",
"message": "Could not find subscriber with given identifier."
}Update subscriber ¶
Update subscriberPUT/subscribers/{identifier}
All attributes in this request are optional. So you can choose which attributes you want to update and skip the rest.
Example URI
- identifier
number(required) Example: 1ID for subscriber to get.
Headers
Content-Type: application/jsonBody
{
"email": "[email protected]",
"phone_number": "+46123456789",
"language": "sv",
"tags": [
"Newsletter"
],
"fields": [
{
"key": "Member.FirstName",
"value": "John",
"type": "text"
}
]
}200Headers
Content-Type: application/jsonBody
{
"message": "Success",
"subscriber": {
"id": 1,
"email": "[email protected]",
"phone_number": "+46123456789",
"language": "sv",
"opted_in": true,
"tags": [
{
"id": 1,
"name": "Newsletter"
}
],
"suppressed": []
}
}400Headers
Content-Type: application/jsonBody
{
"error": "BadRequest",
"message": "Some fields could not be validated.",
"fields": {
"email": ["The email field is required when phone number is not present."]
}
}
{
"error": "BadRequest",
"message": "Invalid language."
}
{
"error": "BadRequest",
"message": "Invalid phone number."
}
{
"error": "InvalidFieldName",
"message": "Invalid name given. Email & phone_number are reserved keyword."
}
{
"error": "InvalidFieldType",
"message": "Invalid type given. Valid types are: [text, single, multiple, json, datetime, date, time]."
}404Headers
Content-Type: application/jsonBody
{
"error": "SubscriberNotFound",
"message": "Subscriber with provided id could not be found"
}
{
"error": "TagNotFound",
"message": "ould not find tag with given ID."
}409Headers
Content-Type: application/jsonBody
{
"error": "BadRequest",
"message": "A subscriber with given email/phone_number already exists."
}Delete subscriber ¶
Delete subscriberDELETE/subscribers/{identifier}{?identified_by}
Example URI
- identifier
string(required) Example: [email protected]-
id (number) - ID belonging to a subscriber.
-
email (string) - Email belonging to a subscriber.
-
phone_number (string) - Phone number belonging to a subscriber. Make sure to
urlencodethe input.
-
- identified_by
enum(optional) Example: emailSpecify your identifier, ID, phone number or email (default: email)
200Headers
Content-Type: application/jsonBody
{
"message": "Success"
}404Headers
Content-Type: application/jsonBody
{
"error": "NotFound",
"message": "Could not find subscriber with given identifier."
}Mass delete subscribers ¶
Mass delete subscribersDELETE/subscribers
Attributes
-
identifier- Valid identifier types isemailorphone_number. -
identified_by- (enum) Specify your identifier email or phone number.
Example URI
Headers
Content-Type: application/jsonBody
{
"subscribers": [
{
"identifier": "[email protected]",
"identified_by": "email"
},
{
"identifier": "+46123456789",
"identified_by": "phone_number"
}
]
}200Headers
Content-Type: application/jsonBody
{
"message": "Success"
}404Headers
Content-Type: application/jsonBody
{
"error": "NotFound",
"message": "Could not find subscriber with given identifier."
}Delete subscriber tag ¶
Delete subscriber tagDELETE/subscribers/{identifier}/tags/{tag_identifier}{?identified_by}
This action will remove subscriber from the chosen tags. The actual tag and subscribers will not be removed.
Example URI
- identifier
string(required) Example: [email protected]-
id (number) - ID belonging to a subscriber.
-
email (string) - Email belonging to a subscriber.
-
phone_number (string) - Phone number belonging to a subscriber. Make sure to
urlencodethe input.
-
- tag_identifier
string(required) Example: 1-
id (number) - ID belonging to a tag.
-
name (string) - Name belonging to a tag. Be sure to
urlencodenames with spaces.
-
- identified_by
enum(optional) Example: emailSpecify your identifier, ID, phone number or email (default: email)
200Headers
Content-Type: application/jsonBody
{
"message": "Success"
}404Headers
Content-Type: application/jsonBody
{
"error": "TagNotFound",
"message": "Could not find tag."
}
{
"error": "SubscriberNotFound",
"message": "Could not find subscriber."
}Transactions ¶
Resources related to sending transactions
Send transaction ¶
Send transactionPOST/transactionals
-
Valid transaction types are:
emailandtext_message. -
For email transactions, both
plainandhtmlcontent must be based64 encoded. -
Sending email transactions with template requires a custom template in Rule. Contact [email protected] for more information.
-
If you want to attach PDF file, it have size up to 50Kb and should be sent as described in the example. Field “attachment”
-
To see which blocks your template supports, refer to the templates section
Sending text message transactions comes with an additional fee of 0.40 SEK per sent text message.
Example URI
email transactionHeaders
Content-Type: application/jsonBody
{
"transaction_type": "email",
"transaction_name": "Password reset",
"subject": "Password reset",
"from": {
"name": "Rule",
"email": "[email protected]"
},
"to": {
"name": "John Doe",
"email": "[email protected]"
},
"content": {
"plain": "UGFzc3dvcmQgcmVzZXQ=",
"html": "PHA+UGFzc3dvcmQgcmVzZXQ8L3A+"
},
"attachment": {
"name": "test.pdf",
"file": "data:application/pdf;base64,JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL01lZGlhQm94IFswIDAgNTk1LjI4MCA4NDEuODkwXQovVHJpbUJveCBbMC4wMDAgMC4wMDAgNTk1L
}
}email with template transactionHeaders
Content-Type: application/jsonBody
{
"transaction_type": "email",
"transaction_name": "Password reset",
"template_id": 1,
"subject": "Password reset",
"from": {
"name": "Rule",
"email": "[email protected]"
},
"to": {
"name": "John Doe",
"email": "[email protected]"
},
"content": [
{
"block_id": "one_column",
"block_content": [
{
"title": "Title number one",
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"image": "http://example.com/one.jpg",
"url": "http://example.com/one"
}
]
}
]
}text message transactionHeaders
Content-Type: application/jsonBody
{
"transaction_type": "text_message",
"from": {
"name": "Rule"
},
"to": {
"phone_number": "+46123456789"
},
"content": "Hello, world!"
}200Headers
Content-Type: application/jsonBody
{
"transaction_id": 1
}400Headers
Content-Type: application/jsonBody
{
"error": "BadTransactionType",
"message": "Valid transaction types are email or text_message."
}
{
"error": "ValidationError",
"message": [
{
"from.email": ["Attribute is required."]
}
]
}
{
"error": "SuppressedSubscriber",
"message": "Subscriber is suppressed and will not receive email transactions."
}
{
"error": "InactiveSubscriber",
"message": "Subscriber has not opted in and will not receive email transactions."
}Templates ¶
Get templates ¶
Get templatesGET/templates
Example URI
200Headers
Content-Type: application/jsonBody
{
"templates": [
{
"id": 1,
"name": "My template"
},
{
"id": 2,
"name": "My other template"
}
]
}Get template ¶
Get templateGET/templates/{id}
Example URI
- id
number(required) Example: 1
200Headers
Content-Type: application/jsonBody
{
"id": 1,
"name": "My template",
"blocks": [
"one_column",
"two_columns"
],
"content": {
"html": "<p>Html Content</p>",
"plain" "Plain Content"
}
}404Headers
Content-Type: application/jsonBody
{
"error": "TemplateNotFound",
"message": "Could not find template."
}Segments ¶
Get sync at segments ¶
Get segmentsGET/segments{?limit}
Example URI
- limit
number(optional) Example: 20Number of segments to fetch. Defaults to 100 and can’t exceed 100.
200Headers
Content-Type: application/jsonBody
{
"segments": [
{
"id": 1,
"name": "Newsletter",
"description": "Newsletter1",
"created_at": "2016-03-29 12:00:00",
"updated_at": "2016-03-29 12:00:00",
"sync_at": "12:00:00"
},
{
"id": 2,
"name": "Customers",
"description": "Newsletter2",
"created_at": "2016-03-29 12:00:00",
"updated_at": "2016-03-29 12:00:00",
"sync_at": "12:00:00"
}
],
"meta": [
"next": "https://app.rule.io/api/v2/segments?page=2&limit=2&apikey=YOUR-API-KEY"
]
}Subscriber fields ¶
Create groups and fields ¶
Create groups and fieldsPOST/customizations
-
The key attribute must have the group name and field name separated with a
.E.gGroupName.FieldName -
Valid field types are:
text, single, multiple, datetime, date, time, json. -
If no type is passed in the request, the field will default to the
textfield type.
Example URI
Headers
Content-Type: application/jsonBody
{
"fields": [
{
"key": "Address.Street",
"type": "text"
},
{
"key": "Order.Created",
"type": "datetime"
}
]
}200Headers
Content-Type: application/jsonBody
{
"message": "Success"
}400Headers
Content-Type: application/jsonBody
{
"error": "BadRequest",
"message": "Fields missing or in wrong format."
}
{
"error": "BadRequest",
"message": "Filed type {type} is not allowed"
}
{
"error": "ReservedKeyword",
"message": "Field name: {name} is a reserved keyword."
}
{
"error": "BadRequest",
"message": "Key: {key} is formatted incorrectly"
}Get groups with fields ¶
Get groupsGET/customizations{?limit}
Example URI
- limit
number(optional) Example: 20Number of items to fetch. Defaults to 100 and can’t exceed 100.
200Headers
Content-Type: application/jsonBody
{
"groups": [
{
"id": 1,
"name": "Address",
"created_at": "2016-03-29 12:00:00",
"updated_at": "2016-03-29 12:00:00",
"fields": [
{
"id": 1,
"name": "Street",
"type": "text"
}
]
},
{
"id": 2,
"name": "Order",
"created_at": "2016-03-29 12:00:00",
"updated_at": "2016-03-29 12:00:00",
"fields": [
{
"id": 2,
"name": "Created",
"type": "datetime"
}
]
}
],
"meta": [
"next": "https://app.rule.io/api/v2/customizations?page=2&limit=3&apikey=YOUR-API-KEY"
]
}Get group with fields ¶
Get groupGET/customizations/{identifier}
Example URI
- identifier
string(required) Example: 1-
id (number) - ID belonging to a group.
-
name (string) - Group name. Make sure to
urlencodethe name.
-
200Headers
Content-Type: application/jsonBody
{
"id": 1,
"name": "Address",
"created_at": "2016-03-29 12:00:00",
"updated_at": "2016-03-29 12:00:00",
"fields": [
{
"id": 1,
"name": "Street",
"type": "text"
}
]
}404Headers
Content-Type: application/jsonBody
{
"error": "NotFound",
"message": "Could not find group."
}Suppressions ¶
Register suppressions ¶
Register suppressionPOST/suppressions
⚠️ Deprecated (closing date: 2026-03-17): use V3 API method for registering suppressions.
You can suppress subscribers by specifying dispatchers and message types. If you want to suppress the subscriber on everything, simply omitt the suppress_on attribute.
-
Valid dispatcher types are:
campaignandtransaction.transaction- ⚠️ Ignored value
-
Valid message types are:
text_messageandemail.
Example URI
totalHeaders
Content-Type: application/jsonBody
{
"subscribers": [
{
"email": "[email protected]"
},
{
"phone_number": "+46123456789"
},
{
"id": 1
}
]
}specifiedHeaders
Content-Type: application/jsonBody
{
"subscribers": [
{
"email": "[email protected]"
},
{
"phone_number": "+46123456789"
},
{
"id": 1
}
],
"suppress_on": {
"campaign": [
"email",
"text_message"
],
"transaction": [
"email"
]
}
}200Headers
Content-Type: application/jsonBody
{
"message": "Success"
}404Headers
Content-Type: application/jsonBody
{
"error": "SubscriberNotFound",
"message": "Could not find subscriber."
}400Headers
Content-Type: application/jsonBody
{
"error": "BadRequest",
"message": "Subscribers missing or in invalid format."
}
{
"error": "InvalidIdentifier",
"message": "Identifier: :identifier is not a valid identifier.",
"valid_identifiers": ["email", "phone_number", "id"]
}
{
"error": "InvalidDispatcherType",
"message": "An invalid dispatcher type was detected.",
"valid_dispatcher_types": ["campaign", "transaction"]
}
{
"error": "InvalidMessageType",
"message": "An invalid message type was detected.",
"valid_message_types": ["email", "text_message"]
}Get suppressions ¶
Get suppressionsGET/suppressions{?limit}
Example URI
- limit
number(optional) Example: 20Number of items to fetch. Defaults to 100 and can’t exceed 100.
200Headers
Content-Type: application/jsonBody
{
"suppressions": [
{
"id": 1,
"created_at": "2016-04-02 12:00:00",
"dispatcher_type": "campaign",
"message_type": "email",
"suppressed_source_type": "bounce",
"subscriber": {
"id": 1,
"email": "[email protected]" ,
"phone_number": "+46123456789"
}
},
{
"id": 2,
"created_at": "2016-04-02 12:00:00",
"dispatcher_type": "transactional",
"message_type": "text_message",
"suppressed_source_type": "user",
"subscriber": {
"id": 2,
"email": "[email protected]" ,
"phone_number": "+46123456987"
}
}
],
"meta": {
"next": "https://app.rule.io/api/v2/suppressions?page=2&limit=3&apikey=YOUR-API-KEY"
}
]
}Delete suppression ¶
Delete suppressionDELETE/suppressions/{identifier}{?identified_by}
⚠️ Deprecated (closing date: 2026-03-17): use V3 API method for deleting suppressions.
Example URI
- identifier
string(required) Example: [email protected]-
id (number) - ID belonging to a supressed subscriber.
-
email (string) - Email belonging to a suppression.
-
phone_number (string) - Phone number belonging to a suppression. Make sure to
urlencodethe input.
-
- identified_by
enum(optional) Example: emailSpecify your identifier, ID, phone number or email (default: email)
- dispatcher_type
enum(optional) Example: campaignDelete specific type, see valid list of types in POST
- message_type
enum(optional) Example: emailDelete specific type, see valid list of types in POST
200Headers
Content-Type: application/jsonBody
{
"message": "Success"
}404Headers
Content-Type: application/jsonBody
{
"error": "SubscriberNotFound",
"message": "Could not find subscriber."
}Campaigns ¶
Campaigns ¶
Get campaignsGET/campaigns{?limit}{&type}{&created_from}{&created_to}{&sent_from}{&sent_to}
Example URI
- limit
number(optional) Example: 20Number of items to fetch. Defaults to 100 and can’t exceed 100.
- type
number(optional) Example: 1Message type of campaign. Email - 1, SMS - 2.
- created_from
string(optional) Example: 2024-05-05To get campaigns created from date.
- created_to
string(optional) Example: 2024-06-05To get campaigns created to date.
- sent_from
string(optional) Example: 2024-05-05To get campaigns sent from date.
- sent_to
string(optional) Example: 2024-06-05To get campaigns sent to date.
200Headers
Content-Type: application/jsonBody
{
"campaigns": [
{
"id": 1,
"name": "My campaign",
"sent_at" "2016-09-26 12:00:00",
"created_at": "2016-04-05 12:00:00",
"status": "draft",
"type": "email"
},
{
"id": 2,
"name": "My other campaign",
"created_at": "2016-04-05 12:00:00",
"status": "sent",
"type": "text_message"
}
],
"meta": {
"next": "https://app.rule.io/api/v2/campaigns?page=2&limit=3&apikey=YOUR-API-KEY"
}
}Campaigns ¶
Create campaignPOST/campaigns
-
Valid message types are:
emailandtext_message. -
email_template_idis optional. -
For email campaigns, both
plainandhtmlcontent must be based64 encoded. -
When passing the
negativeattribute along a tag/segment it will not send send the message to members contained in that tag/segment.
Example URI
createHeaders
Content-Type: application/jsonBody
{
"subject": "My subject",
"from": {
"name": "John Doe",
"email": "[email protected]"
},
"email_template_id": 1,
"message_type": "email",
"language": "sv",
"recipients": {
"tags": [
{
"identifier": "Newsletter"
}
],
"segments": [
{
"identifier": "Stockholm",
"negative": true
}
]
},
"content": {
"plain": "UGFzc3dvcmQgcmVzZXQ=",
"html": "PHA+UGFzc3dvcmQgcmVzZXQ8L3A+"
}
}200Headers
Content-Type: application/jsonBody
{
"id": 1,
"name": "My campaign",
"email_template_id": 1,
"created_at": "2016-04-05 12:00:00",
"status": "draft",
"type": "email",
"recipients": {
"tags": [
{
"id": 1,
"name": "Newsletter",
"negative": false
}
],
"segments": [
{
"id": 1,
"name": "Stockholm",
"negative": true
}
],
"subscribers": []
}
}Get campaign ¶
Get campaignGET/campaigns/{id}
Example URI
- id
number(required) Example: 1
200Headers
Content-Type: application/jsonBody
{
"id": 1,
"name": "My campaign",
"sent_at" "2016-09-26 12:00:00",
"created_at": "2016-04-05 12:00:00",
"status": "sent",
"type": "email",
"recipients": {
"tags": [
{
"id": 1,
"name": "Newsletter",
"negative": false
}
],
"segments": [
{
"id": 1,
"name": "Stockholm",
"negative": true
}
],
"subscribers": [
{
"id": 1,
"email": "[email protected]",
"phone_number": "+46123456789"
}
]
}
}404Headers
Content-Type: application/jsonBody
{
"error": "CampaignNotFound",
"message": "Could not find campaign."
}Get statistics ¶
Statistics overviewGET/campaigns/{id}/statistics
Example URI
- id
number(required) Example: 1
200Headers
Content-Type: application/jsonBody
{
"sent": 10,
"name": "My campaign",
"sent_at" "2016-09-26 12:00:00",
"open": {
"unique": 1,
"total": 5
},
"click": {
"unique": 1,
"total": 5
},
"browser": {
"unique": 1,
"total": 5
},
"bounced": {
"hard": 1,
"soft": 5
},
"unsubscribed": {
"user": 1,
"spam": 5
}
}404Headers
Content-Type: application/jsonBody
{
"error": "CampaignNotFound",
"message": "Could not find campaign."
}Send campaign ¶
-
Valid message types are:
emailandtext_message. -
For email campaigns, both
plainandhtmlcontent must be based64 encoded. -
When passing the
negativeattribute along a tag/segment it will not send send the message to members contained in that tag/segment.
Sending text message campaigns comes with an additional fee of 0.40 SEK per sent text message.
Send campaignPOST/campaigns/send
Example URI
email campaignHeaders
Content-Type: application/jsonBody
{
"subject": "My subject",
"from": {
"email": "[email protected]",
"name": "Rule"
},
"message_type": "email",
"language": "sv",
"recipients": {
"tags": [
{
"identifier": "My tag"
}
],
"segments": [
{
"identifier": "My segment",
"negative": true
}
]
},
"content": {
"plain": "UGFzc3dvcmQgcmVzZXQ=",
"html": "PHA+UGFzc3dvcmQgcmVzZXQ8L3A+"
}
}text message campaignHeaders
Content-Type: application/jsonBody
{
"subject": "My subject",
"from": {
"email": "[email protected]",
"name": "Rule"
},
"message_type": "text_message",
"language": "sv",
"recipients": {
"tags": [
{
"identifier": "My tag"
}
],
"segments": [
{
"identifier": "My segment",
"negative": true
}
]
},
"content": "My content"
}200Headers
Content-Type: application/jsonBody
{
"success": true
"campaign_id": 1
}404Headers
Content-Type: application/jsonBody
{
"error": "TemplateNotFound",
"message": "Could not find email template."
}400Headers
Content-Type: application/jsonBody
{
"error": "ValidationError",
"message": {
"subject": [
"Attribute is required"
]
}
}Delete campaign ¶
Delete campaignDELETE/campaign/{id}
Example URI
- id
string(required) Example: 1- id (number) - ID belonging to a campaign.
200Headers
Content-Type: application/jsonBody
{
"message": "Success"
}404Headers
Content-Type: application/jsonBody
{
"error": "CampaignNotFound",
"message": "Could not find campaign."
}Schedule campaign ¶
-
Valid message types are:
emailandtext_message. -
For email campaigns, both
plainandhtmlcontent must be based64 encoded. -
When passing the
negativeattribute along a tag/segment it will not send send the message to members contained in that tag/segment.
Sending text message campaigns comes with an additional fee of 0.40 SEK per sent text message.
Schedule campaignPOST/campaigns/schedule
Example URI
email campaignHeaders
Content-Type: application/jsonBody
{
"send_at": "2016-05-20 12:00:00",
"subject": "My subject",
"from": {
"email": "[email protected]",
"name": "Rule"
},
"message_type": "email",
"language": "sv",
"recipients": {
"tags": [
{
"identifier": "My tag"
}
],
"segments": [
{
"identifier": "My segment",
"negative": true
}
]
},
"content": {
"plain": "UGFzc3dvcmQgcmVzZXQ=",
"html": "PHA+UGFzc3dvcmQgcmVzZXQ8L3A+"
}
}text message campaignHeaders
Content-Type: application/jsonBody
{
"send_at": "2016-05-20 12:00:00",
"subject": "My subject",
"from": {
"email": "[email protected]",
"name": "Rule"
},
"message_type": "text_message",
"language": "sv",
"recipients": {
"tags": [
{
"identifier": "My tag"
}
],
"segments": [
{
"identifier": "My segment",
"negative": true
}
]
},
"content": "My content"
}200Headers
Content-Type: application/jsonBody
{
"success": true,
"campaign_id": 1
}400Headers
Content-Type: application/jsonBody
{
"error": "ValidationError",
"message": {
"subject": [
"Attribute is required"
]
}
}404Headers
Content-Type: application/jsonBody
{
"error": "TemplateNotFound",
"message": "Could not find email template."
}Webhooks ¶
Webhooks are not part of the REST API but a way for you to get a request to an endpoint of your choice, triggered by an event in Rule.
Webhooks can be setup in your Rule account and more info about web hooks can be found here.
Below you see the data payload in the response from the respective web hook.
Transactions
-
Transaction was sent:
{ "message": { "id": 111111, "transaction_id": 111111, "subject": "dummy-subject", "type": "email/text_message", "created_at": "1970-01-01 00:00:00" }, "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" } } -
Transaction link was clicked
{ "transaction": { "id": 111111, "name": "transaction-name", "message_type": "email/text_message" }, "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" }, "link": "https://www.example.com" } -
Transaction was opened
{ "transaction": { "id": 111111, "name": "transaction-name", "message_type": "email/text_message" }, "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" } }
Campaigns
-
Campaign was sent:
{ "campaign": { "id": 111111, "name": "campaign-name", "message_type": "email/text_message", "number_of_recipients": 123, "total_sent": 123 } } -
Campaign link was clicked
{ "campaign": { "id": 111111, "name": "campaign-name", "message_type": "email/text_message" }, "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" }, "link": "https://www.example.com" } -
Campaign was opened
{ "campaign": { "id": 111111, "name": "campaign-name", "message_type": "email/text_message" }, "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" } }
Subscribers
-
Subscriber was opted in:
{ "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" } } -
Subscriber was suppressed:
{ "dispatcher_type": "campaign/transactional", "message_type": "email/text_message", "suppressed_source_type": "user/admin/spam/api", "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" }, "account": { "name": "account-name" } } -
Subscriber was removed from tag:
{ "tag": { "id": 111111, "name": "tag-name" }, "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" } } -
Subscriber was added to tag:
{ "tag": { "id": 111111, "name": "tag-name" }, "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" } } -
Subscriber was added to filter:
{ "segment": { "id": 111111, "name": "segment-name" }, "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555", "account": { "id": "account-id", "name": "account-name" } } } -
Subscriber was bounced:
{ "bounce": { "dispatcher_id": 111111, "type": "soft/hard", "message_type": "email", "dispatcher_type": "campaign", "bounce_message": "bounce message" }, "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" }, "account": { "name": "account-name" } } -
Subscriber was resubscribed:
{ "subscriber": { "id": 111111, "email": "subscriber-email", "phone_number": "+46705555555" }, "account": { "name": "account-name" } }
Imports
-
Import was finished:
{ "import": { "id": "import-id", "total": "import-total", "new": "import-new", "updated": "import-updated", "failed": "import-failed", "partial_failed": "import-partial-failed" } }
Preferences
-
Subscriber was added to preference
{ "preferences": [ { "id": 111111, "name": "preference-name-1" }, { "id": 222222, "name": "preference-name-2" } ], "preference_group": { "id": 111111, "name": "preference-group-name" }, "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" } } -
Subscriber was removed from preference
{ "preferences": [ { "id": 111111, "name": "preference-name-1" }, { "id": 222222, "name": "preference-name-2" } ], "preference_group": { "id": 111111, "name": "preference-group-name" }, "subscriber": { "id": 111111, "email": "[email protected]", "phone_number": "+46705555555" } }
Preferences ¶
Get preference groups ¶
Get preferences groupsGET/preference-groups
NOTES
- The field
linkhas 2 states:""- the link was changed sometimenull- the link wasn’t set before
Example URI
200Headers
Content-Type: application/jsonBody
[
{
"id": 1,
"account_id": 1,
"name": "Water-group",
"link": null,
"preferences": [
{
"id": 1,
"name": "pref1-water",
"fallback_opt_in": false,
},
{
"id": 2,
"name": "pref2-water",
"fallback_opt_in": false,
}
]
},
{
"id": 2,
"account_id": 1,
"name": "Fire-group",
"link": "",
"preferences": [
{
"id": 3,
"name": "pref1-fire",
"fallback_opt_in": false,
},
{
"id": 4,
"name": "pref2-fire",
"fallback_opt_in": false,
},
{
"id": 5,
"name": "pref3-fire",
"fallback_opt_in": false,
}
]
}
]Get preferences choices for subscriber and group ¶
Get preferences of subscriberGET/subscriber/{identifier}/preference_group/{preference_group_id}?identified_by=email
Example URI
- preference_group_id
int(required) Example: 1- identifier
string(required) Example: [email protected]-
id (number) - ID belonging to a subscriber.
-
email (string) - Email belonging to a subscriber.
-
phone_number (string) - Phone number belonging to a subscriber. Make sure to
urlencodethe input.
-
- identified_by
enum(optional) Example: emailSpecify your identifier, ID, phone number or email (default: email)
200Headers
Content-Type: application/jsonBody
{
"preferences": [
{
"preference_id": 1,
"name": "pref1-water",
"is_opted_in": true
},
{
"preference_id": 2,
"name": "pref2-water",
"is_opted_in": true
}
]
}404Headers
Content-Type: application/jsonBody
{
{
"error": "NotFound",
"message": "Could not find Subscriber/PreferenceGroup with given params."
}
}Update state of all preferences ¶
Update preferences of subscriberPATCH/subscriber/{identifier}/preference_group/{preference_group_id}?identified_by=email
Example URI
- preference_group_id
int(required) Example: 1- identifier
string(required) Example: [email protected]-
id (number) - ID belonging to a subscriber.
-
email (string) - Email belonging to a subscriber.
-
phone_number (string) - Phone number belonging to a subscriber. Make sure to
urlencodethe input.
-
- identified_by
enum(optional) Example: emailSpecify your identifier, ID, phone number or email (default: email)
Headers
Content-Type: application/jsonBody
{
"preferences": [
{
"preference_id": 1,
"is_opted_in": false
},
{
"preference_id": 2,
"is_opted_in": false
}
]
}200Headers
Content-Type: application/jsonBody
{
"preferences": [
{
"preference_id": 1,
"name": "pref1-fire",
"is_opted_in": false
},
{
"preference_id": 2,
"name": "pref2-fire",
"is_opted_in": false
}
]
}400Headers
Content-Type: application/jsonBody
{
"error": "BadRequest",
"message": "Some fields could not be validated",
"fields": {
"preferences": [
"Required fields: preference_id, is_opted_in",
"The is_opted_in field value must be true (1) or false (0).",
[
"Check fields for preferences with id: {id}"
]
]
}
}404Headers
Content-Type: application/jsonBody
{
{
"error": "NotFound",
"message": "Could not find (Preference/PreferenceGroup/Subscriber) with given params. Check your preferences with ids: {list of preferenceIds}"
}
}Journeys ¶
Resources related to Journey Builder
Get journeys ¶
Get journeysGET/journey{?name}{?preference_id}
Example URI
- name
string(optional)Filter journey by name.
- preference_id
int(optional)Filter journeys by ID of a preference group.
200Headers
Content-Type: application/jsonBody
[
{
"id": 8,
"name": "Journey",
"account_id": 9,
"journey_style_id": 1,
"sendout_time_minutes": null,
"created_at": "2022-08-16T22:47:47.000000Z",
"updated_at": "2022-08-16T22:47:47.000000Z",
"sendoutConfiguration": {
"id": 56,
"sendTimeConfiguration": {
"id": 8,
"time_offset_minutes": 780
},
"preferenceConfiguration": {
"id": 16,
"preferences": [
1
]
}
}
}
]