Skip to main content
All /api/v1/* routes and POST /api/mcp require an Authorization header:
Authorization: Bearer <token>
The service validates the token and only returns data for the authenticated Vings user.

Token types

OAuth access tokens

User access tokens from the Vings OAuth flow or from a signed-in Vings session (for example, your app after the user signs in). Use the token value in the Authorization header.

Vings personal access tokens (PAT)

Tokens prefixed with vng_pat_. Create and manage them in your Vings account settings. PATs include explicit Vings scopes and only access your data. Send the token in the Authorization header the same way as an OAuth access token. Cookie-based auth across subdomains is not supported on this API in v1.

OAuth protected-resource metadata

MCP and REST clients that support RFC 9728 discovery can read:
URLResource
GET /.well-known/oauth-protected-resourceMCP at /api/mcp
GET /.well-known/oauth-protected-resource/mcpMCP at /api/mcp
GET /api/.well-known/oauth-protected-resourceREST API
GET /api/.well-known/oauth-protected-resource/mcpMCP at /api/mcp
The metadata includes authorization_servers pointing at the external host (https://external.vin.gs), which publishes authorization-server discovery for sign-in, consent, and ChatGPT refresh tokens.

Authorization-server metadata (refresh tokens)

ChatGPT and other MCP clients discover refresh-token support from the authorization server, not protected-resource metadata:
URLPurpose
GET /.well-known/oauth-authorization-serverOAuth AS metadata with offline_access
GET /.well-known/openid-configurationOIDC discovery (same fields)
GET /api/oauth/authorizeAuthorize proxy (strips offline_access before Supabase)
scopes_supported on these documents includes openid, email, profile, and offline_access. Supabase still issues access and refresh tokens at token_endpoint; the proxy only adjusts the authorize redirect because Supabase rejects offline_access as an authorize scope today. Protected-resource metadata and WWW-Authenticate challenges intentionally omit offline_access (per MCP SEP-2207). After deploying discovery changes, delete and recreate your ChatGPT connector so it refetches metadata (OpenAI help article). Unauthenticated POST /api/mcp requests return 401 with a WWW-Authenticate challenge pointing at the host-root MCP metadata URL. At Supabase authorize time, clients (including ChatGPT) must request only standard OIDC scopes: openid, email, and profile. Protected-resource metadata, WWW-Authenticate challenges, and per-tool MCP securitySchemes from tools/list all advertise those OIDC scopes. Do not send Vings data scopes (for example wallets:read) in the authorize scope parameter — Supabase rejects them with invalid_request. Vings data scopes are stored on the OAuth client when you create it in Vings settings and shown on the consent screen at /oauth/consent. After the user approves, scopes are saved in external_authorization_grants and enforced on REST routes and MCP tools by resolving the OAuth token’s client_id claim to that grant.

Vings scopes

For OAuth access tokens, the external API loads granted Vings scopes from the user’s consent record (keyed by JWT client_id). If the token also includes vings_scopes, scope, or scopes claims with Vings values, enforcement uses the intersection of JWT claims and the consent grant. PATs always include scoped access directly on the token.
ScopeAccess
profile:readUser profile
transactions:readTransactions
cashflow:readCashflow summaries
spending:readSpending aggregates
budgets:readBudgets
banks:readConnected banks status
wallets:readWallet-related data
portfolio:readPortfolio
preferences:readPreferences

OpenAPI security

The live OpenAPI document defines bearerAuth (http + bearer). Use the API Reference playground: enter your token in the auth control, then call GET /v1/me to verify.

Security practices

  • Do not send tokens in query strings or logs.
  • Financial responses are not cached (Cache-Control: no-store).
  • Per-user rate limits apply to REST and MCP; transaction search and portfolio endpoints have stricter limits than aggregate routes.
  • This API exposes only user-scoped read access—no admin or service credentials.