Generic Action Processing

You can create Actions by POSTing to the collection of Actions, i.e. the list_endpoint for the Action resource: /rest/v1/action/.

The only required parameters for action processing are page - the name of the Page - and user email. However, there are many other parameters to control processing and collect information from users.

POSTing to the generic action collection is like submitting a form from the cms or a page hosted outside of ActionKit. You can submit actions as JSON, XML, or x-www-form-url-encoded data.

Note

We've reserved POSTing to the specific Action endpoints, e.g. /rest/v1/signupaction/, for a more RESTful implementation. For now, posting to a typed action endpoint will return an error.

You can process actions without authenticating. This is very similar to submitting a form in a page hosted on the ActionKit CMS or on your servers. The response from ActionKit will contain more information if the connection is authenticated.

Simple Examples

Unauthenticated

The simplest POST you could make to create an Action includes only a page and a user email (or an akid token).

$ curl -i -X POST -H 'Content-type: application/json; charset=utf-8' https://docs.actionkit.com/rest/v1/action/ -d '{ "page": "signup", "email": "signup@example.com" }'
HTTP/1.1 201 CREATED
Date: Mon, 05 Mar 2012 13:19:01 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: text/html; charset=utf-8
Location: https://docs.actionkit.com/rest/v1/signupaction/1/
{"action_id": 21, "akid": ".3.jcWz_1", "rd": 1, "redirect_url": "/cms/thanks/signup/?action_id=21&akid=.3.jcWz_1&rd=1"}

For unauthenticated requests, ActionKit returns only basic information about the newly created Action. You can use the redirect_url to redirect the end-user. Or use the akid token to give them a personalized link to other actions.

While the Location header contains the URI of the newly created action, there is no unauthenticated access to previously created actions.

Authenticated

If you submit a POST using authentication, ActionKit will return the full details of the Action, including a link to the User who took the action:

$ curl -u user:password -i -X POST -H 'Content-type: application/json; charset=utf-8' https://docs.actionkit.com/rest/v1/action/ -d '{ "page": "signup", "email": "signup@example.com" }'
HTTP/1.1 201 CREATED
Date: Fri, 09 Mar 2012 11:38:32 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Location: https://docs.actionkit.com/rest/v1/action/24/
Transfer-Encoding: chunked
{
   "akid": ".1.iWxeUd",
   "created_at": "2012-03-09T11:42:53.147877",
   "created_user": false,
   "fields": {},
   "link": null,
   "mailing": null,
   "opq_id": "",
   "page": "/rest/v1/signuppage/10/",
   "referring_mailing": null,
   "referring_user": null,
   "resource_uri": "/rest/v1/action/26/",
   "source": "website",
   "status": "complete",
   "subscribed_user": false,
   "taf_emails_sent": null,
   "type": "Signup",
   "updated_at": "2012-03-09T11:42:53.174844",
   "user": "/rest/v1/user/1/"
 }

There are a couple of fields you shouldn't miss:

  • subscribed_user - A boolean indicating if this action subscribed the user, including Users who are resubscribed.
  • created_user - A boolean indicating if this action created the user.
  • user - a URI to the full User resource.

Validation

If the input POST'd doesn't validate, ActionKit returns a 400 status code and the invalid fields with messages suitable for display.

$ curl -i -H 'Content-type: application/json; charset=utf-8' -X POST https://docs.actionkit.com/rest/v1/action/ -d '{ "email": "not a valid email", "country": "United States", "zip": "abcdf", "page": "signup" }'
HTTP/1.1 400 BAD REQUEST
Date: Fri, 09 Mar 2012 11:22:47 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Connection: close
Transfer-Encoding: chunked
{"errors": {"email": ["E-mail address is invalid."], "zip": ["ZIP Code is invalid."]}}

Action processing function does provide some validation. Of course, you should verify that the validation is sufficient for your needs. Action processing will:

  • make sure the email field is a syntactically valid email address

ActionKit simply checks the form of the email, not if it's a deliverable address.

  • return an error if required fields are missing or empty

If the request includes a valid akid token, then in addition to looking for required fields in the request, ActionKit will also check the user's existing record for the required fields.

  • if country = 'United States', check zip is 5 characters long and plus4 is 4 characters long

ActionKit sets country to 'United States' by default, so if zip is a required field, then ActionKit will validate it with US rules, even if the Action is POSTed without a country.

That's it. All other validation is up to you!

Required Arguments

Action processing requires the name of the page being processed:

  • page - the name of the Page, i.e. the name column in core_page, a.k.a. the Short name on the Action basics editing page

Submitting an action also requires identifying the user taking the action:

  • email - an email address
  • akid - a token provided by ActionKit representing a user

Optional Arguments

User fields:

  • email - Email address

