> canva-deploy-integration

Deploy Canva Connect API integrations to Vercel, Fly.io, and Cloud Run. Use when deploying Canva-powered applications to production, configuring platform-specific secrets, or setting up deployment pipelines. Trigger with phrases like "deploy canva", "canva Vercel", "canva production deploy", "canva Cloud Run", "canva Fly.io".

fetch
$curl "https://skillshub.wtf/jeremylongshore/claude-code-plugins-plus-skills/canva-deploy-integration?format=md"
SKILL.mdcanva-deploy-integration

Canva Deploy Integration

Overview

Deploy Canva Connect API integrations to popular platforms with secure OAuth credential management. The Canva API requires server-side token exchange — client secrets and refresh tokens must never reach the browser.

Prerequisites

  • Canva OAuth credentials (client ID + secret)
  • Platform CLI installed (vercel, fly, or gcloud)
  • HTTPS domain for OAuth redirect URIs
  • Application code ready for deployment

Vercel

Secrets

# Add Canva OAuth credentials
vercel env add CANVA_CLIENT_ID production
vercel env add CANVA_CLIENT_SECRET production
vercel env add CANVA_REDIRECT_URI production  # e.g. https://your-app.vercel.app/auth/canva/callback

vercel.json

{
  "functions": {
    "api/**/*.ts": {
      "maxDuration": 30
    }
  },
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Cache-Control", "value": "no-store" }
      ]
    }
  ]
}

API Route (Next.js / Vercel Functions)

// api/canva/callback.ts — OAuth callback
export async function GET(req: Request) {
  const url = new URL(req.url);
  const code = url.searchParams.get('code');
  const state = url.searchParams.get('state');

  // Exchange code for tokens (server-side only)
  const tokens = await exchangeCodeForToken({
    code: code!,
    codeVerifier: await getVerifierFromSession(state!),
    clientId: process.env.CANVA_CLIENT_ID!,
    clientSecret: process.env.CANVA_CLIENT_SECRET!,
    redirectUri: process.env.CANVA_REDIRECT_URI!,
  });

  // Store tokens in your database
  await saveTokens(userId, tokens);
  return Response.redirect('/dashboard');
}

Fly.io

fly.toml

app = "my-canva-app"
primary_region = "iad"

[env]
  NODE_ENV = "production"
  CANVA_REDIRECT_URI = "https://my-canva-app.fly.dev/auth/canva/callback"

[http_service]
  internal_port = 3000
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true

Secrets

fly secrets set CANVA_CLIENT_ID=OCAxxxxxxxxxxxxxxxx
fly secrets set CANVA_CLIENT_SECRET=xxxxxxxxxxxxxxxx
fly deploy

Google Cloud Run

Deploy Script

#!/bin/bash
PROJECT_ID="${GOOGLE_CLOUD_PROJECT}"
SERVICE_NAME="canva-integration"
REGION="us-central1"

# Store secrets in Secret Manager
echo -n "OCAxxxxxxxxxxxxxxxx" | gcloud secrets create canva-client-id --data-file=-
echo -n "xxxxxxxxxxxxxxxx" | gcloud secrets create canva-client-secret --data-file=-

# Build and deploy
gcloud builds submit --tag gcr.io/$PROJECT_ID/$SERVICE_NAME

gcloud run deploy $SERVICE_NAME \
  --image gcr.io/$PROJECT_ID/$SERVICE_NAME \
  --region $REGION \
  --platform managed \
  --allow-unauthenticated \
  --set-secrets="CANVA_CLIENT_ID=canva-client-id:latest,CANVA_CLIENT_SECRET=canva-client-secret:latest" \
  --set-env-vars="CANVA_REDIRECT_URI=https://$SERVICE_NAME-xxxxx.run.app/auth/canva/callback"

Health Check

// api/health.ts — confirms Canva API connectivity
export async function GET() {
  const start = Date.now();
  let canvaStatus: string;

  try {
    const res = await fetch('https://api.canva.com/rest/v1/users/me', {
      headers: { 'Authorization': `Bearer ${await getServiceToken()}` },
      signal: AbortSignal.timeout(5000),
    });
    canvaStatus = res.ok ? 'healthy' : `error:${res.status}`;
  } catch {
    canvaStatus = 'unreachable';
  }

  return Response.json({
    status: canvaStatus === 'healthy' ? 'healthy' : 'degraded',
    services: { canva: { status: canvaStatus, latencyMs: Date.now() - start } },
    timestamp: new Date().toISOString(),
  });
}

Redirect URI Configuration

After deploying, update your Canva integration settings with the production redirect URI:

PlatformRedirect URI Pattern
Vercelhttps://your-app.vercel.app/auth/canva/callback
Fly.iohttps://your-app.fly.dev/auth/canva/callback
Cloud Runhttps://your-service-xxxxx.run.app/auth/canva/callback
Custom Domainhttps://app.yourdomain.com/auth/canva/callback

Error Handling

IssueCauseSolution
OAuth callback failsRedirect URI mismatchUpdate URI in Canva dashboard
Secret not foundMissing env varAdd via platform CLI
Cold start timeoutOAuth exchange slowSet min instances to 1
HTTPS requiredHTTP redirect URIAll platforms default to HTTPS

Resources

Next Steps

For webhook handling, see canva-webhooks-events.

┌ stats

installs/wk0
░░░░░░░░░░
github stars1.7K
██████████
first seenMar 23, 2026
└────────────

┌ repo

jeremylongshore/claude-code-plugins-plus-skills
by jeremylongshore
└────────────