Skip to main content

Authentication

The Partner API uses the standard OAuth 2.0 Client Credentials grant. Every request to the API must include a valid access token in the Authorization header.

Machine‑to‑Machine Authentication​

This is a machine‑to‑machine (server‑to‑server) flow. Tokens are issued to your backend service, not to individual end‑users.

Key Points

  • No browser redirects or user interfaces are involved.
  • You request tokens programmatically with client_id, client_secret, scope, and grant_type=client_credentials.
  • Never commit actual credentials to version control. Store client_id, client_secret, and endpoint URLs as environment variables or in secure configuration management systems.
  • The token endpoint does not accept user access tokens from B2C or other interactive sign‑in flows.
  • Refresh tokens are not returned; when a token expires, request a new one with the same credentials.

If you need user-level authentication, you may handle that in your own application. Just let your backend call the Partner API using this machine credential flow.

Authentication Flow​

Step 1: Obtain an Access Token​

Endpoint

POST <https://<token‑endpoint>>/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

Replace <token‑endpoint> with the URL provided by your onboarding contact.

Body Parameters

ParameterTypeRequiredDescription
client_idstringYesThe application (client) ID issued to you
client_secretstringYesThe secret paired with client_id, keep it safe and never share it client-side
scopestringYesAlways api://<client-id>/.default
grant_typestringYesMust be client_credentials

Example Request (Bash)

curl -X POST "https://<token-endpoint>/oauth2/v2.0/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=api://YOUR_CLIENT_ID/.default" \
-d "grant_type=client_credentials"

Example Request (PowerShell)

curl -X POST "https://<token-endpoint>/oauth2/v2.0/token" `
-H "Content-Type: application/x-www-form-urlencoded" `
-d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&scope=api://YOUR_CLIENT_ID/.default&grant_type=client_credentials"

Successful Response

{
"token_type": "Bearer",
"expires_in": 3599,
"ext_expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGci..."
}

expires_in is the token lifetime in seconds (≈ 60 minutes). Request a new token when the current one expires.

Step 2: Call the API​

Include the token in the Authorization header on every request:

GET <partner-api.utopi.io/<resource>>
Authorization: Bearer <access_token>
SiteId: <your_site_id>

If the token is missing, expired, or invalid, the API returns 401 Unauthorized.

Error Reference (Token Endpoint)​

HTTP statusMeaningCommon causes
400Bad RequestMissing or malformed parameter.
401UnauthorizedInvalid client credentials.

Common Authentication Errors​

Authentication errors from the token endpoint follow a different format than Partner API errors. Here are the most common issues:

400 Bad Request - Invalid Grant Type​

Error: unsupported_grant_type

{
"error": "unsupported_grant_type",
"error_description": "The app requested an unsupported grant type 'invalid_grant'.",
"error_codes": [70003],
"timestamp": "2025-08-01T14:27:45Z",
"trace_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"correlation_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Resolution: Ensure grant_type=client_credentials is included in your request.

400 Bad Request - Invalid Client ID​

Error: unauthorized_client

{
"error": "unauthorized_client",
"error_description": "Application with identifier 'invalid-client-id' was not found in the directory.",
"error_codes": [700016],
"timestamp": "2025-08-01T14:27:21Z",
"trace_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"correlation_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"error_uri": "https://login.example.com/error?code=700016"
}

Resolution: Verify your client_id is correct and matches the credentials provided during onboarding.

401 Unauthorized - Invalid Client Secret​

Error: invalid_client

{
"error": "invalid_client",
"error_description": "Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID.",
"error_codes": [7000215],
"timestamp": "2025-08-01T14:29:20Z",
"trace_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"correlation_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"error_uri": "https://login.example.com/error?code=7000215"
}

Resolution: Verify your client_secret is the actual secret value, not the secret ID. Check your stored credentials.

Error Response Structure​

Authentication errors include these fields:

  • error - Short error identifier
  • error_description - Detailed error message with error code
  • error_codes - Array of specific error codes
  • timestamp - When the error occurred
  • trace_id - Trace identifier for debugging
  • correlation_id - Request correlation identifier
  • error_uri - Link to error documentation (when available)

Troubleshooting Steps​

  1. Verify credentials - Ensure client_id and client_secret match your onboarding details
  2. Check parameters - Confirm all required parameters are included with correct values
  3. Review scope format - Ensure scope is api://<your-client-id>/.default
  4. Contact your technical contact if errors persist after verification