---
title: "Authenticate with OAuth2 Client Credentials"
description: "Create a CloudPrint client app, request a short-lived access token and protect credentials with the correct API scopes."
---
<nav class="docs-breadcrumb" aria-label="Breadcrumb"><a href="/docs/">CloudPrint Documentation</a><span aria-hidden="true">/</span><span>Print API</span></nav>

# Authenticate with OAuth2 Client Credentials

<p class="docs-lead">Authentication is server-to-server OAuth2 Client Credentials. The client secret belongs only in a backend secret store; a browser, mobile app, local agent script or public repository must never receive it.</p>

## Create the client and scopes

Create one client app per external system in the account UI. PDF and RAW printing use `printers:read`, `documents:write`, `print_jobs:write` and `print_jobs:read`; add `agents:read` only when the integration reads `/api/v1/agents`. The secret is shown once.

## Request and cache the token

```bash
curl -sS https://public-api.cloudprint.me/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode 'client_id=YOUR_CLIENT_ID' \
  --data-urlencode 'client_secret=YOUR_CLIENT_SECRET' \
  --data-urlencode 'scope=printers:read documents:write print_jobs:write print_jobs:read'
```

```json
{
  "token_type": "Bearer",
  "expires_in": 900,
  "access_token": "eyJ..."
}
```

Cache the token until shortly before its 900-second lifetime expires. Do not request a token for every print.

## Verify identity and scopes

```bash
curl -sS https://public-api.cloudprint.me/api/v1/me \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

```json
{
  "account_id": "44444444-4444-4444-8444-444444444444",
  "account_name": "Acme Print Ops",
  "client_app_id": "33333333-3333-4333-8333-333333333333",
  "client_app_name": "Warehouse integration",
  "scopes": [
    "printers:read",
    "documents:write",
    "print_jobs:write",
    "print_jobs:read"
  ]
}
```

Use this setup check to prove which account and client app the token represents. It prevents a valid token from silently routing work in the wrong customer account.

## Handle OAuth and API failures

`400 invalid_scope` means the requested scope is unknown or not granted. `401 invalid_client` at the token endpoint means the client credentials are wrong. A `401` from an API endpoint means the Bearer token is invalid or expired: refresh once and retry the original request once. `403` means the valid token lacks the required scope.

## Rotate credentials

Issue a replacement client credential, deploy it through the secret manager and verify `/api/v1/me` before revoking the old client. Never print or log `client_secret` or the complete access token. `X-Request-Id` is safe to retain for request correlation.

## Next steps

<div class="docs-card-grid"><a class="docs-card" href="/docs/getting-started/"><strong>CloudPrint API quickstart</strong><span>Connect an agent, obtain an OAuth token, select a printer, send your first print job and confirm its final status.</span></a>
<a class="docs-card" href="/docs/api/overview/"><strong>CloudPrint Public API overview</strong><span>A practical map of CloudPrint authentication, printers, documents, print jobs, statuses and errors for backend integrations.</span></a>
<a class="docs-card" href="/docs/developer-platform/"><strong>CloudPrint Developer Platform</strong><span>Build one application that customers can connect to their own CloudPrint accounts.</span></a></div>

<nav class="docs-resource-links" aria-label="Next steps"><a href="https://cloudprint.me/status/">Service status</a><a href="/docs/api/v1/explorer/">OpenAPI</a><a href="https://developer.cloudprint.me">Developer Portal</a><a href="https://my.cloudprint.me">Open account</a><a href="/docs/legal/privacy/">Privacy Policy</a><a href="/docs/legal/terms/">Terms</a><a href="/docs/legal/data-processing/">DPA</a><a href="/docs/legal/service-level-agreement/">Service Level Agreement</a></nav>