An Example: Users

Let's start with an example - accessing Users via the API.

Note

You've set up a staff user account that can access the API, right? You'll need to in order to try the examples. And you really want to try the examples. The Authentication section has the details on setting up a user.

Get Users Whose Last Name Is "Smith"

We're going to use the User resource to find a collection of Users with the last name 'Smith'. Looking at the root resource we see:

'user': { 'list_endpoint': '/rest/v1/user/',
           'schema': '/rest/v1/user/schema/' }

The "list endpoint" is a URI that returns a collection of objects. You can POST to the collection to create a new object. The full collection is returned in pages and allows filtering on some fields.

The "schema" is a URI that returns a description of the User resource, including which fields we can use to filter the collection. The filtering section of the user schema tells us that we can filter the collection using the last_name field and any operator.

"filtering": {
    "country": "all",
    "email": [
        "exact"
    ],
    "language": "all with relations",
    "last_name": "all",
    "source": "all",
    "state": "all",
    "subscription_status": [
        "exact",
        "in"
    ],
    "zip": "all"
}

Let's get a collection of users filtered by last name!

$ curl -i -u user:password -X GET -H 'Accept: application/json' https://docs.actionkit.com/rest/v1/user/?last_name=Smith
HTTP/1.1 200 OK
Date: Thu, 15 Mar 2012 13:54:32 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked

{
    "meta": {
        "limit": 20,
        "next": null,
        "offset": 0,
        "previous": null,
        "total_count": 0
    },
    "objects": []
}

At least on my development server, there are no users with the last name of Smith. How sad!

In this example, we used the Accept header to tell ActionKit that we wanted the response in JSON. Other valid values are listed under the response formats.

Add A User

Let's try adding a User so that our search will return some Smiths. To do so, we POST to the URI for the collection:

$ curl -i -u user:password -X POST -H 'Content-type: application/json' -H 'Accept: application/json' https://docs.actionkit.com/rest/v1/user/ -d '{ "first_name": "Jürgen", "middle_name": "Müller", "last_name": "Smith", "email": "jurgen@example.com", "address1": "", "country": "Germany", "city": "Berlin", "region": "Berline" }'
HTTP/1.1 201 CREATED
Date: Wed, 28 Mar 2012 15:49: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/1025/
Content-Length: 0

201 CREATED! Success!

Note

Creating a user with the /user/ endpoint does not subscribe that user to any lists! In most cases, you'll create users by creating an action on a page with the /action/ endpoint.

We used the Content-Type header to tell ActionKit we were sending the POST data in JSON. You can send the data in other formats, e.g. XML, x-www-form-urlencoded.

Our POST didn't return any content, but there's a Location header we can use to retrieve the newly created User. How RESTful!

$ curl -i -u user:password -X GET -H 'Accept: application/json' https://docs.actionkit.com/rest/v1/user/1025/
HTTP/1.1 200 OK
Date: Wed, 28 Mar 2012 15:50:01 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
{
    "last_name": "Smith",
    "useroriginal": "/rest/v1/useroriginal/1025/",
    "suffix": "",
    "phones": [],
    "updated_at": "2012-03-28T15:49:03",
    "actions": "/rest/v1/action/?user=1025",
    "prefix": "",
    "orders": "/rest/v1/order/?user=1025",
    "city": "Berlin",
    "first_name": "Jürgen",
    "middle_name": "Müller",
    "zip": "",
    "rand_id": 3100902,
    "subscriptionhistory": "/rest/v1/subscriptionhistory/?user=1025",
    "source": "",
    "state": "",
    "location": "/rest/v1/location/1025/",
    "subscription_status": "never",
    "email": "jurgen@example.com",
    "subscriptions": "/rest/v1/subscription/?user=1025",
    "address1": "",
    "address2": "",
    "orderrecurrings": "/rest/v1/orderrecurring/?user=1025",
    "eventsignups": "/rest/v1/eventsignup/?user=1025",
    "postal": "",
    "lang": null,
    "plus4": "",
    "fields": {},
    "created_at": "2012-03-28T15:49:03",
    "events": "/rest/v1/event/?user=1025",
    "token": ".1025.vwoVf7",
    "usermailings": "/rest/v1/usermailing/?user=1025",
    "country": "Germany",
    "region": "Berline",
    "resource_uri": "/rest/v1/user/1025/"
}

Cool! A new user!

Accessing Sub-Resources

Many resources have sub-resources. For example, ActionKit tries to geocode users' addresses and creates a location sub-resource. A user object includes the URI of the location resource. Let's find out if ActionKit could get a lat/long for Jürgen's location:

