Connected apps with OAuth

Use OAuth when your app or agent needs a revocable token for a Lipafy user. Use an API key only for your own account or server-side automation that you control.

What is supported

Lipafy currently supports:

  • Authorization code flow with PKCE (S256)
  • Refresh tokens with rotation
  • Dynamic client registration
  • Token revocation
  • Public clients with token_endpoint_auth_method: "none"
  • Confidential clients with client_secret_basic or client_secret_post
  • OAuth Protected Resource Metadata for MCP clients

Current scopes:

ScopeMeaning
lipafy.gatewayCall paid capabilities through the gateway/MCP tools
lipafy.wallet.readRead wallet and usage information

Capability execution is still governed by the user’s wallet balance, grants, spending controls, approvals, and mandates.

Discovery

1GET /.well-known/oauth-authorization-server

Returns the OAuth endpoints, supported grants, PKCE methods, token endpoint auth methods, and supported scopes.

For MCP, Lipafy also exposes:

1GET /.well-known/oauth-protected-resource/mcp

Register a client

1POST /oauth/register
2Content-Type: application/json
3
4{
5 "client_name": "Shopping Agent",
6 "redirect_uris": ["https://your-app.example/oauth/callback"],
7 "grant_types": ["authorization_code", "refresh_token"],
8 "scope": "lipafy.gateway lipafy.wallet.read",
9 "token_endpoint_auth_method": "none",
10 "software_id": "com.example.shopping-agent",
11 "software_version": "1.0.0"
12}

For a confidential server-side client, use client_secret_basic or client_secret_post. Lipafy returns a client_secret only when the token endpoint auth method is not none.

Send the user to authorize

Create a PKCE verifier/challenge pair, then redirect the user:

https://api.lipafy.xyz/oauth/authorize?
response_type=code&
client_id=<client-id>&
redirect_uri=https://your-app.example/oauth/callback&
scope=lipafy.gateway+lipafy.wallet.read&
state=<csrf-token>&
code_challenge=<challenge>&
code_challenge_method=S256

If the user is not signed in, Lipafy sends them to the dashboard login page first, then returns them to the same authorization request.

After approval, Lipafy redirects back to your redirect_uri with a single-use code:

https://your-app.example/oauth/callback?code=<code>&state=<csrf-token>

Always verify state before exchanging the code.

Exchange the code

For a public client:

1POST /oauth/token
2Content-Type: application/x-www-form-urlencoded
3
4grant_type=authorization_code&
5client_id=<client-id>&
6code=<code>&
7redirect_uri=https://your-app.example/oauth/callback&
8code_verifier=<verifier>

For a confidential client, authenticate with either HTTP Basic auth or client_secret_post.

The response includes:

1{
2 "access_token": "lipafy_at_...",
3 "token_type": "Bearer",
4 "expires_in": 3600,
5 "refresh_token": "lipafy_rt_..."
6}

Call Lipafy

Use the access token as a bearer token:

1POST /gateway/demo.echo/
2Authorization: Bearer lipafy_at_...
3Content-Type: application/json
4
5{"hello":"world"}

Lipafy resolves the OAuth grant, checks wallet balance and spending controls, and executes the paid call only if it is allowed.

Refresh tokens

1POST /oauth/token
2Content-Type: application/x-www-form-urlencoded
3
4grant_type=refresh_token&
5client_id=<client-id>&
6refresh_token=<refresh-token>

Refresh tokens rotate. Store the new refresh token returned by each refresh response and discard the old one.

Revoke tokens

1POST /oauth/revoke
2Content-Type: application/x-www-form-urlencoded
3
4client_id=<client-id>&
5token=<refresh-token>

Users can also revoke connected apps from the Lipafy dashboard.