Tell an AI agent a feature needs a paid plan

How to answer an AI agent at a paid-plan wall: 402 or 403, a Problem Details body with the required plan, and an upgrade link a person can open.

By AgentDrivesPublished 28 October 20265 min readTopic PaymentsFor agents Markdown

283 of 442 of the capabilities behind a paid plan, those whose wall showed in only the pricing page or the docs

283 of 442 paid-plan capabilities our agent hit showed the wall only on the pricing page or in the docs, never in the API answer. They sat at 84 of 201 products we drove. The fix: return 402, or your existing 403, with a Problem Details body that names the required plan and links to the upgrade page (RFC 9457[1]).

Where the wall showed: the API answer or the pricing page

Per capability, 113 of 442 got an API answer that named the plan. By product, each counted by the clearest signal it gave, 33 of 84 named the plan, payment or limit in the API answer, 14 of 84 gave a refusal that never said a paid plan was needed, and 37 of 84 showed the wall only on the pricing page or in the docs.

How the wall showed Capabilities Products
Named in the API answer 113 of 442 33 of 84
Refusal, no plan named 46 of 442 14 of 84
Pricing page or docs only 283 of 442 37 of 84

What an agent needs at the wall, step by step

An agent needs three things in the answer itself: a status code that says payment is the barrier, the name of the plan it needs, and a link a person can open to upgrade.

  1. The status code. 402, or 403 where existing clients depend on it. Never 401, which an agent reads as a key error and answers by trying another key: 38 of 442 gated capabilities answered 401.
  2. A machine-readable problem type. Send the body as Problem Details with the media type application/problem+json. Its type member is a URI reference that names the problem, so one stable “plan required” URI lets an agent branch on it without parsing prose (RFC 9457[1]).
  3. The current and the required plan. Problem types may add their own extension members, which is where current_plan and required_plan go. The agent can then tell its human exactly which plan to buy.
  4. A detail line for the person who approves the upgrade. The detail member is a human-readable explanation of this occurrence. Write it so the agent can pass it on as is: what was blocked and what it takes to get it.
  5. The upgrade URL, twice. Put it in the body as an extension member, and in a Link header, which RFC 8288[2] defines for links in HTTP headers. A client that only reads headers still finds it.
  6. The gated endpoints in your docs or OpenAPI spec. The pricing page or docs were the only signal for 283 of 442 gated capabilities. Keep them, and add the API answer.

An example answer, built only from standard members plus extension members:

HTTP/1.1 402 Payment Required
Content-Type: application/problem+json
Link: <https://example.com/upgrade>; rel="payment"

{
 "type": "https://example.com/probs/plan",
 "title": "This feature needs a paid plan",
 "detail": "Exports need the Team plan.",
 "current_plan": "Free",
 "required_plan": "Team",
 "upgrade_url": "https://example.com/upgrade"
}

402 or 403: what the standards allow for a plan wall

Use 402 for a paid-plan wall and carry the meaning in a Problem Details body. The standard reserves 402 without defining it, so the body, not the code, is what an agent can rely on.

RFC 9110[3] says: “The 402 (Payment Required) status code is reserved for future use.” For 403 it says: “The 403 (Forbidden) status code indicates that the server understood the request but refuses to fulfill it.” MDN[4] adds that “No standard use convention exists and different systems use it in different contexts,” and that “Actual implementations vary in the format and contents of the response.” RFC 9457’s own billing example, an out-of-credit problem, is returned with 403 and the type https://example.com/probs/out-of-credit.

In our drives, 20 of 442 gated capabilities answered 402 and 41 of 442 answered 403. Both codes have support, so the choice comes down to your clients:

  • New endpoint or new API version: return 402 with a plan-required problem type. The code names payment as the barrier and the body says which plan.
  • Existing clients parse 403: keep 403 and add the same type, required_plan and upgrade_url members, so a 402 and a 403 read the same to an agent.

Good and bad answers from public behaviour

A good wall answer names what blocks the call and what a person must do. A bad one is a bare status the agent cannot tell from a key error.

Good: tells a person what to do. Shopify[5] documents 402 for a frozen shop and says: “The shop owner needs to log in to the shop’s admin and pay the outstanding balance to unfreeze the shop.” An agent can relay that line and stop retrying.

