Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Cloudflare platform skill covering Workers, D1, R2, KV, AI, Durable Objects, and security.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/workers-for-platforms/api.md
1# API Operations23## Deploy User Worker45```bash6curl -X PUT \7"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/dispatch/namespaces/$NAMESPACE/scripts/$SCRIPT_NAME" \8-H "Authorization: Bearer $API_TOKEN" \9-F 'metadata={"main_module": "worker.mjs"};type=application/json' \10-F '[email protected];type=application/javascript+module'11```1213### TypeScript SDK14```typescript15import Cloudflare from "cloudflare";1617const client = new Cloudflare({ apiToken: process.env.API_TOKEN });1819const scriptFile = new File([scriptContent], `${scriptName}.mjs`, {20type: "application/javascript+module",21});2223await client.workersForPlatforms.dispatch.namespaces.scripts.update(24namespace, scriptName,25{26account_id: accountId,27metadata: { main_module: `${scriptName}.mjs` },28files: [scriptFile],29}30);31```3233## TypeScript Types3435```typescript36import type { DispatchNamespace } from '@cloudflare/workers-types';3738interface DispatchNamespace {39get(name: string, options?: Record<string, unknown>, dispatchOptions?: DynamicDispatchOptions): Fetcher;40}4142interface DynamicDispatchOptions {43limits?: DynamicDispatchLimits;44outbound?: Record<string, unknown>;45}4647interface DynamicDispatchLimits {48cpuMs?: number; // Max CPU milliseconds49subRequests?: number; // Max fetch() calls50}5152// Usage53const userWorker = env.DISPATCHER.get('customer-123', {}, {54limits: { cpuMs: 50, subRequests: 20 },55outbound: { customerId: '123', url: request.url }56});57```5859## Deploy with Bindings60```bash61curl -X PUT ".../scripts/$SCRIPT_NAME" \62-F 'metadata={63"main_module": "worker.mjs",64"bindings": [65{"type": "kv_namespace", "name": "MY_KV", "namespace_id": "'$KV_ID'"}66],67"tags": ["customer-123", "production"],68"compatibility_date": "2026-01-01" // Use current date for new projects69};type=application/json' \70-F '[email protected];type=application/javascript+module'71```7273## List/Delete Workers7475```bash76# List77curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/dispatch/namespaces/$NAMESPACE/scripts" \78-H "Authorization: Bearer $API_TOKEN"7980# Delete by name81curl -X DELETE ".../scripts/$SCRIPT_NAME" -H "Authorization: Bearer $API_TOKEN"8283# Delete by tag84curl -X DELETE ".../scripts?tags=customer-123%3Ayes" -H "Authorization: Bearer $API_TOKEN"85```8687**Pagination:** SDK supports async iteration. Manual: add `?per_page=100&page=1` query params.8889## Static Assets9091**3-step process:** Create session → Upload files → Deploy Worker9293### 1. Create Upload Session94```bash95curl -X POST ".../scripts/$SCRIPT_NAME/assets-upload-session" \96-H "Authorization: Bearer $API_TOKEN" \97-d '{98"manifest": {99"/index.html": {"hash": "08f1dfda4574284ab3c21666d1ee8c7d4", "size": 1234}100}101}'102# Returns: jwt, buckets103```104105**Hash:** SHA-256 truncated to first 16 bytes (32 hex characters)106107### 2. Upload Files108```bash109curl -X POST ".../workers/assets/upload?base64=true" \110-H "Authorization: Bearer $UPLOAD_JWT" \111-F '08f1dfda4574284ab3c21666d1ee8c7d4=<BASE64_CONTENT>'112# Returns: completion jwt113```114115**Multiple buckets:** Upload to all returned bucket URLs (typically 2 for redundancy) using same JWT and hash.116117### 3. Deploy with Assets118```bash119curl -X PUT ".../scripts/$SCRIPT_NAME" \120-F 'metadata={121"main_module": "index.js",122"assets": {"jwt": "<COMPLETION_TOKEN>"},123"bindings": [{"type": "assets", "name": "ASSETS"}]124};type=application/json' \125-F 'index.js=export default {...};type=application/javascript+module'126```127128**Asset Isolation:** Assets shared across namespace by default. For customer isolation, salt hash: `sha256(customerId + fileContents).slice(0, 32)`129130## Dispatch Workers131132### Subdomain Routing133```typescript134export default {135async fetch(request: Request, env: Env): Promise<Response> {136const userWorkerName = new URL(request.url).hostname.split(".")[0];137const userWorker = env.DISPATCHER.get(userWorkerName);138return await userWorker.fetch(request);139},140};141```142143### Path Routing144```typescript145const pathParts = new URL(request.url).pathname.split("/").filter(Boolean);146const userWorker = env.DISPATCHER.get(pathParts[0]);147return await userWorker.fetch(request);148```149150### KV Routing151```typescript152const hostname = new URL(request.url).hostname;153const userWorkerName = await env.ROUTING_KV.get(hostname);154const userWorker = env.DISPATCHER.get(userWorkerName);155return await userWorker.fetch(request);156```157158## Outbound Workers159160Control external fetch from user Workers:161162### Configure163```typescript164const userWorker = env.DISPATCHER.get(165workerName, {},166{ outbound: { customer_context: { customer_name: workerName, url: request.url } } }167);168```169170### Implement171```typescript172export default {173async fetch(request: Request, env: Env): Promise<Response> {174const customerName = env.customer_name;175const url = new URL(request.url);176177// Block domains178if (["malicious.com"].some(d => url.hostname.includes(d))) {179return new Response("Blocked", { status: 403 });180}181182// Inject auth183if (url.hostname === "api.example.com") {184const headers = new Headers(request.headers);185headers.set("Authorization", `Bearer ${generateJWT(customerName)}`);186return fetch(new Request(request, { headers }));187}188189return fetch(request);190},191};192```193194**Note:** Doesn't intercept DO/mTLS fetch.195196See [README.md](./README.md), [configuration.md](./configuration.md), [patterns.md](./patterns.md), [gotchas.md](./gotchas.md)197