Claim deployments (temporary accounts)
Last updated Jul 14, 2026 Temporary preview accounts let you deploy and test Workers before you authenticate with Cloudflare. You can then claim the account to keep its deployments and supported resources.
Cloudflare Drop ↗︎ demonstrates this preview-and-claim lifecycle for static sites. Platforms can use the REST API to offer a similar experience for generated applications.
For design context, refer to Temporary Cloudflare Accounts for AI agents ↗︎.

Choose an integration
Choose an integration based on who controls account provisioning:
| Integration | Use when | Provisioning behavior |
|---|---|---|
Wrangler with wrangler deploy --temporary |
An AI agent or tool runs Wrangler | Wrangler creates or reuses the account and prints the claim URL |
REST API at api.cloudflare.com/client/v4/provisioning/previews |
Your platform backend controls the deployment experience | Your backend receives temporary credentials and the claim URL |
For production and continuous integration and continuous deployment (CI/CD), use a permanent Cloudflare account. Authenticate with wrangler login or a Cloudflare API token.
Deploy with Wrangler
Use Wrangler when an AI agent or tool runs deployment commands. Wrangler manages the proof-of-work challenge, credentials, and claim URL.
Wrangler 4.102.0 or later prints guidance to rerun unauthenticated deployments with --temporary.
- Install or update Wrangler to version 4.102.0 or later.
For installation instructions, refer to Install and update. 2. Give your AI agent a deployment prompt.
For example:
Make a very simple Hello World Cloudflare Worker in TypeScript and deploy it using the Wrangler CLI. Do not ask me questions.
```
3. Let the agent run `wrangler deploy`.
In an unauthenticated, non-interactive session, Wrangler prints output similar to the following:
```txt
To continue without logging in, rerun this command with `--temporary`.
Wrangler will use a temporary account and print a claim URL.
```
This output tells the agent to rerun the command with `--temporary`.
4. Rerun the deployment with `--temporary`.npmyarnpnpm
npx wrangler deploy --temporary ```
yarn wrangler deploy --temporary
```
pnpm wrangler deploy --temporary ```
Wrangler prints output similar to the following:
Continuing means you accept Cloudflare's Terms of Service (https://www.cloudflare.com/terms/) and Privacy Policy (https://www.cloudflare.com/privacypolicy/).
Temporary account ready:
Account: example-name (created)
Claim within: 60 minutes
Claim URL: https://dash.cloudflare.com/claim-preview?claimToken=<CLAIM_TOKEN>
Uploaded example-worker
Deployed example-worker triggers
https://example-worker.example-name.workers.dev
```
5. (Optional) Redeploy changes before claiming the account.
Wrangler caches and reuses the account while its credentials and claim URL remain valid. The output identifies whether Wrangler created or reused the account.
Wrangler clears the cached account when you run `wrangler login` or `wrangler logout`.
Wrangler stores these temporary values in the current operating-system user's global configuration directory. Do not share this directory between platform users.
## Integrate with the REST API
Use the REST API when your platform backend controls deployments. The backend provisions an account before the user authenticates, then deploys supported resources.
Make all provisioning and deployment calls from your backend. The provisioning response contains sensitive credentials and a claim URL.
The following diagram shows how the platform keeps temporary credentials in its backend while the user previews and claims the deployment:
flowchart LR accTitle: Platform preview and claim architecture accDescr: A user accepts Cloudflare's policies and requests a preview in the platform UI. The trusted platform backend creates a temporary account, keeps account.apiToken private, deploys the Worker, and returns only the preview and claim URLs to the UI. The claim URL is a bearer credential shown only to the intended user. The user claims the account in the Cloudflare dashboard. Future platform deployments require a separate OAuth flow.
USER((User))
subgraph PLATFORM["Platform"]
direction TB
UI["Platform UI
No temporary API token"]
BACKEND["Trusted platform backend
Stores account.apiToken"]
UI -->|"2. Request preview"| BACKEND
BACKEND -->|"10. Preview URL and bearer claim URL only"| UI
end
subgraph CLOUDFLARE["Cloudflare"]
direction TB
API["Cloudflare API"]
DASHBOARD["Cloudflare dashboard
Claims the account"]
end
USER -->|"1. Accept policies and generate application"| UI
BACKEND -->|"3. Request challenge"| API
API -->|"4. Challenge parameters"| BACKEND
BACKEND -->|"5. Solve challenge locally"| BACKEND
BACKEND -->|"6. Create temporary account with solution"| API
API -->|"7. Account ID, API token, and claim URL"| BACKEND
BACKEND -->|"8. Deploy Worker and request subdomain"| API
API -->|"9. workers.dev subdomain"| BACKEND
UI -->|"11. Show live preview and intended-user-only claim link"| USER
USER -->|"12. Sign in and complete claim"| DASHBOARD
DASHBOARD -.->|"Optional after claim"| OAUTH["Separate OAuth flow
for future platform deployments"]
### Request a challenge
Request a proof-of-work challenge before creating the temporary account:
```bash
curl "https://api.cloudflare.com/client/v4/provisioning/previews/challenge" \
-X POST \
-H "Content-Type: application/json" \
--data '{}'
The response includes the challenge token, seed, and difficulty parameters:
{
"success": true,
"result": {
"challengeToken": "<CHALLENGE_TOKEN>",
"seed": "<BASE64URL_32_BYTE_SEED>",
"k": 8000,
"g": 2000
},
"errors": [],
"messages": []
}
Solve the proof of work
Solve the challenge by computing a sequential SHA-256 checkpoint chain:
- Decode
seedas Base64URL. It must decode to 32 bytes. - Compute
checkpoint[0] = SHA-256(seed). - For each segment from
0tok - 1, computegsequential SHA-256 hashes from the previous checkpoint, then append the result. - Concatenate all
k + 1checkpoints. Each checkpoint is 32 bytes. - Encode the concatenated bytes with standard Base64. Send that value as
solution.checkpoints.
Before solving a challenge, require k and g to be positive integers. Reject the challenge if seed does not decode to 32 bytes or if k * g exceeds 64,000,000.
The following Node.js example applies these bounds and returns the object required by the create request:
solve-preview-challenge.jsjs
import { createHash } from "node:crypto";
function sha256(value) {
return createHash("sha256").update(value).digest();
}
export function solvePreviewChallenge({ challengeToken, seed, k, g }) {
const seedBytes = Buffer.from(seed, "base64url");
if (seedBytes.length !== 32) {
throw new Error("seed must decode to 32 bytes");
}
if (!Number.isInteger(k) || k <= 0) {
throw new Error("k must be a positive integer");
}
if (!Number.isInteger(g) || g <= 0) {
throw new Error("g must be a positive integer");
}
if (k * g > 64_000_000) {
throw new Error("k * g must not exceed 64,000,000");
}
const checkpoints = [];
let hash = sha256(seedBytes);
checkpoints.push(hash);
for (let segment = 0; segment < k; segment++) {
for (let iteration = 0; iteration < g; iteration++) {
hash = sha256(hash);
}
checkpoints.push(hash);
}
return {
challengeToken,
solution: {
checkpoints: Buffer.concat(checkpoints).toString("base64"),
},
};
}
solve-preview-challenge.tsts
import { createHash } from "node:crypto";
type PreviewChallenge = {
challengeToken: string;
seed: string;
k: number;
g: number;
};
function sha256(value: Uint8Array): Buffer {
return createHash("sha256").update(value).digest();
}
export function solvePreviewChallenge({
challengeToken,
seed,
k,
g,
}: PreviewChallenge) {
const seedBytes = Buffer.from(seed, "base64url");
if (seedBytes.length !== 32) {
throw new Error("seed must decode to 32 bytes");
}
if (!Number.isInteger(k) || k <= 0) {
throw new Error("k must be a positive integer");
}
if (!Number.isInteger(g) || g <= 0) {
throw new Error("g must be a positive integer");
}
if (k * g > 64_000_000) {
throw new Error("k * g must not exceed 64,000,000");
}
const checkpoints: Buffer[] = [];
let hash = sha256(seedBytes);
checkpoints.push(hash);
for (let segment = 0; segment < k; segment++) {
for (let iteration = 0; iteration < g; iteration++) {
hash = sha256(hash);
}
checkpoints.push(hash);
}
return {
challengeToken,
solution: {
checkpoints: Buffer.concat(checkpoints).toString("base64"),
},
};
}
Production execution
This synchronous Node.js solver is CPU-intensive and blocks the event loop. Run it outside the main request thread, such as in a worker thread or background job.
Create a temporary account
Require the user to accept Cloudflare's Terms of Service ↗︎ and Privacy Policy ↗︎ before account creation. Set acceptTermsOfService to "yes" only after the user accepts both.
