Authentication
API keys and OAuth 2.1 for the Walletguide API, which to use when, and the scopes and audiences a token carries.
Two ways in. Both arrive as Authorization: Bearer …, and the api tells them apart by the shape of the token.
API keys
A wg_ key, scoped to one wallet, no expiry. Right for your own scripts, CI, and a locally-run MCP server. See creating one.
curl -H "Authorization: Bearer wg_…" https://api.walletguide.com/walletsOAuth 2.1
For software acting on someone else's behalf. They sign in, they see what is being asked for, and they can take it away later. This is what walletguide login and the hosted MCP endpoint use.
Authorization code with PKCE, and nothing else: there is no implicit flow and no client secret for a public client. Dynamic client registration is open, so an MCP client can register itself.
| Authorization | https://api.walletguide.com/auth/oauth2/authorize |
| Token | https://api.walletguide.com/auth/oauth2/token |
| Userinfo | https://api.walletguide.com/auth/oauth2/userinfo |
| Registration | https://api.walletguide.com/auth/oauth2/register |
| Metadata | https://api.walletguide.com/.well-known/oauth-authorization-server |
| Keys | https://api.walletguide.com/auth/jwks |
Scopes
| Scope | What it allows |
|---|---|
walletguide:read | Read everything in the wallets the person can reach |
walletguide:write | Create, change and delete |
openid, profile, email | Who they are |
offline_access | A refresh token, so the session survives the hour |
A person can untick walletguide:write at consent time. Software should handle a read-only grant rather than assume it got what it asked for.
Audiences
An access token is minted for one audience, named with an RFC 8707 resource parameter on both /authorize and /token:
https://api.walletguide.comfor the REST routeshttps://api.walletguide.com/mcpfor the MCP endpoint
They do not substitute for one another. A token for the MCP endpoint is refused on /wallets/* even though the same person consented to the same app, which is the point: an agent connector cannot quietly reuse its MCP grant against the whole REST surface.
Send resource on the token request, not only on the authorization request. Better Auth issues a JWT only when the token request names an audience; without it you get an opaque token, and the api rejects it with nothing pointing at why.
What a credential cannot do
Neither kind reaches /internal/*. Those routes are the app's own, they authenticate with a session cookie, and they are not in the OpenAPI document. Everything a public credential can do is in the reference.