everyapp 0.2.2 → 0.3.0-rc.2

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.
Files changed (128) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +6 -77
  3. package/bin/everyapp.js +235 -0
  4. package/dist/access-LGEN3ABJ.js +1 -0
  5. package/dist/activity-RSD4D66F.js +12 -0
  6. package/dist/apps-4RCFXT74.js +13 -0
  7. package/dist/chunk-23HJ5I2A.js +2 -0
  8. package/dist/chunk-2Y5Q6A5K.js +6 -0
  9. package/dist/chunk-4JRIS6S6.js +1 -0
  10. package/dist/chunk-5PTNYZK6.js +4 -0
  11. package/dist/chunk-6OGVO7QK.js +6 -0
  12. package/dist/chunk-6PGUCTJ6.js +11 -0
  13. package/dist/chunk-AGTCKFRB.js +22 -0
  14. package/dist/chunk-BHMRY53V.js +2 -0
  15. package/dist/chunk-CB4U7H2G.js +4 -0
  16. package/dist/chunk-CCWBPAKH.js +4 -0
  17. package/dist/chunk-CZTEDWZ2.js +22 -0
  18. package/dist/chunk-CZXHKPRZ.js +2 -0
  19. package/dist/chunk-E3EPK27P.js +10 -0
  20. package/dist/chunk-EGEWRFVY.js +1 -0
  21. package/dist/chunk-ELK7QZ2M.js +1 -0
  22. package/dist/chunk-FJJSSVET.js +33 -0
  23. package/dist/chunk-GKBPYVP3.js +25 -0
  24. package/dist/chunk-H6QQMY7B.js +18 -0
  25. package/dist/chunk-H7PDL3X5.js +1 -0
  26. package/dist/chunk-HOUHG236.js +20 -0
  27. package/dist/chunk-IFCPALVC.js +46 -0
  28. package/dist/chunk-IUOBIB5M.js +30 -0
  29. package/dist/chunk-J35DDCNU.js +1 -0
  30. package/dist/chunk-J455FAEN.js +7 -0
  31. package/dist/chunk-JYKRUS5C.js +1 -0
  32. package/dist/chunk-LXYMDZER.js +1 -0
  33. package/dist/chunk-LYNBZ7RV.js +57 -0
  34. package/dist/chunk-M2QQ2UD7.js +132 -0
  35. package/dist/chunk-N4E5YE4X.js +5 -0
  36. package/dist/chunk-N5GQLGEC.js +2 -0
  37. package/dist/chunk-NFU4YFXB.js +1 -0
  38. package/dist/chunk-OM2HDWVP.js +1 -0
  39. package/dist/chunk-ONLNJXVQ.js +32 -0
  40. package/dist/chunk-OP4DYXYI.js +2 -0
  41. package/dist/chunk-PNLU5U3P.js +1 -0
  42. package/dist/chunk-PS7S74DG.js +6 -0
  43. package/dist/chunk-RMF4YGD6.js +98 -0
  44. package/dist/chunk-T2GD7RHS.js +10 -0
  45. package/dist/chunk-TLRM3P7V.js +15 -0
  46. package/dist/chunk-W3JCQHHU.js +1 -0
  47. package/dist/chunk-WOVS3GV5.js +10 -0
  48. package/dist/chunk-YHJZMJYZ.js +1 -0
  49. package/dist/chunk-ZECBN24L.js +15 -0
  50. package/dist/chunk-ZEXVHB22.js +2 -0
  51. package/dist/chunk-ZFCUH5PK.js +7 -0
  52. package/dist/configure-F7UZCJUG.js +8 -0
  53. package/dist/create-2E5HVWYK.js +22 -0
  54. package/dist/db-HEQVTDTM.js +9 -0
  55. package/dist/delete-XCSIQIRS.js +3 -0
  56. package/dist/deploy-3QOZEZHC.js +1 -0
  57. package/dist/dev-JL3ZP5BT.js +86 -0
  58. package/dist/email-RLZFUFUN.js +10 -0
  59. package/dist/events-2V5VRBWP.js +15 -0
  60. package/dist/groups-HDG5DVFY.js +8 -0
  61. package/dist/index.js +97 -1
  62. package/dist/install-Z5FYXUYM.js +1 -0
  63. package/dist/login-KHJBC64Z.js +1 -0
  64. package/dist/mcp-EFDUKJ5V.js +1 -0
  65. package/dist/provider-EOI5PTFH.js +13 -0
  66. package/dist/release-74J5ZIL3.js +1 -0
  67. package/dist/restore-FFGYV7NO.js +3 -0
  68. package/dist/secret-7FKKTLHB.js +1 -0
  69. package/dist/setup-PAKRCAFO.js +1 -0
  70. package/dist/signin-AP3D4XM4.js +12 -0
  71. package/dist/status-RMWNHOEK.js +4 -0
  72. package/dist/teardown-E4JNKAZJ.js +22 -0
  73. package/dist/update-DWVZFNPS.js +1 -0
  74. package/dist/workspace-CJC5I66L.js +21 -0
  75. package/package.json +19 -16
  76. package/skills/build-every-app/SKILL.md +199 -0
  77. package/skills/build-every-app/patterns.md +140 -0
  78. package/skills/everyapp/SKILL.md +292 -0
  79. package/skills/everyapp/mcp.md +350 -0
  80. package/skills/everyapp/security-review.md +61 -0
  81. package/skills/everyapp/setup/README.md +274 -0
  82. package/skills/everyapp/setup/access.md +178 -0
  83. package/skills/everyapp/setup/context.md +117 -0
  84. package/skills/everyapp/setup/dataforseo.md +287 -0
  85. package/skills/everyapp/setup/email.md +366 -0
  86. package/skills/everyapp/setup/gateway.md +243 -0
  87. package/skills/everyapp/setup/google.md +360 -0
  88. package/skills/everyapp/setup/microsoft-365.md +281 -0
  89. package/skills/everyapp/setup/openai.md +318 -0
  90. package/skills/everyapp/setup/openrouter.md +309 -0
  91. package/skills/everyapp/setup/providers.md +1253 -0
  92. package/skills/everyapp/setup/remote-mcp.md +199 -0
  93. package/skills/everyapp/setup/signin-apple.md +178 -0
  94. package/skills/everyapp/setup/signin-cloudflare.md +148 -0
  95. package/skills/everyapp/setup/signin-github.md +139 -0
  96. package/skills/everyapp/setup/signin-google.md +178 -0
  97. package/skills/everyapp/setup/signin-microsoft.md +183 -0
  98. package/skills/everyapp/setup/signin-oidc.md +163 -0
  99. package/skills/everyapp/setup/slack.md +344 -0
  100. package/skills/everyapp/setup/workers-ai.md +138 -0
  101. package/bin/__everyapp_bash_complete.js +0 -12
  102. package/dist/bash-complete.js +0 -3
  103. package/dist/chunk-7BOQJFI5.js +0 -8
  104. package/dist/chunk-7YVJFS4A.js +0 -1
  105. package/dist/chunk-BIXKPCDH.js +0 -2
  106. package/dist/chunk-DLGPLHBH.js +0 -47
  107. package/dist/chunk-FD6K2YA7.js +0 -9
  108. package/dist/chunk-GAJEQYJH.js +0 -39
  109. package/dist/chunk-O2KDOP5R.js +0 -13
  110. package/dist/chunk-OI2MBGBG.js +0 -4
  111. package/dist/chunk-POSDLD3G.js +0 -8
  112. package/dist/chunk-RB5D2R45.js +0 -1
  113. package/dist/chunk-U4LIQ5VR.js +0 -1
  114. package/dist/chunk-VEYSNPDH.js +0 -3
  115. package/dist/chunk-VP6SKW44.js +0 -7
  116. package/dist/chunk-WO3NE7ZU.js +0 -7
  117. package/dist/chunk-XTO2VTPY.js +0 -6
  118. package/dist/chunk-YJ2DKIZS.js +0 -1
  119. package/dist/create-DYQ3NBWJ.js +0 -22
  120. package/dist/deploy-PYTCMDGV.js +0 -7
  121. package/dist/deploy-RMAHOA4Z.js +0 -55
  122. package/dist/dev-SAE237FS.js +0 -0
  123. package/dist/generateConfig-46Z3ERF3.js +0 -1
  124. package/dist/login-B6EF3SMX.js +0 -1
  125. package/dist/logout-XMKZBLNV.js +0 -1
  126. package/dist/remoteD1Shell-A67JMO3H.js +0 -6
  127. package/dist/setupLocal-TZJUW5ES.js +0 -6
  128. package/gateway/every-app-gateway-build.tar.gz +0 -0
