Quickstart

Get CDNsync running in under 5 minutes. We'll install the CLI, initialize a project, connect a CDN provider, and push your first asset to the edge.

Step 1: Install the CLI

CDNsync CLI is available via npm. You'll need Node.js 16+ and npm 7+.

Terminal
# Install globally or as a project dependency
npm install -g @cdnsync/cli

# Verify installation
cdnsync --version

Step 2: Initialize a Project

Create a new CDNsync project in your working directory. The initialization wizard will guide you through basic setup.

Terminal
mkdir my-cdn-project
cd my-cdn-project
cdnsync init

This creates a cdnsync.config.json file with default settings. You can customize providers, TTL policies, and sync behavior.

Step 3: Connect Your First CDN Provider

CDNsync supports 8 major CDN providers. Add your first connection using interactive setup or direct configuration.

Terminal
# Interactive provider setup
cdnsync providers add

# Or configure directly in cdnsync.config.json

Provide your provider's API credentials. CDNsync encrypts and stores them securely in ~/.cdnsync/secrets.

Step 4: Push Your First Asset

Create a file and synchronize it across all connected providers in one command.

Terminal
# Create a sample file
echo '<h1>Hello CDN</h1>' > index.html

# Push to all configured providers
cdnsync push index.html --ttl 3600 --tags web,production

# Check sync status
cdnsync status

Next Steps

Core Concepts

CDNsync introduces several core abstractions that enable multi-cloud synchronization. Understanding these concepts is essential for effective CDN management.

Sync Policies

A sync policy defines how and when content is synchronized across your CDN providers. Each policy specifies TTL (time-to-live), caching behavior, and target providers.

Policies are defined in cdnsync.config.json under the policies section. You can have multiple policies targeting different provider subsets:

"policies": [
  {
    "name": "production",
    "ttl": 3600,
    "providers": ["cloudflare", "fastly", "akamai"],
    "cache_key": "${path}?v=${version}",
    "max_age": 31536000,
    "surrogate_keys": ["assets", "web"]
  }
]

Providers

A provider is a connected CDN service. CDNsync manages authentication, routing, and synchronization for each provider independently. Supported providers include:

  • Cloudflare
  • Fastly
  • Akamai (Linode)
  • AWS CloudFront
  • BunnyCDN
  • StackPath
  • Microsoft Azure CDN
  • Google Cloud CDN

Each provider is authenticated separately and manages its own rate limits, purge queues, and monitoring.

Assets

An asset is any file you push to CDNsync. Assets can be HTML, CSS, JavaScript, images, videos, or any other content type. Each asset has metadata including:

  • Asset ID: Unique identifier (hash of path + content)
  • Path: Remote path where the asset is served
  • Content-Type: MIME type (auto-detected or specified)
  • TTL: Cache lifetime in seconds
  • Tags: Custom labels for organizing and purging assets
  • Surrogate Keys: Keys for intelligent cache invalidation

Asset Tags

Tags are arbitrary labels you assign to assets to enable bulk operations. For example, tag all homepage assets as homepage, then purge only those when updates are needed.

cdnsync push homepage.html --tags homepage,production
cdnsync push styles.css --tags homepage,assets,production
cdnsync purge --tags homepage

Surrogate Keys

Surrogate Keys enable intelligent cache invalidation based on content relationships. Instead of purging by path, purge by semantic relationship.

cdnsync push article.html --surrogate-keys article,news,2024
cdnsync purge --surrogate-keys article # Purge all articles
cdnsync purge --surrogate-keys news # Purge news section

TTL Hierarchy

CDNsync respects TTL at multiple levels, resolved in this order:

  1. Asset-level TTL (specified during push)
  2. Policy TTL (default for matching policy)
  3. Global default TTL (3600 seconds)

This allows fine-grained control: set a global default of 1 hour, override to 5 minutes for dynamic content, and use API-specified values for one-off assets.

Sync States

Each asset tracked by CDNsync has a sync state across providers:

  • pending: Queued for synchronization
  • syncing: Currently uploading to provider
  • synced: Successfully replicated
  • error: Sync failed (check logs)
  • stale: Newer version available on primary, behind on this provider

CLI Commands

The CDNsync CLI is your primary interface for managing assets and providers. All commands support both interactive and scripted workflows.

cdnsync push

Upload a file or directory to CDN providers.

cdnsync push <file|directory> [options]

