Skip to main content

Authentication

The Typograph API uses OAuth 2.0 for authentication. Choose the appropriate flow based on your use case.

Quick Start

For server-to-server integrations, use Client Credentials:

curl -X POST https://api.typograph.nl/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=file document publisher converter"

Response:

{
"access_token": "typ_abc123...",
"token_type": "Bearer",
"expires_in": 172800,
"scope": "file document publisher converter"
}

Getting Credentials

OAuth Client Registration

  1. Log in to the Typograph Portal.
  2. Open your organization — Settings → Organizations → your organization.
  3. Go to the Apps tab and click + Create App.
  4. Fill in the form:
    • Name — a human-readable name for the app.
    • Redirect URIs — add one or more callback URLs if you're building a user-facing app that will use the Authorization Code flow. Leave empty for a backend-only app using Client Credentials.
    • Scopes — tick the scopes your app needs (see the Scopes reference). The available scopes depend on your organization's subscription.
  5. Save. The portal displays your Client ID and Client Secret once — copy both immediately.
caution

The Client Secret is shown only once at creation. Store it in a secret manager or environment variable; the portal can't show it again.

Grant type is inferred
  • App with no redirect URIsclient_credentials grant (server-to-server).
  • App with one or more redirect URIsauthorization_code + refresh_token grants (user-facing).

OAuth 2.0 Flows

Client Credentials Flow

Best for server-to-server integrations where no user interaction is needed.

curl -X POST https://api.typograph.nl/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=publisher converter document"

Authorization Code Flow with PKCE

Best for web applications and mobile apps where users authenticate.

Step 1: Generate PKCE Parameters

// Generate code_verifier (43-128 characters)
const codeVerifier = generateRandomString(64);

// Generate code_challenge
const encoder = new TextEncoder();
const data = encoder.encode(codeVerifier);
const digest = await crypto.subtle.digest('SHA-256', data);
const codeChallenge = btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');

Step 2: Redirect to Authorization

https://api.typograph.nl/oauth/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://your-app.com/callback
&scope=openid profile email file
&state=random_state_string
&code_challenge=CODE_CHALLENGE
&code_challenge_method=S256

Step 3: Exchange Code for Tokens

curl -X POST https://api.typograph.nl/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "code=AUTHORIZATION_CODE" \
-d "redirect_uri=https://your-app.com/callback" \
-d "code_verifier=CODE_VERIFIER"

Response:

{
"access_token": "typ_abc123...",
"token_type": "Bearer",
"expires_in": 172800,
"refresh_token": "typ_refresh_xyz789...",
"scope": "openid profile email file"
}

Refresh Token Flow

Exchange a refresh token for a new access token:

curl -X POST https://api.typograph.nl/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "refresh_token=YOUR_REFRESH_TOKEN"
info

Request the offline_access scope to receive refresh tokens.

Using Access Tokens

Include the access token in the Authorization header:

curl https://api.typograph.nl/v1/publisher/jobs \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Token Types

The Typograph API distinguishes between user tokens (issued via authorization_code / refresh_token) and client tokens (issued via client_credentials). Each gateway route requires one or the other, or accepts either.

See Token Types for the full breakdown of which endpoints require which token type and how to verify a token's type via introspection.

Token Management

Token Lifetimes

Token TypeLifetime
Access Token2 days (172,800 seconds)
Refresh Token3 days (259,200 seconds)
Authorization Code10 minutes

Token Introspection

Verify token validity and get metadata:

curl -X POST https://api.typograph.nl/oauth/introspect \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=YOUR_ACCESS_TOKEN" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"

Response:

{
"active": true,
"client_id": "019b28fb-a11e-7641-a28f-e978f892ec06",
"token_type": "Bearer",
"grant_type": "authorization_code",
"auth_type": "user",
"scope": "file document publisher",
"exp": 1734567890,
"iat": 1734395090,
"sub": "019b28fb-a11e-7641-a28f-e978f892ec07"
}
FieldDescription
grant_typeHow the token was obtained: authorization_code, client_credentials, or refresh_token
auth_typeToken type: user (has user context) or client (no user context)
subUser ID (only present for user tokens)

