Messages Version 2
This document describes the OSDI messages collection and message resource as implemented by the Action Network.
Messages are mass emails created by the organizer or group associated with your API key that are sent to activists subscribed to the group or organizer's email list or portions of the list, based on the email's targeting.
Messages have names (corresponding to our administrative titles), subject lines, from lines, and body contents, and they can have arrays of targets representing queries that are used to target this email, statistics about how the email is doing, and other fields. They are linked to a wrapper representing the email wrapper being used with the message and a list representing the people who received the message.
Messages are not deduplicated except on identifiers, to keep identifiers unique. Identifiers are deduplicated globally, across groups and API keys, so ensure any you set are globally unique.
Unlike other resources on the API, the messages API replicates most of the functionality of our user interface, so it is possible to create, target, schedule or send (using the schedule and send helpers), and report on email statistics all via the API.
Sections:
- Endpoints and URL structures
- Field names and descriptions
- Links
- Related resources
- Scenario: Retrieving a collection of message resources (GET)
- Scenario: Retrieving an individual message resource (GET)
- Scenario: Creating a new message (POST)
- Scenario: Modifying a message (PUT)
- Scenario: Deleting a message (DELETE)
Endpoints and URL structures
Endpoints:
https://actionnetwork.org/api/v2/messages
Message resources live exclusively at the above endpoint. The endpoint returns a collection of all the messages associated with your API key.
URL Structures:
https://actionnetwork.org/api/v2/messages/[id]
To address a specific message, use the identifier without the action_network:
prefix to construct a URL, like https://actionnetwork.org/api/v2/messages/d91b4b2e-ae0e-4cd3-9ed7-d0ec501b0bc3
Field names and descriptions
Petition fields:
Field Name | Type | Required on POST | Description |
---|---|---|---|
identifiers | strings[] |
An array of identifiers in the format [system name]:[id] . Must be globally unique. See the general concepts document for more information about identifiers.
|
|
origin_system | string | A human readable string identifying where this message originated. May be used in the user interface for this purpose. | |
created_date | datetime | The date and time the resource was created. System generated, not editable. | |
modified_date | datetime | The date and time the resource was last modified. System generated, not editable. | |
name | string | The message's administrative title, only shown internally and not publicly. | |
subject | string | Yes | The message's subject line. |
from | string | Yes | The message's from line. |
body | string | Yes | The message's body content. May contain HTML. |
reply-to | string | Yes | The message's reply-to email address. Must be an email address. |
administrative_url | string | The URL to this message's manage page on the Action Network.Not editable. | |
type | enum | The type of message. Always 'email', and not editable. | |
status | enum | The current status of the email. One of 'draft', 'calculating' (if the email's targeting is currently being calculated), 'sending', 'sending_by_timezone' (if the email is sending in local time), 'throttled' (if the email is sending with a throttle setting), 'scheduled', or 'sent'. Not editable. | |
total_targeted | integer | A read-only field indicating the total number of people currently targeted by this message. | |
sent_start_date | datetime | A read-only field indicating when the message was sent, in UTC. | |
scheduled_start_date | datetime | A read-only field indicating when the message is scheduled to be sent, in UTC. | |
targets | Targets[] | An array of URLs to query resources on the API used as includes for this message. Queries that are excluded are not shown. Other targeting options selected in the user interface are not shown. Click here for queries documentation. | |
statistics | Statistics | A hash of the engagement statistics for the message, if it has been sent. |
Target fields:
Field Name | Type | Required on POST | Description |
---|---|---|---|
name | href | The link to the query resource's API endpoint being included on the message. Queries that are excluded are not shown. Other targeting options selected in the user interface are not shown. Click here for queries documentation. |
Statistics fields:
Field Name | Type | Required on POST | Description |
---|---|---|---|
sent | integer | The number of people this message was sent to. Not editable. | |
opened | integer | The number of people who opened this message. Not editable. | |
verified_opened | integer | The total number of opens that can be reasonably verified as real humans. Not editable. | |
machine_opened | integer | The number of opens that occurred on a device with Mail Privacy Protection enabled. There is no way to tell whether these opens were triggered by an activist or by a machine using Mail Privacy Protection. Not editable. | |
clicked | integer | The number of people who clicked a link this message. Not editable. | |
actions | integer | The number of people who took an action such as signed a petition because they received this message. Not editable. Only counts actions that are Action Network pages or widgets or came via the ActBlue sync. | |
action_network:donated | integer | The number donations made because people received this message. Action Network-only feature.Not editable. Only counts donations that are Action Network pages or widgets or came via the ActBlue sync. | |
action_network:total_amount | float | The total amount donated by people because they received this message. Action Network-only feature.Not editable. Only counts donations that are Action Network pages or widgets or came via the ActBlue sync. | |
unsubscribed | integer | The number of people who unsubscribed from your list after receiving this message. Not editable. | |
bounced | integer | The number of people who bounced and were unsubscribed from your list after receiving this message. Not editable. | |
spam_reports | integer | The number of people who marked this message as spam and were unsubscribed from your list. Not editable. |
Links
Link Name | Description |
---|---|
self | A link to this individual message resource. |
osdi:wrapper | A link to the wrapper this message is using. Can be POSTed to attach a specific wrapper to the message you are creating. Only present if the wrapper is not our built-in wrapper. Click here for wrappers documentation. |
osdi:recipients | A link to the list of people this message was sent to. Only present if the message was sent. Click here for lists documentation. |
osdi:send_helper | A link to the send helper for this message. Click here for the send helper documentation. |
osdi:schedule_helper | A link to the schedule helper for this message. Click here for the schedule helper documentation. |
Related resources
Back To Top ↑Scenario: Retrieving a collection of message resources (GET)
Message resources are sometimes presented as collections of messages. For example, calling the messages endpoint will return a collection of all the messages associated with your API key.
Request
GET https://actionnetwork.org/api/v2/messages/
Header:
OSDI-API-Token: your_api_key_here
Response
Back To Top ↑200 OK Content-Type: application/hal+json Cache-Control: max-age=0, private, must-revalidate
{ "total_pages": 7, "per_page": 25, "page": 1, "total_records": 162, "_links": { "next": { "href": "https://actionnetwork.org/api/v2/messages?page=2" }, "self": { "href": "https://actionnetwork.org/api/v2/messages" }, "osdi:messages": [ { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d" }, { "href": "https://actionnetwork.org/api/v2/messages/a27178b9-45c3-4844-8ebf-ebd5da74a1e3" }, //truncated for brevity ], "curies": [ { "name": "osdi", "href": "https://actionnetwork.org/docs/v2/{rel}", "templated": true }, { "name": "action_network", "href": "https://actionnetwork.org/docs/v2/{rel}", "templated": true } ] }, "_embedded": { "osdi:messages": [ { "identifiers": [ "action_network:a4dde5b6-0512-48ea-b4ad-63a71117b43d" ], "origin_system": "Action Network", "created_date": "2014-03-24T18:03:45Z", "modified_date": "2014-03-25T15:00:22Z", "subject": "Stop doing the bad thing", "body": "<p>The mayor should stop doing the bad thing.</p>", "from": "Progressive Action Now", "reply_to": "jane@progressiveactionnow.org", "administrative_url": "https://actionnetwork.org/emails/stop-doing-the-bad-thing/manage", "total_targeted": 2354, "status": "sent", "sent_start_date": "2014-03-26T15:00:22Z", "type": "email", "targets": [ { "href": "https://actionnetwork.org/api/v2/queries/2cba37d8-1fbf-11e7-8cc2-22000aedd9ed" } ], "statistics": { "sent": 2354, "opened": 563, "clicked": 472, "actions": 380, "action_network:donated": 14, "action_network:total_amount": 320.25, "unsubscribed": 12, "bounced": 2, "spam_reports": 1 }, "_links": { "self": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d" }, "osdi:wrapper": { "href": "https://actionnetwork.org/api/v2/wrappers/c945d6fe-929e-11e3-a2e9-12313d316c29" }, "osdi:recipients": { "href": "https://actionnetwork.org/api/v2/lists/950e9954-606f-43e6-be99-2bc0bc2072a1" }, "osdi:send_helper": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d/send" }, "osdi:schedule_helper": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d/schedule" } } }, { "identifiers": [ "action_network:a27178b9-45c3-4844-8ebf-ebd5da74a1e3", "foreign_system:1" ], "origin_system": "My Email Making System", "created_date": "2014-03-27T18:03:45Z", "modified_date": "2014-03-28T15:00:22Z", "subject": "FWD: Stop doing the bad thing", "body": "<p>Have you signed yet? The mayor should stop doing the bad thing.</p>", "from": "Progressive Action Now", "reply_to": "jane@progressiveactionnow.org", "administrative_url": "https://actionnetwork.org/emails/fwd-stop-doing-the-bad-thing/manage", "total_targeted": 12673, "status": "draft", "type": "email", "targets": [], "_links": { "self": { "href": "https://actionnetwork.org/api/v2/messages/a27178b9-45c3-4844-8ebf-ebd5da74a1e3" }, "osdi:send_helper": { "href": "https://actionnetwork.org/api/v2/messages/a27178b9-45c3-4844-8ebf-ebd5da74a1e3/send" }, "osdi:schedule_helper": { "href": "https://actionnetwork.org/api/v2/messages/a27178b9-45c3-4844-8ebf-ebd5da74a1e3/schedule" } } }, //truncated for brevity ] } }
Scenario: Retrieving an individual message resource (GET)
Calling an individual message resource will return the resource directly, along with all associated fields and appropriate links to additional information about the message.
Request
GET https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d
Header:
OSDI-API-Token: your_api_key_here
Response
Back To Top ↑200 OK Content-Type: application/hal+json Cache-Control: max-age=0, private, must-revalidate
{ "identifiers": [ "action_network:a4dde5b6-0512-48ea-b4ad-63a71117b43d" ], "origin_system": "Action Network", "created_date": "2014-03-24T18:03:45Z", "modified_date": "2014-03-25T15:00:22Z", "subject": "Stop doing the bad thing", "body": "<p>The mayor should stop doing the bad thing.</p>", "from": "Progressive Action Now", "reply_to": "jane@progressiveactionnow.org", "administrative_url": "https://actionnetwork.org/emails/stop-doing-the-bad-thing/manage", "total_targeted": 2354, "status": "sent", "sent_start_date": "2014-03-26T15:00:22Z", "type": "email", "targets": [ { "href": "https://actionnetwork.org/api/v2/queries/2cba37d8-1fbf-11e7-8cc2-22000aedd9ed" } ], "statistics": { "sent": 2354, "opened": 563, "clicked": 472, "actions": 380, "action_network:donated": 14, "action_network:total_amount": 320.25, "unsubscribed": 12, "bounced": 2, "spam_reports": 1 }, "_links": { "self": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d" }, "osdi:wrapper": { "href": "https://actionnetwork.org/api/v2/wrappers/c945d6fe-929e-11e3-a2e9-12313d316c29" }, "osdi:recipients": { "href": "https://actionnetwork.org/api/v2/lists/950e9954-606f-43e6-be99-2bc0bc2072a1" }, "osdi:send_helper": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d/send" }, "osdi:schedule_helper": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d/schedule" } } }
Scenario: Creating a new message (POST)
You can post a new message to the messages endpoint and a message resource will be created in our system.
Unlike other resources on the API, messages POSTed via the API will show up as emails in the Action Network user interface, and can be edited and interacted with in the interface just like any other email.
If you include links to valid query resources in the targets array, those queries will be added as includes for your message's targeting. Otherwise, the message's targeting will be blank, targeting the full list. You can edit the message in the user interface to change the targeting, add other targeting options not available on the API, or add a random limit at any time before the message is sent.
If you include a link to a valid wrapper in the links section of your POST, that wrapper will be used for that message. Otherwise, the default wrapper for the organizer or group associated with your API key will be used.
POSTing messages will immediately cause their targeting to run against the queries in the targets array you've provided, or against the full list if the array is empty. This puts the message in the 'calculating' status while targeting calculates. The email cannot be sent until targeting has finished and the status is 'draft' again, with a total_targeted
greater than 0. You should poll the message's endpoint with GET regularly to see when the message moves from 'calculating' to 'draft', indicating targeting has finished and a new total_targeted
count is available.
Note: Because POSTing a message causes targeting -- a computationally expensive calculation -- to kick off immediately, POST requests are heavily rate limited. You can only POST once every 30 seconds. If you attempt to POST more often you will receive a rate limit error. Your application should handle this error and either retry later or inform the user to try again later.
Request
POST https://actionnetwork.org/api/v2/messages Header: Content-Type: application/json OSDI-API-Token: your_api_key_here
{ "subject": "Stop doing the bad thing", "body": "<p>The mayor should stop doing the bad thing.</p>", "from": "Progressive Action Now", "reply_to": "jane@progressiveactionnow.org", "targets": [ { "href": "https://actionnetwork.org/api/v2/queries/2cba37d8-1fbf-11e7-8cc2-22000aedd9ed" } ], "_links": { "osdi:wrapper": { "href": "https://actionnetwork.org/api/v2/wrappers/c945d6fe-929e-11e3-a2e9-12313d316c29" } } }
Response
200 OK Content-Type: application/hal+json Cache-Control: max-age=0, private, must-revalidate
{ "identifiers": [ "action_network:a4dde5b6-0512-48ea-b4ad-63a71117b43d" ], "origin_system": "Action Network", "created_date": "2014-03-24T18:03:45Z", "modified_date": "2014-03-25T15:00:22Z", "subject": "Stop doing the bad thing", "body": "<p>The mayor should stop doing the bad thing.</p>", "from": "Progressive Action Now", "reply_to": "jane@progressiveactionnow.org", "administrative_url": "https://actionnetwork.org/emails/stop-doing-the-bad-thing/manage", "status": "calculating", "type": "email", "targets": [ { "href": "https://actionnetwork.org/api/v2/queries/2cba37d8-1fbf-11e7-8cc2-22000aedd9ed" } ], "_links": { "self": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d" }, "osdi:wrapper": { "href": "https://actionnetwork.org/api/v2/wrappers/c945d6fe-929e-11e3-a2e9-12313d316c29" }, "osdi:send_helper": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d/send" }, "osdi:schedule_helper": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d/schedule" } } }
In the above example, you can see how the foreign identifier being posted is merged into the identifiers array. We will intelligently search and deduplicate based on foreign and native identifiers. So if you post a message with an identifier that matches one already assigned to a message resource, your POST request will update that resource with new information instead of creating a duplicate. Identifiers are deduplicated globally, across groups and API keys, so ensure any you set are globally unique.
You can see that the message also was POSTed with a query in the targets array, causing it to be targeted to that query as an include. The message was immediately put into 'calculating' status while the targeting was calculated.
The message was also POSTed with a link to a wrapper, so that wrapper was used for that message when the resource was returned.
And of course you can post a message with more fields (such as a name) if you'd like, but they are not required.
Back To Top ↑Scenario: Modifying a message (PUT)
You can modify an existing message by using PUT on its individual endpoint.
Request
PUT https://actionnetwork.org/api/v2/messages/9f837109-710d-442f-8a99-857a21f36d25 Header: Content-Type: application/json OSDI-API-Token: your_api_key_here
{ "name": "Stop doing the bad thing email send 1", "subject": "Please! Stop doing the bad thing" }
Response
200 OK Content-Type: application/hal+json Cache-Control: max-age=0, private, must-revalidate
{ "identifiers": [ "action_network:a4dde5b6-0512-48ea-b4ad-63a71117b43d" ], "origin_system": "Action Network", "created_date": "2014-03-24T18:03:45Z", "modified_date": "2014-03-25T15:00:22Z", "name": "Stop doing the bad thing email send 1", "subject": "Please! Stop doing the bad thing", "body": "<p>The mayor should stop doing the bad thing.</p>", "from": "Progressive Action Now", "reply_to": "jane@progressiveactionnow.org", "administrative_url": "https://actionnetwork.org/emails/stop-doing-the-bad-thing/manage", "status": "draft", "total_targeted": 2354, "type": "email", "targets": [ { "href": "https://actionnetwork.org/api/v2/queries/2cba37d8-1fbf-11e7-8cc2-22000aedd9ed" } ], "_links": { "self": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d" }, "osdi:wrapper": { "href": "https://actionnetwork.org/api/v2/wrappers/c945d6fe-929e-11e3-a2e9-12313d316c29" }, "osdi:send_helper": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d/send" }, "osdi:schedule_helper": { "href": "https://actionnetwork.org/api/v2/messages/a4dde5b6-0512-48ea-b4ad-63a71117b43d/schedule" } } }
The above example added a name (an administrative title) to the message and changed the subject line.
Editing of certain fields via PUT is not allowed, and is noted in the field names table above. For example, you can't change the total_targeted
count -- that is a system generated number reflecting a count of the total number of people targeted by the email. Invalid entries will be ignored.
PUTing changes to the targets array will immediately cause the email's targeting to run against the queries in the targets array you've provided, plus any other targeting parameters that have been added on the user interface. (This means you can edit targeting parameters on the UI as much as you'd like. The API will display queries in the includes column of the UI in the targets array on the API, but other parameters will be hidden and are inaccessible over the API, and thus cannot be changed via PUT.) This puts the message in the 'calculating' status while targeting calculates. The email cannot be sent until targeting has finished and the status is 'draft' again, with a total_targeted
greater than 0. You should poll the message's endpoint with GET regularly to see when the message moves from 'calculating' to 'draft', indicating targeting has finished and a new total_targeted
count is available.
If you PUT to change the targets array, the array will be replaced entirely by the contents of the new array you PUT. You can remove all queries from the targets array by PUTing a blank array item:
PUT https://actionnetwork.org/api/v2/messages/9f837109-710d-442f-8a99-857a21f36d25 Header: Content-Type: application/json OSDI-API-Token: your_api_key_here
{ "targets": [ "" ] }
Note: Because PUTing a message that changes the targets array causes targeting -- a computationally expensive calculation -- to kick off immediately, PUT requests that change the targets array are heavily rate limited. You can only PUT to change the targets array once every 30 seconds. If you attempt to PUT more often after changing the targets array, you will receive a rate limit error. Your application should handle this error and either retry later or inform the user to try again later.
Back To Top ↑Scenario: Deleting a message (DELETE)
Deleting messages is not allowed via the API. DELETE requests will return an error.
Back To Top ↑