# Authentication · Reference

> OAuth2 `client_credentials`: an opaque token valid for one hour.

Page: https://safeonuba.com/en/developers/reference/authentication · SafeOnuba API v1 (`api_version: "2026-09-24"`), in preview: the contract may change.

## Request a token (client_credentials)

`POST /v1/oauth/token` · no token · [see it on the web](https://safeonuba.com/en/developers/reference/authentication#createToken)

OAuth2 `client_credentials`. The token is opaque, lasts one hour and is revoked immediately when the client is deactivated.

### Body (`application/x-www-form-urlencoded`, schema `TokenRequest`)

- `grant_type` (string, required) Values: `client_credentials`.
- `client_id` (string, required)
- `client_secret` (string, required)
- `scope` (string): Space-separated; a subset of the client’s. Without it, all of the client’s.

### Responses

- `200`: Token issued. → `TokenResponse` (`application/json`)
- `400`: Malformed request or scope not allowed. → `OAuthError` (`application/json`)
- `401`: Incorrect client or secret. → `OAuthError` (`application/json`)

### Example request (sandbox)

```bash
curl -X POST https://sandbox.api.safeonuba.com/v1/oauth/token \
  -d grant_type=client_credentials \
  -d client_id="$SAFEONUBA_CLIENT_ID" \
  -d client_secret="$SAFEONUBA_CLIENT_SECRET" \
  -d scope="alerts:read musters:read"
```

### Example response (`200`)

```json
{
  "access_token": "at_9c1e…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "alerts:read alerts:write musters:read"
}
```