Token Revocation

Invalidate a token when no longer needed:

curl -X POST https://api.typograph.nl/oauth/revoke \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=YOUR_ACCESS_TOKEN" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"

Single Sign-On (SSO)

Typograph's own login screen supports SSO via Google and Microsoft Azure AD. From your application's perspective, SSO is invisible — you use the standard Authorization Code + PKCE flow exactly as described above. When the user hits the Typograph login screen they see the "Sign in with Google" / "Sign in with Microsoft" buttons in addition to the email/password form, pick whichever they prefer, and are redirected back to your redirect_uri with an authorization code as normal.

You don't need to build anything SSO-specific into your app, and you should not redirect users directly to the /oauth/sso/* endpoints — those are used internally by Typograph's Auth UI during the login flow.

User Information

Get the authenticated user's profile (requires openid scope):

curl https://api.typograph.nl/oauth/userinfo \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response:

{
"sub": "019b28fb-a11e-7641-a28f-e978f892ec07",
"name": "John Doe",
"email": "john@example.com",
"email_verified": true
}

OAuth Discovery

Typograph implements OAuth 2.0 Authorization Server Metadata (RFC 8414):

curl https://api.typograph.nl/.well-known/oauth-authorization-server

Response:

{
"issuer": "https://api.typograph.nl",
"authorization_endpoint": "https://api.typograph.nl/oauth/authorize",
"token_endpoint": "https://api.typograph.nl/oauth/token",
"revocation_endpoint": "https://api.typograph.nl/oauth/revoke",
"introspection_endpoint": "https://api.typograph.nl/oauth/introspect",
"scopes_supported": [
"openid", "profile", "email", "offline_access",
"authorization", "health",
"identity", "identity:read", "identity:write",
"file", "file:read", "file:write", "file:delete",
"document", "document:read", "document:write",
"publisher", "publisher:read", "publisher:write",
"converter", "converter:read", "converter:write",
"webhook", "webhook:read", "webhook:write", "webhook:delete",
"subscription", "subscription:read", "subscription:write"
],
"response_types_supported": ["code"],
"response_modes_supported": ["query"],
"grant_types_supported": ["authorization_code", "client_credentials", "refresh_token"],
"token_endpoint_auth_methods_supported": ["client_secret_basic", "client_secret_post", "none"],
"code_challenge_methods_supported": ["S256", "plain"],
"service_documentation": "https://docs.typograph.nl"
}

The full scope catalog — including descriptions and the parent/child hierarchy — is documented in Scopes.

Client Types

Confidential Clients

Server-side applications that can securely store credentials.

  • Use Client Credentials or Authorization Code flow
  • Must include client_secret in token requests
  • Suitable for: Backend services, server-side web apps

Public Clients

Client-side applications that cannot securely store credentials.

  • Must use Authorization Code flow with PKCE
  • Cannot use client_secret
  • Suitable for: SPAs, mobile apps, desktop applications

Error Handling

OAuth Errors

ErrorDescription
invalid_requestMissing or invalid parameter
invalid_clientClient authentication failed
invalid_grantInvalid authorization code or refresh token
unauthorized_clientClient not authorized for this grant type
unsupported_grant_typeGrant type not supported
invalid_scopeRequested scope is invalid or exceeds granted scopes

Error Response:

{
"error": "invalid_grant",
"error_description": "The authorization code has expired"
}

HTTP Status Codes

CodeDescription
401 UnauthorizedMissing or invalid access token
403 ForbiddenToken lacks required scope or wrong token type

Token Type Errors

Error CodeDescription
invalid_token_typeWrong token type for endpoint (e.g., using client token on user-only endpoint)
insufficient_scopeToken lacks required OAuth scope

Security Best Practices

  1. Store credentials securely - Never commit secrets to version control
  2. Use environment variables - Keep credentials out of your codebase
  3. Request minimal scopes - Only request what your application needs
  4. Use PKCE - Always use PKCE for Authorization Code flow
  5. Rotate credentials - Periodically rotate client secrets
  6. Validate tokens - Use introspection for sensitive operations
  7. Handle expiration - Implement automatic token refresh
  8. Use HTTPS - Always use secure connections