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:
| Environment | URL |
|---|
| Staging | https://login-staging.venly.io/auth/realms/VenlyFinance/protocol/openid-connect/token |
| Production | https://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
| Staging | Production |
|---|
| Token endpoint | login-staging.venly.io | login.venly.io |
| Fundflow API | api-fundflow-staging.venly.io/v1 | api-fundflow.venly.io/v1 |
| Finance API | api-staging.venlyfinance.com/v1 | api.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.