As a developer on the Crunch platform, you have programmatic access to clients’ data and resources, assuming they’ve authorised your application. To do this we provide an Oauth 2.0 implementation for authentication and authorisation, which is designed to allow your application to access the Crunch Accounting API whether the user is interacting with the application or not.
OAuth 2.0 is the industry-standard protocol for authorization. OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices. Source: https://oauth.net/2/
Note: By using the Crunch Accountancy API, you accept our Developer Terms of Service
To begin with you will need to obtain your Oauth 2 client credentials by creating a new application. While our API is in its initial beta phase we will onboard your new application to allow us to get a better understanding of how you plan to use the API. Please email api@crunch.co.uk with your name, company name, a brief overview of what you’ll be using the API for, whether it’s a confidential or a public type of application, and we will help you get setup straight away.
Before your application can access data using Crunch Accountancy API, it must obtain an access token that grants access to the API. The scope
parameter used while requesting the access token controls the set of resources and operations that an access token permits. During the access-token request, your application sends one or more values in the scope
parameter.
Obtaining the token requires an authentication step where the user logs in with their Crunch account. After logging in, the user is asked whether they are willing to grant the permissions that your application is requesting. This process is called user consent.
If the user grants the permission, the Crunch Oauth API sends your application an authorisation code
at the redirect URL that you defined when setting up your application. This authorisation code can be exchanged to obtain the access token. If the user does not grant the permission, the server returns an error.
The first step is to generate a URL with all the parameters to identify your application, and the permissions (scopes) that the user will be asked to grant when they authorise your application. When the URL is constructed you can redirect the user to that URL to allow them to authorise your application. The URL takes the following form:
GET https://oauth.crunch.co.uk/authorize
The following parameters are used with the authorize
request:
Type | Name | Description | Schema | Default |
---|---|---|---|---|
Query | client_id required |
The client identifier. | string | |
Query | redirect_uri optional |
The URL to which the browser will be redirected after authorization has been granted by the user. | string | |
Query | response_type required |
Use code for Authorization Code Grant Flow. |
string | |
Query | scope optional |
The scopes your app needs to request authorization for. These must be separated by a space. See Scopes. | string | |
Query | state recommended |
An opaque value used by the client to maintain state between the request and callback. This value must be used by the application to prevent CSRF attacks. | string | |
Query | code_challenge optional |
Code challenge. REQUIRED if the type of the client app is public, when PKCE must be used. | string | |
Query | code_challenge_method optional |
Code verifier transformation method for PKCE. | enum (S256, plain) | plain |
All query parameters must be URL encoded.
For example, for this set of parameters:
client_id
: gf98we...78vyytc243
redirect_uri
: https://my.app/integration/crunch
response_type
: code
scope
: all offline_access
state
: k45$oi£j6#52=j
The resulting URL would look like:
https://oauth.crunch.co.uk/authorize?client_id=gf98we...78vyytc243&redirect_uri=https%3A%2F%2Fmy.app%2Fintegration%2Fcrunch&response_type=code&scope=all+offline_access&state=k45%24oi%A3j6%2352%3Dj
Please note that if your application is a public client, then the PKCE extension to the OAuth 2.0 flow must be used. Confidential clients can use PKCE optionally, for extra security.
At the moment Crunch defines 2 possible scope values:
This is an all-encompassing scope, granting access to all the available Crunch resources. This can be narrowed down by
using CRUD semantics, i.e. prefix the scope with either create
, read
, update
or delete
followed by a colon (:
).
e.g. If your application only needs to create & read expenses, then you could use this scope value (unencoded for clarity):
create:all read:all
The API Documentation specifies which scope is required for each individual endpoint under the
Security
group.
Use offline_access
in order to get a Refresh Token along with the Access Token.
See Refreshing the access token for further details.
Should the user authorise your application to access their Crunch account they will be redirected
to the URL you specified in the redirect_uri
URL parameter with the authorisation code as a code
URL parameter:
https://my.app/integration/crunch&code=eyJz93a...k4laUWw&state=k45oi...j652j
The code
you receive is a short-lived token and should be exchanged for an access token straight away.
The next step is to use the code
to obtain an access token
. The access token will allow you to access the Crunch API. The code
exchange is performed via the /token
endpoint:
POST https://oauth.crunch.co.uk/token
The /token
endpoint takes the following request payload for the code exchange and should use the application/x-www-form-urlencoded
content type (as supplied by the Content-Type
http header):
Name | Description | Type |
---|---|---|
client_id optional |
The Client ID that was issued to the API User during signup. Example : "gf98we...78vyytc243" |
string |
client_secret optional |
The Client Secret provided by the API User on signup. Example : "something-gr33n" |
string |
code required |
The Authorization Code received from the initial /authorize call. Required when grant_type is authorization_code only. Example : "4kjh234...cviu9ads" |
string |
grant_type required |
Denotes the flow you are using. For Authorization Code, use authorization_code . Example : "authorization_code" |
enum (authorization_code, refresh_token) |
redirect_uri optional |
This is required only if it was set at the GET /authorize endpoint. The values must match. Example : "https://my.app/integration/crunch" |
string |
code_verifier optional |
Code verifier. REQUIRED for public client apps, when PKCE must be used. Example : "54i_ji...FDG~88" |
string |
Confidential clients must authenticate the request. The preferred way is via basic authentication,
using the client_id
& client_secret
values as user & password, respectively. e.g. the header would look like:
Authorization: Basic <base64_encode(client_id:client_secret)>
If basic authentication is used, then the client_id
& client_secret
fields must not be passed in the payload!
If basic authentication cannot be used for any reason, then authentication is performed via the form fields instead.
Public clients must use the client_id
& code_verifier
form fields.
The /token
endpoint returns a JSON object that contains a new access token. The following snippet shows a sample response:
{
"access_token": "22deaca1-d19a-4591-aaae-f20ccbc2bb65",
"token_type": "Bearer",
"expires_in": 172800,
"refresh_token": "63d3e15c-9601-4dcf-99bc-aeea70fd1f1f",
"scope": "all offline_access"
}
The access token response payload is described below:
Name | Description | Type |
---|---|---|
access_token required |
The access token issued by the authorization server. Example : "eyJz93a...k4laUWw" |
string |
expires_in optional |
The lifetime in seconds of the access token. Example : 86400 |
integer (int64) |
refresh_token optional |
The refresh token, which can be used to obtain new access tokens using the same authorization grant. Issued only if the offline_access scope has been authorised. Example : "GEbRxBN...edjnXbL" |
string |
scope optional |
The permissions granted by the User. Optional if identical to the scope requested by the client. Example : "all offline_access" |
string |
token_type required |
The type of the token issued. Value is case insensitive. At this time, this field will always have the value Bearer . Example : "Bearer" |
string |
Access tokens are valid for a period of time, after which you need to get a new one using the latest refresh token returned to you from the previous request. You must write your code to anticipate the possibility that a granted access token might no longer work.
You only use the refresh token to obtain a new access token when the prior access token expires. Keep in mind that a refresh token is only for getting new (i.e., “refreshing”) access tokens; you can’t pass a refresh token when calling the Crunch API. You can refresh an access token without prompting the user for permission.
You refresh the access token by posting to the /token
endpoint
POST https://oauth.crunch.co.uk/token
The /token
endpoint takes the following request payload for access token refresh and should use the application/x-www-form-urlencoded
content type (as supplied by the Content-Type
http header):
Name | Description | Type |
---|---|---|
client_id optional |
The Client ID that was issued to the API User during signup. Example : "gf98we...78vyytc243" |
string |
client_secret optional |
The Client Secret provided by the API User on signup. Example : "something-gr33n" |
string |
grant_type required |
refresh_token |
enum (authorization_code, refresh_token) |
refresh_token required |
The refresh token previously issued to the API User. Example : "GEbRxBN...edjnXbL" |
string |
scope optional |
The scope of the access request. It MUST NOT include any scope not originally granted by the User, and if omitted it is treated as equal to the scope originally granted by the User. Example : "all offline_access" |
string |
Confidential clients must authenticate in the same way as for the Access Token request.
Public clients must use the client_id
form field only.
Refresh tokens must be stored securely since they allow a user to remain authenticated essentially forever. Especially important for public clients!
The /token
endpoint returns a JSON object that contains a new access token. The following snippet shows a sample response:
{
"access_token": "22deaca1-d19a-4591-aaae-f20ccbc2bb65",
"token_type": "Bearer",
"expires_in": 172800,
"refresh_token": "63d3e15c-9601-4dcf-99bc-aeea70fd1f1f",
"scope": "all offline_access"
}
The access token response payload is described below:
Name | Description | Type |
---|---|---|
access_token required |
The access token issued by the authorization server. Example : "eyJz93a...k4laUWw" |
string |
expires_in optional |
The lifetime in seconds of the access token. Example : 86400 |
integer (int64) |
refresh_token optional |
The refresh token, which can be used to obtain new access tokens using the same authorization grant. Example : "GEbRxBN...edjnXbL" |
string |
scope optional |
The permissions granted by the User. Optional if identical to the scope requested by the client. Example : “all offline_access” |
string |
token_type required |
The type of the token issued. Value is case insensitive. At this time, this field will always have the value Bearer . Example : "Bearer" |
string |
Now you have a valid access token you can use this to access the Crunch resources. To do this you simply include the access token in the Authorization
header with your API requests.
curl --location -g --request GET 'https://public-api.crunch.co.uk/v1/expenses' \
--header 'MediaType: application/json' \
--header 'Authorization: Bearer <access_token>'