Wijzigingen opgeslagen

Er is een fout opgetreden

Chainels API Documentation

Welcome developer. Here you can find all kinds of documentation and examples of the Chainels V2 API.

To the left you can find various topics concerning our API.

Documentation for the deprecated V1 API can be found here, this version is no longer maintained.

Authentication

In order to use our API, you need an access token. We use OAuth 2.0 standard for this purpose.


Creating a client

You can manage your OAuth clients here.


Getting an access token

The OAuth 2.0 spec describes several "flows" of getting an access token. These are called grants. We support:

  • client_credentials
  • authorization_code
  • group_token (this is a custom grant type we have implemented)
  • refresh_token

Client Credentials Grant

With the client credentials grant you can get an access token purely with the client id and client secret. This is also commonly referred to as userless access.

The following diagram describes this flow:

+---------+                                  +---------------+
|         |                                  |               |
|         |>--(A)- Client Authentication --->| Authorization |
| Client  |                                  |     Server    |
|         |<--(B)---- Access Token ---------<|               |
|         |                                  |               |
+---------+                                  +---------------+

A POST request must be made to https://www.chainels.com/oauth/access_token with the following parameters in the body (form encoded):

  • grant_type=client_credentials: specifying that you want to use the client credentials grant
  • client_id: Your client id
  • client_secret: Your client secret

An sample request:

 curl -F 'client_id=CLIENT_ID' \
    -F 'client_secret=CLIENT_SECRET' \
    -F 'grant_type=client_credentials' \
    https://www.chainels.com/oauth/access_token

The response will be a JSON object containing the access token, the expire time, and the refresh token:

{
    "access_token": "<access token>",
    "expires_in": <seconds>,
    "token_type": "Bearer",
    "refresh_token": "<refresh_token>"
}

When to use

The access rights of access tokens granted through client credentials are limited, simply because there is no associated user. Therefore this grant is only useful for accessing public data.

Authorization Code Grant

The Authorization Code grant is probably the flow you are most familiar with regarding OAuth. This flow involves several steps.

Step 1 Direct the user to the authorization url:

https://www.chainels.com/oauth/authorize?grant_type=authorization_code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&response_type=code

The redirect uri, is the one you specified when creating the client.

The user is then presented with a login page (if he is logged out) and a page where he will accept (or decline) your authorization request.

Note: You may provide an optional scope parameter to request additional permissions outside of the basic scope. This must be a space delimited list of scopes. See the scope section below for more information.

Note: You may provide an optional state parameter to carry through a server-specific state. For example, you can use this to protect against CSRF issues.

Step 2 Now you must handle the redirect.

Once a user authorizes (or declines) your request, he will be redirected to your specified redirect uri. We will pass a code query parameter to this uri:

http://your-redirect-uri?code=CODE

This code (the authorization code) can then be used to request an access token. A POST request must be made to https://www.chainels.com/oauth/access_token with the following parameters in the body (form encoded):

  • grant_type=authorization_code: specifying that you want to use the client credentials grant
  • client_id: Your client id
  • client_secret: Your client secret
  • redirect_uri: The redirect uri
  • code: The authorization code.

A sample request:

    curl -F 'client_id=CLIENT_ID' \
    -F 'client_secret=CLIENT_SECRET' \
    -F 'grant_type=authorization_code' \
    -F 'redirect_uri=REDIRECT_URI' \
    -F 'code=CODE' \
    https://www.chainels.com/oauth/access_token

The response will be a JSON object containing the access token, the expire time, and the refresh token:

{
    "access_token": "<access token>",
    "expires_in": <seconds>,
    "token_type": "Bearer",
    "refresh_token": "<refresh_token>"
}

When to use

This is the preferred way for 3rd party apps to authenticate users. Once you have an acces token via this grant, you can perform actions on behalf of a user and have access rights based on that user.

Group Token Grant

The group token grant is used for the specific use case on Chainels, where you want to perform actions on behalf of a community (group). Because managers of communities often change, the normal authorization code flow would not be ideal as accounts can suddenly no longer be part of a community thereby breaking the client.

To this end we implemented the group token grant. This token will survive, regardless of changes in accounts of managers in the community.

The group token grant works exactly the same as the authorization code grant but with two small additions:

  • The grant_type must be group_token
  • The authorization url must include an additional group parameter, which is the id of the community you want to authorize.

Authorization only works when:

  • The group is a valid community id (will not work for regular companies)
  • The one authorizing app is a Manager type account in the specified community.

The authorization url would be:

https://www.chainels.com/oauth/authorize?grant_type=group_token&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&response_type=code&group=GROUP_ID

A sample request would be (the group parameter is no longer necessary here):

    curl -F 'client_id=CLIENT_ID' \
    -F 'client_secret=CLIENT_SECRET' \
    -F 'grant_type=group_token' \
    -F 'redirect_uri=REDIRECT_URI' \
    -F 'code=CODE' \
    https://www.chainels.com/oauth/access_token

The access token will allow you to make calls as if you were a (manager) account of this community.

Note, as there is no actual account associated with the calls made with this grant, the grant is mostly limited to read-only actions. You cannot write messages for example. Exactly which scopes can be used with this grant is described in the API reference.

When to use

Use this grant type when you are making an application for a community. In this case you as a developer will probably have a relationship with the group and will be trusted. If you have no contact with a community, we do not recommend using this grant out of trust and security reasons.

Refresh Token Grant

Each access token request also returns a refresh token. This token can be used when the access token is expired.