Options:
  --policy <name>           Apply a specific sync policy (default: "default")
  --ttl <seconds>           Override policy TTL
  --tags <tag1,tag2>        Comma-separated tags for bulk operations
  --surrogate-keys <keys>   Comma-separated surrogate keys
  --no-verify               Skip provider availability check
  --parallel <n>            Max concurrent provider uploads (default: 4)
  --dry-run                 Show what would be synced without executing

Examples:
cdnsync push src/
cdnsync push assets/logo.svg --ttl 86400 --tags assets,branding
cdnsync push --dry-run

cdnsync purge

Remove content from provider caches.

cdnsync purge [options]

Options:
  --path <path>             Purge specific path
  --tags <tag1,tag2>        Purge assets with specific tags
  --surrogate-keys <keys>   Purge by surrogate key
  --all                     Purge all assets (requires confirmation)
  --force                   Skip confirmation prompt

Examples:
cdnsync purge --path /old-page.html
cdnsync purge --tags homepage --force
cdnsync purge --surrogate-keys v1.0 --surrogate-keys deprecated

cdnsync status

Check synchronization status across all providers.

cdnsync status [options]

Options:
  --asset <id>              Show status for specific asset
  --provider <name>         Filter by provider
  --tags <tag1,tag2>        Filter by asset tags
  --verbose                 Show detailed sync logs
  --json                    Output JSON format

Examples:
cdnsync status
cdnsync status --tags production --verbose
cdnsync status --provider cloudflare --json

cdnsync rollback

Revert to a previous version of an asset.

cdnsync rollback <asset-id> [version] [options]

Options:
  --to <version>            Rollback to specific version (default: previous)
  --all-providers           Rollback across all providers (default: current)
  --confirm                 Skip confirmation

Examples:
cdnsync rollback /index.html
cdnsync rollback /api.js --to 3
cdnsync rollback /config.json --all-providers

cdnsync providers

Manage CDN provider connections.

cdnsync providers list           List all configured providers
cdnsync providers add            Add new provider (interactive)
cdnsync providers remove <name> Remove provider
cdnsync providers test           Test all provider connections
cdnsync providers config <name> Show provider configuration

cdnsync policies

Manage synchronization policies.

cdnsync policies list            List all policies
cdnsync policies create <name>  Create new policy (interactive)
cdnsync policies edit <name>    Edit existing policy
cdnsync policies delete <name>  Delete policy
cdnsync policies sync            Validate all policies

cdnsync init

Initialize a new CDNsync project.

cdnsync init [options]

Options:
  --template <type>        Use template (basic, nextjs, vue, static)
  --providers <list>       Pre-configure providers
  --no-interactive          Use all defaults

Examples:
cdnsync init
cdnsync init --template nextjs --providers cloudflare,fastly

cdnsync config

Manage CDNsync configuration.

cdnsync config get <key>         Get config value
cdnsync config set <key> <val>  Set config value
cdnsync config show               Show entire config
cdnsync config validate           Validate config syntax

REST API

The CDNsync REST API enables programmatic access to all synchronization operations. All API endpoints require authentication via bearer token.

Authentication

Include your API token in the Authorization header:

Authorization: Bearer sk_live_abc123def456...

Generate API tokens in the CDNsync dashboard under Settings → Tokens. Tokens are environment-specific (development, staging, production).

Base URL

https://api.cdnsync.io/v1

Rate Limiting

API requests are rate-limited to 1000 requests per minute per token. Rate limit headers indicate your current status:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1641234567

Endpoints

POST /api/v1/sync

Synchronize an asset to connected providers.

POST/api/v1/sync
Parameter Type Description
path string (required) Remote path for the asset (e.g., "/assets/logo.svg")
content string or base64 File content (provide content OR url, not both)
url string URL to fetch content from
ttl integer Cache lifetime in seconds (default: 3600)
tags array Asset tags: ["production", "assets"]
surrogate_keys array Surrogate keys for purging
policy string Policy name to apply
providers array Target providers (default: all)

Request:

curl -X POST https://api.cdnsync.io/v1/sync \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "path": "/assets/image.png",
    "url": "https://source.example.com/image.png",
    "ttl": 86400,
    "tags": ["production", "images"],
    "surrogate_keys": ["assets", "v2.1"]
  }'

Response:

{
  "id": "asset_1a2b3c4d5e6f",
  "path": "/assets/image.png",
  "status": "syncing",
  "size_bytes": 45231,
  "content_type": "image/png",
  "created_at": "2026-05-05T14:23:15Z",
  "ttl": 86400,
  "providers": [
    {
      "name": "cloudflare",
      "status": "synced",
      "synced_at": "2026-05-05T14:23:18Z"
    },
    {
      "name": "fastly",
      "status": "syncing",
      "synced_at": null
    },
    {
      "name": "akamai",
      "status": "pending",
      "synced_at": null
    }
  ]
}

POST /api/v1/purge

Purge content from provider caches.

POST/api/v1/purge
Parameter Type Description
paths array Paths to purge (provide paths OR tags OR surrogate_keys)
tags array Purge assets with these tags
surrogate_keys array Purge by surrogate key
providers array Target providers (default: all)

Request:

curl -X POST https://api.cdnsync.io/v1/purge \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "surrogate_keys": ["homepage"],
    "providers": ["cloudflare", "fastly"]
  }'

Response:

{
  "id": "purge_9x8y7z6w5v4u",
  "status": "processing",
  "created_at": "2026-05-05T14:25:02Z",
  "purge_count": 12,
  "providers": {
    "cloudflare": "completed",
    "fastly": "in_progress",
    "akamai": "queued"
  }
}

GET /api/v1/providers

List all configured providers.

GET/api/v1/providers

Response:

{
  "providers": [
    {
      "id": "prov_cloudflare_1",
      "name": "cloudflare",
      "type": "cloudflare",
      "status": "connected",
      "last_sync": "2026-05-05T14:20:00Z",
      "asset_count": 245,
      "rate_limit": {
        "limit": 1200,
        "remaining": 1100,
        "reset_at": "2026-05-05T15:00:00Z"
      }
    },
    {
      "id": "prov_fastly_1",
      "name": "fastly",
      "type": "fastly",
      "status": "connected",
      "last_sync": "2026-05-05T14:22:00Z",
      "asset_count": 245
    }
  ]
}

GET /api/v1/assets/:id

Get details about a specific asset.

GET/api/v1/assets/:id

Response:

{
  "id": "asset_1a2b3c4d5e6f",
  "path": "/assets/image.png",
  "size_bytes": 45231,
  "content_type": "image/png",
  "ttl": 86400,
  "tags": ["production", "images"],
  "surrogate_keys": ["assets", "v2.1"],
  "created_at": "2026-05-01T10:00:00Z",
  "updated_at": "2026-05-05T14:23:15Z",
  "versions": 3,
  "current_version": 3,
  "providers": {
    "cloudflare": {
      "status": "synced",
      "synced_at": "2026-05-05T14:23:18Z",
      "url": "https://cdn.example.com/assets/image.png"
    },
    "fastly": {
      "status": "synced",
      "synced_at": "2026-05-05T14:23:22Z"
    },
    "akamai": {
      "status": "synced",
      "synced_at": "2026-05-05T14:23:25Z"
    }
  }
}

DELETE /api/v1/assets/:id

Delete an asset from all providers.

DELETE/api/v1/assets/:id

Response (204 No Content):

GET /api/v1/status

Get synchronization status summary.

GET/api/v1/status

Response:

{
  "overall_status": "healthy",
  "uptime_percent": 99.99,
  "total_assets": 1247,
  "sync_queue_depth": 3,
  "providers": {
    "cloudflare": "operational",
    "fastly": "operational",
    "akamai": "operational",
    "cloudfront": "operational",
    "bunnycdn": "operational",
    "stackpath": "operational",
    "azure_cdn": "operational",
    "gcp_cdn": "operational"
  },
  "last_sync": "2026-05-05T14:30:00Z"
}

Supported CDN Providers

CDNsync integrates with 8 major CDN providers. Each has its own authentication method, purge strategy, and rate limits. Configuration is provider-specific but follows the same pattern.

Cloudflare

Fast, reliable global CDN with intelligent caching. Perfect for web applications.

Required credentials:

  • API Token (Zone-scoped, read/write)
  • Zone ID

Configuration:

{
  "name": "cloudflare",
  "type": "cloudflare",
  "api_token": "v1.abc123def456...",
  "zone_id": "a1b2c3d4e5f6g7h8"
}

Fastly

High-performance edge computing platform with instant purging. Ideal for dynamic content.