Names can either be sent as multiple fields:

  • prefix
  • first_name
  • middle_name
  • last_name
  • suffix

or as just

  • name

and ActionKit will split into the other name fields.

Address fields vary a bit between international and US users. International users should use postal and region, US users should use zip and state. (ActionKit will set postal for all users.)

  • address1
  • address2
  • city
  • state
  • zip
  • postal
  • region
  • country

ActionKit will try to geocode a user's address. The result is available as a Location resource, linked off of the User resource.

Phone numbers can be provided in multiple ways. Either as a phone field and a phone_type field, good for letting users provide one phone number and letting them pick the type:

  • phone
  • phone_type

Or as type specific fields, good for providing more than one phone number in the same request:

  • home_phone
  • home_fax_phone
  • work_fax_phone
  • work_phone
  • mobile_phone
  • emergency_phone

Custom User Fields

Any field prefixed with 'user_' is a custom user field. You have to create an AllowedUserField before submitting actions.

To create an AllowedUserField POST to the AllowedUserField collection:

$ curl -i -H 'Content-type: application/json; charset=utf-8' -u user:password -d '{ "name": "favorite_color" }' -X POST https://docs.actionkit.com/rest/v1/alloweduserfield/
HTTP/1.1 201 CREATED
Date: Wed, 14 Mar 2012 15:18:06 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: text/html; charset=utf-8
Location: https://docs.actionkit.com/rest/v1/alloweduserfield/favorite_color/
Transfer-Encoding: chunked

Custom Action Fields

Any field prefixed with 'action_' is a custom action field. You do not have to do anything to use a new action field, just submit it with the rest of the POST.

Tell A Friend Fields

If PageFollowup.send_taf is true, the following fields can be submitted to send a message to a user's friends:

  • taf_note - a user submitted note to their friends that will appear before the text in PageFollowup.email_body
  • taf_subject - a user submitted subject
  • taf_emails - a list of emails

Referral fields

  • referring_akid - if this is a valid akid, the action will store the referring user id and mailing (if present) along with the action.

Parameters

You can control the way the act method works using the following parameters. These should be included in the JSON body of your request.

  • opt_in

If opt_in is True, ActionKit will only subscribe users to the lists submitted with the POST. If opt_in is False or not provided, ActionKit will subscribe users to the List associated with the Page. Or to the list of list ids provided in the POST. If you want to require users to opt-in via checkbox, then set opt_in to a true value in a hidden field and create a checkbox for at least one list.

  • lists

An optional list of list ids to subscribe the user to. Interacts with opt_in, described above.

  • required

A required field to be added to the fields required by the Page. You can include required multiple times to require multiple fields.

  • skip_confirmation

If you pass a value of 1 for this parameter the confirmation email set up for the page will be skipped.

Default Values

By default:

  • Users will be subscribed to the list associated with the Page (the list attribute of the Page resource) if there is no 'lists' argument.
  • country will be set to 'United States' if there is no 'country' argument provided.

JSON Examples

POST a SignupAction without authenticating

$ curl -i -X POST -H 'Content-type: application/json; charset=utf-8' https://docs.actionkit.com/rest/v1/action/ -d '{ "page": "signup", "first_name": "Example", "last_name": "User", "email": "user@example.com", "zip": "12345" }'
HTTP/1.1 201 CREATED
Date: Wed, 14 Mar 2012 09:06:20 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Location: https://docs.actionkit.com/rest/v1/action/1/
Transfer-Encoding: chunked
{
    "action_id": 1,
    "akid": ".1.iWxeUd",
    "rd": 1,
    "redirect_url": "/cms/thanks/signup?action_id=1&akid=.1.iWxeUd&rd=1"
}

Hint

If you get a 404 NOT FOUND, check that a page with the name 'signup' exists. If not, create one!

POST a SignupAction with authentication

$ curl -u user:password -i -X POST -H 'Content-type: application/json; charset=utf-8' https://docs.actionkit.com/rest/v1/action/ -d '{ "page": "signup", "first_name": "Example", "last_name": "User", "email": "user@example.com", "zip": "12345" }'
HTTP/1.1 201 CREATED
Date: Wed, 14 Mar 2012 10:33:24 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Location: https://docs.actionkit.com/rest/v1/action/2/
Transfer-Encoding: chunked
{
    "akid": ".1.iWxeUd",
    "created_at": "2012-03-14T10:33:24.427113",
    "created_user": false,
    "fields": {},
    "link": null,
    "mailing": null,
    "opq_id": "",
    "page": "/rest/v1/signuppage/10/",
    "redirect_url": "/cms/thanks/signup?action_id=2&akid=.1.iWxeUd&rd=1",
    "referring_mailing": null,
    "referring_user": null,
    "resource_uri": "/rest/v1/action/2/",
    "source": "website",
    "status": "complete",
    "subscribed_user": false,
    "taf_emails_sent": null,
    "type": "Signup",
    "updated_at": "2012-03-14T10:33:24.474059",
    "user": "/rest/v1/user/1/"
}