A sample refresh request:

    curl -F 'client_id=CLIENT_ID' \
    -F 'client_secret=CLIENT_SECRET' \
    -F 'grant_type=refresh_token' \
    -F 'redirect_uri=REDIRECT_URI' \
    -F 'refresh_token=REFRESH_TOKEN' \
    https://www.chainels.com/oauth/access_token

Note: Refresh tokens can also expire, keep this in mind, a refresh token is not valid indefinitely.


Scopes

To access certain data, you must include one or more scopes in your access token request.

Available scopes

We aim to keep the available scopes simple. We currently have the following scopes:

  • basic: Basic read access to all data on the users behalf. This is the default scope if no scope is specified.
  • read.account.notifications: Read access to the notifications of an account.
  • write.account: Edit access to account info
  • write.company: Edit access to company info
  • write.messages: Write or edit messages, replies, poll votes, and recommends.

For each REST endpoint you can see which scope is required to access it.


Authenticating Requests

Once you have an access token, you must use it in the Authorization HTTP header. All tokens are Bearer tokens, which means the full header must look like this:

Authorization: Bearer <access_token>

Expired Tokens

Access Tokens have an expiration time, or can be revoked by the user. If the token is no longer valid, we will return a 401 HTTP status code. You can then refresh the token using the refresh token grant (only if the access token is expired. If it was revoked you must re-authorize).

Access Tokens have a lifetime of 6 months, refresh tokens are valid an additional 1 month

User Agent

Not required, but if possible, please include a User-Agent HTTP header telling us who you are. If you decide to add a User-Agent, please use your Oauth client name.

User-Agent: <My client name>

Limits

We do not currently have any rate limits. This will most likely change in the future, but for now, please be considerate in the amount of requests you make and cache your calls where possible. If we feel you are abusing our systems we will contact you and possibly block your client.


Client

We provide an OAuth 2.0 client for PHP that enables you to easily grab access tokens. You can check it out on our GitHub page

API Clients

The main benefit of the swagger definition is that the swagger project has several code generators, which can transform the definition file into a full fledged API client. Please refer to the swagger-codegen GitHub page for documentation on how to generate a client in your desired language. Again, Swagger Codegen is an active open source project, and sometimes the generated clients contain bugs, do not rely blindly on the generated code!

You can also simply write your own client, using existing OAuth Client libraries to handle authentication (we are fully compliant with the OAuth 2.0 spec, so any good library should work with us).

Official Clients

We have the following official (and supported) clients available:

PHP

Wordpress

  • We also have a Wordpress plugin available. However we have not open sourced it yet. If you are developing for Wordpress, contact us and we can help you.

You can check out our GitHub page for all our available code.

Including Sub Resources

You will notice that almost every GET endpoint has an include query parameter. With this parameter you can include resources in resources.

Example: Companies

It is easiest to explain through an example. When doing a call to GET /companies/{id} you will get the full Company resource:

GET /api/v2/companies/{id}

Returns:

FullCompany {
    id (string, optional, read only): Company id ,
    name (string): The name of the company ,
    sector (Industry, optional): The sector of the company ,
    branche (SubIndustry, optional): The branche of the company ,
    retail (RetailType, optional): The branch specific company sector ,
    company_type (string, optional): Indicates the type of the company = ['other', 'entrepeneur', 'franchise', 'chainstore'],
    group (boolean, optional): If this company is a group or not ,
    logo (string, optional, read only): The url to the full size logo of the company ,
    logo_thumbnail (string, optional, read only): The url to the cropped thumbnail of the logo ,
    about (About, optional),
    address (Address, optional),
    contact (Contact, optional),
    covers (Array[File], optional): An array of cover images of this company
}

A call to that endpoint is the only time you get the full company by default. However, when a Company is included in another resource, for example a message, or an array of members of a group, not every property of the company will be included to keep the response sizes limited. In these cases you will get a smaller company resource:

GET /api/v2/companies/{id}/members

Returns:

Chains [
    Chain
]

Chain {
    id (string, optional): The unique id of this connection ,
    chain_type (string, optional): The type of the connection. = ['member', 'partner'],
    company (Company, optional): The company on the other end of the connection 
}

Company {
    id (string, optional, read only): Company id ,
    name (string): The name of the company ,
    sector (Industry, optional): The sector of the company ,
    branche (SubIndustry, optional): The branche of the company ,
    retail (RetailType, optional): The branch specific company sector ,
    company_type (string, optional): Indicates the type of the company = ['other', 'entrepeneur', 'franchise', 'chainstore'],
    group (boolean, optional): If this company is a group or not ,
    logo (string, optional, read only): The url to the full size logo of the company ,
    logo_thumbnail (string, optional, read only): The url to the cropped thumbnail of the logo
}

As you can see, the Company included in a Chain does not include the about, address, contact and covers properties.

This is fine for most use cases, however, suppose you have a use case where you want to retrieve the members of a group and show their address. Using the default responses, you would first have to do a call to GET /api/v2/companies/{id}/members and then for each member do a call to GET /api/v2/companies/{id} to get the full company with address. This is very inefficient, that's why we have the include parameter.

Using dot notation you can specify that want to include the address resource of the company:

GET /api/v2/companies/{id}/members?include=company.address

Or if you also want covers:

GET /api/v2/companies/{id}/members?include=company.address,company.covers

As you can see, using the include parameters allows for a lot of flexibility in requesting data.

Available includes

Here we will describe the available properties for various resources. These properties are only present when you get the resource directly, or when adding it to the include parameter.

Account

  • companies

Company

  • address
  • about
  • contact
  • covers
  • supply
  • custom_fields

Quicklist

  • companies

Directory

  • children