OpenAI's Sign in with ChatGPT lets Plus and Pro users spend their own plan allowance inside your app, so the inference bill moves off your account and onto theirs.

The requests that draw on that plan can't carry max_tool_calls, max_output_tokens, background, or temperature, so the caps you used to put on an agent loop have to live in your own code.

The first signal that a user's allowance is gone is a 429 in the middle of a task, and OpenAI's docs tell you not to quietly switch to your own key when it happens.

What shipped at DevDay

Last week at DevDay, OpenAI announced Sign in with ChatGPT with 16 launch partners. Devin, Notion, Vercel, T3, OpenClaw and Dactyl are the names in the official material, and press recaps add tools like Amp, Kilo Code, Warp and OpenCode.

There are two parts to it. The identity part is a login button, available globally, which hands your app a name, email address and profile picture. No conversations, no memories, no API keys.

The second part is the one developers will care about. With an extra scope, your app can send Responses API requests that count against the user's ChatGPT plan instead of your API account. No API key is involved. For now that's limited to open-source and locally running apps, and paid or hosted products go through an interest form.

For anyone building a coding agent, a desktop assistant or an open-source CLI, that's a real change. The hardest question in shipping one has always been who pays for the tokens. Bring-your-own-key works for developers and scares everyone else. Now the user clicks a button they already recognize and the cost lands on a subscription they're already paying.

The parameters you lose

The catch is in the preview limitations page, and it's specific. Requests on the plan-usage path must set store: false and stream: true. The following fields aren't supported: background, conversation, max_output_tokens, max_tool_calls, metadata, moderation, multi_agent, prompt, prompt_cache_retention, safety_identifier, temperature, top_logprobs, top_p, truncation and user.

Two of those matter more than the rest. max_output_tokens and max_tool_calls are how most agent builders put a ceiling on a single turn. If a model goes into a loop of reading files or calling a search tool, those are the server-side limits that stop it.

On this path, they're gone. If your agent was relying on the API to stop a runaway turn, nothing stops it now except the user's allowance running out. Since that allowance is the user's own money, the user is the one who pays for the loop.

The tool list is narrower too. Image generation, file search, Code Interpreter, native computer use, hosted MCP connectors and tool search aren't available. Your own function tools work if you group them in namespaces. previous_response_id doesn't work over HTTP either, so you send the full history in input on every call.

None of this is unreasonable for a preview. It does mean a request that works fine against your API key can fail with a 400 subscription_sharing_unsupported_capability the moment you route it through a user's plan. Run your test suite against both paths before you ship the button.

The cap belongs to someone else

Users can set a weekly cap for each connected app in their ChatGPT settings. That's good for them. For you it means there are now three limits on any given task: the user's plan, the weekly cap they set for your app, and whatever you enforce yourself. You can see only the last one.

The docs don't describe a way to ask how much allowance is left before you start. You find out when a request comes back with subscription_sharing_usage_limit_exceeded and a 429. OpenAI's recovery guidance is to pause and point the user to the Usage page in ChatGPT settings.

The same page says not to silently fall back to other billing paths, and to preserve the real status code and error. If your app has a paid tier, a credit balance or a house API key, the tempting move is to catch the 429 and keep the task running on your own account. Don't. The user gave you permission to spend their plan, not a blank check against yours, and the docs are explicit about it.

The practical consequence is that every long task needs to be resumable. A refactor across 40 files that stops at file 23 because the user's weekly cap ran out needs to save its state, tell the user why it stopped, and pick up where it left off after they raise the cap or the week resets. If your agent can't do that today, the plan-usage path will expose it fast.

Signing out isn't disconnecting

There's one detail for users, and for anyone writing internal guidance about these tools. Signing out of an app doesn't remove its connection to the ChatGPT account. The app stays linked and can keep drawing on the plan until the user removes it under Settings, Security and login, Sign in with ChatGPT.

Disconnecting also doesn't undo anything. Usage that was already counted stays counted, and data the app already received stays with the app. Eligible usage only means the inference went through OpenAI. It doesn't mean the partner didn't store your prompts, so their data policy still matters.

If you run an engineering team where people will happily click "Sign in with ChatGPT" on every new coding tool this month, add the disconnect path to your offboarding checklist next to revoking OAuth apps in GitHub and Google.

What I'd do before adding the button

Write your own turn budget. Count tool calls and output tokens in your agent loop and stop the turn yourself. You need this on every path anyway, and on the plan path it's the only limit you have.

Handle 429 as a pause, not a failure. Persist the task state on every step. When subscription_sharing_usage_limit_exceeded comes back, save, show the user exactly what happened, and give them a resume button.

Keep billing paths visibly separate. If you offer your own paid tier, make switching to it a choice the user makes on screen, with the cost shown. Never as an automatic retry.

Test both routes. Build a small matrix of your real requests and run it against an API key and a plan token. Strip temperature, max_output_tokens and hosted tools from the plan route, and send full history instead of previous_response_id.

Treat 503s differently from 429s. subscription_sharing_usage_unavailable means the usage check itself failed. Retry that with bounded backoff. A 429 means stop.

Who holds the meter

Sign in with ChatGPT solves a real problem. A lot of good open-source agents never got past developers because nobody else wanted to paste in an API key and watch a meter they didn't understand.

The meter hasn't gone away, though. It now sits in the user's ChatGPT settings, and the controls that used to sit on your side of the request, the output ceiling and the tool call ceiling, aren't on the request anymore.

If you ship this, build the budget into your loop, make the stop graceful, and assume every user's allowance will run out at the worst point in the longest task they ever give you.