Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Configure Canva Connect API across development, staging, and production environments. Use when setting up multi-environment deployments, managing OAuth credentials per environment, or implementing environment-specific Canva configurations. Trigger with phrases like "canva environments", "canva staging", "canva dev prod", "canva environment setup", "canva config by env".
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-19 | ✗→✓ | ▲ Improved | 25% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 7% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 97% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 58% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 25% | 0% |
Configure Canva Connect API integrations across development, staging, and production. Each environment needs separate OAuth integrations registered in the Canva developer portal with distinct redirect URIs.
| Environment | Canva Integration | Redirect URI | Data | |-------------|------------------|--------------|------| | Development | my-app-dev | http://localhost:3000/auth/canva/callback | Test account | | Staging | my-app-staging | https://staging.myapp.com/auth/canva/callback | Staging account | | Production | my-app-prod | https://myapp.com/auth/canva/callback | Real users |
Important: Register a separate Canva integration per environment. Each gets its own client ID and secret.
typescript// src/config/canva.ts interface CanvaEnvConfig { clientId: string; clientSecret: string; redirectUri: string; baseUrl: string; // Always api.canva.com — Canva has no sandbox API scopes: string[]; debug: boolean; } const configs: Record<string, CanvaEnvConfig> = { development: { clientId: process.env.CANVA_CLIENT_ID!, clientSecret: process.env.CANVA_CLIENT_SECRET!, redirectUri: 'http://localhost:3000/auth/canva/callback', baseUrl: 'https://api.canva.com/rest/v1', // No sandbox exists scopes: ['design:content:write', 'design:content:read', 'design:meta:read', 'asset:write', 'asset:read'], debug: true, }, staging: { clientId: process.env.CANVA_CLIENT_ID!, clientSecret: process.env.CANVA_CLIENT_SECRET!, redirectUri: process.env.CANVA_REDIRECT_URI!, baseUrl: 'https://api.canva.com/rest/v1', scopes: ['design:content:write', 'design:content:read', 'design:meta:read', 'asset:write', 'asset:read'], debug: false, }, production: { clientId: process.env.CANVA_CLIENT_ID!, clientSecret: process.env.CANVA_CLIENT_SECRET!, redirectUri: process.env.CANVA_REDIRECT_URI!, baseUrl: 'https://api.canva.com/rest/v1', scopes: ['design:content:write', 'design:content:read', 'design:meta:read'], debug: false, }, }; export function getCanvaConfig(): CanvaEnvConfig { const env = process.env.NODE_ENV || 'development'; return configs[env] || configs.development; }
bash# .env.local (git-ignored) CANVA_CLIENT_ID=OCA_dev_xxxxxxxx CANVA_CLIENT_SECRET=dev_xxxxxxxx
bash# Per-environment secrets gh secret set CANVA_CLIENT_ID --env staging --body "OCA_staging_xxx" gh secret set CANVA_CLIENT_SECRET --env staging --body "staging_xxx" gh secret set CANVA_CLIENT_ID --env production --body "OCA_prod_xxx" gh secret set CANVA_CLIENT_SECRET --env production --body "prod_xxx"
bash# GCP Secret Manager gcloud secrets create canva-client-id-prod --data-file=- gcloud secrets create canva-client-secret-prod --data-file=- # AWS Secrets Manager aws secretsmanager create-secret \ --name canva/production/client-id \ --secret-string "OCA_prod_xxx" # HashiCorp Vault vault kv put secret/canva/production \ client_id="OCA_prod_xxx" \ client_secret="prod_xxx"
typescript// Prevent accidental cross-environment operations function assertEnvironment(expected: string): void { const actual = process.env.NODE_ENV || 'development'; if (actual !== expected) { throw new Error(`Expected ${expected} environment, got ${actual}`); } } // Guard destructive operations async function deleteAllUserDesigns(userId: string, token: string) { assertEnvironment('development'); // Block in staging/production // ... }
typescript// Development: file-based for convenience // Staging/Production: encrypted database function getTokenStore(): TokenStore { const env = process.env.NODE_ENV || 'development'; if (env === 'development') { return new FileTokenStore('.canva-tokens.json'); // git-ignored } return new DatabaseTokenStore({ connectionString: process.env.DATABASE_URL!, encryptionKey: process.env.TOKEN_ENCRYPTION_KEY!, }); }
api.canva.com/rest/v1. Use separate Canva accounts for dev/staging.| Issue | Cause | Solution | |-------|-------|----------| | Wrong redirect URI | Environment mismatch | Use per-environment integration | | Missing secret | Not deployed to env | Add via secret manager | | Token cross-contamination | Shared token store | Isolate by environment prefix | | Production guard triggered | Wrong NODE_ENV | Set correct environment variable |
For observability setup, see canva-observability.
Other measured skills in the registry, with their headline benchmark lift.