The ChatShipper Developer Hub

Welcome to the ChatShipper developer hub. You'll find comprehensive guides and documentation to help you start working with ChatShipper as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started

3. Fetching Resources

ChatShipper accepts many options to manipulate list and detail results for top-level resource types. These options can be added to your request via the querystring to filter, limit, sort and transform your resultsets.

Examples:

GET <apibase>/conversations
GET <apibase>/conversations?field=value
GET <apibase>/conversations?populate=contact,messages
GET <apibase>/conversations?sort=field,-field2
GET <apibase>/conversations?offset=10&limit=10

<apibase>: https://api.chatshipper.com/v2

Mandatory Query Parameters

Most resource listings can have zero or more query filters.

For fetching messages at least one of the following parameters should be supplied:
id, organization, conversation, type, role or createdAt.

For fetching conversations using a query for a meta variable, at least one of the following parameters is required: id, type, participants.user, status, createdAt, categoryIndex, category, organization, createdAt or updatedAt.

Example:

GET <apibase>/conversations?meta.intent=greeting&type=contact
In this example, when searching for a `meta.intent`, we limit the results to only conversations with the "contact" conversation type.

# Reserved Query Parameters

In general, document field names can be used as query parameters to filter search result. Additionally, a number of specialized parameters can be used to limit, sort and transform the results. These special parameters are:

* `sort` - Sorts by the given fields in the given order, comma delimited. A `-` sign will sort descending.
* `limit` - Limits the number of returned results.
* `offset` - Skips a number of results. Useful for pagination when combined with `limit`.
* `select` - Comma-delimited list of fields to select.
* `populate` - Comma-delimited list of fields to populate.

---

## Sorting

Getting a sorted list is as easy as adding a `sort` querystring parameter with the property you want to sort on. `/users/?sort=name` will give you a list sorted on the name property, with an ascending sort order. `/users/?sort=-name` will return the same list as before with a descending sort order.
GET <apibase>/users?sort=name
GET <apibase>/users?sort=-name
Response documents may be sorted by multiple criteria. Here's how you'd sort the collection by `name` in ascending order, then by `email` in descending order.
GET <apibase>/users?sort=name,-age

Pagination

By default, endpoints paginate results at 200 records per page, ordered by the _id field. Pagination is supported via offset and limit query parameters. When implementing pagination you might want to use offset and limit parameters, to skip a given amount of items or limit to a set amount of items.

GET <apibase>/users?offset=10&limit=10

offset

Skip sending the first n matched documents in the response. Useful for paging.

GET <apibase>/users?offset=5

limit

Limit the response document count to n at maximum. The default limit is 200.

GET <apibase>/users?limit=5

Examples

  • GET <apibase>/users/?limit=5 will give you the first 5 items
  • GET <apibase>/users/?offset=5 will skip the first 5 and give you the rest
  • GET <apibase>/users/?offset=5&limit=5 will skip the first 5 and then give you the second 5

Response Headers

Resultsets are accompanied by meta information in the response headers, which can be useful for pagination. The relevant response headers are:

  • X-Total: total number of results;
  • X-Total-Pages: total number of pages;
  • X-Per-Page: the number of results per page, corresponding to the limit parameter;
  • X-Page: the page number in a paginated set of results;
  • X-Range: the offset and the index of the last paged result, separated by a hyphen.

For example, consider a request for /users/?offset=5&limit=5, where the total number of users available is 9. The corresponding response headers in this case would be:

X-Total: 9
X-Total-Pages: 2
X-Page: 2
X-Per-Page: 5
X-Range: 6-9

A list of these response headers are specified in the standard Access-Control-Expose-Headers header, making them accessible to browser-based applications.

Link Header

Page navigation links are provided by the API to help your application request further pages of results. API responses, for paged results, contain HTTP Link headers providing a URL used to request other results pages.

Link: <https://api.chatshipper.com.v2/users>; rel="first",
      <https://api.chatshipper.com<apibase>/users>; rel="prev"

Four relationship types are possible:

  • first shows the URL of the first page of results. Not present if the response is the first page in a collection.
  • prev shows the URL of the immediate previous page of results. Not present if the response is the first page in a collection.
  • next shows the URL of the immediate next page of results. Not present if the response is the last page in a collection.
  • last shows the URL of the last page of results. Not present if the response is the last page in a collection.

Field Selection

Selecting the entity-properties you need (collections and details)

If you only need a few properties instead of the entire model, you can ask the service to only give just the properties you need. The select query parameter sets which fields should be selected for response documents.

A GET request to /users?select=name,email would result in something like:

[
    {
        "id": "543adb9c7a0f149e3ac29438",
        "name": "user1",
        "email": "[email protected]"
    },
    {
        "id": "543adb9c7a0f149e3ac2943b",
        "name": "user2",
        "email": "[email protected]"
    }
]
As can be seen, the `id` field is always returned irrespective of selected fields.

### Excluding properties from the selection