Required credentials:

  • API Token
  • Service ID

Configuration:

{
  "name": "fastly",
  "type": "fastly",
  "api_token": "abcdef123456...",
  "service_id": "xyz123abc456"
}

Akamai

Enterprise-grade CDN with advanced security. Used by major corporations.

Required credentials:

  • Client Token
  • Client Secret
  • Access Token
  • Host

Configuration:

{
  "name": "akamai",
  "type": "akamai",
  "client_token": "akaa-abc123...",
  "client_secret": "secret123...",
  "access_token": "akaa-access-...",
  "host": "akaa-baseurl-xxxxx.luna.akamaiapis.net"
}

AWS CloudFront

Scalable CDN integrated with AWS ecosystem. Great for AWS-native applications.

Required credentials:

  • AWS Access Key ID
  • AWS Secret Access Key
  • Distribution ID

Configuration:

{
  "name": "cloudfront",
  "type": "aws_cloudfront",
  "aws_access_key_id": "AKIAIOSFODNN7EXAMPLE",
  "aws_secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "distribution_id": "E1234ABCD"
}

BunnyCDN

Affordable CDN with excellent value. Perfect for startups and indie projects.

Required credentials:

  • API Key
  • Pull Zone ID

Configuration:

{
  "name": "bunnycdn",
  "type": "bunnycdn",
  "api_key": "123456-abcdef-789...",
  "pull_zone_id": "12345"
}

StackPath

Edge computing platform with flexible pricing. Good for media and streaming.

Required credentials:

  • Client ID
  • Client Secret
  • Stack ID

Configuration:

{
  "name": "stackpath",
  "type": "stackpath",
  "client_id": "client_123...",
  "client_secret": "secret_abc...",
  "stack_id": "stack_xyz123"
}

Microsoft Azure CDN

Enterprise CDN integrated with Azure cloud. Excellent for Azure-native workloads.

Required credentials:

  • Subscription ID
  • Resource Group Name
  • Profile Name
  • Endpoint Name

Configuration:

{
  "name": "azure_cdn",
  "type": "azure_cdn",
  "subscription_id": "12a34b5c-6d7e-8f9a-b0c1-d2e3f4a5b6c7",
  "resource_group": "my-resource-group",
  "profile_name": "my-profile",
  "endpoint_name": "my-endpoint"
}

Google Cloud CDN

Integrated with Google Cloud Platform. Great for GCP deployments.

Required credentials:

  • Service Account JSON Key
  • Project ID
  • Backend Service Name

Configuration:

{
  "name": "gcp_cdn",
  "type": "gcp_cdn",
  "service_account_key": { /* JSON key content */ },
  "project_id": "my-project-123",
  "backend_service_name": "my-backend-service"
}

Webhooks

Webhooks enable real-time notifications of CDNsync events. Configure webhook endpoints in the dashboard to receive HTTP POST callbacks on sync completion, purging, provider status changes, and errors.

Setting Up Webhooks

In the CDNsync dashboard, navigate to Settings → Webhooks. Create an endpoint with:

  • URL: Your HTTPS endpoint
  • Events: Which events trigger the webhook
  • Auth: HMAC signing secret

Webhook Events

sync.completed

Fired when an asset has been successfully synchronized to all target providers.

{
  "event": "sync.completed",
  "timestamp": "2026-05-05T14:30:45Z",
  "data": {
    "asset_id": "asset_1a2b3c4d5e6f",
    "path": "/assets/bundle.js",
    "size_bytes": 125480,
    "providers_synced": ["cloudflare", "fastly", "akamai"],
    "duration_ms": 2847,
    "tags": ["production", "assets"]
  }
}

purge.completed

Fired when a purge operation has completed on all target providers.

{
  "event": "purge.completed",
  "timestamp": "2026-05-05T14:32:10Z",
  "data": {
    "purge_id": "purge_9x8y7z6w5v4u",
    "method": "tags",
    "tags": ["homepage"],
    "assets_purged": 12,
    "providers_purged": ["cloudflare", "fastly"],
    "duration_ms": 1243
  }
}

provider.disconnected

Fired when a provider connection fails or is manually disconnected.

{
  "event": "provider.disconnected",
  "timestamp": "2026-05-05T14:35:22Z",
  "data": {
    "provider_id": "prov_fastly_1",
    "provider_name": "fastly",
    "reason": "authentication_failed",
    "error_message": "Invalid API token",
    "action_required": "Please update credentials in dashboard"
  }
}

