Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.venlyfinance.com/llms.txt

Use this file to discover all available pages before exploring further.

Both APIs use OAuth2 client credentials flow. Every request requires a short-lived Bearer token in the Authorization header.

Get an Access Token

Exchange your Client ID and Secret at the token endpoint for your environment:
EnvironmentURL
Staginghttps://login-staging.venly.io/auth/realms/VenlyFinance/protocol/openid-connect/token
Productionhttps://login.venly.io/auth/realms/VenlyFinance/protocol/openid-connect/token
curl -X POST https://login-staging.venly.io/auth/realms/VenlyFinance/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"
Response:
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_in": 300,
  "token_type": "Bearer"
}
Tokens expire after 5 minutes (300 seconds). Build token refresh into your client — see Token Refresh below.

Use the Token

Pass the access_token as a Bearer token on every request: Fundflow API:
curl -X GET https://api-fundflow-staging.venly.io/v1/company \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Finance API:
curl -X GET https://api-staging.venlyfinance.com/v1/parties \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Token Refresh

Request a new token before the current one expires. A 30-second buffer is sufficient:
let accessToken = null;
let tokenExpiresAt = 0;

async function getToken() {
  if (Date.now() < tokenExpiresAt - 30_000) return accessToken;

  const res = await fetch(TOKEN_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: process.env.CLIENT_ID,
      client_secret: process.env.CLIENT_SECRET,
    }),
  });

  const data = await res.json();
  accessToken = data.access_token;
  tokenExpiresAt = Date.now() + data.expires_in * 1000;
  return accessToken;
}
A 401 Unauthorized response means the token has expired — re-authenticate and retry the request once.

Environments

StagingProduction
Token endpointlogin-staging.venly.iologin.venly.io
Fundflow APIapi-fundflow-staging.venly.io/v1api-fundflow.venly.io/v1
Finance APIapi-staging.venlyfinance.com/v1api.venlyfinance.com/v1
Staging credentials and production credentials are separate. Staging calls do not move real funds.
See Endpoints & URLs for the complete base URL reference.

Security

  • Store CLIENT_ID and CLIENT_SECRET in environment variables or a secrets manager — never in source code or version control.
  • Never log or expose tokens in client-side code.
  • Treat a leaked secret as compromised immediately — rotate it via your Venly account and invalidate any outstanding tokens.