Users¶
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.
URI: /rest/v1/user/
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.
Properties¶
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. |
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. |
Filtering¶
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 |
exact | |
language | ALL_WITH_RELATIONS |
last_name | ALL |
source | ALL |
state | ALL |
subscription_status | exact, in |
zip | ALL |
Methods¶
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.
Examples¶
Here are a few examples of retrieving User resources.
GET¶
GET many users¶
$ curl -i -u user:password https://docs.actionkit.com/rest/v1/user/?_limit=1&format=json
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": "1-1332924870@example.com",
"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 https://docs.actionkit.com/rest/v1/user/1/
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'1-1332924870@example.com',
'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'
}
POST¶
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": "myshinynewuser@example.com" }' https://docs.actionkit.com/rest/v1/user/
HTTP/1.1 201 CREATED
Date: Wed, 28 Mar 2012 15:43:03 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: text/html; charset=utf-8
Location: https://www-default.actionkit.com:8807/rest/v1/user/1024/
Content-Length: 0
Note the Location header, which has the URI of the new user.
PATCH¶
Use PATCH to update existing user records, by sending a subset of fields with new information.
Note
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": "updated+email@example.com" }' https://www-default.actionkit.com:8807/rest/v1/user/1024/
HTTP/1.1 202 ACCEPTED
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=/
DELETE¶
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 https://docs.actionkit.com/rest/v1/user/1024/
HTTP/1.1 204 NO CONTENT
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 https://docs.actionkit.com/rest/v1/user/1024/
HTTP/1.1 404 NOT FOUND
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.
Returns:
token - a string you can use in an ActionKit URL
You can use the token in an ActionKit URL like this:
act.you.org/event/campaignname/123/host/?i={{ token }}&l=1 act.you.org/login/?next=/me/&i={{ 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 'https://www-default.actionkit.com:8807/rest/v1/user/21/logintoken/'
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.
Parameters:
- 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. |
Eraser¶
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 incore_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 incore_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" }' https://docs.actionkit.com/rest/v1/salesforcemap/
HTTP/2 201
date: Fri, 30 Oct 2020 18:02:42 GMT
content-type: text/html; charset=utf-8
location: https://docs.actionkit.com/rest/v1/salesforcemap/3730/
server: openresty
vary: Accept, Cookie, Origin
Errors are reported back in the format:
{
"errors":
{
"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.