XML Examples

POST a SignupAction without authenticating

$ curl -i -X POST -H 'Accept: application/xml' -H 'Content-type: application/xml; charset=utf-8' https://docs.actionkit.com/rest/v1/action/ -d '<?xml version="1.0" encoding="utf-8"?><request type="hash"><page>signup</page><first_name>Example</first_name><last_name>User</last_name><email>user@example.com</email><zip>12345</zip></request>'
HTTP/1.1 201 CREATED
Date: Wed, 14 Mar 2012 11:12:34 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/xml; charset=utf-8
Location: https://docs.actionkit.com/rest/v1/action/5/
Transfer-Encoding: chunked
<?xml version="1.0" encoding="utf-8"?>
<response>
  <rd type="integer">1</rd>
  <akid>.1.iWxeUd</akid>
  <redirect_url>/cms/thanks/signup?action_id=5&amp;akid=.1.iWxeUd&amp;rd=1</redirect_url>
  <action_id type="integer">5</action_id>
</response>

POST a SignupAction with authentication

$ curl -X POST -u user:password -H 'Accept: application/xml' -H 'Content-type: application/xml; charset=utf-8' https://docs.actionkit.com/rest/v1/action/ -d '<?xml version="1.0" encoding="utf-8"?><request type="hash"><page>signup</page><first_name>Example</first_name><last_name>User</last_name><email>user@example.com</email><zip>12345</zip></request>'
HTTP/1.1 201 CREATED
Date: Wed, 14 Mar 2012 11:19:34 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/xml; charset=utf-8
Location: https://docs.actionkit.com/rest/v1/action/7/
Transfer-Encoding: chunked
<?xml version="1.0" encoding="utf-8"?>
<object>
  <status>complete</status>
  <referring_mailing type="null"/>
  <opq_id/>
  <fields type="hash"/>
  <created_at>2012-03-14T11:17:58.350421</created_at>
  <taf_emails_sent type="null"/>
  <updated_at>2012-03-14T11:17:58.380278</updated_at>
  <source>website</source>
  <created_user type="boolean">False</created_user>
  <akid>.1.iWxeUd</akid>
  <referring_user type="null"/>
  <subscribed_user type="boolean">False</subscribed_user>
  <redirect_url>/cms/thanks/signup?action_id=7&amp;akid=.1.iWxeUd&amp;rd=1</redirect_url>
  <type>Signup</type>
  <link type="null"/>
  <user>/rest/v1/user/1/</user>
  <mailing type="null"/>
  <page>/rest/v1/signuppage/10/</page>
  <resource_uri>/rest/v1/action/7/</resource_uri>
</object>

x-www-form-url-encoded Examples

In these examples we submit x-www-form-url-encoded data, but set the Accept header to application/json. Other combinations are possible.

POST a SignupAction without authenticating

$ curl -i -X POST -H 'Accept: application/json' -H 'Content-type: application/x-www-form-urlencoded; charset=utf-8' https://docs.actionkit.com/rest/v1/action/ -d 'page=signup&first_name=Example&last_name=User&email=user@example.com&zip=12345'
HTTP/1.1 201 CREATED
Date: Wed, 14 Mar 2012 11:46:22 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Location: https://docs.actionkit.com/rest/v1/action/11/
Transfer-Encoding: chunked
{
    "action_id": 11,
    "akid": ".1.iWxeUd",
    "rd": 1,
    "redirect_url": "/cms/thanks/signup?action_id=11&akid=.1.iWxeUd&rd=1"
}

POST a SignupAction with authentication

$ curl -u user:password -i -X POST -H 'Accept: application/json' -H 'Content-type: application/x-www-form-urlencoded; charset=utf-8' https://docs.actionkit.com/rest/v1/action/ -d 'page=signup&first_name=Example&last_name=User&email=user@example.com&zip=12345'
HTTP/1.1 201 CREATED
Date: Wed, 14 Mar 2012 11:58:24 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Location: https://docs.actionkit.com/rest/v1/action/12/
Transfer-Encoding: chunked
{
    "akid": ".1.iWxeUd",
    "created_at": "2012-03-14T11:58:23.979349",
    "created_user": false,
    "fields": {},
    "link": null,
    "mailing": null,
    "opq_id": "",
    "page": "/rest/v1/signuppage/10/",
    "redirect_url": "/cms/thanks/signup?action_id=12&akid=.1.iWxeUd&rd=1",
    "referring_mailing": null,
    "referring_user": null,
    "resource_uri": "/rest/v1/action/12/",
    "source": "website",
    "status": "complete",
    "subscribed_user": false,
    "taf_emails_sent": null,
    "type": "Signup",
    "updated_at": "2012-03-14T11:58:24.012273",
    "user": "/rest/v1/user/1/"
}

