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