Mixed: a retry code for a condition only payment fixes. OpenAI[6] documents a 429 error with the code credit_balance_exhausted: “Your organization has no prepaid credits remaining.” Used-up credits don’t clear with time. A plan wall should not borrow 429 at all, because waiting never opens it.

Bad: a bare 403 with no body.

HTTP/1.1 403 Forbidden
Content-Length: 0

The agent cannot tell a missing scope from an expired key from a plan it does not have.

Checklist for a paid-plan wall an agent can act on

Return 402, or your existing 403, with an application/problem+json body that has a plan-required type, the required plan, a detail line for the person and an upgrade URL, plus a Link header. List gated endpoints in your docs.

  • Status 402, or 403 where existing clients depend on it
  • Content-Type: application/problem+json
  • A stable type URI for “plan required”
  • current_plan and required_plan as extension members
  • A detail line written for the person who approves the upgrade
  • An upgrade_url a person can open in a browser
  • The same URL in a Link header
  • Not 401 and not 429 for a plan wall
  • Gated endpoints marked in your docs or OpenAPI spec

How we test it

Our drives ran from 1 October 2026 to 1 November 2026. At each product our agent tried the capabilities it found and recorded, for every one behind a paid plan, the status code and where the wall showed: in an API answer that named the plan, in a refusal that never said a paid plan was needed, or only on the pricing page or in the docs. Each product is also counted once, by the clearest signal it gave. The method is on how we drive.

What to do this week

Call one gated endpoint with a free-plan key and read the raw answer. If it has a status and nothing else, add a Problem Details body with type, required_plan and upgrade_url. Then check that the docs page for that endpoint names the plan it needs. For the rest of your errors, see Write API errors an AI agent can act on.

See what an agent finds on your pricing and sign-up.

Free: what an agent finds, any wall in its way and how many things to fix. The Audit ($499) gives you every fix.

Pages this guide cites.

As linked when it was written. ↩ goes back to where the text cites it.

  1. 1rfc-editor.org · RFC 9457rfc/rfc9457.html↩
  2. 2rfc-editor.org · RFC 8288rfc/rfc8288.html↩
  3. 3rfc-editor.org · RFC 9110rfc/rfc9110.html↩
  4. 4developer.mozilla.org · MDNen-US/docs/Web/HTTP/Reference/Status/402↩
  5. 5shopify.dev · Shopifydocs/api/usage/response-codes↩
  6. 6developers.openai.com · OpenAIapi/docs/guides/error-codes↩

Asked about this guide.

6 questions
Should a feature that needs a paid plan return 402, 403 or something else?

402 for new endpoints, with a Problem Details body. RFC 9110 reserves 402 without a defined meaning, and RFC 9457's own out-of-credit example uses 403, so both have support. Never 401, which an agent reads as a key error, and never 429, which tells it to wait.

What should the error body contain so an AI agent knows to ask its human to upgrade?

An application/problem+json body with a plan-required type URI, a detail line for the human, and extension members for the current plan, the required plan and the upgrade URL, plus the URL in a Link header.

How do I add the plan name and upgrade link without breaking clients that expect 403?

Keep the 403 and add the same members to its body: the plan-required type, the required plan and the upgrade URL. Clients that check only the status keep working, and an agent reads a 402 and a 403 the same way.

Does 402 have a standard meaning?

No. RFC 9110 reserves it for future use, and MDN notes there is no standard use convention and that response formats vary. Put the meaning in the body.

How is a paid-plan wall different from a rate limit or used-up credits?

A rate limit clears with time, so 429 and Retry-After fit it. Used-up credits and a missing plan don't clear with time: only a payment or an upgrade opens them, so the answer should say what to buy and where.

Should gated endpoints be listed in the docs or OpenAPI spec?

Yes, next to the API answer, not instead of it. An agent in the middle of a task reads the answer it got, not the pricing page.

Cite this

AgentDrives. “Tell an AI agent a feature needs a paid plan.” 28 October 2026. agentdrives.com/guides/tell-ai-agents-a-feature-needs-a-paid-plan

Drive data is CC BY 4.0. The text as Markdown. Every fact with its evidence.

More from the drives.