Stripe | Financial Infrastructure to Grow Your Revenue

Stripe | Financial Infrastructure to Grow Your Revenue

4466 articles

Set up OAuth for Link CLI


Set up OAuth for Link CLI

Before your agent can retrieve payment credentials or financial data, it needs an access token from a customer. Hosted agents use the authorization code flow described here, which uses a registered OAuth client.

To authorize a local agent running on your own machine, use the device authorization flow instead. See the link-cli repository.

Before you begin

Before you begin, make sure that:

  • You have a Stripe account .
  • Your agent is a hosted service that you operate on behalf of your customers.
  • Your customers are US consumers. Your own business can be outside the US.
  • You’re familiar with OAuth 2.0 authorization code flow concepts.

Both authorization flows authenticate against login.link.com and produce an access token that Link CLI reads from the related setting. The difference is who holds the client credentials. With device authorization, Link CLI uses a built-in public client, so there’s nothing for you to register.

Register a confidential OAuth client

A hosted agent requires a confidential OAuth client to securely authenticate and manage customer authorization. Unlike public clients, a confidential client stores credentials server-side—appropriate when you control the backend.

To register:

  1. Contact Stripe to request an OAuth client from Link .
  2. Complete the registration form that Stripe sends you.
  3. Stripe provides your client _ id and client _ secret .
  4. Store both values securely on your server.

Protect your client credentials

Never embed client_secret in client-side code, agent skill files, or version control. Store it in a secrets manager accessible only to your backend.

Construct the authorization URL

Redirect the customer to the Link authorization endpoint to request access to their wallet.

Authorization request

https://login.link.com/auth?key=pk_live_YOUR_PUBLISHABLE_KEY&client_id=YOUR_CLIENT_ID&redirect_uri=https://yourapp.com/callback&response_type=code&scope=payment_methods.agentic%20userinfo:read&state=RANDOM_STATE_VALUE&code_challenge=YOUR_PKCE_CODE_CHALLENGE&code_challenge_method=S256

URL-encode each parameter value. The scope parameter takes a space-separated list, so encode the separators as %20.

Parameters

The authorization URL has the following parameters:

ParameterRequiredDescription
keyYesYour Stripe publishable key.
client_idYesYour OAuth client ID.
redirect_uriYesThe URI where Link redirects the customer after authorization. Must match the URI registered with your OAuth client.
response_typeYesMust be code.
scopeYesSpace-separated list of OAuth scopes. See Available scopes. Scope delimiters aren’t uniform— payment_methods.agentic uses a period, and userinfo:read uses a colon.
stateYesA random string to prevent the related setting attacks. Verify this value when the customer returns to your redirect URI.
code_challengeYesA the related setting code challenge. Generate a random code_verifier (43–128 characters, URL-safe), then compute the related setting(the related setting(code_verifier)).
code_challenge_methodYesMust be the related setting.
authorization_detailsConditionalRequired for financial insights. A JSON array specifying the data access your agent needs. See Add financial insights to your agent for the required actions.

Available scopes

Request only the scopes your agent uses. The set of available scopes grows over time.

ScopeGrants access to
payment_methods.agenticCreating spend requests to retrieve one-time-use payment credentials.
userinfo:readBasic customer information, which you can use to prefill checkout and to check whether a customer is eligible before starting a purchase.

Financial insights uses the authorization_details parameter rather than a scope. See Add financial insights to your agent.

After the customer authenticates and approves, Link redirects to:

Redirect response

https://yourapp.com/callback?code=AUTHORIZATION_CODE&state=YOUR_STATE_VALUE

Your backend must:

  1. Verify that state matches the value you sent.
  2. Extract the code parameter.
  3. Exchange the code for tokens within 10 minutes (codes are single-use).

Exchange the code for tokens

To exchange the code for tokens, make a request to the authorization endpoint. The Authorization header contains the Stripe publishable key associated with your integration. client_secret remains in the request body as the OAuth client credential.

Token exchange

Token response

{
 "access_token": "liwltoken_...",
 "refresh_token": "liwlrefresh_...",
 "token_type": "Bearer",
 "expires_in": 3600,
 "scope": "payment_methods.agentic userinfo:read"
}

Store both tokens securely on your server.

Token lifecycle

The token response includes the following tokens:

Token typeLifetimeBehavior
Access token1 hourRefresh before expiry using the refresh token.
Refresh token1 yearRotated on each use. Store the new refresh token from each response.

Refresh an access token

To refresh an access token, make a request to the authorization endpoint:

Refresh request

The response includes a new access_token and a rotated refresh_token. Store the new refresh token, because the previous refresh token is invalidated.

Set the access token as an environment variable so Link CLI can authenticate requests:

Set token

export LINK_ACCESS_TOKEN=liwltoken_...

Verify the connection:

Verify authentication

link-cli user-info retrieve

For production, inject the related setting from your secrets manager at runtime.

Revoke access

To revoke a customer’s access when they disconnect from your agent:

Revoke token

Security requirements

To secure your OAuth implementation:

  • Always use the related setting ( code _ challenge _ method=the related setting ) in the authorization request.
  • Always validate the state parameter on the OAuth callback.
  • Store client _ secret server-side only.
  • Store refresh tokens securely server-side.
  • Refresh access tokens before expiry instead of waiting for 401 responses.
  • Exchange authorization codes within 10 minutes (they’re single-use).

See also

Last verified 2026-09-24

Is this helpful?