Skip to main content
Use the OAuth 2.1 Authorization Code flow with PKCE when a browser-based MCP client (Cursor, Claude, and the like) connects to a paid Nevermined agent and the user approves in a browser. It’s the browser-based counterpart to the no-browser device flow — the two grants differ only in how the human approves.
Which credential you receive is chosen by the requested resource, not by the grant (details). To obtain an x402 payment permission — the credential you attach to x402 requests against the agent — request that agent’s resource. If you omit resource and send only a plan_id (a plan-only binding with no delegation), the exchange returns an NVM API key instead. A resource matching the Nevermined API host also returns an API key.

Prerequisites

  • An authenticated user. POST /oauth/authorize runs in the signed-in user’s context — the browser client calls it with the user’s Nevermined API key. Without an authenticated user it fails with BCK.OAUTH.0007.
  • A pre-registered client_id. Same as the device flow — connectors are onboarded out of band (no dynamic client registration). An unregistered client_id is rejected with BCK.OAUTH.0016.
  • PKCE is mandatory. Generate a code_verifier and its code_challenge (S256). There is no non-PKCE path.

The flow

1

Request an authorization code

From the signed-in browser session, POST to the authorization endpoint with your PKCE challenge. The request is authenticated as the user (their Nevermined API key):
client_id, redirect_uri, code_challenge, and code_challenge_method are required; agent_id, plan_id, state, and resource are optional. resource is optional but load-bearing: the agent’s resource here is what makes the exchange mint an x402 payment permission rather than an API key. Once the user approves the connection, the endpoint returns the code in the response body:
Your client then completes the OAuth hand-off by redirecting the browser to redirect_uri with the code (and your state) appended.
2

Exchange the code for the credential

Prove possession of the PKCE verifier and exchange the code:
Response:
3

Pay the agent

Because you requested the agent’s resource, the access_token is an x402 payment permission for the agent+plan you were authorized against (unlike an NVM API key, it is a JWT and is not environment-prefixed). Use it on your x402 requests to that agent. See the MCP integration for how a paywalled MCP server consumes it.
The connection the user approves is recorded as an AgentBinding — the consent receipt. The client_id is the connector fronting the connection (Cursor, Claude, LangSmith Fleet), which is distinct from the agent the consent is for. Users can review and revoke these at any time from the Connected agents surface.
Both the authorization_endpoint and the authorization_code grant are advertised in the RFC 8414 metadata. As with the device flow, discovery doesn’t substitute for a pre-registered client_id.