Skip to main content

Client Credentials Token Exchange Guide

Overview​

This guide explains how to obtain a hub-scoped DFU (Device Firmware Update) access token using the OAuth2 client credentials flow. The token allows you to perform DFU operations on a specific hub.

Prerequisites​

Before you begin, ensure you have the following information:

  • Organization ID: Your organization identifier
  • Hub Serial Number: The serial number of the hub you want to perform DFU operations on (e.g., HUB001)
  • Client ID: Your Custom Service client ID
  • Client Secret: Your Custom Service client secret
  • Auth API Endpoint: The base URL for the authentication API (e.g., https://connect.cambrionix.com/api/v1)
  • Hub API Service ID: The audience value expected by the local Hub API instance you're targeting (see below)

Finding your Hub API Service ID​

The token's audience must match the service ID of the local Hub API you intend to call, not a fixed string. You can retrieve it directly from the Hub API itself:

  1. With the Hub API running locally (default port 43424), open the Swagger UI in your browser at http://localhost:43424/swagger.
  2. Expand the Utility section and select the GET /api/v1/details endpoint.
  3. Click Execute to call it with no parameters.
  4. In the response body, copy the value of result.guid.id — this is your Hub API Service ID.
{
"result": {
"guid": {
"id": "16626f7f-4abc-5314-a285-9476625c2e92"
}
}
}

You can also fetch this from the command line:

curl -s "http://localhost:43424/api/v1/details" | jq -r '.result.guid.id'

Step 1: Request the Token​

Use the following curl command to exchange your client credentials for a DFU-scoped access token:

curl -X POST "https://connect.cambrionix.com/api/v1/organizations/<YOUR_ORG_ID>/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=<YOUR_CLIENT_ID>" \
-d "client_secret=<YOUR_CLIENT_SECRET>" \
-d "audience=<YOUR_HUB_API_SERVICE_ID>" \
-d "scope=API.DFU.<YOUR_HUB_ID>"

Replace the following placeholders:

  • <YOUR_ORG_ID> - Your organization ID
  • <YOUR_CLIENT_ID> - Your OAuth2 client ID
  • <YOUR_CLIENT_SECRET> - Your OAuth2 client secret
  • <YOUR_HUB_API_SERVICE_ID> - The local Hub API's service ID, from result.guid.id at http://localhost:43424/api/v1/details (see Finding your Hub API Service ID)
  • <YOUR_HUB_ID> - The hub serial number (e.g., HUB001)

Example:

curl -X POST "https://connect.cambrionix.com/api/v1/organizations/org-123/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=abc123xyz" \
-d "client_secret=secret456" \
-d "audience=16626f7f-4abc-5314-a285-9476625c2e92" \
-d "scope=API.DFU.4J4LHF9J"

Step 2: Parse the Response​

A successful response will look like this:

{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 3600,
"scope": "API.DFU.4J4LHF9J",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"issued_at": 1234567890
}

Important fields:

  • access_token: The token to use in API requests (save this)
  • expires_in: Token validity in seconds
  • scope: Confirms the token is scoped to the correct hub

If the request fails, you'll receive an error response:

{
"error": "invalid_client",
"error_description": "Client authentication failed"
}

Step 3: Use the Token​

Include the access token in the Authorization header of your API requests:

curl -X GET "https://api.example.com/v1/hubs/HUB001/firmware" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Example:

curl -X GET "https://api.example.com/v1/hubs/HUB001/firmware" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

Important Notes​

  1. Token Scope: The token is scoped to a specific hub using the format API.DFU.{HUB_ID}. You cannot use this token for operations on other hubs.

  2. Token Expiration: The token expires after the duration specified in expires_in (typically 3600 seconds / 1 hour). You'll need to request a new token when it expires.

  3. Audience: The audience parameter must be the specific Hub API's service ID (result.guid.id from its /api/v1/details endpoint), not a fixed value — a token issued for one hub's service ID will not be accepted by another.

  4. Security: Never share your client secret or access tokens. Treat them as sensitive credentials.

Troubleshooting​

Error: "invalid_client"​

  • Verify your client_id and client_secret are correct
  • Ensure your client credentials are active and not revoked

Error: "invalid_scope"​

  • Verify the hub serial number is correct
  • Ensure your client has permission to request DFU scopes for this hub
    • Your Connect custom service needs to be added to a Group that contains a role which has the API.DFU permission.

Error: "invalid_target" / audience rejected​

  • Confirm you copied result.guid.id from the same Hub API instance you're targeting — re-check http://localhost:43424/api/v1/details if the hub's service ID may have changed (e.g. after a reinstall).
  • Make sure the Hub API is running and reachable at localhost:43424 before fetching the details endpoint.

Error: "invalid_request"​

  • Check that all required parameters are included
  • Verify the organization ID is correct
  • Ensure the Content-Type header is set to application/x-www-form-urlencoded

Network Errors​

  • Verify the auth API endpoint URL is correct and accessible
  • Check your network connection and firewall settings