Connected Apps (OAuth)

Settings → Connected Apps (OAuth) registers integrations that sign in with OAuth 2.0 client credentials. The integration swaps its client ID and secret for a short-lived access token, then calls the CRMSix API with it. Like an API key, a connected app acts as a run-as user you choose.

Connected app or API key?

Both give an integration access to the same API, acting as a run-as user. Choose a connected app when:

  • the integration platform expects OAuth 2.0 (many iPaaS and ETL tools do);
  • you’d rather the credential sent with each API call expire on its own after minutes or hours;
  • you want to rotate the secret without creating a new integration.

For a simple script, an API key is quicker.

Create a connected app

  1. Go to Settings → Connected Apps (OAuth) and choose New Connected App.
  2. Give it a name, for example “Data warehouse”.
  3. Choose the run-as user. The app can see and change exactly what this user can.
  4. Choose the access token lifetime: 15 minutes, 1 hour (the default), 8 hours or 24 hours.
  5. Tick Read-only if the app only needs to read. It then can’t create, change or delete anything, in the API or over MCP.
  6. Save, then copy the client ID and client secret into your integration’s secret store. This is the only time the secret is shown.

Only admins can manage connected apps. An organization can have up to 50 active apps.

Get an access token

The top of the page shows your token endpoint (POST /api/oauth/token on your CRMSix address), the grant type client_credentials, and the two ways to send the client’s credentials: HTTP Basic (client_secret_basic) or in the form body (client_secret_post). Use one, not both.

curl -X POST https://<your CRMSix address>/api/oauth/token \
  -u '<client_id>:<client_secret>' \
  -d grant_type=client_credentials

The response:

{
  "access_token": "eyJ…",
  "token_type": "Bearer",
  "expires_in": 3600
}

Call the API

Send the access token with each request:

curl https://<your CRMSix address>/api/cases \
  -H "Authorization: Bearer <access_token>"

When the token expires (expires_in seconds later), request a new one the same way. Most OAuth libraries do this for you. The API reference is at /apidoc on your CRMSix address.

What a connected app can do

  • Same access as its userThe run-as user’s object permissions, field security and sharing apply to every call.
  • Read-only appsCan only read; requests that would change data are refused.
  • Sign-ins are recordedEach token request, successful or not, appears in the run-as user’s login history.
  • Inactive user, no tokensIf the run-as user is deactivated, the app can’t get tokens.

Reset a secret or revoke an app

The list shows each app’s client ID, run-as user, token lifetime, status, when it last got a token, and when it was created.

Action What happens
Reset secretA new secret is shown once. The old secret, and every token issued with it, stops working immediately. The client ID stays the same.
RevokeThe app can’t get new tokens and its current tokens stop working now. This can’t be undone.
Rotating a secret without downtime: reset it at a quiet time and paste the new secret into the integration straight away; its next token request uses the new secret.

Good practice

  • Keep the client secret in a secrets store, never in source code or chat.
  • Use a dedicated integration user with only the access the app needs, and tick Read-only where you can.
  • Pick the shortest token lifetime your integration copes with.
  • One connected app per integration, so each can be revoked on its own.

Troubleshooting

invalid_client (401) from the token endpoint
The client ID or secret is wrong, the secret was reset, the app was revoked, or its run-as user is inactive.
“Use one client authentication method, not two”
Send the credentials either with HTTP Basic or in the body, not both.
unsupported_grant_type
Send grant_type=client_credentials as a form field (application/x-www-form-urlencoded).
401 from the API after a while
The access token has expired. Request a new one.
403 from the API
The run-as user isn’t allowed to do this, or the app is read-only.