API requests are made via HTTPS using the api.capsulecrm.com
subdomain.
Each request must be authenticated with a user's Bearer token.
You must include a valid bearer token inside the Authorization header of each request made to Capsule.
Here’s an example using curl that will return a list of users on your account (remember to
replace {token}
with your actual bearer token).
$ curl -H "Authorization: Bearer {token}" https://api.capsulecrm.com/api/v2/users
API v2 offers two options for obtaining a bearer token to authenticate your requests.
When sharing your application with other people use the OAuth 2 flow. This provides a simple, friendly process for the user to share their bearer token with your application.
If you’re building a one-off integration for internal use, or you just want a quick start to trying out our API, you can generate a token directly from your Capsule account to avoid the oAuth 2 flow. You can create these from the My Preferences > API Authentication Tokens page in your Capsule account:
If the bearer token is invalid or expired you will receive a response with the status code set to HTTP 401 Unauthorized
.
If the access_token
is valid but you don't have enough scope to perform this request you will receive a response
with the status code set to HTTP 403 Forbidden
.
In both cases the body and WWW-Authenticate
header will include additional information about the error.
OAuth 2 is a protocol that lets external applications request authorization to details in a user's Capsule account without accessing their password. This is preferred over using API keys because tokens are limited to a specific application, and can be revoked by the users at any time.
You will need to register the application before getting started. A registered application is assigned a unique client ID. Web application are also issued a client secret. This value must be kept only server-side and not shared or included in any source code or compiled binaries that are distributed to the users.
If your application will be running on users' devices (e.g. mobile application, desktop application, browser extension) you will have to select the Application type as "installed" when registering the application.
Most of the programing languages and frameworks provide libraries and tools to easily integrate with OAuth 2 protected services. Capsule is compatible with most of these tools and we recommend that you use them.
Capsule implements the authorization code grant defined by RFC6749.
First, you will need to redirect the user to Capsule to grant access to your application:
Name | Type | Description |
---|---|---|
response_type | String | Value MUST be set to code . |
client_id | String | The client ID you received when you registered the application. |
redirect_uri | String | The URL in your app where users will be sent after authorization. If provided it should be exactly the same as the one you configured in the application settings. |
scope | String |
The scope of the access request. Accepted values are: read , read write and read write user_preference .
Default: read write .
|
state | String | An unguessable random string. It is used to protect against cross-site request forgery attacks. |
Capsule will display a page asking the user to approve or deny access to your application.
However, if you provided an invalid client_id
or redirect_uri
the user will instead see an error page.
After the user approves your application, Capsule will redirect to the URL provided in the request with a temporary
code in the code
parameter as well as the state you provided in the previous step in the state
parameter. To protect
against CSRF attacks, you must check if the value of the state
is same as the one you provided in the first step.
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
If the user denies the access request or if the request fails, the user will be redirected to your application with
an error
and error_description
parameter. The exact values of the error parameter can be found in section
4.1.2.1 of RFC6749.
HTTP/1.1 302 Found
Location:
https://client.example.com/cb?error=access_denied&state=xyz&error_description=User%20denied%20access%20to%20your%20application
Once you have obtained an authorization code, you can exchange it for an access and refresh token. The body of the request
should be valid JSON
or x-www-form-urlencoded
.
{
"code": "5lkdysut02m4z7kstxgy5zl1xy70qbc6e3nhmps3oo0gbh3uz7",
"client_id": "1ng7irbzhvmqe",
"client_secret": "2rw6x7b1r9whd3ayxuzruv91zyxyubp28m6vdo2qmf9pn0qhsr",
"grant_type": "authorization_code"
}
Name | Type | Description |
---|---|---|
code | String | Value of the code parameter from the previous step. |
client_id | String | The client ID you received when you registered the application. |
client_secret | String | The client secret you received when you registered the application. Not required for "installed applications" |
grant_type | String | Value MUST be set to authorization_code . |
The server response will contain a JSON
object with the access and refresh token, the granted
scope, the token type (which is always bearer
), the expiration time of the access token, and the subdomain of the
user's Capsule account.
In case of and invalid request, Capsule will respond with an HTTP 400 (Bad Request)
status code and include an error
and
error_description
parameter in the response. These parameters are defined in section 5.2 of RFC 6749.
HTTP/1.1 200 OK
{
"refresh_token":"68hpw0l714stokog519t4yi8tamlb53494n93vvz3v6xw3zbkw",
"access_token":"2dkduvodqxm2npzypf75x1cctn77592hv4l3hf8nnxh6r4gjl8",
"expires_in":604799,
"token_type":"bearer",
"scope":"read write",
"subdomain": "exampleco"
}
The access token allows you to make requests to the API on behalf of a user by including it in the Authorization
header: Authorization: Bearer access_token
. More details are included in the Authentication section.
After the access token expires, you will not the able to use it to make API requests. However, you can use the refresh
token to obtain a new access token. The body of the request should be valid JSON
or x-www-form-urlencoded
.
{
"client_id": "1ng7irbzhvmqe",
"client_secret": "2rw6x7b1r9whd3ayxuzruv91zyxyubp28m6vdo2qmf9pn0qhsr",
"refresh_token": "68hpw0l714stokog519t4yi8tamlb53494n93vvz3v6xw3zbkw",
"grant_type": "refresh_token"
}
Name | Type | Description |
---|---|---|
refresh_token | String | The refresh token obtained at step 3. |
client_id | String | The client ID you received when you registered the application. |
client_secret | String | The client secret you received when you registered the application. Not required for "installed applications" |
grant_type | String | Value MUST be set to refresh_token . |
The response is the same as the response from step 3. It will contain a JSON
object with the access
and refresh token, the granted scope, the token type (which is always bearer
), the expiration time of the access token,
and the subdomain of the user's Capsule account.
Note that you might receive a new refresh token as part of the response. In this case you must discard the old refresh token and replace it with the new refresh token.
In the case of an invalid request, Capsule will respond with an HTTP 400 (Bad Request)
status code and includes an error
and
error_description
parameter in the response. These parameters are defined in section
5.2 of RFC 6749.
HTTP/1.1 200 OK
{
"refresh_token":"68hpw0l714stokog519t4yi8tamlb53494n93vvz3v6xw3zbkw",
"access_token":"2dkduvodqxm2npzypf75x1cctn77592hv4l3hf8nnxh6r4gjl8",
"expires_in":604799,
"token_type":"bearer",
"scope":"read write",
"subdomain": "exampleco"
}
We encourage OAuth2 clients to revoke tokens when they are no longer needed. This is useful for ensuring that tokens, if stolen, aren't usable, and just for acting as a good citizen when the user "logs out" of your application (as an example).
Revoking a refresh token will also revoke any associated access tokens and remove the application from the list of authorised applications in Capsule. This step should be performed when a user chooses to disable an integration with Capsule to make it clear that the application is fully disconnected.
When your client is completely done with a token and will not use it anymore, it can make a POST request to revoke the
token. The body of the request should be valid JSON
or x-www-form-urlencoded
and contain a token
parameter.
{
"token": "68hpw0l714stokog519t4yi8tamlb53494n93vvz3v6xw3zbkw"
}
Name | Type | Description |
---|---|---|
token | String | The access or refresh token that you want to revoke. Note that revoking an refresh token will also revoke all access tokens associated with it. |
To be fully compatible with RFC 7009 Capsule will also accept the token_type_hint
parameter, however the presence or value of this parameter will not affect the end result of your request.
There are a few things that can go wrong in the process of obtaining an OAuth token for a user.
If an error occurs, the response body or URL will include error
and error_description
parameters.
Additionally, when possible, the status code of the response will be HTTP 400 Bad Request
.
If you provide a redirect_uri
that doesn't match what you've registered with your application, Capsule will display an error page to the user and not redirect to the registered callback URL.
To correct this error, either provide a redirect_uri
that matches what you registered or leave out this parameter to
use the default value registered with your application.
If the user rejects access to your application, Capsule will redirect to the registered callback URL with error
and
error_description
parameters summarizing the error:
https://client.example.com/cb?error=access_denied&state=xyz&error_description=User%20denied%20access%20to%20your%20application"
There's nothing you can do here as users are free to choose not to provide access to your application.
If the client_id
and or client_secret
you pass are incorrect you will receive this error response.
{
"error":"invalid_client",
"error_description":"no client found with provided key and secret"
}
To resolve this error, make sure you have included the correct credentials for your application.
When exchanging the authorization code for an access token you must provide the same redirect_uri
used to obtain the code.
If these do not match, you will receive this error message:
{
"error":"invalid_request",
"error_description":"invalid redirect_uri"
}
To resolve this error, make sure that you provide the same redirect_uri
at both steps of the OAuth 2 flow.
If the authorization code is invalid, expired or already used, you will receive this error:
{
"error":"invalid_grant",
"error_description":"incorrect authorization code"
}
To resolve this error, start the OAuth process over from the beginning to obtain a new authorisation code.