Authentication

This guide explains how to authenticate with the Cadasto API using the OAuth 2.0 Client Credentials flow. This is the standard approach for server-to-server (machine-to-machine) integrations where no interactive user login is needed.

After completing this guide you will be able to obtain an access token and make authenticated API requests.

Prerequisites

  • A registered OAuth client (client_id and client_secret) issued by Cadasto. If you don't have credentials yet, see Requesting Client Credentials.
  • Your Cadasto environment base URLs:
    • Auth server: https://<mycompany>.auth.prod.cadasto.io
    • API server: https://<mycompany>.api.prod.cadasto.io

Service discovery

Instead of hardcoding endpoint URLs, you can discover them automatically from the SMART configuration endpoint:

curl "https://<mycompany>.auth.prod.cadasto.io/.well-known/smart-configuration" \
  -H "Accept: application/json"

This returns a JSON document advertising the available endpoints and capabilities:

{
  "authorization_endpoint": "https://<mycompany>.auth.prod.cadasto.io/oauth/authorize",
  "token_endpoint": "https://<mycompany>.auth.prod.cadasto.io/oauth/token",
  "grant_types_supported": ["client_credentials"],
  "scopes_supported": ["api.read", "api.write"]
}

The actual response may include additional fields such as API service URLs (e.g., org.openehr.rest), supported client authentication methods, and SMART capabilities. For the Client Credentials flow described below, you only need the token_endpoint.

Using the discovery endpoint makes your integration more resilient to future URL changes.

How the Client Credentials flow works

The Client Credentials flow lets a backend service authenticate directly with the authorization server, without a user being present. Your application sends its client_id and client_secret to the token endpoint and receives a time-limited access token in return.

Authentication sequence — Client Credentials flow through discovery, token request, and authenticated API calls

For more detail on the underlying standard, see RFC 6749 Section 4.4.

Obtain an access token

Send a POST request to the token endpoint with your client credentials. The recommended approach is HTTP Basic authentication (credentials in the Authorization header).

Token endpoint

POST https://<mycompany>.auth.prod.cadasto.io/oauth/token

Parameters

Parameter Location Required Description
grant_type Body Yes Must be client_credentials
client_id Header (Basic Auth) Yes Your OAuth client ID
client_secret Header (Basic Auth) Yes Your OAuth client secret
audience Body Yes The API you want to access, e.g. https://<mycompany>.api.prod.cadasto.io/openehr/v1
scope Body No Space-separated list of scopes, e.g. api.read api.write

Example request

curl -X POST "https://<mycompany>.auth.prod.cadasto.io/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "<client_id>:<client_secret>" \
  -d "grant_type=client_credentials" \
  -d "audience=https://<mycompany>.api.prod.cadasto.io/openehr/v1" \
  -d "scope=api.read+api.write"

If you cannot use HTTP Basic authentication, you may include client_id and client_secret as form body parameters instead (less preferred).

Successful response

{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "api.read api.write"
}
Field Description
access_token The Bearer token to include in API requests
token_type Always Bearer
expires_in Token lifetime in seconds (typically 3600 = 1 hour)
scope The scopes granted by the server

Use the access token

Include the token in the Authorization header of every API request:

curl "https://<mycompany>.api.prod.cadasto.io/openehr/v1/definition/template/adl1.4" \
  -H "Authorization: Bearer <access_token>" \
  -H "Accept: application/json"

Example response (list of uploaded templates):

[
  {
    "template_id": "vital_signs.v1",
    "concept": "Vital Signs",
    "archetype_id": "openEHR-EHR-COMPOSITION.encounter.v1"
  }
]

Handle token expiry

The Client Credentials flow does not return a refresh_token. When your access token expires, request a new one by repeating the token request above.

Recommended approach: Check the expires_in value from the token response and schedule a new token request before the current token expires. This avoids failed API calls due to expired tokens.

Token received at 14:00:00 with expires_in=3600
  → Token expires at 15:00:00
  → Request new token at ~14:55:00 (with a safety margin)

Error responses

If the token request fails, the auth server returns an error in the standard OAuth 2.0 error format:

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

Common errors:

Error Cause
invalid_client Wrong client_id or client_secret
invalid_grant Incorrect grant_type
invalid_request Invalid client credentials or refresh token
invalid_scope Requested scope not allowed for this client

Next steps

  • Quick Start — Create your first EHR, upload a template, and commit a composition
  • AQL Guide — Query your openEHR data
  • openEHR Concepts — Understand the data model behind the APIs