All the users in your ActionKit instance are accessible via the REST API. You can retrieve, update, create and delete user resources. The user collection contains the full set of your users in ActionKit.

There is also a publicly available view of users that requires an AKID, and returns a limited set of information about a user. You can use this endpoint for validating AKID tokens.

URI: /rest/v1/userpublic/{{ akid }}/

See Unauthenticated User Info below.

You can get a time limited login token for users (e.g. for use on event pages) by POSTing to:

URI: /rest/v1/user/{{ user id }}/logintoken/

See Login Tokens below.


Property Description
actions A link to the actions a user has taken.
address1 The user's address.
address2 The user's address, second line.
city The user's city.
country The user's country.
created_at The date/time that this user was first created in the database.
email The user's email address.
events A link to a list of events created by this user.
eventsignups A link to a list of events this user signed up for.
fields A dictionary of custom user fields.
first_name The user's first name.
lang The user's language preference.
last_name The user's last name.
location An estimated geo-location for this user.
logintoken URI to get a login token for this user.
middle_name The user's middle name.
orderrecurrings A link to a list of a user's recurring orders.
orders A link to a list of a user's orders.
original The address data as it came in from the user in its pristine uncorrected state. Only used for US peeps.
phones A list of a user's phone numbers
plus4 The user's zip plus 4 digit code.
postal The user's postal code.
prefix The user's prefix.
rand_id No longer in use.
region The user's region.
resource_uri The uri for this resource, relative to the base url.
sent_mails Sent mailings, a link to a list of mails sent to a user.
source Source of the first action the user took.
state The user's state.
subscriptionhistory A link to a list of the changes to a user's subscriptions.
subscriptions A link to a list of a user's current subscriptions.
subscription_status Subscribed, unsubscribed, bounced, never. You cannot edit this directly; to change a user's subscriptions use generic action processing against a signup or unsubscribe page.
suffix The user's suffix.
token A hashed identifier for this user.
updated_at The date/time the user record was last updated.
zip The user's zip.


You can filter (search) on the following fields. ALL means that you can use any of the comparison operators, ALL_WITH_RELATIONS means you can compare and join to the related resource.

Filter Allowed operators
country ALL
email exact
last_name ALL
source ALL
state ALL
subscription_status exact, in
zip ALL


URI Allowed HTTP Methods
/user/ GET, POST
/user/{ user id } GET, PUT, PATCH, DELETE

You can create new users by POSTing to the collection. You can update users by PUTing to the specific object. You can also DELETE users, but there's no undo. Creating and updating users this way bypasses the validation that happens during Generic Action Processing, however address correction and geolocation still occur.


Here are a few examples of retrieving User resources.


GET many users

$ curl -i -u user:password

