eCDN Turnstile
Cloudflare Turnstile is a bot-mitigation solution that verifies that visitors are real without requiring them to solve a CAPTCHA. The eCDN Turnstile endpoints let you manage Turnstile widgets for your Commerce Cloud storefronts—creating, listing, updating, and deleting widgets programmatically.
Each widget is identified by a sitekey (the public key embedded in your storefront HTML) and has a corresponding secret (used server-side to validate challenge responses). The API returns the secret so that you can store it in your application’s server-side configuration.
For general eCDN concepts and the zones API, see CDN Zones.
A widget operates in one of three modes:
| Mode | Behavior |
|---|---|
managed | Cloudflare determines the optimal challenge type (recommended for most use cases). |
non-interactive | A non-interactive challenge runs automatically without user action. |
invisible | The challenge runs entirely in the background with no visible widget rendered. |
Widgets are scoped to the realm and environment derived from the organization ID. For example, a GET request from f_ecom_bcxj_prd returns only production widgets for realm bcxj.
Each widget is associated with one or more domains (hostnames) where it can be presented. Only requests that originate from a listed domain pass validation. Update the domain list as hostnames are added to or removed from your storefront.
All Turnstile endpoints require an OAuth 2.0 bearer token with the sfcc.cdn-zones.rw scope.
The Turnstile endpoints are relative to the following base URL:
https://{shortCode}.api.commercecloud.salesforce.com/cdn/zones/v1/organizations/{organizationId}
Retrieves all Turnstile widgets for the requesting instance. Results are paginated and cached for 5 minutes.
GET /organizations/{organizationId}/turnstile/widgets
Query parameters:
| Parameter | Required | Default | Description |
|---|---|---|---|
name | No | — | Filter by widget name (exact match). |
offset | No | 0 | Pagination offset. |
limit | No | 25 | Results per page (1–50). |
A 200 OK response includes the following pagination headers:
SFDC-Pagination-OffsetSFDC-Pagination-LimitSFDC-Pagination-Total-CountSFDC-Pagination-Result-Count
Example response body:
Creates a new Cloudflare Turnstile widget for the requesting instance. Each instance allows up to 5,000 widgets.
POST /organizations/{organizationId}/turnstile/widgets
Required attributes:
| Attribute | Type | Description |
|---|---|---|
name | string | Logical widget name. |
domains | array of strings | Hostnames allowed to present the widget. At least one required. |
mode | string | Widget mode: managed, non-interactive, or invisible. |
Example request body:
A 201 Created response returns the new widget, including its secret:
The response includes the secret. Store it securely in your server-side configuration—you need it to validate Turnstile challenge responses.
Retrieves the full configuration of a widget by sitekey, including the shared secret.
GET /organizations/{organizationId}/turnstile/widgets/{sitekey}
Path parameters:
| Parameter | Description |
|---|---|
sitekey | The unique identifier of the widget. |
A 200 OK response returns the widget. The endpoint returns 404 Not Found if the widget doesn’t exist.
Updates the domains and/or mode of an existing widget.
PUT /organizations/{organizationId}/turnstile/widgets/{sitekey}
Path parameters:
| Parameter | Description |
|---|---|
sitekey | The unique identifier of the widget to update. |
Optional attributes (at least one required):
| Attribute | Type | Description |
|---|---|---|
domains | array of strings | Replacement list of allowed hostnames. |
mode | string | New widget mode: managed, non-interactive, or invisible. |
Example request body:
A 200 OK response returns the updated widget. The endpoint returns 404 Not Found if the widget doesn’t exist, and 400 Bad Request if the request exceeds the Cloudflare hostname limit for the widget.
Deletes an existing widget. This operation is irreversible and immediately invalidates the sitekey and secret.
DELETE /organizations/{organizationId}/turnstile/widgets/{sitekey}
Path parameters:
| Parameter | Description |
|---|---|
sitekey | The unique identifier of the widget to delete. |
Query parameters:
| Parameter | Required | Default | Description |
|---|---|---|---|
forceProduction | No | false | Must be true to delete a production widget. Without this flag, deleting a production widget returns 403 Forbidden. |
dryRun | No | false | When true, validates the request without performing the deletion. |
A successful deletion returns 204 No Content. The endpoint returns 404 Not Found if the widget doesn’t exist, and 403 Forbidden if you attempt to delete a production widget without forceProduction=true.
Production widgets (environment = prd) require an explicit forceProduction=true. Use dryRun=true to validate parameters before committing to deletion. Post-deletion verification runs automatically to confirm removal.
All Turnstile endpoints return errors in application/problem+json format:
| Status Code | Meaning |
|---|---|
400 | Bad request—invalid input, name too long, hostname limit exceeded, and so on. |
401 | Unauthorized—missing or invalid bearer token. |
403 | Forbidden—insufficient scope, or production deletion without the force flag. |
404 | Not found—a widget with the given sitekey doesn’t exist. |
500 | Internal server error. |
A typical workflow:
- Create a widget. Call
POST /turnstile/widgetswith your desired name, domains, and mode. - Configure your storefront. Add the
sitekeyandsecretfrom the response to your Managed Runtime application’s.envfile. For the exact environment variables and configuration, see steps 2(a) and 2(b) in the Storefront Next One-Click Checkout guide. - Update domains. As you add or remove storefront hostnames, call
PUT /turnstile/widgets/{sitekey}to keep the domain list in sync.
- Each instance allows up to 5,000 widgets.
- Each widget’s domain list is subject to Cloudflare’s per-widget hostname limit.
- List results are cached for 5 minutes, so newly created widgets can take up to 5 minutes to appear in list responses. To retrieve a new widget right away, use
GET /turnstile/widgets/{sitekey}, which isn’t cached. - You can’t change the
nameafter creation. To rename a widget, delete and recreate it. - Each environment (development, staging, production) has its own widgets. Widgets can’t be shared across environments.
- If you delete a widget that is still in use, its sitekey and secret are immediately invalidated, and any Turnstile challenges that use that sitekey fail. Remove the widget HTML from your storefront before, or immediately after, deletion.
To choose a mode, use this guidance:
- Use
managed(recommended) for most storefronts—Cloudflare picks the optimal challenge. - Use
invisiblefor a seamless experience where no widget is shown. - Use
non-interactivewhen you want the challenge to run automatically without a visible puzzle but still show the widget.