Authentication & Authorization
There are three ways to access the Cacoo API.
1. API Key
The API key allows you make requests to the Cacoo API. You can make an API key here
Send your API key with requests to the API to return data from your account.
The API key can be sent as the request header X-Api-Key or as the query parameter apiKey.
We recommend the request header, because an API key in the URL may be recorded in access logs, browser history and Referer headers.
Example (Request Header)
Send your API key in the X-Api-Key request header.
curl -H "X-Api-Key: abcdefghijklmn" https://cacoo.com/api/v1/diagrams.json
Example (Query Parameter)
You can also send your API key as the apiKey query parameter. This is still supported so that existing integrations keep working, but it is not recommended.
If a request contains both the header and the query parameter, the query parameter is used.
https://cacoo.com/api/v1/diagrams.json?apiKey=abcdefghijklmn
2. OAuth 1.0a
OAuth 1.0a is supported as an authorization method for Cacoo. You can register applications here.
You can get your Access Token from the following links.
Access Token:
https://cacoo.com/oauth/access_token
Authorize:
https://cacoo.com/oauth/authorize
Request Token:
https://cacoo.com/oauth/request_token
If the following parameters are added to the Authorize URL, they will be entered initially into the sign up form via OAuth authorization.
| Name | Description |
|---|---|
| signup.mailAddress | Acount mail address |
| signup.nickname | Acount nickname |
3. OAuth 2.0
OAuth 2.0 (authorization code flow) is also supported. You can register applications here. Dynamic client registration (RFC 7591) is not supported: MCP clients and others also use the client_id of an application registered in advance.
Endpoints
| Purpose | URL |
|---|---|
| Authorization | https://cacoo.com/oauth2/authorize |
| Token | https://cacoo.com/oauth2/token |
| Revocation | https://cacoo.com/oauth2/revoke |
| Authorization server metadata | https://cacoo.com/.well-known/oauth-authorization-server |
Application types
| Type | For | client_secret | PKCE |
|---|---|---|---|
| Client | Applications that can keep client_secret safe, such as servers | Required to get, refresh and revoke tokens | Recommended |
| Browser | Applications that cannot keep client_secret, such as browser, mobile, desktop and AI agent apps | Not used | Required |
The Consumer Key on the registration screen is the client_id, and the Consumer Secret is the client_secret. For the Client type, send client_id and client_secret either with HTTP Basic authentication (client_secret_basic) or in the request body (client_secret_post), not both.
Register the callback URL in advance. The redirect_uri of an authorization request must match a registered URL exactly, port included. Loopback addresses with a varying port (RFC 8252) are not supported: register a fixed port to receive the code locally too.
Step 1. Authorization request
Send the user’s browser to the authorization URL. When the user approves, the browser comes back to the callback URL with code and state.
| Parameter | Required | Description |
|---|---|---|
| response_type | Yes | code |
| client_id | Yes | The Consumer Key |
| redirect_uri | One of the registered callback URLs. May be omitted when only one is registered | |
| scope | The permissions to ask for, separated by spaces (see below) | |
| state | A value against CSRF, returned to the callback as it is | |
| code_challenge | The PKCE challenge (43 to 128 characters). Required for the Browser type | |
| code_challenge_method | S256 (recommended) or plain. plain when omitted |
When the user denies or a parameter is wrong, the browser comes back to the callback URL with error (access_denied, invalid_scope, invalid_request, …) and state. When the client_id or the callback URL is wrong, it does not come back and gets 400.
Step 2. Getting tokens
Within 10 minutes of receiving the code, POST to the token endpoint (application/x-www-form-urlencoded). A code works once.
| Parameter | Required | Description |
|---|---|---|
| grant_type | Yes | authorization_code |
| code | Yes | The code received |
| redirect_uri | Yes | The callback URL of the authorization (the registered one if it was omitted there) |
| client_id | Yes | The Consumer Key (not needed with HTTP Basic authentication) |
| client_secret | The Consumer Secret. Required for the Client type without HTTP Basic authentication | |
| code_verifier | The PKCE verifier. Required when the authorization request had a code_challenge |
{
"access_token": "...",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "...",
"scope": "api"
}
An access token is valid for one hour. A refresh token is valid for 30 days from its issue, and each refresh issues a new one, so refreshing within 30 days keeps the access going. scope holds the granted scopes, or api for an authorization without scope.
Step 3. Calling the API
Send the access token in the Authorization header. On 401, refresh the tokens and send the request again.
Authorization: Bearer <access_token>
Step 4. Refreshing tokens
When the access token expires, get new tokens with the refresh token.
| Parameter | Required | Description |
|---|---|---|
| grant_type | Yes | refresh_token |
| refresh_token | Yes | The refresh token |
| client_id | Yes | The Consumer Key (not needed with HTTP Basic authentication) |
| client_secret | The Consumer Secret. Required for the Client type without HTTP Basic authentication | |
| scope | For an access token with fewer permissions than were granted |
The response has the same format as when getting tokens. It carries a new refresh token, and the one used stops working. Use the new refresh token for the next refresh.
Step 5. Revoking tokens
To disconnect, POST to the revocation endpoint (RFC 7009).
| Parameter | Required | Description |
|---|---|---|
| token | Yes | The token to revoke |
| token_type_hint | refresh_token or access_token | |
| client_id | Yes | The Consumer Key (not needed with HTTP Basic authentication) |
| client_secret | The Consumer Secret. Required for the Client type without HTTP Basic authentication |
Revoking a refresh token revokes every token the user gave the application. Revoking an access token revokes that token only. An unknown token also gets 200.
Scopes
Scopes are for API v2, which is coming. API v1 takes only tokens authorized without scope.
| Scope | Allows |
|---|---|
| diagram:read | Viewing and exporting diagrams, comments and chat messages, and viewing the folders and organizations to find them |
| diagram:write | Creating, editing, copying and moving diagrams |
| diagram:archive | Archiving and unarchiving diagrams (archiving turns off public links, removes collaborators from organization diagrams, and deletes the diagram after 90 days) |
| diagram:delete | Deleting diagrams (cannot be undone) |
| comment:write | Posting comments under the user’s name |
- An application with the Read-only access type (Default Access Type) is granted
diagram:readonly. Asking only for other scopes returnsinvalid_scope. - A token authorized without scope works on API v1 only, not on API v2.
- A token with scopes does not work on API v1.
Errors
The token and revocation endpoints answer errors with JSON in the format of RFC 6749.
{
"error": "invalid_grant",
"error_description": "..."
}