Skip to main content
All CollectionsIntegrations
Using the CoffeeCup API
Using the CoffeeCup API

Learn how to authorize and use the CoffeeCup API

Updated today

The CoffeeCup API offers a JSON REST API with access to all objects in addition to numerous aggregated analytics feeds. You can use the REST API to access, create, and modify CoffeeCup data.

An alternative to direct API access is our Zapier integration, which abstracts away some of the more complicated permissions and settings and allows for the integration into various workflows with other 3rd party apps.

Permissions

Access to the API is based on the permissions of the individual user accounts. This means that an API developer using their personal CoffeeCup will only have access to the resources that their account has. For maximum flexibility, we recommend creating an additional utility user within CoffeeCup with the appropriate permissions for API access. Note that some models, like Time Entries, have properties that can only be modified by the owner/creator of the object.

API Feed Overview

A complete list of all API endpoints available to CoffeeCup can be found on our Swagger at https://dev.coffeecupapp.com.

While the automated Swagger list represents the complete set of available feeds, the page does not include all the possible query / post parameter options available. We recommend examining the network traffic sent by the Browser client to craft the query parameters to your use case.

Authenticating with Swagger

The Swagger can also be used for testing and experimenting. Use the Authorize button in the top right to log in.

⚠️ Important: The login form on the Swagger is active once per session. If the login page does not look like this, please refresh the page and click Authorize again.

Once authorized, the button will switch to a lock icon

You can then select an example feed and send a test request using the “Try It Out” and “Execute” buttons.

We strongly recommend using a separate development account/domain to test any API integrations that modify data. If your company does not currently have a development account, please contact us.

Authorization

CoffeeCup uses OAuth 2.0 with the password grant type. As part of the token request, users must identify which CoffeeCup tenant they are via the origin or companyurl headers. After successful authentication, API feeds can be accessed with Bearer authentication.

Password Authentication

The following fields should be sent, form encoded, to the oauth2/token endpoint:

  • grant_type: password

  • username: {your email address}

  • password: {your password}

  • client_id: {an arbitrary string describing your app}

  • client_secret: {an arbitrary string}

The client_id and client_secret values are not validated for normal API usage, however they must be present. We recommend using a client_id that identified your app. The fields are reserved for future non-password / non-user-account related authentication methods.

Either the origin, referrer, or companyurl headers must be present to identify the target account. API access can optionally be directed at the neutral api.coffeecup.app address rather than a company-specific domain, but the header must identify the target account.

Here are two example requests, for cURL and JavaScript Fetch. Items in {brackets} should be replaced with your appropriate values.

cURL

curl 'https://{your-domain}.coffeecup.app/oauth2/token' \
-H 'content-type: application/x-www-form-urlencoded' \
-H 'origin: https://{your-domain}.coffeecup.app'
--data-raw 'grant_type=password&username={your-username}&password={your-passowrd}&client_id={your-app-name}&client_secret={must-be-present}'

JavaScript / Node.js Fetch

fetch("https://{your-domain}.coffeecup.app/oauth2/token", {
"headers": {
"content-type": "application/x-www-form-urlencoded",
"companyurl": "{your-domain}.coffeecup.app",
},
"body": "grant_type=password&username={your-username}&password={your-passowrd}&client_id={your-app-name}&client_secret={must-be-present}",
"method": "POST", });

Response

The standard OAuth 2.0 response in JSON format includes the access token, refresh time, and expire time (in seconds — usually 1 hour / 3600 seconds).

{
"access_token": "0001112223334445556667778899aabbccddeeff",
"token_type": "Bearer",
"expires_in": 3599,
"refresh_token": "0001112223334445556667778899aabbccddeeff"
}

Token Refresh

After initial password auth, the access_token can be renewed via an OAuth 2.0 refresh request.

  • grant_type: refresh_token

  • refresh_token: {your previously issued refresh token}

  • client_id: {an arbitrary string describing your app}

  • client_secret: {an arbitrary string}

cURL

curl 'https://{your-domain}.coffeecup.app/oauth2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'origin: https://{your-domain}.coffeecup.app'
--data-raw 'grant_type=refresh_token&refresh_token={your-refresh-token}&client_id={your-app-name}&client_secret={must-be-present}'

JavaScript / Node.js Fetch

fetch("https://{your-domain}.coffeecup.app/oauth2/token", {
"headers": {
"content-type": "application/x-www-form-urlencoded",
"companyurl": "{your-domain}.coffeecup.app",
},
"body": "grant_type=refresh_token&refresh_token={your-refresh-token}&client_id={your-app-name}&client_secret={must-be-present}",
"method": "POST",
});

Authenticating API Requests

Once an access_token has been retrieved, the token can be used in the authorization header as a bearer token.

Here are two examples to the “me” endpoint, showing info about the currently logged in user:

cURL

curl 'https://{your-domain}.coffeecup.app/v1/users/me' \
-H 'authorization: Bearer {your-access-token}'

JavaScript / Node Fetch

fetch('https://{your-domain}.coffeecup.app/v1/users/me', {
"headers": {
"authorization": 'Bearer {your-access-token}'
},
});

Support

For additional help, guidance, and questions, please reach out to our support team via Intercom in the CoffeeCup web browser client or via email. We are happy to troubleshoot issues or to point you towards the right feeds for your usecase. When contacting us, please provide some background information for your use case so we can provide a tailored answer.

Did this answer your question?