Instead of specifying which properties to select, you can _exclude_ properties from payloads by prepending the `select` parameter with a minus character.

A `GET` request to `/conversations?type=contact&select=-messages,-participants` would result in a conversations listing with messages and participants excluded from the payload.

***CAVEAT***

It's not possible to mix inclusion and exclusion of properties; for example the following would be invalid: `?select=-participants,messages`.

## Field Population

### Populating referenced sub-entities

When resulting documents contain properties referencing other entities, you can ask the API service to **populate** them for you. The `populate` parameter sets which fields should be populated for response documents.

A `GET` request to `/conversations` will result in:
[
    {
        "id": "542edff9fffc55dd29d99346",
        "contact": "591506e18a280627f8dcfede"
        ...
    }
]
A `GET` request to `/conversations?populate=contact` will expand the contact for all conversations found, resulting in:
[
    {
        "id": "542edff9fffc55dd29d99346",
        "contact": {
          "organization": "591508af8a280627f8dcfef1",
          "conversation": "222fff111333000000000fff",
          "profile": {
            "name": "John Doe",
            "gender": "male"
          },
          ...
        },
        ...
    }
]
Multiple `populate` parameters may be specified, separated by a comma. Populated fields will be fetched alongside with, but independent of selected fields (using the `select` parameter). Population can be applied both to resource listings and individual resources.

### Populating arrays of resource IDs

Population also works for resources that have an array of resource IDs as a property. As an example, a conversation has a list of message IDs; to populate all message objects, use:

    GET <apibase>/conversations?populate=messages
[
    {
        "id": "542edff9fffc55dd29d99346",
        "messages": [
            {
                "type": "chat",
                ... rest of full message
            }
        ]
        ...
    }
]

Populating Nested Properties

To populate nested properties (inside arrays or objects), use the dot-notation to specify the path to populate. For example, to expand all user IDs into user objects in a conversation's list of participants, use:

GET <apibase>/conversations?populate=participants.user
[
    {
        "id": "542edff9fffc55dd29d99346",
        "participants": [
            {
                "user": {
                    "id": "5a4fd7419feede6a19b18713"
                    "name": "John Johnson",
                    ... rest of full user
                },
                ... rest of participant
            }
        ]
        ...
    }
]

Selecting wich fields of the related document to populate

When populating referenced resources, you may be only interested in some properties of the underlying resource - if only to keep the payload size managable. The select parameter mentioned earlier only applies to the immediate resource; to select a set of fields for populated resources, append the populated property with a colon (:) and one or more fields separated by a pipe (|) symbol.

For example, say we want to fetch a single conversation with just the conversation status, the name of the owning organization, the name of participants and two message properties (type and text). The request would look like this:

>GET <apibase>/conversations/5a4fd7419feede6a19b18712?select=status& //
     populate=messages:type|text,organization:name,participants.user:givenName|familyName

This would result in a structure similar to:

{
    "id": "5a4fd7419feede6a19b18712",
    "status": "closed",
    "organization": {
        "name": "Acme, Inc",
        "id": "5a53e8e4dcfa875e82ed2ab3"
    },
    "participants": [
        {
            "user": {
                "givenName": "Edgar",
                "familyName": "Poe",
                "name": "Edgar Poe",
                "id": "5a53e98944cf9c622117fd28"
            }
        }
    ],
    "messages": [
        {
            "type": "postback",
            "text": "startcbot",
            "id": "5a4fd7419feede6a19b18714"
        },
        {
            "type": "command",
            "text": "/join",
            "id": "5a4fd7419feede6a19b18713"
        }
    ]
}

CAVEAT

As you can see, resource IDs are always provided, regardless of field selection. In addition to ids, "derived" resource properties (like participants.user.name) are always included; however these derived property values may be inaccurate if based on non-populated fields. In the above example, any participant's additionalName is not part of the generated "name", because additionalName (here: "Allan") was not part of the populated fieldset.


Search Filters

Any query string parameters, other than those mentioned, will be matched against document properties as search filters to narrow down the resultset. You can ask the service for equality, or values greater or less than, give it an array of values it should match to, or even a regular expression match.

Please note that repeating the same field multiple times in the query string is not supported.

GET <apibase>/messages?text=!
GET <apibase>/messages?text=~regex
GET <apibase>/messages?text=value
GET <apibase>/messages?text=>value
GET <apibase>/messages?text=>=value
GET <apibase>/messages?text=<value
GET <apibase>/messages?text=<=value
GET <apibase>/messages?text=>value1,<=value2
GET <apibase>/messages?text=!=value
GET <apibase>/messages?text=[value1,value2]
GET <apibase>/messages?text=![value1,value2]

Filter Operators

While exact matching using just the equals sign is most common results filter, various types of search filters may be specified by prefixing or surrounding query value(s) with special operators:

