Skip to main content
Build a personal dashboard that reads your Vings data through the External API. Use v0, Lovable, or any stack you control. This path uses OAuth + REST (/api/v1/*). It is not the MCP integration used for ChatGPT and Claude connectors.

What you get

Personal dashboard OAuth clients are owner-only: only the Vings user who created the client can approve consent. They are public clients (PKCE, no client secret).

Reference implementation

Use this public v0 example app as the canonical pattern for OAuth (PKCE), httpOnly cookies, and server-side API proxies: github.com/chriskrogh/v0-personal-finance-dashboard When building with v0 or Lovable, point your agent at that repository (and this guide) instead of inventing routes or field names from scratch.

Setup steps

  1. Deploy or preview your app with a fixed HTTPS callback path (for example https://your-app.vercel.app/auth/callback). Localhost callbacks are also allowed when registered.
  2. Copy the callback URL from your deployment (scheme, host, path, and trailing slash must match exactly).
  3. In Vings, open Settings → Integrations → Personal dashboards, choose Add dashboard, paste the redirect URI, and copy the Client ID.
  4. Set VINGS_OAUTH_CLIENT_ID in your project to that Client ID.
  5. Discover OAuth endpoints — fetch GET /api/.well-known/oauth-protected-resource, then GET {authorization_servers[0]}/.well-known/openid-configuration. Use authorization_endpoint and token_endpoint from that JSON (see OAuth flow).
  6. PKCE sign-in — public client, S256 code_challenge, scopes openid email profile; exchange the authorization code at the token endpoint with code_verifier (no client secret). After login, approve access on /oauth/consent.
  7. Proxy API calls server-side — browser apps cannot call external.vin.gs directly (CORS). Add Next.js (or similar) routes that attach the bearer token, then call your proxy from the client.
  8. Verify — GET /v1/me through your proxy. Use REST only — not MCP.

Give your builder the right instructions

On the Personal dashboards settings page, open the v0 or Lovable tab and copy the platform-specific agent prompt into your project instructions or project knowledge. It links back to this guide and the live OpenAPI document so the agent does not invent endpoints or use MCP by mistake.

v0

  • Paste the v0 agent prompt into project instructions before scaffolding OAuth.
  • Add the reference implementation repo URL so the agent can mirror working routes.
  • Add VINGS_OAUTH_CLIENT_ID in the project environment.
  • If your preview or production URL changes, update the redirect URI in Vings and redeploy.

Lovable

  • Paste the Lovable agent prompt into project knowledge so generated code uses REST, not MCP.
  • Link the reference implementation in project knowledge.
  • Set VINGS_OAUTH_CLIENT_ID in env or secrets.
  • Re-check the redirect URI in Vings when Lovable changes your published domain.

OAuth flow

Common mistake: Personal dashboard OAuth uses the Vings authorize proxy at /api/oauth/authorize and Supabase /auth/v1/oauth/token. Do not use /auth/v1/authorize or /auth/v1/token — those are for Google/Apple social sign-in and return errors like Unsupported provider: Provider could not be found.
Expected URL shapes after discovery:
Always prefer the authorization_endpoint and token_endpoint values from OpenID discovery rather than guessing paths.

Discovery

Step 1 — protected resource metadata:
Read authorization_servers[0] as the external host (for example https://external.vin.gs), not the Supabase /auth/v1 path. Step 2 — OpenID configuration:
Use the authorization_endpoint and token_endpoint fields from that JSON verbatim in your authorize and token requests. authorization_endpoint is the Vings authorize proxy (/api/oauth/authorize); token_endpoint remains on Supabase Auth. Manual fallback (only if you cannot read discovery): use https://external.vin.gs/api/oauth/authorize for authorize and the Supabase …/auth/v1/oauth/token URL for token exchange. Do not append bare /authorize or /token to Supabase.

Public client + PKCE

Vings registers personal dashboards as public clients with token_endpoint_auth_method: none. Your app must:
  • Generate a code_verifier / code_challenge (S256) for each sign-in.
  • Send client_id, redirect_uri, response_type=code, code_challenge, and code_challenge_method=S256 to the OAuth authorization endpoint.
  • Exchange the authorization code at the token endpoint with code_verifier (no client secret).
At authorize time, request standard OIDC scopes (openid, email, profile). Vings data scopes (for example portfolio:read, transactions:read) are attached to the OAuth client when you create it in settings and are shown on the Vings consent screen at /oauth/consent. After the user signs in to Vings (if needed), they approve readonly access on the Vings consent page. If someone other than the client owner tries to authorize a personal dashboard client, consent is rejected. Store OAuth state and code_verifier in httpOnly cookies before redirecting to the authorization endpoint. After token exchange, store the access token the same way (not localStorage in production).
  • httpOnly: true — tokens are not readable from client JavaScript.
  • sameSite: "lax" (not "strict") — cookies are sent when the identity provider redirects back to your callback.
  • secure: true in production (HTTPS).
  • Short maxAge for state and verifier (for example 10 minutes).
See the reference implementation for a working Next.js layout (/auth/login, /auth/callback, and cookie names).

Server-side API proxy (required for browser apps)

The External API does not allow direct browser requests (CORS). Every dashboard UI should call your own server routes, which forward requests with Authorization: Bearer <access_token>.
  • Create one route file per upstream endpoint (for example /api/vings/me, /api/vings/transactions).
  • Read the access token from your httpOnly cookie on the server, then fetch https://external.vin.gs/api/....
  • Do not use catch-all proxy routes like app/api/vings/[...path]/route.ts — they can return 404 or behave inconsistently on some hosts.
  • From the browser, call only your /api/vings/* routes — never https://external.vin.gs/api/... directly.
The reference implementation shows this pattern end to end.

Call the API (server or curl)

Verify with GET /v1/me, then add endpoints for the widgets you need. See Authentication for scopes and Introduction for the full REST list. Example (after you have a token):

Common field names

The OpenAPI spec is authoritative. These names differ from what many agents guess:

Suggested dashboard endpoints

Use OpenAPI for parameters and response shapes. Do not expose tokens in query strings, logs, or client-side analytics.

Prototype without OAuth (optional)

For local experiments only, you can use a personal access token (vng_pat_*) created under Settings → Integrations → API keys. PATs are for scripts and quick tests—not for shipping a multi-user hosted dashboard. Production personal apps should use OAuth.

Security practices

  • Treat the access token like a password; never commit it or pass it in URLs.
  • Responses are user-specific and use Cache-Control: no-store.
  • The External API is read-only; no writes or bank linking through this API.
  • Revoke the OAuth client in Vings settings to cut off access immediately.
  • Do not use MCP (/api/mcp) for v0/Lovable dashboard UIs unless you are explicitly building an MCP host.

Troubleshooting