Importing Donations

By taking a few extra steps, you can use the REST API to record donations you receive from users outside of ActionKit.

Stub Payment Accounts

ActionKit comes configured with a "Default ActBlue" stub account. You can use a single stub payment account for all of your external donations, or configure multiple stubs with different names if you want to distinguish between several types of external donations, such as varying fund-raising channels, payment processors, or bank accounts. To configure additional accounts, go to the gear menu, then Configure ActionKit->Donation Settings->Payment Accounts->edit, where you can add or change stub accounts.

Once that configuration change is in place, when you use the admin interface to define donation pages you will be able to choose these stubs in the "Payment account" menu.

You can either create dedicated donation pages linked to each stub payment account, or use existing donation pages and override the payment account via the account parameter described below.

Donations made with a stub payment account won't result in a credit card charge -- it's assumed that you've already collected the payment some other way -- but the donation will be recorded as database rows in the core_order and core_transaction tables for use in your site's reports.

You can send 'donation_date' and 'created_at' to control the dates ActionKit will save in core_action and core_order. The logic is similar to that used by Imports:

  • created_at - (optional) Use any of the supported date formats (see above) to set the created_at timestamp in core_order, core_transaction, and core_action. If you don't include this column, or it's empty for a given row, ActionKit uses the current timestamp.
  • donation_date - (optional) Use any of the supported date formats to set the created_at timestamp in core_order and core_transaction only. Core_action is set to the current time.

These accounts do not support recurring donations.

Donation Action Requests

To record individual donations via the REST API, make a POST request to the Action list_endpoint, passing either the name of a donation page linked to a stub payment account, or the name of a regular donation page plus the name of a stub payment account.

You can use unauthenticated requests to create donations, but the response from authenticated requests includes additional information; in particular, only authenticated requests will receive the status value in responses, which is needed to detect failures due to incorrect card_code values.

$ curl -u user:password -i -X POST -H 'Content-type: application/json; charset=utf-8' https://docs.actionkit.com/rest/v1/action/ -d '{ "page": "your_donation_page", "payment_account": "Your Stub Account", "card_num": "4111111111111111", "card_code": "007", "exp_date_month": "12", "exp_date_year": "25", "name": "Jane Doe", "email": "my-api-donor@example.com", "address1": "123 Main Street", "city": "New York", "state": "NY", "zip": "90210",  "amount_other": "123.45" }'
{
  "akid": ".11.sE5Sju",
  "created_at": "2014-02-25T21:38:39.197149",
  "created_user": false,
  "fields": {},
  "id": 48,
  "ip_address": "47.37.134.18",
  "is_forwarded": false,
  "link": null,
  "mailing": null,
  "opq_id": "",
  "page": "/rest/v1/donationpage/15/",
  "redirect_url": "/cms/thanks/your_donation_page?action_id=48&akid=.11.sE5Sju&ar=1&rd=1&total=123.45",
  "referring_mailing": null,
  "referring_user": null,
  "resource_uri": "/rest/v1/donationaction/48/",
  "source": "restful_api",
  "status": "complete",
  "subscribed_user": false,
  "taf_emails_sent": null,
  "type": "Donation",
  "updated_at": "2014-02-25T21:38:39.487840",
  "user": "/rest/v1/user/11/"
}

The "email" field is required. The "name" field is required unless a user with the given email address already exists. The address-related fields are optional and may be skipped if you want to avoid overwriting the user's current location.

The "card_num" value can not be empty, but it does not need need to be a valid credit card number. The last four characters of the value you send will be saved in the core_order table, so you can send the full card number, or just the last four digits, or a placeholder value such as "4111111111111111".

The "card_code" must always contain the stub payment account's verification number, which is typically "007" unless ActionKit support has specifically assigned you a different code.

Products And Candidates

You can import product purchases and candidate donations as long as you first set up appropriately-configured donation pages.

You can record purchases of products by selecting those products on the donation page's "Action basics" screen and then including the purchased quantity in a parameter named "product_1". You can record shipping addresses by including fields named "shipping_address1", "shipping_address2", "shipping_city", "shipping_state", and "shipping_zip".

You can record donations to candidates by selecting those candidates on the donation page's "Action basics" screen and then including the donation amount in a parameter named "candidate_1".

Donation Responses

A successful request will receive a response containing "status": "complete" as well as other details about the request. The donation may be declined if you provide the wrong card_code, or if you submit the exact same transaction twice in a row; in these cases, the response hash will instead contain "status": "failed".