For Neil · set up once, 20 minutes

Give ChatGPT the keys to your Cloudflare

When you finish this page you will be able to open ChatGPT's Codex on your Mac and say "make me a page about X and put it online", and get back a working https://something.pages.dev address. No Sean in the loop.

This page is the proof. It is one HTML file that Sean's Claude wrote and published to Cloudflare Pages with an API token and one command, the same way you are about to set up for Codex.

0 of 6 steps done

Fill these in first and every command below rewrites itself

Becomes nwioi-hello.pages.dev. Must be unused by anyone on Cloudflare, and cannot be renamed later.

Not a secret. Stays in this browser only.

There is no box for the token on purpose. The token (step 1) goes into one file on your Mac and nowhere else. Never paste it into a web page, a chat with ChatGPT or Claude, an email, or a text.

What you need before you start

1 Make the API token

An API token is a password that only works for the things you tick. It can be deleted any time without touching your real login. You will make one that can publish Pages sites and nothing else.

  1. Sign in at dash.cloudflare.com/profile/api-tokens. (That is your profile icon, top right → My Profile → API Tokens tab.)
  2. Click Create Token.
  3. Ignore the templates. Scroll to Create Custom Token and click Get started.
  4. Token name: something you will recognise in a year, for example codex-pages-publish.
  5. Permissions: each row is three dropdowns. Set them to exactly this, using + Add more for the second and third rows:
    First boxSecond boxThird boxWhy
    AccountCloudflare PagesEditCreate projects and upload sites. The only permission that does anything.
    UserUser DetailsReadLets the tool print which account it is using, so you can see it worked.
    UserMembershipsReadLets the tool list your account without being told the ID.
  6. Account Resources: Include → your account (it is the only one in the list).
  7. Client IP Address Filtering: leave empty. Your home IP changes.
  8. TTL: set an end date about a year out. When it expires nothing breaks except publishing; you make a new one and repeat step 3.
  9. Click Continue to summary, check it says Cloudflare Pages: Edit, then Create Token.
  10. The token is shown once. It starts with cfut_. Click Copy and paste it straight into Apple Passwords (or 1Password) under the name you gave it. You will paste it from there in step 3.

Below the token Cloudflare shows a curl test. You do not need it now; step 4 tests the whole chain for you.

2 Find your Account ID

This is a 32-character code that names your account. It is not secret.

  1. Go to Workers & Pages in the dashboard.
  2. On the right side there is an Account details panel with Account ID and a copy button next to it. It is also the long code in the address bar right after dash.cloudflare.com/.
  3. Paste it into the Account ID box at the top of this page so the commands below fill in.

3 Tell Codex about them

Codex reads one settings file, ~/.codex/config.toml, and hands the values in it to every command it runs. Both the Codex app and the codex command in Terminal read the same file, so you do this once.

  1. Open Terminal and paste this. It creates the file if it is missing and opens it in TextEdit:
    mkdir -p ~/.codex && touch ~/.codex/config.toml && open -a TextEdit ~/.codex/config.toml
  2. Paste this block at the end of the file. Replace the red part with the token from your password manager, keeping the quotes:
    # Cloudflare publishing for Codex (added )
    [shell_environment_policy]
    set = { CLOUDFLARE_ACCOUNT_ID = "YOUR_ACCOUNT_ID", CLOUDFLARE_API_TOKEN = "cfut_paste_the_token_here" }
  3. Save (⌘ S) and close TextEdit.

If the file already has a [shell_environment_policy] line, do not add a second one. Put the two values inside the existing set = { … }, separated by commas.

Terminal-only alternative. If you only ever use codex from Terminal, you can instead add two export CLOUDFLARE_ACCOUNT_ID=… and export CLOUDFLARE_API_TOKEN=… lines to ~/.zshrc. The Codex desktop app does not read that file, which is why the config.toml route is the default here.

