pi-cloudflare 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +67 -0
- package/bin/setup.mjs +103 -0
- package/dist/auth-flow.d.ts +15 -0
- package/dist/auth-flow.d.ts.map +1 -0
- package/dist/auth-flow.js +90 -0
- package/dist/auth-flow.js.map +1 -0
- package/dist/client.d.ts +18 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +47 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +10 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +109 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth.d.ts +44 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +135 -0
- package/dist/oauth.js.map +1 -0
- package/dist/proxy.d.ts +29 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +39 -0
- package/dist/proxy.js.map +1 -0
- package/dist/servers.d.ts +19 -0
- package/dist/servers.d.ts.map +1 -0
- package/dist/servers.js +40 -0
- package/dist/servers.js.map +1 -0
- package/dist/token-store.d.ts +23 -0
- package/dist/token-store.d.ts.map +1 -0
- package/dist/token-store.js +47 -0
- package/dist/token-store.js.map +1 -0
- package/package.json +67 -0
- package/skills/agents-sdk/SKILL.md +221 -0
- package/skills/agents-sdk/references/browse-the-web.md +63 -0
- package/skills/agents-sdk/references/callable.md +92 -0
- package/skills/agents-sdk/references/client-sdk.md +110 -0
- package/skills/agents-sdk/references/codemode.md +110 -0
- package/skills/agents-sdk/references/configuration.md +72 -0
- package/skills/agents-sdk/references/durable-execution.md +51 -0
- package/skills/agents-sdk/references/email.md +146 -0
- package/skills/agents-sdk/references/human-in-the-loop.md +67 -0
- package/skills/agents-sdk/references/mcp.md +188 -0
- package/skills/agents-sdk/references/observability.md +44 -0
- package/skills/agents-sdk/references/queue-retries.md +79 -0
- package/skills/agents-sdk/references/routing.md +75 -0
- package/skills/agents-sdk/references/server-driven-messages.md +63 -0
- package/skills/agents-sdk/references/state-scheduling.md +171 -0
- package/skills/agents-sdk/references/streaming-chat.md +198 -0
- package/skills/agents-sdk/references/think.md +112 -0
- package/skills/agents-sdk/references/voice.md +68 -0
- package/skills/agents-sdk/references/webhooks-push.md +86 -0
- package/skills/agents-sdk/references/workflows.md +132 -0
- package/skills/cloudflare/SKILL.md +248 -0
- package/skills/cloudflare/references/agents-sdk/README.md +89 -0
- package/skills/cloudflare/references/agents-sdk/api.md +190 -0
- package/skills/cloudflare/references/agents-sdk/configuration.md +182 -0
- package/skills/cloudflare/references/agents-sdk/gotchas.md +158 -0
- package/skills/cloudflare/references/agents-sdk/patterns.md +192 -0
- package/skills/cloudflare/references/ai-gateway/README.md +175 -0
- package/skills/cloudflare/references/ai-gateway/configuration.md +111 -0
- package/skills/cloudflare/references/ai-gateway/dynamic-routing.md +82 -0
- package/skills/cloudflare/references/ai-gateway/features.md +96 -0
- package/skills/cloudflare/references/ai-gateway/sdk-integration.md +114 -0
- package/skills/cloudflare/references/ai-gateway/troubleshooting.md +88 -0
- package/skills/cloudflare/references/ai-search/README.md +138 -0
- package/skills/cloudflare/references/ai-search/api.md +87 -0
- package/skills/cloudflare/references/ai-search/configuration.md +88 -0
- package/skills/cloudflare/references/ai-search/gotchas.md +81 -0
- package/skills/cloudflare/references/ai-search/patterns.md +85 -0
- package/skills/cloudflare/references/analytics-engine/README.md +94 -0
- package/skills/cloudflare/references/analytics-engine/api.md +112 -0
- package/skills/cloudflare/references/analytics-engine/configuration.md +112 -0
- package/skills/cloudflare/references/analytics-engine/gotchas.md +85 -0
- package/skills/cloudflare/references/analytics-engine/patterns.md +83 -0
- package/skills/cloudflare/references/api/README.md +66 -0
- package/skills/cloudflare/references/api/api.md +204 -0
- package/skills/cloudflare/references/api/configuration.md +160 -0
- package/skills/cloudflare/references/api/gotchas.md +225 -0
- package/skills/cloudflare/references/api/patterns.md +204 -0
- package/skills/cloudflare/references/api-shield/README.md +44 -0
- package/skills/cloudflare/references/api-shield/api.md +141 -0
- package/skills/cloudflare/references/api-shield/configuration.md +192 -0
- package/skills/cloudflare/references/api-shield/gotchas.md +125 -0
- package/skills/cloudflare/references/api-shield/patterns.md +180 -0
- package/skills/cloudflare/references/argo-smart-routing/README.md +90 -0
- package/skills/cloudflare/references/argo-smart-routing/api.md +240 -0
- package/skills/cloudflare/references/argo-smart-routing/configuration.md +197 -0
- package/skills/cloudflare/references/argo-smart-routing/gotchas.md +111 -0
- package/skills/cloudflare/references/argo-smart-routing/patterns.md +104 -0
- package/skills/cloudflare/references/artifacts/README.md +79 -0
- package/skills/cloudflare/references/artifacts/api.md +128 -0
- package/skills/cloudflare/references/artifacts/configuration.md +92 -0
- package/skills/cloudflare/references/bindings/README.md +122 -0
- package/skills/cloudflare/references/bindings/api.md +203 -0
- package/skills/cloudflare/references/bindings/configuration.md +188 -0
- package/skills/cloudflare/references/bindings/gotchas.md +208 -0
- package/skills/cloudflare/references/bindings/patterns.md +200 -0
- package/skills/cloudflare/references/bot-management/README.md +94 -0
- package/skills/cloudflare/references/bot-management/api.md +169 -0
- package/skills/cloudflare/references/bot-management/configuration.md +163 -0
- package/skills/cloudflare/references/bot-management/gotchas.md +114 -0
- package/skills/cloudflare/references/bot-management/patterns.md +182 -0
- package/skills/cloudflare/references/browser-rendering/README.md +78 -0
- package/skills/cloudflare/references/browser-rendering/api.md +108 -0
- package/skills/cloudflare/references/browser-rendering/configuration.md +78 -0
- package/skills/cloudflare/references/browser-rendering/gotchas.md +88 -0
- package/skills/cloudflare/references/browser-rendering/patterns.md +91 -0
- package/skills/cloudflare/references/c3/README.md +111 -0
- package/skills/cloudflare/references/c3/api.md +71 -0
- package/skills/cloudflare/references/c3/configuration.md +81 -0
- package/skills/cloudflare/references/c3/gotchas.md +92 -0
- package/skills/cloudflare/references/c3/patterns.md +82 -0
- package/skills/cloudflare/references/cache-reserve/README.md +147 -0
- package/skills/cloudflare/references/cache-reserve/api.md +194 -0
- package/skills/cloudflare/references/cache-reserve/configuration.md +169 -0
- package/skills/cloudflare/references/cache-reserve/gotchas.md +132 -0
- package/skills/cloudflare/references/cache-reserve/patterns.md +197 -0
- package/skills/cloudflare/references/containers/README.md +85 -0
- package/skills/cloudflare/references/containers/api.md +187 -0
- package/skills/cloudflare/references/containers/configuration.md +188 -0
- package/skills/cloudflare/references/containers/gotchas.md +178 -0
- package/skills/cloudflare/references/containers/patterns.md +202 -0
- package/skills/cloudflare/references/cron-triggers/README.md +99 -0
- package/skills/cloudflare/references/cron-triggers/api.md +196 -0
- package/skills/cloudflare/references/cron-triggers/configuration.md +180 -0
- package/skills/cloudflare/references/cron-triggers/gotchas.md +199 -0
- package/skills/cloudflare/references/cron-triggers/patterns.md +190 -0
- package/skills/cloudflare/references/d1/README.md +133 -0
- package/skills/cloudflare/references/d1/api.md +196 -0
- package/skills/cloudflare/references/d1/configuration.md +191 -0
- package/skills/cloudflare/references/d1/gotchas.md +98 -0
- package/skills/cloudflare/references/d1/patterns.md +189 -0
- package/skills/cloudflare/references/ddos/README.md +41 -0
- package/skills/cloudflare/references/ddos/api.md +164 -0
- package/skills/cloudflare/references/ddos/configuration.md +93 -0
- package/skills/cloudflare/references/ddos/gotchas.md +107 -0
- package/skills/cloudflare/references/ddos/patterns.md +174 -0
- package/skills/cloudflare/references/do-storage/README.md +75 -0
- package/skills/cloudflare/references/do-storage/api.md +102 -0
- package/skills/cloudflare/references/do-storage/configuration.md +112 -0
- package/skills/cloudflare/references/do-storage/gotchas.md +150 -0
- package/skills/cloudflare/references/do-storage/patterns.md +194 -0
- package/skills/cloudflare/references/do-storage/testing.md +183 -0
- package/skills/cloudflare/references/durable-objects/README.md +185 -0
- package/skills/cloudflare/references/durable-objects/api.md +187 -0
- package/skills/cloudflare/references/durable-objects/configuration.md +160 -0
- package/skills/cloudflare/references/durable-objects/gotchas.md +197 -0
- package/skills/cloudflare/references/durable-objects/patterns.md +201 -0
- package/skills/cloudflare/references/email-routing/README.md +89 -0
- package/skills/cloudflare/references/email-routing/api.md +195 -0
- package/skills/cloudflare/references/email-routing/configuration.md +186 -0
- package/skills/cloudflare/references/email-routing/gotchas.md +196 -0
- package/skills/cloudflare/references/email-routing/patterns.md +229 -0
- package/skills/cloudflare/references/email-workers/README.md +151 -0
- package/skills/cloudflare/references/email-workers/api.md +237 -0
- package/skills/cloudflare/references/email-workers/configuration.md +112 -0
- package/skills/cloudflare/references/email-workers/gotchas.md +125 -0
- package/skills/cloudflare/references/email-workers/patterns.md +102 -0
- package/skills/cloudflare/references/flagship/README.md +59 -0
- package/skills/cloudflare/references/flagship/api.md +390 -0
- package/skills/cloudflare/references/flagship/configuration.md +202 -0
- package/skills/cloudflare/references/flagship/gotchas.md +178 -0
- package/skills/cloudflare/references/flagship/patterns.md +469 -0
- package/skills/cloudflare/references/graphql-api/README.md +147 -0
- package/skills/cloudflare/references/graphql-api/api.md +175 -0
- package/skills/cloudflare/references/graphql-api/configuration.md +118 -0
- package/skills/cloudflare/references/graphql-api/gotchas.md +110 -0
- package/skills/cloudflare/references/graphql-api/patterns.md +225 -0
- package/skills/cloudflare/references/hyperdrive/README.md +82 -0
- package/skills/cloudflare/references/hyperdrive/api.md +143 -0
- package/skills/cloudflare/references/hyperdrive/configuration.md +159 -0
- package/skills/cloudflare/references/hyperdrive/gotchas.md +77 -0
- package/skills/cloudflare/references/hyperdrive/patterns.md +190 -0
- package/skills/cloudflare/references/images/README.md +61 -0
- package/skills/cloudflare/references/images/api.md +96 -0
- package/skills/cloudflare/references/images/configuration.md +211 -0
- package/skills/cloudflare/references/images/gotchas.md +99 -0
- package/skills/cloudflare/references/images/patterns.md +115 -0
- package/skills/cloudflare/references/kv/README.md +89 -0
- package/skills/cloudflare/references/kv/api.md +160 -0
- package/skills/cloudflare/references/kv/configuration.md +144 -0
- package/skills/cloudflare/references/kv/gotchas.md +131 -0
- package/skills/cloudflare/references/kv/patterns.md +196 -0
- package/skills/cloudflare/references/miniflare/README.md +105 -0
- package/skills/cloudflare/references/miniflare/api.md +187 -0
- package/skills/cloudflare/references/miniflare/configuration.md +173 -0
- package/skills/cloudflare/references/miniflare/gotchas.md +160 -0
- package/skills/cloudflare/references/miniflare/patterns.md +181 -0
- package/skills/cloudflare/references/network-interconnect/README.md +99 -0
- package/skills/cloudflare/references/network-interconnect/api.md +199 -0
- package/skills/cloudflare/references/network-interconnect/configuration.md +114 -0
- package/skills/cloudflare/references/network-interconnect/gotchas.md +165 -0
- package/skills/cloudflare/references/network-interconnect/patterns.md +166 -0
- package/skills/cloudflare/references/observability/README.md +88 -0
- package/skills/cloudflare/references/observability/api.md +164 -0
- package/skills/cloudflare/references/observability/configuration.md +169 -0
- package/skills/cloudflare/references/observability/gotchas.md +115 -0
- package/skills/cloudflare/references/observability/patterns.md +105 -0
- package/skills/cloudflare/references/pages/README.md +88 -0
- package/skills/cloudflare/references/pages/api.md +204 -0
- package/skills/cloudflare/references/pages/configuration.md +201 -0
- package/skills/cloudflare/references/pages/gotchas.md +203 -0
- package/skills/cloudflare/references/pages/patterns.md +204 -0
- package/skills/cloudflare/references/pages-functions/README.md +98 -0
- package/skills/cloudflare/references/pages-functions/api.md +143 -0
- package/skills/cloudflare/references/pages-functions/configuration.md +122 -0
- package/skills/cloudflare/references/pages-functions/gotchas.md +94 -0
- package/skills/cloudflare/references/pages-functions/patterns.md +137 -0
- package/skills/cloudflare/references/pipelines/README.md +90 -0
- package/skills/cloudflare/references/pipelines/api.md +124 -0
- package/skills/cloudflare/references/pipelines/configuration.md +155 -0
- package/skills/cloudflare/references/pipelines/gotchas.md +58 -0
- package/skills/cloudflare/references/pipelines/patterns.md +130 -0
- package/skills/cloudflare/references/pulumi/README.md +100 -0
- package/skills/cloudflare/references/pulumi/api.md +200 -0
- package/skills/cloudflare/references/pulumi/configuration.md +198 -0
- package/skills/cloudflare/references/pulumi/gotchas.md +181 -0
- package/skills/cloudflare/references/pulumi/patterns.md +191 -0
- package/skills/cloudflare/references/queues/README.md +96 -0
- package/skills/cloudflare/references/queues/api.md +206 -0
- package/skills/cloudflare/references/queues/configuration.md +144 -0
- package/skills/cloudflare/references/queues/gotchas.md +206 -0
- package/skills/cloudflare/references/queues/patterns.md +220 -0
- package/skills/cloudflare/references/r2/README.md +95 -0
- package/skills/cloudflare/references/r2/api.md +200 -0
- package/skills/cloudflare/references/r2/configuration.md +165 -0
- package/skills/cloudflare/references/r2/gotchas.md +190 -0
- package/skills/cloudflare/references/r2/patterns.md +193 -0
- package/skills/cloudflare/references/r2-data-catalog/README.md +75 -0
- package/skills/cloudflare/references/r2-data-catalog/api.md +122 -0
- package/skills/cloudflare/references/r2-data-catalog/configuration.md +98 -0
- package/skills/cloudflare/references/r2-data-catalog/gotchas.md +55 -0
- package/skills/cloudflare/references/r2-data-catalog/patterns.md +122 -0
- package/skills/cloudflare/references/r2-sql/README.md +64 -0
- package/skills/cloudflare/references/r2-sql/api.md +121 -0
- package/skills/cloudflare/references/r2-sql/configuration.md +50 -0
- package/skills/cloudflare/references/r2-sql/gotchas.md +39 -0
- package/skills/cloudflare/references/r2-sql/patterns.md +118 -0
- package/skills/cloudflare/references/realtime-sfu/README.md +65 -0
- package/skills/cloudflare/references/realtime-sfu/api.md +158 -0
- package/skills/cloudflare/references/realtime-sfu/configuration.md +137 -0
- package/skills/cloudflare/references/realtime-sfu/gotchas.md +133 -0
- package/skills/cloudflare/references/realtime-sfu/patterns.md +174 -0
- package/skills/cloudflare/references/realtimekit/README.md +113 -0
- package/skills/cloudflare/references/realtimekit/api.md +212 -0
- package/skills/cloudflare/references/realtimekit/configuration.md +203 -0
- package/skills/cloudflare/references/realtimekit/gotchas.md +169 -0
- package/skills/cloudflare/references/realtimekit/patterns.md +223 -0
- package/skills/cloudflare/references/sandbox/README.md +96 -0
- package/skills/cloudflare/references/sandbox/api.md +198 -0
- package/skills/cloudflare/references/sandbox/configuration.md +143 -0
- package/skills/cloudflare/references/sandbox/gotchas.md +194 -0
- package/skills/cloudflare/references/sandbox/patterns.md +201 -0
- package/skills/cloudflare/references/secrets-store/README.md +74 -0
- package/skills/cloudflare/references/secrets-store/api.md +200 -0
- package/skills/cloudflare/references/secrets-store/configuration.md +185 -0
- package/skills/cloudflare/references/secrets-store/gotchas.md +97 -0
- package/skills/cloudflare/references/secrets-store/patterns.md +207 -0
- package/skills/cloudflare/references/smart-placement/README.md +138 -0
- package/skills/cloudflare/references/smart-placement/api.md +183 -0
- package/skills/cloudflare/references/smart-placement/configuration.md +196 -0
- package/skills/cloudflare/references/smart-placement/gotchas.md +174 -0
- package/skills/cloudflare/references/smart-placement/patterns.md +183 -0
- package/skills/cloudflare/references/snippets/README.md +68 -0
- package/skills/cloudflare/references/snippets/api.md +198 -0
- package/skills/cloudflare/references/snippets/configuration.md +227 -0
- package/skills/cloudflare/references/snippets/gotchas.md +86 -0
- package/skills/cloudflare/references/snippets/patterns.md +135 -0
- package/skills/cloudflare/references/spectrum/README.md +52 -0
- package/skills/cloudflare/references/spectrum/api.md +181 -0
- package/skills/cloudflare/references/spectrum/configuration.md +194 -0
- package/skills/cloudflare/references/spectrum/gotchas.md +145 -0
- package/skills/cloudflare/references/spectrum/patterns.md +196 -0
- package/skills/cloudflare/references/static-assets/README.md +65 -0
- package/skills/cloudflare/references/static-assets/api.md +199 -0
- package/skills/cloudflare/references/static-assets/configuration.md +186 -0
- package/skills/cloudflare/references/static-assets/gotchas.md +162 -0
- package/skills/cloudflare/references/static-assets/patterns.md +189 -0
- package/skills/cloudflare/references/stream/README.md +114 -0
- package/skills/cloudflare/references/stream/api-live.md +195 -0
- package/skills/cloudflare/references/stream/api.md +199 -0
- package/skills/cloudflare/references/stream/configuration.md +141 -0
- package/skills/cloudflare/references/stream/gotchas.md +130 -0
- package/skills/cloudflare/references/stream/patterns.md +184 -0
- package/skills/cloudflare/references/tail-workers/README.md +89 -0
- package/skills/cloudflare/references/tail-workers/api.md +200 -0
- package/skills/cloudflare/references/tail-workers/configuration.md +176 -0
- package/skills/cloudflare/references/tail-workers/gotchas.md +192 -0
- package/skills/cloudflare/references/tail-workers/patterns.md +180 -0
- package/skills/cloudflare/references/terraform/README.md +102 -0
- package/skills/cloudflare/references/terraform/api.md +178 -0
- package/skills/cloudflare/references/terraform/configuration.md +197 -0
- package/skills/cloudflare/references/terraform/gotchas.md +150 -0
- package/skills/cloudflare/references/terraform/patterns.md +174 -0
- package/skills/cloudflare/references/tunnel/README.md +129 -0
- package/skills/cloudflare/references/tunnel/api.md +193 -0
- package/skills/cloudflare/references/tunnel/configuration.md +157 -0
- package/skills/cloudflare/references/tunnel/gotchas.md +147 -0
- package/skills/cloudflare/references/tunnel/networking.md +168 -0
- package/skills/cloudflare/references/tunnel/patterns.md +192 -0
- package/skills/cloudflare/references/turn/README.md +82 -0
- package/skills/cloudflare/references/turn/api.md +239 -0
- package/skills/cloudflare/references/turn/configuration.md +179 -0
- package/skills/cloudflare/references/turn/gotchas.md +231 -0
- package/skills/cloudflare/references/turn/patterns.md +213 -0
- package/skills/cloudflare/references/turnstile/README.md +99 -0
- package/skills/cloudflare/references/turnstile/api.md +240 -0
- package/skills/cloudflare/references/turnstile/configuration.md +222 -0
- package/skills/cloudflare/references/turnstile/gotchas.md +218 -0
- package/skills/cloudflare/references/turnstile/patterns.md +193 -0
- package/skills/cloudflare/references/vectorize/README.md +133 -0
- package/skills/cloudflare/references/vectorize/api.md +88 -0
- package/skills/cloudflare/references/vectorize/configuration.md +88 -0
- package/skills/cloudflare/references/vectorize/gotchas.md +76 -0
- package/skills/cloudflare/references/vectorize/patterns.md +90 -0
- package/skills/cloudflare/references/waf/README.md +113 -0
- package/skills/cloudflare/references/waf/api.md +202 -0
- package/skills/cloudflare/references/waf/configuration.md +203 -0
- package/skills/cloudflare/references/waf/gotchas.md +204 -0
- package/skills/cloudflare/references/waf/patterns.md +197 -0
- package/skills/cloudflare/references/web-analytics/README.md +141 -0
- package/skills/cloudflare/references/web-analytics/configuration.md +76 -0
- package/skills/cloudflare/references/web-analytics/gotchas.md +82 -0
- package/skills/cloudflare/references/web-analytics/integration.md +60 -0
- package/skills/cloudflare/references/web-analytics/patterns.md +91 -0
- package/skills/cloudflare/references/workerd/README.md +78 -0
- package/skills/cloudflare/references/workerd/api.md +185 -0
- package/skills/cloudflare/references/workerd/configuration.md +183 -0
- package/skills/cloudflare/references/workerd/gotchas.md +139 -0
- package/skills/cloudflare/references/workerd/patterns.md +192 -0
- package/skills/cloudflare/references/workers/README.md +108 -0
- package/skills/cloudflare/references/workers/api.md +195 -0
- package/skills/cloudflare/references/workers/configuration.md +185 -0
- package/skills/cloudflare/references/workers/frameworks.md +197 -0
- package/skills/cloudflare/references/workers/gotchas.md +137 -0
- package/skills/cloudflare/references/workers/patterns.md +198 -0
- package/skills/cloudflare/references/workers-ai/README.md +197 -0
- package/skills/cloudflare/references/workers-ai/api.md +112 -0
- package/skills/cloudflare/references/workers-ai/configuration.md +97 -0
- package/skills/cloudflare/references/workers-ai/gotchas.md +114 -0
- package/skills/cloudflare/references/workers-ai/patterns.md +120 -0
- package/skills/cloudflare/references/workers-for-platforms/README.md +89 -0
- package/skills/cloudflare/references/workers-for-platforms/api.md +196 -0
- package/skills/cloudflare/references/workers-for-platforms/configuration.md +167 -0
- package/skills/cloudflare/references/workers-for-platforms/gotchas.md +134 -0
- package/skills/cloudflare/references/workers-for-platforms/patterns.md +188 -0
- package/skills/cloudflare/references/workers-playground/README.md +127 -0
- package/skills/cloudflare/references/workers-playground/api.md +101 -0
- package/skills/cloudflare/references/workers-playground/configuration.md +163 -0
- package/skills/cloudflare/references/workers-playground/gotchas.md +88 -0
- package/skills/cloudflare/references/workers-playground/patterns.md +132 -0
- package/skills/cloudflare/references/workers-vpc/README.md +127 -0
- package/skills/cloudflare/references/workers-vpc/api.md +202 -0
- package/skills/cloudflare/references/workers-vpc/configuration.md +147 -0
- package/skills/cloudflare/references/workers-vpc/gotchas.md +167 -0
- package/skills/cloudflare/references/workers-vpc/patterns.md +209 -0
- package/skills/cloudflare/references/workflows/README.md +77 -0
- package/skills/cloudflare/references/workflows/api.md +218 -0
- package/skills/cloudflare/references/workflows/configuration.md +152 -0
- package/skills/cloudflare/references/workflows/gotchas.md +90 -0
- package/skills/cloudflare/references/workflows/patterns.md +175 -0
- package/skills/cloudflare/references/wrangler/README.md +135 -0
- package/skills/cloudflare/references/wrangler/api.md +188 -0
- package/skills/cloudflare/references/wrangler/configuration.md +197 -0
- package/skills/cloudflare/references/wrangler/gotchas.md +197 -0
- package/skills/cloudflare/references/wrangler/patterns.md +209 -0
- package/skills/cloudflare/references/zaraz/IMPLEMENTATION_SUMMARY.md +121 -0
- package/skills/cloudflare/references/zaraz/README.md +111 -0
- package/skills/cloudflare/references/zaraz/api.md +112 -0
- package/skills/cloudflare/references/zaraz/configuration.md +90 -0
- package/skills/cloudflare/references/zaraz/gotchas.md +81 -0
- package/skills/cloudflare/references/zaraz/patterns.md +74 -0
- package/skills/cloudflare-email-service/SKILL.md +103 -0
- package/skills/cloudflare-email-service/references/cli-and-mcp.md +125 -0
- package/skills/cloudflare-email-service/references/deliverability.md +285 -0
- package/skills/cloudflare-email-service/references/rest-api.md +184 -0
- package/skills/cloudflare-email-service/references/routing.md +199 -0
- package/skills/cloudflare-email-service/references/sending.md +252 -0
- package/skills/cloudflare-one/SKILL.md +176 -0
- package/skills/cloudflare-one-migrations/SKILL.md +110 -0
- package/skills/durable-objects/SKILL.md +186 -0
- package/skills/durable-objects/references/rules.md +295 -0
- package/skills/durable-objects/references/testing.md +264 -0
- package/skills/durable-objects/references/workers.md +346 -0
- package/skills/sandbox-migrate-to-next/SKILL.md +185 -0
- package/skills/sandbox-next/SKILL.md +91 -0
- package/skills/sandbox-next/references/api-quick-ref.md +94 -0
- package/skills/sandbox-next/references/examples.md +15 -0
- package/skills/sandbox-stable/SKILL.md +110 -0
- package/skills/turnstile-spin/README.md +51 -0
- package/skills/turnstile-spin/SKILL.md +330 -0
- package/skills/turnstile-spin/references/astro.md +199 -0
- package/skills/turnstile-spin/references/hugo.md +114 -0
- package/skills/turnstile-spin/references/nextjs-app.md +261 -0
- package/skills/turnstile-spin/references/nextjs-pages.md +82 -0
- package/skills/turnstile-spin/references/sveltekit.md +191 -0
- package/skills/turnstile-spin/references/vanilla-html.md +157 -0
- package/skills/turnstile-spin/scripts/auth-probe.sh +285 -0
- package/skills/turnstile-spin/scripts/persist-skill.sh +114 -0
- package/skills/turnstile-spin/scripts/validate.sh +137 -0
- package/skills/turnstile-spin/scripts/widget-create.sh +121 -0
- package/skills/turnstile-spin/tests/validation.md +62 -0
- package/skills/workers-best-practices/SKILL.md +127 -0
- package/skills/workers-best-practices/references/review.md +174 -0
- package/skills/workers-best-practices/references/rules.md +467 -0
- package/skills/wrangler/SKILL.md +922 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Sending Emails — REST API
|
|
2
|
+
|
|
3
|
+
Send emails via HTTP requests from any application. If your app runs on Cloudflare Workers, use the [Workers binding](sending.md) instead — simpler and more performant.
|
|
4
|
+
|
|
5
|
+
For the full OpenAPI specification, refer to the [Email Sending API reference](https://developers.cloudflare.com/api/resources/email_sending/methods/send).
|
|
6
|
+
|
|
7
|
+
## Endpoint
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
POST https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Authentication
|
|
14
|
+
|
|
15
|
+
Authenticate with a [Cloudflare API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) that has email sending permission:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Authorization: Bearer <API_TOKEN>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Request Fields
|
|
22
|
+
|
|
23
|
+
**IMPORTANT:** The REST API uses different field names than the Workers binding in some cases.
|
|
24
|
+
|
|
25
|
+
| Field | Type | Required | Description |
|
|
26
|
+
|-------|------|----------|-------------|
|
|
27
|
+
| `to` | string or string[] | Yes | Recipient(s), max 50 combined with cc/bcc |
|
|
28
|
+
| `from` | string or `{address, name}` | Yes | Sender — **uses `address` not `email`** for object form |
|
|
29
|
+
| `subject` | string | Yes | Email subject line |
|
|
30
|
+
| `html` | string | No* | HTML body |
|
|
31
|
+
| `text` | string | No* | Plain text body |
|
|
32
|
+
| `cc` | string or string[] | No | CC recipients |
|
|
33
|
+
| `bcc` | string or string[] | No | BCC recipients |
|
|
34
|
+
| `reply_to` | string or `{address, name}` | No | **Snake_case**, not camelCase |
|
|
35
|
+
| `attachments` | array | No | File attachments and inline images |
|
|
36
|
+
| `headers` | object | No | Custom email headers |
|
|
37
|
+
|
|
38
|
+
*At least one of `html` or `text` required. Include both for best deliverability.
|
|
39
|
+
|
|
40
|
+
**Key differences from Workers binding:** `from` uses `address` (REST) vs `email` (Workers), `reply_to` (REST) vs `replyTo` (Workers), `content_id` (REST) vs `contentId` (Workers) for inline attachments, errors use numeric codes (REST) vs string `E_*` codes (Workers), and responses return delivery status (`delivered`/`permanent_bounces`/`queued`) instead of just `messageId`.
|
|
41
|
+
|
|
42
|
+
## Examples
|
|
43
|
+
|
|
44
|
+
Simple send:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
|
|
48
|
+
--header "Authorization: Bearer <API_TOKEN>" \
|
|
49
|
+
--header "Content-Type: application/json" \
|
|
50
|
+
--data '{
|
|
51
|
+
"to": "user@example.com",
|
|
52
|
+
"from": "welcome@yourdomain.com",
|
|
53
|
+
"subject": "Welcome!",
|
|
54
|
+
"html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
|
|
55
|
+
"text": "Welcome! Thanks for signing up."
|
|
56
|
+
}'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Multiple recipients with CC/BCC:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
|
|
63
|
+
--header "Authorization: Bearer <API_TOKEN>" \
|
|
64
|
+
--header "Content-Type: application/json" \
|
|
65
|
+
--data '{
|
|
66
|
+
"to": ["user1@example.com", "user2@example.com"],
|
|
67
|
+
"cc": ["manager@company.com"],
|
|
68
|
+
"bcc": ["archive@company.com"],
|
|
69
|
+
"from": { "address": "orders@yourdomain.com", "name": "Orders" },
|
|
70
|
+
"reply_to": "support@yourdomain.com",
|
|
71
|
+
"subject": "Order Confirmation",
|
|
72
|
+
"html": "<h1>Your order is confirmed</h1>",
|
|
73
|
+
"text": "Your order is confirmed"
|
|
74
|
+
}'
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
With attachments:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
|
|
81
|
+
--header "Authorization: Bearer <API_TOKEN>" \
|
|
82
|
+
--header "Content-Type: application/json" \
|
|
83
|
+
--data '{
|
|
84
|
+
"to": "customer@example.com",
|
|
85
|
+
"from": "invoices@yourdomain.com",
|
|
86
|
+
"subject": "Your Invoice",
|
|
87
|
+
"html": "<h1>Invoice attached</h1>",
|
|
88
|
+
"attachments": [
|
|
89
|
+
{
|
|
90
|
+
"content": "JVBERi0xLjQKJeLjz9MK...",
|
|
91
|
+
"filename": "invoice.pdf",
|
|
92
|
+
"type": "application/pdf",
|
|
93
|
+
"disposition": "attachment"
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}'
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
With inline images (embedded via `cid:` URI):
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
|
|
103
|
+
--header "Authorization: Bearer <API_TOKEN>" \
|
|
104
|
+
--header "Content-Type: application/json" \
|
|
105
|
+
--data '{
|
|
106
|
+
"to": "user@example.com",
|
|
107
|
+
"from": "newsletter@yourdomain.com",
|
|
108
|
+
"subject": "Check this out",
|
|
109
|
+
"html": "<h1>Hello!</h1><img src=\"cid:logo\">",
|
|
110
|
+
"attachments": [
|
|
111
|
+
{
|
|
112
|
+
"content": "iVBORw0KGgoAAAANSUhEUg...",
|
|
113
|
+
"filename": "logo.png",
|
|
114
|
+
"type": "image/png",
|
|
115
|
+
"disposition": "inline",
|
|
116
|
+
"content_id": "logo"
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
}'
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Attachment fields differ by type:
|
|
123
|
+
- **Regular attachment**: `content` (base64), `filename`, `type` (MIME), `disposition: "attachment"`
|
|
124
|
+
- **Inline image**: `content` (base64), `filename`, `type` (MIME), `disposition: "inline"`, `content_id` (referenced in HTML as `cid:<content_id>`)
|
|
125
|
+
|
|
126
|
+
With custom headers:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
|
|
130
|
+
--header "Authorization: Bearer <API_TOKEN>" \
|
|
131
|
+
--header "Content-Type: application/json" \
|
|
132
|
+
--data '{
|
|
133
|
+
"to": "user@example.com",
|
|
134
|
+
"from": "notifications@yourdomain.com",
|
|
135
|
+
"subject": "Your weekly digest",
|
|
136
|
+
"html": "<h1>Weekly Digest</h1>",
|
|
137
|
+
"headers": {
|
|
138
|
+
"List-Unsubscribe": "<https://yourdomain.com/unsubscribe?id=abc123>",
|
|
139
|
+
"List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
|
|
140
|
+
"X-Campaign-ID": "weekly-digest-2026-03"
|
|
141
|
+
}
|
|
142
|
+
}'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
See the [email headers reference](https://developers.cloudflare.com/email-service/reference/headers/) for the full list of allowed headers.
|
|
146
|
+
|
|
147
|
+
## Response
|
|
148
|
+
|
|
149
|
+
Success:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"success": true,
|
|
154
|
+
"errors": [],
|
|
155
|
+
"messages": [],
|
|
156
|
+
"result": {
|
|
157
|
+
"delivered": ["recipient@example.com"],
|
|
158
|
+
"permanent_bounces": [],
|
|
159
|
+
"queued": []
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Error (numeric codes, not `E_*` string codes like Workers):
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"success": false,
|
|
169
|
+
"errors": [{ "code": 1000, "message": "Sender domain not verified" }],
|
|
170
|
+
"result": null
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Error Handling
|
|
175
|
+
|
|
176
|
+
| Status | Meaning | Retry? |
|
|
177
|
+
|--------|---------|--------|
|
|
178
|
+
| 200 | Success | N/A |
|
|
179
|
+
| 400 | Validation error | No — fix the request |
|
|
180
|
+
| 401 | Invalid API token | No — check your token |
|
|
181
|
+
| 429 | Rate limited | Yes — exponential backoff |
|
|
182
|
+
| 500 | Server error | Yes — exponential backoff |
|
|
183
|
+
|
|
184
|
+
Only retry on 429 and 500. Validation errors (400) won't succeed on retry.
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Receiving & Routing Inbound Email
|
|
2
|
+
|
|
3
|
+
Handle incoming emails sent to your domain via a Worker's `email()` handler. Forward, reply, reject, or parse emails programmatically.
|
|
4
|
+
|
|
5
|
+
For full API details, see the [Email Routing docs](https://developers.cloudflare.com/email-service/api/route-emails/email-handler/).
|
|
6
|
+
|
|
7
|
+
## Email Handler
|
|
8
|
+
|
|
9
|
+
Export an `email()` function from your Worker. No special wrangler binding needed — a routing rule connects incoming addresses to your Worker.
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
export default {
|
|
13
|
+
async email(message, env, ctx): Promise<void> {
|
|
14
|
+
console.log(`Email from ${message.from} to ${message.to}`);
|
|
15
|
+
await message.forward("team@company.com");
|
|
16
|
+
},
|
|
17
|
+
} satisfies ExportedHandler<Env>;
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Set up routing rules in **Dashboard** > **Compute & AI** > **Email Service** > **Email Routing** > **Routing Rules**, or via `wrangler email routing rules create`.
|
|
21
|
+
|
|
22
|
+
## ForwardableEmailMessage
|
|
23
|
+
|
|
24
|
+
The `message` parameter is a `ForwardableEmailMessage`. Run `npx wrangler types` to get the full type definition. Key properties and methods:
|
|
25
|
+
|
|
26
|
+
- `message.from` / `message.to` — envelope addresses (SMTP MAIL FROM / RCPT TO). `message.from` is trustworthy; header addresses can be spoofed.
|
|
27
|
+
- `message.headers` — `Headers` object (use `.get("subject")`, `.get("message-id")`, etc.)
|
|
28
|
+
- `message.raw` — `ReadableStream<Uint8Array>` of raw MIME content. **Single use** — buffer before accessing.
|
|
29
|
+
- `message.rawSize` — size in bytes
|
|
30
|
+
- `message.setReject(reason)` — reject with a permanent SMTP error
|
|
31
|
+
- `message.forward(rcptTo, headers?)` — forward to a verified destination
|
|
32
|
+
- `message.reply(emailMessage)` — reply with an `EmailMessage` object
|
|
33
|
+
|
|
34
|
+
## Core Operations
|
|
35
|
+
|
|
36
|
+
### Forward
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
await message.forward("team@company.com");
|
|
40
|
+
|
|
41
|
+
// With custom headers
|
|
42
|
+
await message.forward("team@company.com", new Headers({
|
|
43
|
+
"X-Original-Recipient": message.to,
|
|
44
|
+
}));
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Destination must be verified first (Dashboard or `wrangler email routing addresses create`).
|
|
48
|
+
|
|
49
|
+
### Reject
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
message.setReject("Your message was blocked");
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Reply
|
|
56
|
+
|
|
57
|
+
Using `env.EMAIL.send()` (recommended — no extra dependencies):
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
async email(message, env, ctx) {
|
|
61
|
+
const subject = message.headers.get("subject") || "";
|
|
62
|
+
await env.EMAIL.send({
|
|
63
|
+
to: message.from,
|
|
64
|
+
from: message.to,
|
|
65
|
+
subject: `Re: ${subject}`,
|
|
66
|
+
html: "<p>Thanks! We'll respond shortly.</p>",
|
|
67
|
+
text: "Thanks! We'll respond shortly.",
|
|
68
|
+
});
|
|
69
|
+
await message.forward("team@company.com");
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Using `message.reply()` with MIME (more control, requires `mimetext` + `nodejs_compat`):
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { EmailMessage } from "cloudflare:email";
|
|
77
|
+
import { createMimeMessage } from "mimetext";
|
|
78
|
+
|
|
79
|
+
async email(message, env, ctx) {
|
|
80
|
+
const msg = createMimeMessage();
|
|
81
|
+
const messageId = message.headers.get("Message-ID");
|
|
82
|
+
if (messageId) msg.setHeader("In-Reply-To", messageId);
|
|
83
|
+
msg.setSender({ name: "Support", addr: "support@yourdomain.com" });
|
|
84
|
+
msg.setRecipient(message.from);
|
|
85
|
+
msg.setSubject("Re: " + (message.headers.get("subject") || ""));
|
|
86
|
+
msg.addMessage({ contentType: "text/plain", data: "Thanks for reaching out!" });
|
|
87
|
+
|
|
88
|
+
await message.reply(new EmailMessage("support@yourdomain.com", message.from, msg.asRaw()));
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Parsing Emails
|
|
93
|
+
|
|
94
|
+
Use [postal-mime](https://www.npmjs.com/package/postal-mime) to parse raw MIME content:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import PostalMime from "postal-mime";
|
|
98
|
+
|
|
99
|
+
async email(message, env, ctx) {
|
|
100
|
+
const rawBuffer = await new Response(message.raw).arrayBuffer();
|
|
101
|
+
const parsed = await PostalMime.parse(rawBuffer);
|
|
102
|
+
|
|
103
|
+
console.log("Subject:", parsed.subject);
|
|
104
|
+
console.log("Text:", parsed.text);
|
|
105
|
+
console.log("Attachments:", parsed.attachments.length);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Store and Reply Later (Human-in-the-Loop)
|
|
110
|
+
|
|
111
|
+
A common pattern is to store incoming emails in a Durable Object (SQLite) so a human or AI agent can review and reply later — rather than replying immediately in the `email()` handler. This enables support inboxes, approval workflows, and AI-drafted replies.
|
|
112
|
+
|
|
113
|
+
### Architecture
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
Email Routing → email() handler → parse + store in DO → user reviews later → reply via send_email binding
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The `email()` handler stores the email and returns immediately. Replies happen later via a separate HTTP request or agent action.
|
|
120
|
+
|
|
121
|
+
### Receive and Store
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import PostalMime from "postal-mime";
|
|
125
|
+
|
|
126
|
+
export class MailboxDO extends DurableObject {
|
|
127
|
+
async storeEmail(from: string, to: string, subject: string, body: string,
|
|
128
|
+
messageId: string, inReplyTo: string | null) {
|
|
129
|
+
this.ctx.storage.sql.exec(
|
|
130
|
+
`INSERT INTO emails (sender, recipient, subject, body, message_id, in_reply_to, date, read)
|
|
131
|
+
VALUES (?, ?, ?, ?, ?, ?, datetime('now'), 0)`,
|
|
132
|
+
from, to, subject, body, messageId, inReplyTo
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default {
|
|
138
|
+
async email(message, env, ctx) {
|
|
139
|
+
const raw = await new Response(message.raw).arrayBuffer();
|
|
140
|
+
const parsed = await PostalMime.parse(raw);
|
|
141
|
+
|
|
142
|
+
const id = env.MAILBOX.idFromName(message.to);
|
|
143
|
+
const stub = env.MAILBOX.get(id);
|
|
144
|
+
|
|
145
|
+
await stub.storeEmail(
|
|
146
|
+
message.from,
|
|
147
|
+
message.to,
|
|
148
|
+
parsed.subject || "(no subject)",
|
|
149
|
+
parsed.text || parsed.html || "",
|
|
150
|
+
message.headers.get("message-id") || "",
|
|
151
|
+
message.headers.get("in-reply-to") || null,
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
// Optionally trigger an AI agent to draft a reply (non-blocking)
|
|
155
|
+
// ctx.waitUntil(notifyAgent(env, message.to, emailId));
|
|
156
|
+
},
|
|
157
|
+
} satisfies ExportedHandler<Env>;
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Reply Later
|
|
161
|
+
|
|
162
|
+
When a user (or agent) decides to reply, build proper threading headers and send via the `send_email` binding:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// In an HTTP handler or agent tool — not in the email() handler
|
|
166
|
+
async function replyToStoredEmail(env: Env, original: StoredEmail, replyBody: string) {
|
|
167
|
+
// Build threading headers (In-Reply-To + References per RFC 2822)
|
|
168
|
+
const headers: Record<string, string> = {};
|
|
169
|
+
if (original.messageId) {
|
|
170
|
+
headers["In-Reply-To"] = original.messageId;
|
|
171
|
+
headers["References"] = original.messageId;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
await env.EMAIL.send({
|
|
175
|
+
to: original.sender,
|
|
176
|
+
from: original.recipient,
|
|
177
|
+
subject: `Re: ${original.subject}`,
|
|
178
|
+
text: replyBody,
|
|
179
|
+
html: `<p>${replyBody}</p>`,
|
|
180
|
+
headers,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Key Design Points
|
|
186
|
+
|
|
187
|
+
- **Buffer `message.raw` once**, parse with `postal-mime`, then store structured fields. Don't store the raw stream.
|
|
188
|
+
- **Extract `Message-ID`, `In-Reply-To`, and `References`** headers during ingest for threading. Fall back to subject-based matching for emails without threading headers.
|
|
189
|
+
- **Use Durable Object SQLite** for per-mailbox storage — each mailbox gets its own DO instance keyed by email address, providing natural isolation.
|
|
190
|
+
- **Store attachments separately** in R2 (binary blobs), with metadata in SQLite.
|
|
191
|
+
- **Defer heavy work** (AI drafting, notifications) via `ctx.waitUntil()` so the `email()` handler returns quickly.
|
|
192
|
+
- **Never auto-send from the `email()` handler** in a human-in-the-loop flow. Store a draft, let the user review, then send via a separate action.
|
|
193
|
+
|
|
194
|
+
## Gotchas
|
|
195
|
+
|
|
196
|
+
- **`message.raw` is single-use.** Buffer first: `const raw = await new Response(message.raw).arrayBuffer()`
|
|
197
|
+
- **Destinations must be verified.** Forwarding to unverified addresses fails silently.
|
|
198
|
+
- **Handler must act.** If your handler returns without consuming raw, forwarding, or rejecting, the email is dropped.
|
|
199
|
+
- **DMARC/SPF for replies.** If sending replies, ensure your domain has proper SPF/DKIM records (auto-configured on domain onboarding).
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Sending Emails — Workers Binding & Agents SDK
|
|
2
|
+
|
|
3
|
+
Send emails from Cloudflare Workers using the native binding, or from AI agents using the Agents SDK. If your app is NOT on Workers, use the [REST API](rest-api.md) instead.
|
|
4
|
+
|
|
5
|
+
## Workers Binding
|
|
6
|
+
|
|
7
|
+
### Configuration
|
|
8
|
+
|
|
9
|
+
```jsonc
|
|
10
|
+
// wrangler.jsonc
|
|
11
|
+
{
|
|
12
|
+
"send_email": [
|
|
13
|
+
{ "name": "EMAIL" }
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
For local development, add `"remote": true` so email sends are proxied to the real service:
|
|
19
|
+
|
|
20
|
+
```jsonc
|
|
21
|
+
{ "send_email": [{ "name": "EMAIL", "remote": true }] }
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Run `npx wrangler types` to auto-generate the `Env` interface with your `EMAIL` binding. This produces a `worker-configuration.d.ts` with the real `SendEmail`, `EmailAttachment`, `EmailAddress`, and related types from the workerd runtime. Always use these generated types — do not define them manually.
|
|
25
|
+
|
|
26
|
+
**Note:** Workers binding uses `email` in the from object (`EmailAddress` type). REST API uses `address`. See [rest-api.md](rest-api.md).
|
|
27
|
+
|
|
28
|
+
## send()
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
export default {
|
|
32
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
33
|
+
const response = await env.EMAIL.send({
|
|
34
|
+
to: "user@example.com",
|
|
35
|
+
from: { email: "welcome@yourdomain.com", name: "My App" },
|
|
36
|
+
subject: "Welcome!",
|
|
37
|
+
html: "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
|
|
38
|
+
text: "Welcome! Thanks for signing up.",
|
|
39
|
+
});
|
|
40
|
+
return new Response(`Sent: ${response.messageId}`);
|
|
41
|
+
},
|
|
42
|
+
} satisfies ExportedHandler<Env>;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Multiple recipients (max 50 combined to + cc + bcc):
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
const response = await env.EMAIL.send({
|
|
49
|
+
to: ["user1@example.com", "user2@example.com"],
|
|
50
|
+
cc: ["manager@company.com"],
|
|
51
|
+
bcc: ["archive@company.com"],
|
|
52
|
+
from: { email: "orders@yourdomain.com", name: "Orders" },
|
|
53
|
+
replyTo: "support@yourdomain.com",
|
|
54
|
+
subject: "Order Confirmation #12345",
|
|
55
|
+
html: "<h1>Your order is confirmed</h1>",
|
|
56
|
+
text: "Your order is confirmed",
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Attachments
|
|
61
|
+
|
|
62
|
+
**Important:** The Workers binding and REST API handle attachment content differently:
|
|
63
|
+
- **Workers binding:** `content` accepts `string | ArrayBuffer | ArrayBufferView`. Strings are treated as **raw content** (not base64). For text files, pass the raw string. For binary files (images, PDFs), pass an `ArrayBuffer`. Note: `ArrayBuffer` does not work with `"remote": true` in local dev — deploy to test binary attachments.
|
|
64
|
+
- **REST API:** `content` is always a **base64-encoded string**. See [rest-api.md](rest-api.md).
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// Text file attachment — pass raw string content
|
|
68
|
+
const response = await env.EMAIL.send({
|
|
69
|
+
to: "customer@example.com",
|
|
70
|
+
from: "invoices@yourdomain.com",
|
|
71
|
+
subject: "Your Report",
|
|
72
|
+
html: "<h1>Report attached</h1>",
|
|
73
|
+
text: "Report attached.",
|
|
74
|
+
attachments: [{
|
|
75
|
+
content: "Name,Amount\nWidget A,100\nWidget B,250", // Raw text, NOT base64
|
|
76
|
+
filename: "report.csv",
|
|
77
|
+
type: "text/csv",
|
|
78
|
+
disposition: "attachment",
|
|
79
|
+
}],
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Binary file attachment — use ArrayBuffer
|
|
83
|
+
const pdfBytes = await fetchPdfFromSomewhere(); // Returns ArrayBuffer
|
|
84
|
+
const response = await env.EMAIL.send({
|
|
85
|
+
to: "customer@example.com",
|
|
86
|
+
from: "invoices@yourdomain.com",
|
|
87
|
+
subject: "Your Invoice",
|
|
88
|
+
html: "<h1>Invoice attached</h1>",
|
|
89
|
+
text: "Invoice attached.",
|
|
90
|
+
attachments: [{
|
|
91
|
+
content: pdfBytes,
|
|
92
|
+
filename: "invoice-12345.pdf",
|
|
93
|
+
type: "application/pdf",
|
|
94
|
+
disposition: "attachment",
|
|
95
|
+
}],
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Inline image — reference in HTML with cid:<contentId>
|
|
99
|
+
const imageBytes = await fetchImageFromSomewhere(); // Returns ArrayBuffer
|
|
100
|
+
const response = await env.EMAIL.send({
|
|
101
|
+
to: "user@example.com",
|
|
102
|
+
from: "marketing@yourdomain.com",
|
|
103
|
+
subject: "New Product",
|
|
104
|
+
html: '<img src="cid:product-hero" alt="Product" />',
|
|
105
|
+
attachments: [{
|
|
106
|
+
content: imageBytes,
|
|
107
|
+
filename: "product.png",
|
|
108
|
+
type: "image/png",
|
|
109
|
+
disposition: "inline",
|
|
110
|
+
contentId: "product-hero",
|
|
111
|
+
}],
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Total email size (body + attachments) cannot exceed 25 MiB.
|
|
116
|
+
|
|
117
|
+
## Custom Headers
|
|
118
|
+
|
|
119
|
+
Only whitelisted headers allowed. See the [headers reference](https://developers.cloudflare.com/email-service/reference/headers/).
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
const response = await env.EMAIL.send({
|
|
123
|
+
to: "user@example.com",
|
|
124
|
+
from: "notifications@yourdomain.com",
|
|
125
|
+
subject: "Your weekly digest",
|
|
126
|
+
html: "<h1>Weekly Digest</h1>",
|
|
127
|
+
headers: {
|
|
128
|
+
"In-Reply-To": "<original-message-id@yourdomain.com>",
|
|
129
|
+
"List-Unsubscribe": "<https://yourdomain.com/unsubscribe?id=abc123>",
|
|
130
|
+
"List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
|
|
131
|
+
"X-Campaign-ID": "weekly-digest-2026-03",
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Legacy EmailMessage API
|
|
137
|
+
|
|
138
|
+
The `EmailMessage` API remains supported. Uses raw MIME via `mimetext`:
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { EmailMessage } from "cloudflare:email";
|
|
142
|
+
import { createMimeMessage } from "mimetext";
|
|
143
|
+
|
|
144
|
+
const msg = createMimeMessage();
|
|
145
|
+
msg.setSender({ name: "Sender", addr: "sender@yourdomain.com" });
|
|
146
|
+
msg.setRecipient("recipient@example.com");
|
|
147
|
+
msg.setSubject("Hello");
|
|
148
|
+
msg.addMessage({ contentType: "text/html", data: "<h1>Hello</h1>" });
|
|
149
|
+
|
|
150
|
+
await env.EMAIL.send(new EmailMessage("sender@yourdomain.com", "recipient@example.com", msg.asRaw()));
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Requires `npm install mimetext` and `"nodejs_compat"` in compatibility flags.
|
|
154
|
+
|
|
155
|
+
## Agents SDK Email
|
|
156
|
+
|
|
157
|
+
Agents can receive and reply to emails natively via the Agents SDK.
|
|
158
|
+
|
|
159
|
+
```jsonc
|
|
160
|
+
// wrangler.jsonc
|
|
161
|
+
{
|
|
162
|
+
"durable_objects": {
|
|
163
|
+
"bindings": [{ "name": "EmailAgent", "class_name": "EmailAgent" }]
|
|
164
|
+
},
|
|
165
|
+
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["EmailAgent"] }],
|
|
166
|
+
"send_email": [{ "name": "EMAIL", "destination_address": "reply@yourdomain.com" }]
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { Agent } from "agents";
|
|
172
|
+
import { type AgentEmail } from "agents/email";
|
|
173
|
+
import PostalMime from "postal-mime";
|
|
174
|
+
|
|
175
|
+
export class EmailAgent extends Agent<Env, State> {
|
|
176
|
+
async onEmail(email: AgentEmail) {
|
|
177
|
+
const parsed = await PostalMime.parse(await email.getRaw());
|
|
178
|
+
await this.replyToEmail(email, {
|
|
179
|
+
fromName: "My Agent",
|
|
180
|
+
subject: `Re: ${parsed.subject}`,
|
|
181
|
+
body: "Thanks for your email! I'll look into this.",
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Route emails to agents with resolvers:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
import { routeAgentEmail } from "agents";
|
|
191
|
+
import { createAddressBasedEmailResolver } from "agents/email";
|
|
192
|
+
|
|
193
|
+
export default {
|
|
194
|
+
async email(message, env) {
|
|
195
|
+
await routeAgentEmail(message, env, {
|
|
196
|
+
resolver: createAddressBasedEmailResolver("EmailAgent"),
|
|
197
|
+
});
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Resolver types: `createAddressBasedEmailResolver` (recipient → instance name), `createSecureReplyEmailResolver(secret)` (HMAC-signed replies), `createCatchAllEmailResolver("Agent", "default")` (single inbox). Use `isAutoReplyEmail(email.headers)` to skip vacation responders.
|
|
203
|
+
|
|
204
|
+
## Error Handling
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
try {
|
|
208
|
+
const response = await env.EMAIL.send({ /* ... */ });
|
|
209
|
+
} catch (error) {
|
|
210
|
+
// error.code is one of the E_* error codes
|
|
211
|
+
console.error(`Failed: ${error.code} - ${error.message}`);
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
These error codes are for the **Workers binding** (thrown as Error objects with `.code` and `.message`). The **REST API** returns standard Cloudflare API numeric error codes instead — see [rest-api.md](rest-api.md).
|
|
216
|
+
|
|
217
|
+
| Error Code | What It Means | What to Do |
|
|
218
|
+
|------------|---------------|------------|
|
|
219
|
+
| `E_VALIDATION_ERROR` | Invalid payload | Check email format, required fields |
|
|
220
|
+
| `E_FIELD_MISSING` | Required field missing | Add `to`, `from`, or `subject` |
|
|
221
|
+
| `E_TOO_MANY_RECIPIENTS` | Combined to/cc/bcc exceeds 50 | Split into multiple sends |
|
|
222
|
+
| `E_SENDER_NOT_VERIFIED` | Domain not onboarded | Run `wrangler email sending enable yourdomain.com` or onboard in Dashboard |
|
|
223
|
+
| `E_RECIPIENT_NOT_ALLOWED` | Recipient not in allowed list | Add to `allowed_destination_addresses` |
|
|
224
|
+
| `E_RECIPIENT_SUPPRESSED` | Address bounced or reported spam | Remove from your list; check suppression list in Dashboard |
|
|
225
|
+
| `E_SENDER_DOMAIN_NOT_AVAILABLE` | Domain not available for sending | Complete domain onboarding |
|
|
226
|
+
| `E_CONTENT_TOO_LARGE` | Content exceeds 25 MiB | Reduce attachments or body |
|
|
227
|
+
| `E_RATE_LIMIT_EXCEEDED` | Rate limit hit | Retry with exponential backoff |
|
|
228
|
+
| `E_DAILY_LIMIT_EXCEEDED` | Daily quota reached | Wait or request limit increase |
|
|
229
|
+
| `E_DELIVERY_FAILED` | SMTP delivery failure | Check recipient address, retry if transient |
|
|
230
|
+
| `E_INTERNAL_SERVER_ERROR` | Service temporarily unavailable | Retry with exponential backoff |
|
|
231
|
+
| `E_HEADER_NOT_ALLOWED` | Header not on whitelist | Use an allowed header; see [headers reference](https://developers.cloudflare.com/email-service/reference/headers/) |
|
|
232
|
+
| `E_HEADER_USE_API_FIELD` | Must use API field instead | Set `From`, `To`, etc. via the dedicated API fields, not `headers` |
|
|
233
|
+
| `E_HEADER_VALUE_INVALID` | Header value is malformed or empty | Fix the value format (e.g., List-Unsubscribe needs angle-bracket URIs) |
|
|
234
|
+
| `E_HEADER_VALUE_TOO_LONG` | Header value exceeds 2,048 bytes | Shorten the header value |
|
|
235
|
+
| `E_HEADER_NAME_INVALID` | Invalid header name | Fix characters or keep under 100 bytes |
|
|
236
|
+
| `E_HEADERS_TOO_LARGE` | Total headers exceed 16 KB | Reduce number or size of custom headers |
|
|
237
|
+
| `E_HEADERS_TOO_MANY` | More than 20 non-X headers | Reduce to 20 or fewer whitelisted headers |
|
|
238
|
+
|
|
239
|
+
For `E_RATE_LIMIT_EXCEEDED` and `E_DELIVERY_FAILED`, retry with exponential backoff. For validation errors (`E_VALIDATION_ERROR`, `E_FIELD_MISSING`, `E_SENDER_NOT_VERIFIED`), fix the request — retrying won't help.
|
|
240
|
+
|
|
241
|
+
## Restricted Bindings
|
|
242
|
+
|
|
243
|
+
Restrict which `from` addresses a binding can use:
|
|
244
|
+
|
|
245
|
+
```jsonc
|
|
246
|
+
{
|
|
247
|
+
"send_email": [{
|
|
248
|
+
"name": "RESTRICTED_EMAIL",
|
|
249
|
+
"allowed_sender_addresses": ["noreply@yourdomain.com", "support@yourdomain.com"]
|
|
250
|
+
}]
|
|
251
|
+
}
|
|
252
|
+
```
|