HMAC Signature Verification

All webhooks are signed using HMAC-SHA256. Verify the signature in the X-CDNsync-Signature header:

// Node.js example
const crypto = require('crypto');
const webhook_secret = 'whsec_abc123...';

app.post('/webhooks/cdnsync', (req, res) => {
  const signature = req.headers['x-cdnsync-signature'];
  const timestamp = req.headers['x-cdnsync-timestamp'];
  const body = JSON.stringify(req.body);

  const expected = crypto
    .createHmac('sha256', webhook_secret)
    .update(timestamp + '.' + body)
    .digest('hex');

  if (signature !== expected) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Process webhook
  console.log('Valid webhook:', req.body);
  res.json({ ok: true });
});

Security & Compliance

CDNsync implements enterprise-grade security practices to protect your assets and credentials.

API Token Management

API tokens grant access to your CDNsync account. Handle them with care:

  • Never commit tokens to version control
  • Use environment variables or secrets management systems
  • Rotate tokens regularly (quarterly minimum)
  • Revoke compromised tokens immediately
  • Use the smallest scope needed (environment-specific tokens)

Rotate a token by generating a new one and updating your configuration, then revoke the old token.

IP Allowlisting

Restrict API access to specific IP addresses. Configure in Settings → Security:

# Allow requests from office and CI/CD
203.0.113.0/24
198.51.100.42
192.0.2.0/24

Requests from other IPs will be rejected with 403 Forbidden.

Signed URLs

Generate time-limited, signed URLs for sharing assets without exposing API tokens:

cdnsync sign-url /assets/report.pdf --expires 3600 --allow-ips 203.0.113.0/24

# Output:
https://cdn.example.com/assets/report.pdf?sig=abc123...&exp=1651234567&ip=203.0.113.0

Encryption at Rest

All credentials and sensitive data are encrypted using AES-256-GCM before storage. Master keys are managed by AWS KMS.

Encryption in Transit

All API communications use TLS 1.2+. Webhook endpoints must be HTTPS. Peer certificates are verified.

Data Retention & GDPR Compliance

CDNsync respects data privacy regulations:

  • Access logs: Retained 90 days
  • Purge history: Retained 1 year
  • User data: Deleted within 30 days of account deletion

Request data export or deletion via the Privacy section in Settings.

Audit Logging

All API operations are logged with timestamp, user/token, action, resource, and result. Access audit logs in the dashboard under Compliance → Audit Log.

Troubleshooting

Sync Failures

Problem: Assets not syncing to all providers.

Diagnosis:

cdnsync status --verbose

Common causes:

  • Provider authentication failed: Verify API tokens/credentials are current
  • Rate limit exceeded: Wait 1 minute before retrying
  • Invalid asset path: Paths must start with / and contain no special characters
  • File too large: Some providers have size limits (check provider docs)

Solution: Run cdnsync providers test to verify all connections are working.

Purge Not Taking Effect

Problem: Old content still being served after purge.

Diagnosis:

cdnsync purge --path /old-file.html --verbose

Causes:

  • Browser cache: Clear browser cache (Ctrl+Shift+Delete)
  • ISP cache: Wait 5-10 minutes for ISP caches to expire
  • Wrong purge target: Ensure you're purging the correct path or tag
  • Provider delay: Some providers take 30-60 seconds to process purges

CLI Authentication Errors

Problem: "Unauthorized" or "Invalid token" when running CLI commands.

Solution:

# Log in again
cdnsync login

# Or set token via environment
export CDNSYNC_TOKEN=sk_live_abc123...
cdnsync status

Rate Limiting

Problem: Hitting 429 Too Many Requests errors.

Solution: Reduce request rate or use parallel limits:

cdnsync push assets/ --parallel 2 # Reduce concurrency
cdnsync push assets/ --delay 500 # Add delay between requests

Provider Configuration Issues

Problem: Provider validation fails during setup.

Common issues:

  • Cloudflare: Ensure token has Zone.Zone.Read and Zone.Cache.Purge scopes
  • Fastly: Service ID must be visible in service URL (dashboard → Services)
  • Akamai: Ensure credentials have PAPI access enabled
  • CloudFront: Distribution must allow S3 origins or custom origins

Test each provider individually:

cdnsync providers test --name cloudflare