The REST documentation is recommended for advanced users that want to write their own API clients.
Have a look below at the official clients, framework integrations, and community-contributed libraries.
All POST data must be JSON encoded.
This allows you to send complex data structures to the Stream API endpoint!
API Keys and Token
Every API request to Stream must include: the API Key of the app performing the request and an authentication token generated using the API Key secret.
Token must be a JWT token including a signature generated with the HS256 algorithm.
You can find more information on JWT at jwt.io/introduction.
Libraries to generate JWT are available for most programming languages. The full list is available here.
The authentication token must include the correct claims (also called payload). A token valid for a type of request or for a user_id might not be valid
for another one. Your application should generate the appropriate token; when using client-side auth, each user should have its own unique token.
Sending an authenticated request
All API requests to Stream must include a query parameter called api_key with the API Key in use.
Once the token is generated correctly it is used to authenticate a request. This is done by setting two HTTP
headers on the request:
Important: Some JWT libraries prefix the generated token with the string "Bearer".
This prefix should be removed before sending the request to Stream.
When dealing with authentication tokens, you should keep in mind that tokens are like passwords.
Never share tokens with untrusted parties.
Stream uses JWT to provide two types of authentication:
Requests from a back-end application to the Stream API for a specific single resource use Server-Side Authentication to authenticate requests.
JWT usage for server-side authentication
For server-side authentication, the application should send a token that is signed with the API Secret of the Stream app.
This token must include a permission scope compatible to the request that is being performed.
Permission scopes are defined using the following fields:
resource, action and feed_id.
The resource field of the JWT payload allows you to define which API endpoints can be accessed, you can pick one of the following:
The action field of the JWT payload allows you to define which HTTP verbs are allowed by a request:
The feed_id field in the JWT payload specifies for which feed/resource the permissions specified before are granted.
The value of this field should be a concatenation of the feed group's slug and the user_id
of the feed instance. For example, if your feed group is called "news" and your user ID is 1234, the resulting
concatenation would be "news1234". Similarly to the resource and action field, a single
* character will grant the permissions on all feeds.
Below are some example tokens for different use cases:
// A token which allows every possible action on all feeds. Useful for
// development and server side, but unsuitable for usage on the client.
// A token which allows reading, modification and deletion of activities on
// the feed of the user with id 123.
// A token which allows reading the followers of the feed of user with id 123.
Requests from a front-end application to the Stream API to certain endpoints use Client-Side Authentication to authenticate requests.
JWT usage for client-side authentication
When using Stream on web or mobile apps, you can use a different kind of auth that allows you to authenticate users instead of your server-side application.
This authentication enforces per-user permission checks.
Client-side auth is selected when a JWT token includes user_id in the payload. You can include additional fields in the JWT payload as long as they don't overlap with the server-side authentication ones.
A common approach is to have your users authenticate with your app server-side and to provision a user token so that API calls to Stream can be done on their behalf directly on your mobile/web app.
# The token claims contain only user_id
# "user_id": "bob_johnson_1"
# The token claims contain user_id and extra fields
# "user_id": "bob_johnson_1",
# "user_group": "admins"
The Feed endpoint is to retrieve activities in a feed (GET),
or to submit an activity or list of activities (POST).
For retrieving the activities in a feed the following parameters as shown below are supported.
If URI contains word "enrich", the response will be enriched.
The amount of activities requested from the APIs
Filter the feed on ids greater than or equal to the given value
Filter the feed on ids greater than the given value
Filter the feed on ids smaller than or equal to the given value
Filter the feed on ids smaller than the given value
If true activity object will have attribute "latest_reactions" that contains list of recently created reactions
Specify number of reactions in the "latest_reactions" attribute, maximum value is 25.
If true activity object will have attribute "own_reactions" that contains list of reactions created by the user himself.
If true activity object will have attribute "reaction_counts" that contains number of reactions for each kind
Passing both id_lt[e]andid_gt[e] is not supported.
Note on Pagination:
Using id_lte for pagination is preferable to using offset.
Note on Aggregated Feeds:
When using id_lte to paginate an aggregated feed, use the ID of the group that is returned from the API.
Using an ID of an individual activity within the group will not work and result in an error.
If ranking is enabled on your feed group you can supply the ranking method to use by supplying the ranking method's slug on the following GET parameter:
The slug of the ranking method to use
For the POST request, you can either submit the data for one single activity or a list of activities.
In addition to these base fields, extra data will be parsed as custom fields.
The Feed Detail endpoint allows you to delete activities.
The Stream API allows you to delete activities by the activity id generated by Stream, or by the
foreign id you generate and put within your activity:
The activity id is returned to you in the response when the activity is first created.
The foreign id is a unique reference which represents the activity in your database.
Note: By setting foreign ids you ensure uniqueness and no longer need to store the
Stream-generated activity id in your database. Read more about foreign ids versus activity ids
over at the Stream general docs.
Note: Deleting an activity using your foreign id requires setting
a foreign_id URL query parameter to "1":
Send a value of 1 to indicate you want to delete by foreign id
The collections detail endpoint can be used can be used to retrieve (GET), upsert (POST) and delete (DELETE) multiple collection objects at once.
Comma separated list of foreign ids. A foreign id has the format <collection_name>:<collection_object_id>. The maximum number of foreign ids is 1000. E.g.: collection1:id1,collection1:id2,collection3:id5
Returned object schema
Response object containing a data field which is an array of collection objects. The schema for the objects can be found in the collection docs.
Location/Region should be configurable when initializing the Stream client.
The request timeout should be configurable. We recommend 3 seconds as a default.
On average, it takes ~60ms to retrieve your feed.
However, it is possible for network latency to spike, which is why we recommend setting a timeout.
Here's a brief list of best practices that we recommend when building a new API SDK for interacting with Stream:
Test Code Coverage (>95%)
We recommend building both unit and integration tests, and ensuring a code coverage above 95%.
Code Examples - Every API Endpoint
Document the API calls for every operation.
Check out the README of the stream-python
repo for a good starting point.
Feed slugs and user ids need to match the \w+ regular expression. Your client should validate input before
sending an API call.
Errors from the Stream API should be mapped to exception classes and properly raised.
We recommend using the MIT or BSD license when releasing open-source software.
If you release your software as open-source, and place it on GitHub, we ask that you pay close attention to any issues
and pull requests by other community members. If your SDK gains significant support, we may also request to take
over your open-source project as an officially-supported library so we can assist with support efforts.
We try to keep our variable names consistent amongst the various API clients, except in the case where common
lint-checker software will raise too many errors. This section explains some common terminology we use in our