HTTP/1.1 200 OK
Date: Wed, 29 Feb 2012 16:35:24 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
    "meta": {
        "previous": null,
        "total_count": 1000,
        "offset": 0,
        "limit": 1,
        "next": "/rest/v1/user/?_offset=1&_limit=1&format=json"
    "objects": [
            "last_name": "Testerson",
            "useroriginal": "/rest/v1/useroriginal/1/",
            "suffix": "",
            "phones": [],
            "updated_at": "2012-03-28T08:54:30",
            "actions": "/rest/v1/action/?user=1",
            "prefix": "",
            "orders": "/rest/v1/order/?user=1",
            "city": "",
            "first_name": "Testy",
            "middle_name": "",
            "zip": "00783",
            "rand_id": 170631374,
            "subscriptionhistory": "/rest/v1/subscriptionhistory/?user=1",
            "source": "makemeusers",
            "state": "PR",
            "location": "/rest/v1/location/1/",
            "logintoken": "/rest/v1/logintoken/1/",
            "subscription_status": "subscribed",
            "email": "",
            "subscriptions": "/rest/v1/subscription/?user=1",
            "address1": "",
            "address2": "",
            "orderrecurrings": "/rest/v1/orderrecurring/?user=1",
            "eventsignups": "/rest/v1/eventsignup/?user=1",
            "postal": "",
            "lang": "/rest/v1/language/100/",
            "plus4": "",
            "fields": {},
            "created_at": "2012-03-28T08:54:30",
            "events": "/rest/v1/event/?user=1",
            "token": ".1.iWxeUd",
            "usermailings": "/rest/v1/usermailing/?user=1",
            "country": "United States",
            "region": "",
            "resource_uri": "/rest/v1/user/1/"

GET A Single User

You can load a single user record as well.

$ curl -i -u user:password
HTTP/1.1 200 OK
Date: Fri, 02 Mar 2012 13:06:21 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
{   'actions': /rest/v1/action/?user=1,
    'address1': u'',
    'address2': u'',
    'city': u'',
    'country': u'United States',
    'created_at': '2012-03-28T08:54:30',
    'email': u'',
    'events': /rest/v1/event/?user=1,
    'eventsignups': /rest/v1/eventsignup/?user=1,
    'fields': {   },
    'first_name': u'Testy',
    'lang': /rest/v1/language/100/,
    'last_name': u'Testerson',
    'location': /rest/v1/location/1/,
    'logintoken': /rest/v1/user/1/logintoken/,
    'middle_name': u'',
    'orderrecurrings': /rest/v1/orderrecurring/?user=1,
    'orders': /rest/v1/order/?user=1,
    'phones': [],
    'plus4': u'',
    'postal': u'',
    'prefix': u'',
    'rand_id': 170631374,
    'region': u'',
    'resource_uri': /rest/v1/user/1/,
    'source': u'makemeusers',
    'state': u'PR',
    'subscription_status': u'subscribed',
    'subscriptionhistory': /rest/v1/subscriptionhistory/?user=1,
    'subscriptions': /rest/v1/subscription/?user=1,
    'suffix': u'',
    'token': u'.1.iWxeUd',
    'updated_at': '2012-03-28T08:54:30',
    'usermailings': /rest/v1/usermailing/?user=1,
    'useroriginal': /rest/v1/useroriginal/1/,
    'zip': u'00783'


Create new users by POSTing to /rest/v1/user/ - but consider using Generic Action Processing for creating users. It runs more validation, and provides tools for sending new users emails, subscribing them to mailing lists, and more. Yes, more!

$ curl -i -u user:password -H 'Content-Type: application/json' -X POST -d '{ "email": "" }'
Date: Wed, 28 Mar 2012 15:43:03 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: text/html; charset=utf-8
Content-Length: 0

Note the Location header, which has the URI of the new user.


Use PATCH to update existing user records, by sending a subset of fields with new information.


You cannot update subscription_status directly. To change a user's subscription status, you need to process an Action. Try POSTing a SignupAction to subscribe a user, or an UnsubscribeAction to unsubscribe a user.

$ curl -u user:password  -i -H 'Content-type: application/json' -X PATCH -H 'Accept: text/xml' -d '{ "email": "" }'
Server: openresty
Date: Thu, 04 Feb 2016 14:20:06 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Vary: Accept,Cookie,Accept-Encoding,User-Agent
Set-Cookie: sid=55gdgrgoig9gw3u84cgte7w0q7nwhvdk; expires=Thu, 04-Feb-2016 22:07:24 GMT; httponly; Max-Age=28800; Path=/


See PATCH - for Users they are synonyms.


You can delete users with a simple DELETE http request. Do you really want to delete these users? We don't think you do, but you can. Deleting a user will also delete all of their actions, donations, subscription history, subscriptions, event signups, phones, recurring donations, sent mails, location, and custom user fields.

$ curl -i -u user:password -X DELETE
Date: Fri, 20 Apr 2012 20:02:18 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Length: 0
Content-Type: text/html; charset=utf-8

And now trying to load the user, we get a 404.

$ curl -u user:password -i
Date: Fri, 20 Apr 2012 20:02:22 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked

Now that you know how to delete users, be careful!

Unauthenticated User Info

URI Allowed Methods
/rest/v1/userpublic/{{ akid }}/ GET

You can access /rest/v1/userpublic/{{ akid }}/ without authentication. This can be useful for validation AKIDs, and for retrieving (very) basic user information, i.e. name and language.

{ 'akid': u'.21.qpecj6',
  'lang': None,
  'language': {   'iso_code': u'en', 'name': u'English'},
  'name': u'Testy Testerson',
  'token': u'.21.qpecj6' }

Login Tokens

URI Allowed Methods
/rest/v1/user/{{ user id }}/logintoken/ POST

Returns a token that logs a user into ActionKit. This token is not the same as an akid.

Optional parameter:

ttl - seconds until token expires (default=86400, one day),
86400*30, or 30 days, is the max.


token - a string you can use in an ActionKit URL

You can use the token in an ActionKit URL like this:{{ token }}&l=1{{ token }}&l=1&next=/path/to/another/ak/page/

Note the &l=1, which keeps ActionKit from asking the user to set a password first. The token is not recognized on all pages.

You should be careful where you use the token:

  • ONLY give the token to users who are logged into your system. An akid= or a new user's email address isn't enough.
  • If you email the token, warn the user that forwarding the link will compromise their account. (event_email_created.html has sample warning text.)
  • Use the default 1-day expiration period if you can. For example, it should work for a redirect or link to ActionKit in your site's UI. Otherwise, use up to 30 days.

Securing tokens is important because if one leaks (for instance, if a user forwards an email with token), anyone could use it to:

  • See the victim's street address, phone number, etc.
  • View or cancel the victim's recurring donations
  • Edit the victim's in-person events and email attendees
  • Use any future ActionKit features that require login

Finally, be sure your login system is secure. Some basics:

  • If there's a login system provided by your framework, you may want to use it rather than roll your own, both for security and simplicity.
  • We suggest hashing the user's password, not storing the raw password in the user's cookies or the database.
  • Require users to confirm their email address by mailing them a link with a secret token in it. This means, for instance, that you can't let users "log in" the first time without confirming their email.
  • Your password change token also must not be 'browsable': just adding 1 to the user's ID shouldn't give access to another user's account.
$ curl -u user:password -i -X POST ''
HTTP/1.1 200 OK
Server: openresty
Date: Thu, 04 Feb 2016 14:40:58 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept,Cookie,Accept-Encoding,User-Agent

{"token": "al.1454596096.86400.21.L6LgPl"}

User Merge

URI Allowed Methods
/rest/v1/usermerge/ POST

Create a user merge job to combine records from two or more users.


  • primary_user - URI of user that you want to keep
  • users - List of URIs for users that will be merged into the primary user
  • address_user - URI of user with the mailing address that you want to keep
  • source_user - URI of user with the user source that you want to keep

Optional parameters:

  • sms_user - URI of user with the SMS address (aka, phone number) and list subscriptions that you want to keep
  • lists - List of URIs for mailing lists that the primary user will be subscribed to. If not included, the default subscription merge method of merging all subscriptions except the re-engagement list will be used. If included and empty, the primary user will be unsubscribed from all mailing lists. You can only subscribe the primary user to lists that they (or another merge user) are already subscribed to. Additionally, while the primary user may remain on the re-engagment list if they're already subscribed, a merge cannot otherwise subscribe a user to the re-engagement list.

Returns HttpCreated on success. The URI in the Location header points to a new user merge resource, which includes a status that matches one of the following values:

status description
pending User merge job has not started yet.
complete User merge job completed successfully.
failed User merge job failed.


URI Allowed Methods
/rest/v1/eraser/ POST

You can use this endpoint to delete user data.

This endpoint requires one (but not both) of these parameters:

  • user_id - User ID of the user you want to erase.
  • email - Email address of the user you want to erase.

You can optionally specify any of these parameters:

  • order_user_details - Sending a true value for this will clear any records for this user in core_order_user_detail and clear the data in core_donationattemptlog.args which can contain the user's name and email. The orders will remain but without this user data.
  • user_fields - Sending a true value for this will delete any custom user fields for this user.
  • action_fields - Sending a true value for this will delete any custom action or event fields for this user.
  • transactional_mailings - Sending a true value for this will clear the email field from any records for this user in core_transactionalmailingssent.

Returns a redirect to the (now empty) user record on success.

Salesforce Mapping

URI Method Parameters
/rest/v1/salesforcemap/ GET  
/rest/v1/salesforcemap/ POST user_id - required
/rest/v1/salesforcemap/{{map_id}}/disconnect_user/ POST  
/rest/v1/salesforcemap/{{map_id}}/sync_user/ POST  

Use this endpoint to create or manage users in the SalesForce sync.

To retrieve mapping details:

GET /rest/v1/salesforcemap/

The id field included in the GET response will be used to force an immediate sync or disconnecting a user from the sync.

To trigger an immediate sync for the mapping's user:

POST /rest/v1/salesforcemap/{{map_id}}/sync_user/

To remove a mapping's user from the sync:

POST /rest/v1/salesforcemap/{{map_id}}/disconnect_user/

A user can be added to the sync and sent to SalesForce immediately, even if they don't match a User Sync report:

$ curl -i -u username:password -H 'Content-Type: application/json' -X POST -d '{ "user_id": "7140" }'
HTTP/2 201
date: Fri, 30 Oct 2020 18:02:42 GMT
content-type: text/html; charset=utf-8
server: openresty
vary: Accept, Cookie, Origin

Errors are reported back in the format:

        "salesforcemap": "ActionKit to SalesForce Sync is disabled."


EveryAction Integration Mapping

URI Method Parameters
/rest/v1/everyactionusermap/ GET user_id, van_id
/rest/v1/everyactionusermap/{{map_id}}/ POST, PATCH, DELETE user_id, van_id
/rest/v1/everyactionordermap/ GET order_id, contribution_id
/rest/v1/everyactionordermap/{{map_id}}/ POST, PATCH, DELETE order_id, contribution_id
/rest/v1/everyactiontransactionmap/ GET transaction_id, contribution_id
/rest/v1/everyactiontransactionmap/{{map_id}}/ POST, PATCH, DELETE transaction_id, contribution_id

Use these endpoints to query and adjust the mapping from Users, Orders and Transactions in ActionKit to Contacts and Contributions in EveryAction.

For example, to adjust the VAN ID assigned to a User, first find their mapping:

GET /rest/v1/everyactionusermap/?user_id=12345

Then PATCH the mapping with a new VAN ID:

PATCH /rest/v1/everyactionusermap/123/

   'van_id': 456789

You can do the same with an order or a transaction (used for payments on recurring orders). You can also DELETE mappings, which may be useful if you'd like trigger the integration to create a new record in EA for that resource on its next run.