$ curl -i -u user:password -X GET -H 'Accept: application/json' https://docs.actionkit.com/rest/v1/location/1025/
HTTP/1.1 200 OK
Date: Wed, 28 Mar 2012 15:51:11 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
{
    "us_state_senate": "",
    "region_code": "16",
    "us_state_district": "",
    "us_county": "",
    "lat_lon_precision": "city",
    "created_at": "2012-03-28T15:49:03",
    "updated_at": "2012-03-28T15:49:03",
    "longitude": 13.410500000000001,
    "loc_code": "G2950159",
    "country_code": "DE",
    "latitude": 52.5244,
    "us_district": "",
    "resource_uri": "/rest/v1/location/1025/"
}

We've located Jürgen!

Searching Again

Let's try our search again. While you were getting another cup of coffee, I secretly created a thousand other users with the last name Smith.

$ curl -i -u user:password -X GET -H 'Accept: application/json' 'https://docs.actionkit.com/rest/v1/user/?last_name=Smith&_limit=5'
HTTP/1.1 200 OK
Date: Wed, 28 Mar 2012 15:58:16 GMT
Vary: Cookie,Accept-Encoding,User-Agent
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
{
    "meta": {
        "limit": 5,
        "next": "/rest/v1/user/?last_name=Smith&_limit=5&_offset=5",
        "offset": 0,
        "previous": null,
        "total_count": 1000
    },
    "objects": [
        {
            "actions": "/rest/v1/action/?user=1",
            "address1": "",
            "address2": "",
            "city": "",
            "country": "United States",
            "created_at": "2012-03-28T15:57:03",
            "email": "1-1332950223@example.com",
            "events": "/rest/v1/event/?user=1",
            "eventsignups": "/rest/v1/eventsignup/?user=1",
            "fields": {},
            "first_name": "Testy",
            "lang": "/rest/v1/language/100/",
            "last_name": "Smith",
            "location": "/rest/v1/location/1/",
            "middle_name": "",
            "orderrecurrings": "/rest/v1/orderrecurring/?user=1",
            "orders": "/rest/v1/order/?user=1",
            "phones": [],
            "plus4": "",
            "postal": "",
            "prefix": "",
            "rand_id": 286964973,
            "region": "",
            "resource_uri": "/rest/v1/user/1/",
            "source": "makemeusers",
            "state": "FL",
            "subscription_status": "subscribed",
            "subscriptionhistory": "/rest/v1/subscriptionhistory/?user=1",
            "subscriptions": "/rest/v1/subscription/?user=1",
            "suffix": "",
            "token": ".1.iWxeUd",
            "updated_at": "2012-03-28T15:57:03",
            "usermailings": "/rest/v1/usermailing/?user=1",
            "useroriginal": "/rest/v1/useroriginal/1/",
            "zip": "33847"
        },
        {
            "actions": "/rest/v1/action/?user=2",
            "address1": "",
            "address2": "",
            "city": "",
            "country": "United States",
            "created_at": "2012-03-28T15:57:03",
            "email": "2-1332950223@example.com",
            "events": "/rest/v1/event/?user=2",
            "eventsignups": "/rest/v1/eventsignup/?user=2",
            "fields": {},
            "first_name": "Testy",
            "lang": "/rest/v1/language/100/",
            "last_name": "Smith",
            "location": "/rest/v1/location/2/",
            "middle_name": "",
            "orderrecurrings": "/rest/v1/orderrecurring/?user=2",
            "orders": "/rest/v1/order/?user=2",
            "phones": [],
            "plus4": "",
            "postal": "",
            "prefix": "",
            "rand_id": 469753118,
            "region": "",
            "resource_uri": "/rest/v1/user/2/",
            "source": "makemeusers",
            "state": "NM",
            "subscription_status": "subscribed",
            "subscriptionhistory": "/rest/v1/subscriptionhistory/?user=2",
            "subscriptions": "/rest/v1/subscription/?user=2",
            "suffix": "",
            "token": ".2.KETAXE",
            "updated_at": "2012-03-28T15:57:03",
            "usermailings": "/rest/v1/usermailing/?user=2",
            "useroriginal": "/rest/v1/useroriginal/2/",
            "zip": "87131"
        },
        {
            "actions": "/rest/v1/action/?user=3",
            "address1": "",
            "address2": "",
            "city": "",
            "country": "United States",
            "created_at": "2012-03-28T15:57:03",
            "email": "3-1332950223@example.com",
            "events": "/rest/v1/event/?user=3",
            "eventsignups": "/rest/v1/eventsignup/?user=3",
            "fields": {},
            "first_name": "Testy",
            "lang": "/rest/v1/language/100/",
            "last_name": "Smith",
            "location": "/rest/v1/location/3/",
            "middle_name": "",
            "orderrecurrings": "/rest/v1/orderrecurring/?user=3",
            "orders": "/rest/v1/order/?user=3",
            "phones": [],
            "plus4": "",
            "postal": "",
            "prefix": "",
            "rand_id": 487870701,
            "region": "",
            "resource_uri": "/rest/v1/user/3/",
            "source": "makemeusers",
            "state": "CO",
            "subscription_status": "subscribed",
            "subscriptionhistory": "/rest/v1/subscriptionhistory/?user=3",
            "subscriptions": "/rest/v1/subscription/?user=3",
            "suffix": "",
            "token": ".3.jcWz_1",
            "updated_at": "2012-03-28T15:57:03",
            "usermailings": "/rest/v1/usermailing/?user=3",
            "useroriginal": "/rest/v1/useroriginal/3/",
            "zip": "81419"
        },
        {
            "actions": "/rest/v1/action/?user=4",
            "address1": "",
            "address2": "",
            "city": "",
            "country": "United States",
            "created_at": "2012-03-28T15:57:03",
            "email": "4-1332950223@example.com",
            "events": "/rest/v1/event/?user=4",
            "eventsignups": "/rest/v1/eventsignup/?user=4",
            "fields": {},
            "first_name": "Testy",
            "lang": "/rest/v1/language/100/",
            "last_name": "Smith",
            "location": "/rest/v1/location/4/",
            "middle_name": "",
            "orderrecurrings": "/rest/v1/orderrecurring/?user=4",
            "orders": "/rest/v1/order/?user=4",
            "phones": [],
            "plus4": "",
            "postal": "",
            "prefix": "",
            "rand_id": 30094183,
            "region": "",
            "resource_uri": "/rest/v1/user/4/",
            "source": "makemeusers",
            "state": "OH",
            "subscription_status": "subscribed",
            "subscriptionhistory": "/rest/v1/subscriptionhistory/?user=4",
            "subscriptions": "/rest/v1/subscription/?user=4",
            "suffix": "",
            "token": ".4.k7ZS8P",
            "updated_at": "2012-03-28T15:57:03",
            "usermailings": "/rest/v1/usermailing/?user=4",
            "useroriginal": "/rest/v1/useroriginal/4/",
            "zip": "45760"
        },
        {
            "actions": "/rest/v1/action/?user=5",
            "address1": "",
            "address2": "",
            "city": "",
            "country": "United States",
            "created_at": "2012-03-28T15:57:03",
            "email": "5-1332950223@example.com",
            "events": "/rest/v1/event/?user=5",
            "eventsignups": "/rest/v1/eventsignup/?user=5",
            "fields": {},
            "first_name": "Testy",
            "lang": "/rest/v1/language/100/",
            "last_name": "Smith",
            "location": "/rest/v1/location/5/",
            "middle_name": "",
            "orderrecurrings": "/rest/v1/orderrecurring/?user=5",
            "orders": "/rest/v1/order/?user=5",
            "phones": [],
            "plus4": "",
            "postal": "",
            "prefix": "",
            "rand_id": 686858843,
            "region": "",
            "resource_uri": "/rest/v1/user/5/",
            "source": "makemeusers",
            "state": "OH",
            "subscription_status": "subscribed",
            "subscriptionhistory": "/rest/v1/subscriptionhistory/?user=5",
            "subscriptions": "/rest/v1/subscription/?user=5",
            "suffix": "",
            "token": ".5.sbIRUh",
            "updated_at": "2012-03-28T15:57:03",
            "usermailings": "/rest/v1/usermailing/?user=5",
            "useroriginal": "/rest/v1/useroriginal/5/",
            "zip": "44202"
        }
    ]
}

This time we found some users!

Collections have two data structures: meta and objects.

The metadata has information about the collection, including links to the next and previous pages of objects, a total count of objects in the collection that match, and the limit currently being used to split the collection into pages. You can see that in this example we set the limit to 5, we got back 5 objects and there's a link in the metadata to the next page of objects.

Note

The limit and offset parameters must be prefixed with an underscore when sent to the server: _limit and _offset. That's to avoid conflicting with columns named limit and offset.

The objects data structure is - not surprisingly - a list of objects.

That's it for our example. Hopefully, it will give you some context for the more detailed parts of our documentation. A good next step is to read about the details of Requests or responses.