The XML-RPC API is no longer under active development. While it is still supported, no further improvements or changes will be made to it.

We strongly recommend that you use the REST API instead.

Processing User Actions

The act() function is the easiest way to process user actions remotely. It will validate input, process the actions, and return processing status information.


Step one for using the act() function is to create a Page using the ActionKit admin. In the following examples, we'll use assume a SignupPage with a 'Short name' of 'everyhome', that requires the fields first name, last name, address1, city, state and zip.


act() is the main entry point for processing User actions using the API. **kwargs is the Python syntax for variable length list of keyword arguments. When you call act() using XML-RPC clients, send the arguments as a struct.


The act() function provides some validation, but not all. You should verify that the validation is sufficient for your needs.

When you create the Page in the ActionKit Admin you can select the fields you want to require (see the Required fields option under Advanced Options on the first page of the Page editor).

act() will:

  • return an error if required fields are missing or empty, unless the user already has a value for the field on file.
  • always make sure the email field Email is a valid email address.
  • always check zip is 5 characters long, and plus4 is 4 characters long.

We hope to improve and expand validation of zip and address fields soon, including checking for valid postal codes by country. For fields specified as 'Always Required' in the admin, we might also begin verifying that a new value was passed in with the action, rather than counting an existing value in the user record as satisfying the requirement.

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

Required Arguments

All Actions are associated with specific pages, so all calls to act require the name of the Page that is being processed.

  • page - the name of the Page

Submitting an action also requires identifying the user taking the action. ActionKit allow you to use three ways to uniquely identify a user:

  • email - an email address.
  • akid - a token provided by ActionKit representing a user.
  • id - unique integer id for this User in ActionKit.

Optional Arguments

User fields:

See User for the full list of User fields.

Custom user fields

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

Custom action fields

  • Any field prefixed with 'action_' is treated as a custom action field. You do not have to do anything to use an action field.

Tell a friend fields

  • taf_note, taf_body, taf_subject, taf_emails - If FollowupPage.send_taf is true, these arguments will control the message sent and the emails to which it is sent.

Referral fields

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

See also Advanced Topics (Templates) and Embedding


You can control the way the act method works using the following parameters:

  • opt_in - If optin_in is True, act() requires a list of lists to which to subscribe a user. If opt_in is False, act() will subscribe users to the list associated with the page (or the list of lists provided in the argument lists).
  • required - A list of required fields to be added to the fields required by the Page.
  • posted - if True, the default, then the action will be processed normally. If False, the action will not be processed. Instead, ActionKit will try to load an existing user, returned in the 'user' key. If the user has already taken action on this page, 'action' will contain the details of that action. If the page only allows a single response - is a CallPage or PetitionPage - ActionKit will return the user who previously took action to the 'referring_user' key.

Default Values

act() has several defaults:

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

Return Data

act() will always return the following fields:

  • success - Boolean
  • status - 'success', 'processing_error', 'invalid_input', 'page_not_found'

If success is False, act will also return

  • errors - a struct mapping fields to error messages

If success is True, act will also return

  • user - the User created by or provided in the input
  • action - the action record we created
  • redirect - the URL to which the action would send the User
  • related - a struct containing objects related to the action just taken. For example, for a DonationAction, related will contain a key 'order' with a value of a struct containing details about the order.


Let's process some actions! Here's a simple example:

import xmlrpclib
import pprint

actionkit = xmlrpclib.Server('https://%s:%s@%s/api/' % (user,password,host))

action = actionkit.act({
    'page': 'everyhome',
    'first_name': 'XML',
    'last_name': 'RPC',
    'email': 'test+xmlrpc+actions@example.com',
    'zip': '12345'

if action['success']:
    print "Signed up! Your ActionKit token is %s" % action['user']['token']
    print pprint.pprint(action)
    print "Whoops!"
    for (field, error) in action['errors'].items():
        print "%s: %s" % (field, error)


See Setup for the hostname, user and password.


If you get a 404 NOT FOUND, check that you are using the correct Short name for the page you created as the 'page' parameter.

And here's the output:

[aaron roboticdogs]$ python test.py
city: ['City is required.']
state: ['State is required.']
address1: ['Street address is required.']

Let's update the call to act() to include the missing fields:

action = actionkit.act({
    'page': 'everyhome',
    'first_name': 'Puppy',
    'last_name': 'Pupperson',
    'email': 'robotic+dog+lover@example.com',
    'address1': '1 Pound Ave',
    'city': 'Dogville',
    'state': 'DOG',
    'zip': '10014'

Re-running, now we get:

[aaron roboticdogs]$ python test.py
Signed up! Your ActionKit token is .2.49ReX3

The full return value is:

{'action': {'created_user': True,
            'id': 10,
            'link': None,
            'mailing': None,
            'opq_id': '',
            'page': 6,
            'referring_mailing': None,
            'referring_user': None,
            'source': 'website',
            'status': 'complete',
            'subscribed_user': True,
            'user': 2},
 'redirect': 'http://roboticdogs.me/thanks.html?action_id=10&akid=.2.49ReX3',
 'status': 'success',
 'success': True,
 'user': {'address1': '1 Pound Ave',
          'address2': '',
          'city': 'Dogville',
          'country': 'United States',
          'email': 'robotic+dog+lover@example.com',
          'first_name': 'Puppy',
          'id': 2,
          'lang_id': None,
          'last_name': 'Pupperson',
          'middle_name': '',
          'password': '',
          'plus4': '',
          'postal': '',
          'prefix': '',
          'region': '',
          'source': 'website',
          'state': 'NY',
          'state_name': 'New York',
          'subscription_status': 'subscribed',
          'suffix': '',
          'token': '.2.49ReX3',
          'zip': '10014'}}

The complete return value has a couple of very useful fields. In the 'action' struct, the 'created_user' value indicates if this email is new to your database. The 'subscribed_user' value indicates if this email was just subscribed to one of your lists.

The 'redirect' field gives you a complete URL for the PageFollowup, with the action id and the ActionKit user token appended. (You can configure the redirect URL in the ActionKit Admin by editing a page. )


When you change any part of a user's address through the API, we clear the user's other address fields. So, if you change a user's ZIP, we'll clear their old address1. That keeps our automatic ZIP+4 lookup from overwriting your new ZIP with a ZIP based on the old address.

As a result, your API apps need to update all address fields at once to work right. For example, it wouldn't work to write a script that updates just user ZIPs in one pass and user street addresses in another.

No address info will be cleared as long as all the fields you submit either match what was on file or are blank. Submitting the ZIP that's already on file, or no address info at all, is safe.