4 Test it

  1. In Terminal, make a folder for your sites and start Codex inside it:
    mkdir -p ~/sites && cd ~/sites && codex
    (Or open the Codex app and choose the sites folder in your home folder.)
  2. Type this to Codex:
    Run `npx -y wrangler@4 whoami` and show me the output.
  3. Codex asks for permission to run it. Say yes. You want to see:
    👋 You are logged in with an User API Token, associated with the email you@…
    ┌───────────────┬──────────────────────────────────┐
    │ Account Name  │ Account ID                       │
    ├───────────────┼──────────────────────────────────┤
    │ your account  │ YOUR_ACCOUNT_ID                 │
    └───────────────┴──────────────────────────────────┘
If it saysIt means
You are not authenticated or it tries to open a browser loginCodex did not get the values. Re-check step 3: file saved, spelled CLOUDFLARE_API_TOKEN, quotes intact. Quit Codex fully and start it again.
Unable to retrieve email… missing User → User Details → ReadPublishing will still work. The token is just missing the cosmetic permission from the table in step 1.
Invalid API Token or Authentication error [code: 10000]The token was pasted wrong or has been deleted. Make a new one (step 1) and update the file (step 3).
Nothing about Cloudflare, just Node install chatterNormal the first time; npx is downloading wrangler. Wait for it.

5 Publish your first page

Paste the whole block below into Codex. It carries the recipe so Codex does not have to guess, and it says what to do when run a second time. Change the first sentence to whatever you want the page to be about.

Build a one-page website that says hello from NWIOI and shows today's date, then publish it to Cloudflare Pages. Follow this recipe exactly:

1. Put the site in ~/sites/nwioi-hello/ with an index.html (plain HTML and CSS, no build step, no framework).
2. The Cloudflare Pages project is named "nwioi-hello". Check whether it already exists:
   curl -s -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/pages/projects/nwioi-hello
   If the response has "success": false, create it with the API (do NOT use `wrangler pages project create`):
   curl -s -X POST -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" -H "Content-Type: application/json" -d '{"name":"nwioi-hello","production_branch":"main"}' https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/pages/projects
   If it already exists, reuse it; this same recipe is how updates get published.
3. Deploy the folder:
   npx -y wrangler@4 pages deploy ~/sites/nwioi-hello --project-name nwioi-hello --branch main --commit-dirty=true
4. Open https://nwioi-hello.pages.dev with curl to confirm it returns the page, then give me that URL.

Never print the value of CLOUDFLARE_API_TOKEN. Do not create a wrangler.toml or wrangler.jsonc file.

Codex will ask permission for the curl and wrangler commands. Say yes to each. About a minute later it hands you https://nwioi-hello.pages.dev. Open it on your phone. It is live for anyone with the address.

Why the recipe avoids wrangler pages project create: recent wrangler versions turn that command into a Workers deployment and drop a config file into the folder that then breaks pages deploy. Creating the project through the API sidesteps it. Sean hit this on 2026-09-28.

6 From here on

Changing a page

Tell Codex what to change and to "publish it the same way as before". The deploy command in step 5 is the update command too; every run replaces what is live. If Codex has forgotten the recipe (new conversation), paste step 5 again with the new instructions in the first sentence.

Another site

Pick a new name, paste step 5 with it. Each name is its own project and its own .pages.dev address. Lowercase letters, numbers and hyphens only; Cloudflare refuses names someone else already has.

A real domain instead of .pages.dev

That is a separate half hour: the domain's DNS has to be on Cloudflare, then Workers & Pages → the project → Custom domains. Do it with Sean the first time.

Taking something down

Dashboard → Workers & Pages → the project → Settings → scroll to the bottom → Delete project. The address stops working within a minute.

If the token ever leaks

API Tokens → the row's ⋯ menu → Delete. Anyone holding the old value is locked out instantly. Make a new one (step 1), update the file (step 3). Your Cloudflare login itself is never at risk from this token.

What this token can and cannot do

Cost

Cloudflare Pages on the free plan: unlimited sites and bandwidth, 20,000 files per site, 25 MB per file. Nothing in this page costs money.