FilterOperatorExampleDescription
equal(none)/users?gender=malereturn all male users
not equal!=/users?gender=!=malereturns all users who are not male
exist(none)/users?gender=return all users with any gender specified
not exist!/users?gender=!returns all users without a gender
greater than>/users?age=>18returns all users older than 18 (age should be a number property)
greater than or equal to>=/users?age=>=18returns all users 18 and older
less than</users?age=<30returns all users age 29 and younger
less than or equal to<=/users?age=<=30returns all users age 30 and younger
between>,</users?age=>18,<=30returns all users older than 18, but younger than or equal to 30
in[]/users?gender=[female,male]returns all female and male users
nin![]/users?age=![18,30]returns all users with age other than 18 or 30
regex~/users?name=~oostreturns all users with a name containing 'oost'
nested array{}/conversations?participants={role=admin;accepted=true}returns all conversations that are accepted by an admin participant'

Use OR-criteria for alternate/multiple conditions

To perform OR-queries on multiple fields, separate them with a comma. OR-queries do not support the above operator prefixes, but always perform a case-insensitive regular expression match, or an exact match if the field represents a resource ID. For example:

GET <apibase>/organizations?name,displayName=acme
This would return all organizations where either `name` or `displayName` contain the string "acme".

## Use dot-notation to search in nested objects

To **search in nested data structures**, use `dot`-notation in your filters. For example, to find all users with their language preference set to Dutch, find the appropriate value in the user's _settings_ object:
GET <apibase>/users?settings.locale=nl

Nested arrays can be searched for a single condition by using the dot-notation, too. For example, to find all conversations where a specific user is a participant:

GET <apibase>/conversations?participants.user=5da507d56f7cab2c446f4a50
If you specify _multiple_ nested array fields, the search request will return all records that match _any_ of the conditions (OR-query). For example, to find all organizations with categories that match 'car' _and/or_ contain some specific form:
GET <apibase>/organizations?categories.name=~car&categories.forms=590c76bdde1b762f2113e81c
See the curly brackets method below to match an element on multiple conditions.

## Use indexes to count nested array members

To **limit by nested arrays**, combine the index with the exist/non-exists operator. For example, to fetch all conversations with at least two participants, do
GET <apibase>/conversations?participants.1

Likewise, to fetch all conversations with no more than one participant, do

GET <apibase>/conversations?participants.1=!

Use curly brackets to find nested array members matching multiple fields

In some cases, you may want to find records that match a nested array member on multiple criteria. Using the dot-notation with multiple fields (see above) will not necessarily match the same array member - to look those records, wrap your conditions as key-value pairs inside curly brackets.

For example, to get all conversations in a user's inbox, do:

GET <apibase>/conversations?participants={user=5db4e0fbbf878c1e9643138a;inbox=true}
As an alternative, keys and values may be separated by a colon, and key-value pairs by a comma. Whitespaces are ignored. The following query is identical the previous one:
GET <apibase>/conversations?participants={ user: 5db4e0fbbf878c1e9643138a, inbox: true }

Examples

Get all active conversations

GET <apibase>/conversations?status=active

Get all queued conversations for an organization

GET <apibase>/conversations?status=queued&organization=5db4e3bf4c14a433f2f8b644

Get all active conversations for any participant of an organization

GET <apibase>/conversations?status=active&participants.organization=5db4e3bf4c14a433f2f8b644

Get all active participants for an organization's closed conversations (lingering bots)

GET <apibase>/conversations?status=closed&participants={organization=5db4e3bf4c14a433f2f8b644;status=active}

Get all conversations where a user is active (has joined or accepted)

GET <apibase>/conversations?participants={user=5db4e0fbbf878c1e9643138a;active=true}

Get all conversations that a user has joined

GET <apibase>/conversations?participants={user=5db4e0fbbf878c1e9643138a;active=true;accepted=false}

Get all conversations that a user has accepted

GET <apibase>/conversations?participants={user=5db4e0fbbf878c1e9643138a;accepted=true}

Get all conversations in a user's inbox

GET <apibase>/conversations?participants={user=5db4e0fbbf878c1e9643138a;inbox=true}

Get all conversations that a user is following, and has an inbox notification

GET <apibase>/conversations?participants={user:5db4e0fbbf878c1e9643138a,follow:true,inbox:true}

Get all conversations that are being followed by an organization's users

GET <apibase>/conversations?participants={organization=5db4e3bf4c14a433f2f8b644;inbox=true}

Get all conversations accepted by bots

GET <apibase>/conversations?status=active&participants={role=bot;accepted=true}

Get all queued conversations with active joined-only bots

GET <apibase>/conversations?status=queued&participants={role=bot;active=true,accepted=false}

Get all queued in any participant's subscribed channels

GET <apibase>/conversations?status=queued&channels=[5ebdd19745e6ba59efa6b094]

Get all online users for any channel

GET v2/channels?members.online=true

Get all online channels for a user

GET <apibase>/channels?members={user=5db4e0fbbf878c1e9643138a;online=true}

Updated 2 months ago


What's Next

4. API Endpoints

3. Fetching Resources


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.