Authentication¶
The Contio Partner API supports two authentication methods, each designed for different use cases.
Authentication Methods Overview¶
| Method | Use Case | Required Credentials |
|---|---|---|
| OAuth 2.0 | User data access (meetings, action items) | Client ID, Client Secret |
| API Key | Admin operations (workflows, webhooks) | API Key, Client ID |
OAuth 2.0 Authentication¶
OAuth 2.0 is used to access data on behalf of connected users. The flow follows the standard Authorization Code Grant with PKCE support.
Available Scopes¶
| Scope | Description |
|---|---|
openid | Required for OIDC compliance |
profile | Access user profile information |
email | Access user email address |
meetings:read | Read meetings, participants, agenda items, and notes |
meetings:write | Create and update meetings, participants, and agenda |
action-items:read | Read action items |
action-items:write | Create, update, and delete action items |
calendar:read | Read calendar events |
calendar:write | Link/unlink calendar events to meetings |
Authorization Flow¶
sequenceDiagram
participant User
participant YourApp
participant Contio
YourApp->>Contio: Redirect to /oauth2/authorize
Contio->>User: Login & Consent Page
User->>Contio: Grant Permission
Contio->>YourApp: Redirect with code
YourApp->>Contio: POST /oauth2/token
Contio->>YourApp: Access Token + Refresh Token Implementation¶
import { ContioPartnerSDK } from '@contio/partner-sdk';
const { oauth, user } = ContioPartnerSDK.forUser({
clientId: process.env.CONTIO_CLIENT_ID!,
clientSecret: process.env.CONTIO_CLIENT_SECRET!,
redirectUri: 'https://your-app.com/callback',
// Optional: specify scopes (defaults to all)
scopes: ['openid', 'profile', 'meetings:read', 'action-items:read']
});
// Step 1: Generate authorization URL and redirect user
const authUrl = oauth.getAuthorizationUrl('random-state-for-csrf');
// res.redirect(authUrl);
// Step 2: User completes OAuth flow in browser:
// - Enters email and verifies via OTP
// - Reviews and grants consent for requested scopes
// - Gets redirected back to your app with authorization code
// Step 3: Exchange authorization code for tokens
const tokens = await oauth.exchangeCodeForToken(authorizationCode);
// Step 3: Use tokens for API calls
// The SDK automatically includes the access token in requests
const meetings = await user.getMeetings();
// Step 4: Refresh tokens when needed
const newTokens = await oauth.refreshToken(tokens.refresh_token);
Token Format¶
Contio uses opaque tokens for improved security:
| Token Type | Format | Validity |
|---|---|---|
| Authorization code | Opaque | 5 minutes |
| Access token | cto_at_v1_... | 24 hours |
| Refresh token | cto_rt_v1_... | 30 days |
| ID token | Standard JWT | 24 hours |
Opaque Tokens
Access and refresh tokens are opaque strings with no readable claims. Use oauth.introspectToken() to retrieve token metadata like scopes and expiration.
Token Management¶
Security Best Practices
- Store tokens encrypted at rest
- Never expose tokens in client-side code
- Implement token refresh before expiration (recommend 5-minute buffer)
- Handle token revocation gracefully
Client Authentication Requirements¶
Some OAuth methods require client authentication using your client_id and client_secret. The SDK automatically handles this for:
| Method | Authentication | Safe for Frontend? |
|---|---|---|
getAuthorizationUrl() | None | ✅ Yes |
exchangeCodeForToken() | Client credentials | ❌ Backend only |
refreshToken() | Client credentials | ❌ Backend only |
getPartnerInfo() | None (public) | ✅ Yes |
getAvailableScopes() | Client credentials | ❌ Backend only |
checkConsent() | Client credentials | ❌ Backend only |
introspectToken() | Client credentials | ❌ Backend only |
Never Expose Client Secret
Your client_secret must never be included in frontend JavaScript code. Only use methods requiring client authentication on your backend server.
API Key Authentication¶
API Keys are used for server-to-server admin operations that don't require user context.
Required Headers¶
| Header | Description |
|---|---|
X-Client-ID | Your partner app's client ID |
X-API-Key | Your partner app's API key |
Implementation¶
import { ContioPartnerSDK } from '@contio/partner-sdk';
const { admin } = ContioPartnerSDK.forAdmin({
apiKey: process.env.CONTIO_API_KEY!,
clientId: process.env.CONTIO_CLIENT_ID // Optional if using SDK
});
// Make admin API calls
const workflows = await admin.getWorkflows();
const stats = await admin.getStats();
API Key Rotation¶
Rotate your API key periodically for security:
// Request new credentials (old key remains valid for 24 hours)
const newCredentials = await admin.rotateCredentials();
// Update your environment with new API key
console.log('New API Key:', newCredentials.api_key);
Error Handling¶
Both authentication methods return standard OAuth 2.0 error responses:
try {
const tokens = await oauth.exchangeCodeForToken(code);
} catch (error) {
if (error.code === 'invalid_grant') {
// Authorization code expired or already used
} else if (error.code === 'invalid_client') {
// Invalid client credentials
}
}
Next Steps¶
- API Guide - Complete endpoint reference
- OAuth Flow Example - Detailed OAuth implementation