@@ -0,0 +1,318 @@
1
+ # OpenAI for the Gateway
2
+
3
+ One `OPENAI_API_KEY` on the Gateway lets every app whose `everyapp.config.ts`
4
+ lists `providers: ["openai"]` call OpenAI's inference endpoints through the
5
+ Gateway, which puts the key on each call; no app holds it. No launch app
6
+ lists it (OpenSEO, Open CRM and agentic-inbox use OpenRouter; Open Analytics
7
+ has no AI provider); an app that lists `providers: ["openai"]` in its manifest does. Set it up when
8
+ `pnpm everyapp secret list <app id> --json` lists `OPENAI_API_KEY` in
9
+ `data.app.setup.unmet`, or `status` says the app needs setup and names this
10
+ file. At the end the person has an
11
+ OpenAI organization with a card and prepaid credits, one project API key
12
+ the Gateway holds, and a call that answers.
13
+
14
+ ## Settings
15
+
16
+ | Name | Required or optional | What it holds |
17
+ | ----------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
18
+ | `OPENAI_API_KEY` | required by any app listing the `openai` provider | one OpenAI project API key, exactly as shown once at creation (starts with `sk-`); the Gateway sends it as `Authorization: Bearer` to `api.openai.com` only |
19
+ | `AI_PROXY_EXTRA_ROUTES` | optional; required when the app's manifest has `ai.routes` | OpenAI paths beyond inference the Gateway may forward: comma or space separated, each starting with `/v1/` and made of lowercase letters, digits, `_` and `-` (`/v1/files`, or `/v1/files,/v1/batches`); each covers its sub-paths; an entry in any other shape is dropped silently; one list for every app on the Gateway, replaced whole by each `secret set`; not a secret |
20
+
21
+ Inference needs no extra route: POST to `/v1/responses`,
22
+ `/v1/chat/completions`, `/v1/embeddings`, `/v1/audio/speech`,
23
+ `/v1/audio/transcriptions`, `/v1/audio/translations`,
24
+ `/v1/images/generations`, `/v1/images/edits`, `/v1/images/variations`. On
25
+ `/v1/responses` and `/v1/chat/completions` the Gateway sets `store: false`:
26
+ OpenAI keeps no copy of the response for later retrieval, so an app can't
27
+ chain `previous_response_id` through it; OpenAI's usual API retention
28
+ (abuse-monitoring logs, up to 30 days, unless the organization is approved
29
+ for Zero Data Retention) still applies. Any other path goes through only
30
+ when both `AI_PROXY_EXTRA_ROUTES` and the app's `ai.routes` cover it: one
31
+ key serves every app in every organization, and OpenAI keeps files, batches
32
+ and fine-tunes per account.
33
+
34
+ ## Costs and plans
35
+
36
+ As of October 2026 the API is prepaid. Billing needs a card; the first
37
+ purchase is $5 at least ($10 by default), auto-reload is on by default
38
+ during setup, credits expire after one year and are not refunded. New
39
+ accounts get no sign-up credits (unverified: third-party reports; OpenAI's
40
+ own pages don't say). Usage tiers rise with total credit purchases: Free
41
+ ($100 a month ceiling, allowed geographies only), Build ($5 bought, $500 a
42
+ month), Launch ($100, $5,000 a month), Grow ($500, $200,000 a month); each
43
+ tier sets requests and tokens per minute per model, reported in
44
+ `x-ratelimit-*` response headers. A ChatGPT subscription is separate and
45
+ gives no API credit.
46
+
47
+ ## Only a person can
48
+
49
+ - Sign up or sign in at platform.openai.com and accept OpenAI's terms.
50
+ - Add a card and buy credits.
51
+ - Verify a phone number when the account creates its first key.
52
+ - Create the project API key and copy it off the screen; it is shown once.
53
+ - Set a spend limit on the organization or project, if they want one.
54
+ - Complete API Organization Verification (a government ID upload) when a
55
+ model the app uses asks for it.
56
+
57
+ ## Before you start
58
+
59
+ 1. `pnpm everyapp secret list <app id> --json`, from any directory (the app
60
+ id is `data.apps[].id` in `status`, 2, or the `id` in the app's
61
+ `everyapp.config.ts`; in the app's directory `pnpm everyapp secret list
62
+ --json` reads that file instead of the registry and works before the
63
+ first deploy too): the `OPENAI_API_KEY` entry in `data.app.setup.unmet`
64
+ (`names` `["OPENAI_API_KEY"]`, `need.kind` `required`, `holder`
65
+ `gateway`, `setup` `setup/openai.md`; a manifest with `ai.routes` adds
66
+ an entry `"id": "ai-routes"` with `names` `["AI_PROXY_EXTRA_ROUTES"]` and
67
+ the same `setup`) means this file applies, and the app doesn't open until
68
+ it is set: the Gateway lists it as needing setup, sends a browser opening
69
+ `https://<app>.<app base domain>` to its setup dialog and answers
70
+ anything else 503 `app_needs_setup`. `data.app.setup.command` is
71
+ `pnpm everyapp configure <app id>`, which asks for every missing setting
72
+ (`data.next` repeats it). No `OPENAI_API_KEY` entry in
73
+ `data.app.setup.settings`: the manifest's `providers` doesn't list
74
+ `openai`; nothing to do. The entry with `"set": true`: ask before
75
+ replacing it; the old value can't be read back, so replacing means a new
76
+ key. A manifest that writes the provider as `{ id: "openai", optional:
77
+ true }` puts it in `settings` with `need.kind` `optional` and never in
78
+ `unmet`: the app opens without it, and this file still applies while
79
+ `set` is false. The older fields still say the same:
80
+ `data.gateway.needed` has `{"name":"OPENAI_API_KEY","required":true,"set":false}`
81
+ (and `AI_PROXY_EXTRA_ROUTES` when the manifest has `ai.routes`), and
82
+ `data.gateway.missing` lists what is still to set. This is how an agent
83
+ lands here: `status` (under "<app> needs setup") and `secret list <app id>`
84
+ (under the unmet setting) print `Guide:
85
+ .claude/skills/everyapp/setup/openai.md`, and `secret list --json` carries the path as the entry's `setup` (in the
86
+ checkout: `packages/cli/skills/everyapp/setup/openai.md`).
87
+ 2. `pnpm everyapp status --json`: `data.installed` and `data.claimed` are
88
+ true, `data.gatewayUrl` is `https://<gateway host>`; the app's entry in
89
+ `data.apps` carries the same `setup`, and while a required setting is
90
+ missing `data.fixes` has `APP_NEEDS_SETUP` for it (severity `warning`,
91
+ headline "<app> needs setup", `run` the same command). Not installed, or
92
+ no owner: [gateway.md](gateway.md) first.
93
+ 3. Same output as 1, `data.app.deployed`: false means the app isn't deployed
94
+ yet (from anywhere, an app that was never deployed ends `secret list
95
+ <app id>` with the error `APP_NOT_FOUND`, "<app> isn't deployed to this
96
+ Gateway yet", instead; the directory form shows `deployed: false`). A
97
+ Gateway setting is set anyway, from any directory; deploy the app after,
98
+ or before, as the person likes.
99
+ 4. The question step 1 asks: do they already have an OpenAI API account
100
+ with credits, and a project key they want to use? A key that was ever
101
+ pasted in a chat or a ticket has been seen: make a new one.
102
+
103
+ ## Steps
104
+
105
+ One Person step per message: give the step, wait for the words it ends
106
+ with ("signed in", "credits bought", the project's name, "done"), then the
107
+ next. Not a checklist to send at once; only steps 5 and 6 go together, so
108
+ the key goes from the clipboard to the hidden prompt with nothing to wait
109
+ for in between. Where to begin is step 1's answer: no account, step 2; an
110
+ account without credits, step 3; account and credits, step 5; step 4 only
111
+ when they want a project of their own.
112
+
113
+ 1. **You:** Tell the person what Before you start found (set, missing,
114
+ deployed or not), say in one line what the key is for (the Gateway adds
115
+ it to every OpenAI call the app makes; the app never holds it), ask the
116
+ question in Before you start 4, and stop. Nothing from the steps below
117
+ until they answer.
118
+ 2. **Person:** Sign in or sign up. Open https://platform.openai.com; signed
119
+ out, it offers "Sign up or login with an OpenAI account". Continue with
120
+ an email, Google, Microsoft or Apple account and confirm the email. The
121
+ first sign-in creates an organization with a "Default project". It
122
+ worked when the dashboard at https://platform.openai.com opens. Wait for
123
+ "signed in".
124
+ 3. **Person:** Add billing. Open
125
+ https://platform.openai.com/settings/organization/billing/overview (in
126
+ the dashboard: Settings, Organization, Billing). Click "Add payment
127
+ details", pick Individual or Company, enter the card, then the initial
128
+ credit amount (minimum $5, default $10). Auto-reload (a balance
129
+ threshold, the balance to restore to, an optional monthly limit) is on
130
+ by default on that screen; turn it off unless they want it. Credits
131
+ belong to the organization, not to a project. It worked when the
132
+ billing overview shows a credit balance; a new balance can take a few
133
+ minutes to appear. Wait for "credits bought".
134
+ 4. **Person:** A project, optional. The Default project is fine for one
135
+ Gateway. For a separate one: on https://platform.openai.com, the project
136
+ selector (top left), "Create project", a name (description and website
137
+ optional), "Create"; only organization owners can. The projects list is
138
+ at https://platform.openai.com/projects (owners only). Wait for the
139
+ project's name.
140
+ 5. **Person:** Create the key. In several organizations, pick the one with
141
+ the credits top left first. Open https://platform.openai.com/api-keys.
142
+ Click "+ Create new secret key". In the dialog: Owned by "You"; Name
143
+ such as `every-app gateway`; Project: any project of that organization
144
+ (the Default project is fine); Permissions "All"; Expiration: leave it
145
+ unset, or set a date and note it where they'll see it, since the key
146
+ stops working that day (Rotate, below). The account's first key asks
147
+ for a phone number (a code by SMS or WhatsApp; no VoIP, landline or
148
+ Google Voice numbers; a number serves at most three OpenAI accounts,
149
+ deleted ones counted). Click "Create secret key", then "Copy". The key
150
+ is shown once; after the dialog closes it can't be viewed again. Not in
151
+ the chat: straight on to step 6, with the dialog still open.
152
+ Aside: "Restricted" works with "Model Capabilities: Request" (add
153
+ "Responses API: Write" when the app posts to `/v1/responses`) and "List
154
+ Models: Read" for the smoke check; "Read Only" cannot run inference. A
155
+ service account's key works only in a project from step 4 (none can be
156
+ added to the Default project) and gets full project permissions, with
157
+ no Permissions choice at creation.
158
+ 6. **Person:** Set it, the README's first way (the value is on a dashboard
159
+ they are looking at). In a second terminal, in the `every-app` folder:
160
+ `pnpm everyapp configure <app id>`, which asks for this key among the
161
+ app's other unset settings (`AI_PROXY_EXTRA_ROUTES` too, at a visible
162
+ prompt, when the manifest has `ai.routes`: step 7 says what it takes),
163
+ or `pnpm everyapp secret set OPENAI_API_KEY` for just this one; paste at
164
+ the hidden prompt (nothing is echoed). It prints
165
+ `Set OPENAI_API_KEY on the Gateway`, then "Live now. No deploy needed."
166
+ (`secret set`: "Live now on <gateway host>. No deploy needed."). Wait
167
+ for "done".
168
+ Alternative, the README's third way, when the person exported
169
+ `OPENAI_API_KEY` before starting you: **You:**
170
+ `pnpm everyapp configure <app id> --from-env --json` (the `done` event's
171
+ `data.set` holds `OPENAI_API_KEY`) or
172
+ `pnpm everyapp secret set OPENAI_API_KEY --from-env OPENAI_API_KEY --json`
173
+ (its `data.gateway.names` holds `OPENAI_API_KEY`).
174
+ 7. **You:** Only when a manifest has `ai.routes`. The value is one list for
175
+ every app on the Gateway, and `secret set` replaces it whole, so a list
176
+ set for one app drops another's: `pnpm everyapp status --json` lists
177
+ the apps (`data.apps[].id`), and each app with `ai.routes` has, in its
178
+ `setup.settings`, an entry `"id": "ai-routes"` whose `why` names them
179
+ ("Lets the app call /v1/files, /v1/batches through the AI proxy."); no
180
+ checkout needed (one with an `everyapp.config.ts` at hand says the same
181
+ under `ai.routes`). Pipe the union, comma separated, every time. It
182
+ isn't a secret, so echo is fine:
183
+ `echo "/v1/files,/v1/batches" | pnpm everyapp secret set AI_PROXY_EXTRA_ROUTES --json`;
184
+ the `done` event's `data.gateway.names` holds `AI_PROXY_EXTRA_ROUTES`.
185
+ One name per pipe. It can't be read back: tell the person what it holds.
186
+ 8. **You:** Verify, below.
187
+
188
+ ## Verify
189
+
190
+ 1. `pnpm everyapp secret list <app id> --json`, from anywhere: the
191
+ `OPENAI_API_KEY` entry in `data.app.setup.settings` has `"set": true`
192
+ and has left `data.app.setup.unmet` (the `ai-routes` entry too, after
193
+ step 7); `data.app.setup.ready` is true once nothing else of the app's
194
+ is missing, and `data.app.setup.command` is null then. In the older
195
+ fields, `OPENAI_API_KEY` is in `data.gateway.names`, its
196
+ `data.gateway.needed` entry has `"set": true`, and it left
197
+ `data.gateway.missing` (the `next` array no longer names it). Then
198
+ `pnpm everyapp status --json`: the app's `setup.ready` is true and
199
+ `data.fixes` has no `APP_NEEDS_SETUP` for it.
200
+ 2. Smoke check, in the person's terminal, with the key exported there
201
+ (never in yours; it bills nothing). If they typed it at the prompt in
202
+ step 6 and have no variable, skip to 3; or they read it in hidden in
203
+ their own terminal (README's third way: `read -rs OPENAI_API_KEY &&
204
+ export OPENAI_API_KEY`, paste, Enter; never a typed `export …=`, which
205
+ the shell history keeps) and `unset` it after.
206
+
207
+ ```bash
208
+ curl -s https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY" | head -c 300
209
+ ```
210
+
211
+ Expected: `{"object":"list","data":[{"id":"…","object":"model",…`.
212
+ A 401 body means the key is wrong; a 429 with
213
+ `"type":"insufficient_quota"` means the key is right and the billing
214
+ isn't (see below). Then `unset OPENAI_API_KEY`. A "Restricted" key
215
+ without "List Models: Read" fails this GET while inference still works;
216
+ use the app check instead.
217
+ 3. The app: open `https://<app>.<app base domain>` and use the feature that
218
+ calls OpenAI. A browser sent to `https://<gateway host>/?setup=<app id>`
219
+ instead (a page's own fetch: 503 with the body
220
+ `{"error":"app_needs_setup","app":"<app id>"}`) is the Gateway's setup
221
+ gate: a required setting is still unset, Verify 1 says which. Any
222
+ response with an `x-everyapp-error` header is the Gateway's, and the
223
+ header names the code: 503 `ai_provider_not_configured` means it holds
224
+ no key under that name (behind the gate only an app whose manifest marks
225
+ `openai` `optional: true` opens in that state and sees this); a 401
226
+ `missing_caller_identity` or `caller_identity_invalid` means the
227
+ call didn't carry the app's identity (an app or SDK problem, nothing to
228
+ set). A response without the header is OpenAI's, status and body
229
+ unchanged. In the app's code the call is
230
+ `createGatewayFetch({ env, for })` to
231
+ `http://every-app-gateway.internal/api/ai/openai/v1/chat/completions`.
232
+ 4. The Gateway's logs, when the app's error isn't clear: Cloudflare
233
+ dashboard, README's path: **Workers & Pages** → `every-app-gateway` → **Observability** (**Logs** on older accounts) → **Live**
234
+ streams now (nothing stored, 10 viewers at most); Workers Logs is on
235
+ for the Gateway, so the same page keeps them too. Each OpenAI call logs
236
+ `ai.proxy.usage` with `provider`, `appId`, `route`, `model`, `status`,
237
+ `requestId` (OpenAI's `x-request-id`) and `usage`; a connection that
238
+ failed logs `ai.proxy.upstream_failed`; never the prompt or the key.
239
+ `cf` has no Worker tail command (`cf workers --help` lists none);
240
+ `npx wrangler tail every-app-gateway` streams the same (wrangler isn't
241
+ in the checkout: npx fetches it, and it asks for its own Cloudflare
242
+ login the first time; unverified whether cf's login carries over).
243
+
244
+ ## If it fails
245
+
246
+ | Error or symptom | Meaning | What to do |
247
+ | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
248
+ | `SECRET_VALUE_REQUIRED` from `secret set` | nothing was piped and there is no terminal to ask in | one of README's three ways: the person's terminal, a pipe, or `--from-env` |
249
+ | `SECRET_VALUE_REQUIRED` from `pnpm everyapp configure <app id> --json` | nothing was piped (with `--from-env`, stdin isn't read), no variable of a missing name was found, and there is no terminal; the message names what the app still needs | the person's terminal (step 6), `NAME=value` lines on stdin, or the hidden read then its `data.rerun`, `pnpm everyapp configure <app id> --from-env` |
250
+ | `SECRET_SEVERAL_NAMES` | several names with `--from-env` or a pipe, which carry one value | one call per name |
251
+ | `SECRET_EMPTY` | the `--from-env` variable is unset or empty in your process | the person reads it in hidden (README's third way) in the shell that runs the command, or types it at the prompt |
252
+ | `SECRET_NOT_DECLARED` with `data.didYouMean` | the name is misspelt | rerun with the name in `data.didYouMean` and the same value source (`--from-env VAR --json`, or the same pipe); `data.rerun` carries only the names, so run as is it stops with `SECRET_VALUE_REQUIRED` |
253
+ | `CONFIRMATION_REQUIRED` from `secret unset --json` | no `--yes`, and no terminal to ask in | that is the ask: show it to the person; rerun with `--yes` only if they say so |
254
+ | a browser opening the app is sent to `https://<gateway host>/?setup=<app id>`; any other request gets 503 with the body `{"error":"app_needs_setup","app":"<app id>"}` | the Gateway's setup gate: a required setting of the app is still unset (this key, `AI_PROXY_EXTRA_ROUTES` when the manifest has `ai.routes`, or another the manifest requires) | `data.app.setup.command`, `pnpm everyapp configure <app id>` (step 6), then Verify step 1 |
255
+ | 503, `x-everyapp-error: ai_provider_not_configured` | the Gateway holds no `OPENAI_API_KEY` (behind the setup gate an app whose manifest requires `openai` doesn't open in this state; one that marks it `optional: true` sees this) | `secret set` it; then Verify step 1 |
256
+ | 400 `ai_request_invalid` | an inference POST whose body isn't a JSON object, or a malformed path | an app bug; nothing to set |
257
+ | 403 `provider_not_allowed` | the app's manifest `providers` doesn't list `openai` | add it and `pnpm everyapp deploy --json` |
258
+ | 403 `ai_route_not_allowed` | not an inference POST, and the path isn't covered by both `ai.routes` and `AI_PROXY_EXTRA_ROUTES` | step 7 with the union including that path, and `ai.routes` in the manifest, then deploy |
259
+ | 403 `model_not_allowed` | the manifest's `ai.models` doesn't list the model | add it there and deploy |
260
+ | 502 `ai_upstream_failed` | `api.openai.com` didn't answer | retry; check https://status.openai.com |
261
+ | OpenAI 401 "Incorrect API key provided" | the key is wrong: a typo, trailing text, a revoked key, an expired one (its Expiration date passed), or a deleted project | a new key (step 5), `secret set` again; see Rotate |
262
+ | OpenAI 401 "You must be a member of an organization to use the API" | the account is in no organization | the person asks an organization owner to invite them, or OpenAI support |
263
+ | OpenAI "insufficient permissions … Missing scopes: model.request" | a "Restricted" key without "Model Capabilities: Request" | a new key with Permissions "All" (step 5), `secret set` again |
264
+ | OpenAI 403 "Country, region, or territory not supported" | the call's origin isn't served; the Gateway runs on Cloudflare's edge | the person checks https://developers.openai.com/api/docs/supported-countries; nothing to set |
265
+ | OpenAI 403 "Your organization must be verified to use the model …" | that model needs API Organization Verification (GPT Image models; summaries with the latest reasoning models); no model page says so, only this error | **Person:** https://platform.openai.com/settings/organization/general, "Verify Organization", a government ID from a supported country (one ID verifies one organization every 90 days; not every organization qualifies), then up to 15 minutes; Verify step 3 again. Or a model that isn't gated, in `ai.models` |
266
+ | OpenAI 429, `type` `insufficient_quota` or `code` `credit_balance_exhausted` | the key is valid but the organization has no prepaid credits: none bought yet, a balance still posting, or credits expired | step 3; wait a few minutes after buying; https://platform.openai.com/settings/organization/limits |
267
+ | OpenAI 429 `project_spend_limit_exceeded` or `organization_spend_limit_exceeded` | a hard spend limit the person set was reached | raise or remove it on the limits page, or the project's settings |
268
+ | OpenAI 429 `organization_usage_limit_exceeded` | the tier's monthly ceiling | more credit purchases raise the tier; or OpenAI support |
269
+ | OpenAI 429 "Rate limit reached" or `slow_down` | requests too fast for the tier | follow `Retry-After`; a higher tier |
270
+ | OpenAI 503 `server_is_overloaded` | the model is overloaded | retry after `Retry-After` |
271
+ | `done`, but the app still says 503 | the app got the error before the Gateway's new version served | try once more; then Verify step 1 |
272
+
273
+ ## Rerun, rotate, remove
274
+
275
+ - Rerun: every step is safe to repeat; `configure` and `secret set`
276
+ replace the value. Interrupted or back later: start at Verify and
277
+ continue at the first step that isn't done.
278
+ - Rotate: step 5 for a new key (OpenAI recommends an Expiration date and a
279
+ regular rotation: make the replacement before the old key expires), step
280
+ 6, Verify, then revoke the old key at https://platform.openai.com/api-keys
281
+ (its row's delete action). Apps switch at the Gateway's next request.
282
+ - Remove: `pnpm everyapp secret unset OPENAI_API_KEY --json`. Without
283
+ `--yes` it stops with `CONFIRMATION_REQUIRED`: that is the ask; show it
284
+ to the person and rerun with `--yes` only if they say so. The `done`
285
+ event's `data.gateway.names` lists what was removed; when nothing held
286
+ the name, `done` has `data.removed: false`. Then revoke the key at
287
+ https://platform.openai.com/api-keys: a key the Gateway no longer holds
288
+ is still a key. The same for `AI_PROXY_EXTRA_ROUTES` (it empties the list
289
+ for every app). Apps whose manifest requires `openai` (or, through
290
+ `ai.routes`, the routes list) then need setup again: the Gateway closes
291
+ them until the setting is back (`status` says so, with this file's
292
+ path); an app that marks the provider `optional: true` keeps opening and
293
+ answers 503 `ai_provider_not_configured` on each call instead.
294
+
295
+ ## Sources
296
+
297
+ Verified on 2026-10-23:
298
+
299
+ - https://developers.openai.com/api/docs/guides/error-codes (401, 403 with the supported-countries link, 429 codes, `credit_balance_exhausted`, 503)
300
+ - https://developers.openai.com/api/docs/guides/rate-limits (usage tiers Free, Build, Launch, Grow; Free needs an allowed geography; `x-ratelimit-*` headers)
301
+ - https://developers.openai.com/api/docs/guides/rbac ("Model capabilities: Request", "Responses API: Read, Write", "List models: Read"; `/v1/models` needs `api.model.read`)
302
+ - https://developers.openai.com/api/docs/api-reference/models/list (the smoke check and its response)
303
+ - https://developers.openai.com/api/docs/guides/your-data (abuse-monitoring logs kept up to 30 days on every endpoint; a Response is kept 30 days when `store` is true; Zero Data Retention needs OpenAI's approval and forces `store` to false) and https://developers.openai.com/api/docs/api-reference/responses/create (`store`: "Whether to store the generated model response for later retrieval via API", true when omitted)
304
+ - https://developers.openai.com/api/docs/guides/production-best-practices (projects, key expiration and rotation, limits page)
305
+ - https://developers.openai.com/api/docs/guides/spend-limits (organization and project spend limits; credits are the organization's)
306
+ - https://developers.openai.com/api/docs/guides/image-generation and https://developers.openai.com/api/docs/guides/reasoning (API Organization Verification for GPT Image models and reasoning summaries)
307
+ - https://developers.openai.com/api/docs/supported-countries
308
+ - https://help.openai.com/en/articles/8264644-setting-up-and-managing-prepaid-api-billing and https://help.openai.com/en/articles/8264778-what-is-prepaid-billing (the organization's billing overview, "Add payment details", minimum $5, default $10, auto-reload with its threshold, restore-to amount and monthly limit, one-year expiry), https://help.openai.com/en/articles/8156019-how-can-i-start-using-the-api and https://help.openai.com/en/articles/9039756-billing-settings-in-the-api-platform (both link the billing overview as `/settings/organization/billing/overview`); help.openai.com refuses direct fetches: read through a reader proxy, or search snippets
309
+ - https://help.openai.com/en/articles/9186755-managing-projects-in-the-api-platform (the Default project takes no members or service accounts, "Create project" with name, description and website, owners only; the Projects page is https://platform.openai.com/projects; reader proxy)
310
+ - https://platform.openai.com signed out (rendered through a reader proxy: "Sign up or login with an OpenAI account"); OpenAI's own pages cite no `/signup` URL, only https://platform.openai.com/login
311
+ - https://help.openai.com/en/articles/8867743-assign-api-key-permissions (All, Restricted, Read Only; service account keys get no permission controls at creation; snippets)
312
+ - https://help.openai.com/en/articles/8983040-what-does-phone-verification-look-like and https://help.openai.com/en/articles/8983024-can-i-use-a-premium-number-landline-google-voice-or-other-voip-phone-number (phone verification at the first key, SMS or WhatsApp, no VoIP; snippets)
313
+ - https://help.openai.com/en/articles/10910291-api-organization-verification (government ID; Settings, Organization, General, "Verify Organization"; snippets) and https://techcrunch.com/2025/04/13/access-to-future-ai-models-in-openais-api-may-require-a-verified-id/ (one ID per organization every 90 days; not every organization qualifies)
314
+ - https://help.openai.com/en/articles/4936824 (sign-in with Google, Microsoft or Apple; snippets)
315
+ - https://community.openai.com/t/missing-scopes-model-request-on-restricted-api-key/1371602 (the Restricted dialog's labels and the `model.request` error), https://community.openai.com/t/unable-to-use-api-phone-number-reached-max-uses/625230 (three accounts per number, deleted ones counted), https://github.com/openai/codex/issues/1982 (the verification error's text)
316
+ - https://help.specinnovations.com/openai-api-key (third party: the key dialog's fields)
317
+ - https://developers.cloudflare.com/workers/observability/logs/real-time-logs/ (the dashboard path, `npx wrangler tail`, 10 viewers, nothing stored) and wrangler's `src/tail/index.ts` (the Worker name as an optional positional)
318
+ - In this checkout: `apps/every-app-gateway/src/server/ai-proxy.ts` (routes, `store: false`, `AI_PROXY_EXTRA_ROUTES` parsing, refusal codes, log events), `apps/every-app-gateway/src/server/app-gateway-entrypoint.ts` (identity refusals on `/api/ai/*`), `apps/every-app-gateway/cloudflare.config.ts` (Workers Logs on), `packages/perimeter/src/manifest/manifest.ts` (`ai.routes`), `packages/sdk/src/internal/gatewaySettings.ts`, `packages/sdk/src/internal/appSettings.ts` (`AppSetup`: `unmet`, `settings`, `groups`, `command`; the `ai-routes` entry and its `why`; `needOf`: a plain provider id is required, `optional: true` isn't; `setup/openai.md` from the provider registry, `packages/sdk/src/internal/aiProviders.ts`), `packages/cli/src/commands/secret/index.ts` (`secret list <app>` from anywhere, `data.app.setup`, `data.app.deployed`, `APP_NOT_FOUND`, `SECRET_NOT_DECLARED` and its `data.rerun`, `data.gateway.names`, `data.gateway.needed`, `data.removed`), `packages/cli/src/commands/configure/index.ts` (`configure <app>`: the prompts, `NAME=value` lines on stdin, `--from-env`, `SECRET_VALUE_REQUIRED`), `packages/cli/src/lib/app/settings.ts` (the `Guide:` line), `packages/cli/src/commands/status/problems.ts` (`APP_NEEDS_SETUP`), `apps/every-app-gateway/src/server/app-needs-setup.ts` (the setup gate: the redirect to `/?setup=<app id>` and 503 `app_needs_setup`), `packages/cli/src/lib/secretValue.ts` (`SECRET_VALUE_REQUIRED`, `SECRET_SEVERAL_NAMES`, `SECRET_EMPTY`), `packages/cli/src/lib/output/prompt.ts` (`CONFIRMATION_REQUIRED`), `landing-page/content/docs/create-an-app.mdx`, `docs/capabilities.md`