Skip to navigation

Authentication

How to authenticate with Vitable's API using API keys and bound access tokens.

Vitable uses API keys for trusted server-to-server requests and bound access tokens for Vitable Drops running in a browser.

CredentialUse it fromScopeTypical use
API keyYour backend onlyYour organizationCall the Vitable Connect API and issue bound access tokens
Employee-bound access tokenYour frontend through a DropOne employeeRender the Employee Dashboard
Employer-bound access tokenYour frontend through a DropOne employerRender Employer Benefits or Employer Billing

Get an API Key

Contact the Vitable team to request credentials. Store the API key in a secret manager or protected environment variable and use a different key for each environment when available.

Never expose an API key in frontend code, a mobile application, logs, or a public repository. Treat it like a password.

Authenticate Server Requests

Send the API key as a Bearer token in the Authorization header:

curl https://api.vitablehealth.com/v1/employers \
--header "Authorization: Bearer $VITABLE_API_KEY" \
--header "Content-Type: application/json"
import os
import requests
response = requests.get(
"https://api.vitablehealth.com/v1/employers",
headers={"Authorization": f"Bearer {os.environ['VITABLE_API_KEY']}"},
)
response.raise_for_status()
data = response.json()
const response = await fetch("https://api.vitablehealth.com/v1/employers", {
headers: { Authorization: `Bearer ${process.env.VITABLE_API_KEY}` },
})
if (!response.ok) {
throw new Error(`Vitable request failed: ${response.status}`)
}
const data = await response.json()

All timestamps in API requests and responses use ISO 8601 in UTC, such as 2026-01-23T14:30:00+00:00.

Issue Bound Access Tokens

A Drop must never receive your API key. Instead, your backend calls POST /v1/auth/access-tokens and returns the short-lived result to your frontend.

Choose a bound_entity that matches the widget:

Widgetbound_entity.typebound_entity.id
Employee DashboardemployeeVitable employee ID, such as empl_abc123
Employer BenefitsemployerVitable employer ID, such as empr_abc123
Employer BillingemployerVitable employer ID, such as empr_abc123
curl --request POST https://api.vitablehealth.com/v1/auth/access-tokens \
--header "Authorization: Bearer $VITABLE_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"grant_type": "client_credentials",
"bound_entity": {
"type": "employee",
"id": "empl_abc123"
}
}'

The response contains access_token and expires_in. Do not assume a fixed lifetime: pass both values to the Drops SDK so it can refresh the session before expiration.

{
"access_token": "vit_at_...",
"expires_in": 910
}

See Set Up Vitable Drops for a complete backend endpoint and provider configuration.

Handle Rate Limits

When a request exceeds its rate limit, the API returns 429 Too Many Requests. Inspect these response headers instead of assuming a fixed limit:

HeaderMeaning
X-RateLimit-LimitMaximum requests allowed in the active window
X-RateLimit-RemainingRequests remaining in that window
X-RateLimit-ResetWhen the limit resets
RateLimit-ReasonWhy the request was limited, when provided

Retry 429 responses with exponential backoff and jitter. For lifecycle changes, use webhooks instead of frequent polling.

Security Checklist

  • Keep API calls and bound-token issuance on an authenticated backend.
  • Authorize the signed-in user before issuing a token for an employee or employer.
  • Return only the bound token and its expiration to the browser.
  • Restrict CORS and protect token endpoints against cross-site request forgery.
  • Do not log credentials or place them in query strings.