01Reference · Authentication

Bearer keys, prefixed and hashed.

Every public-API call carries a single header. Keys are minted in the dashboard, shown to you exactly once, and stored as SHA-256 digests on our side.

Key format

Keys look like vv_live_ followed by 32 URL-safe random characters. The first 8 of those random characters become the public key_prefix shown in the dashboard so you can identify a key without revealing the secret.

Header

FieldTypeNotes
AuthorizationrequiredstringBearer vv_live_… — the key plaintext. The header must be exact; we accept either casing on the header name itself.
Content-Typestringapplication/json for any request with a body. Bodies are capped at 4 KB.
curl
# Header on every public-API request:
# Authorization: Bearer vv_live_<random>
#
# Mint a key in the dashboard, copy it ONCE, store it in a vault.
# We only persist the SHA-256 hash; we cannot show the plaintext again.
curl -X POST https://www.vaanilabs.in/api/public/v1/textvoice/session \
-H "Authorization: Bearer vv_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{}'
javascript
// Server-side Node — never ship the key to a browser bundle.
const apiKey = process.env.VAANI_API_KEY;
if (!apiKey?.startsWith("vv_live_")) {
throw new Error("VAANI_API_KEY missing or malformed");
}

const headers = {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json",
};
python
import os, requests

API_KEY = os.environ["VAANI_API_KEY"]
assert API_KEY.startswith("vv_live_"), "expected vv_live_ prefix"

session = requests.Session()
session.headers.update({
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
})

Scopes

A key is born with all four surfaces by default: textvoice, voicebot, meeting-agent, meeting. You can narrow that list at creation time. Hitting an out-of-scope surface returns 403 scope_denied.

Lifecycle

Create

POST /api/api-keys from the dashboard. Returns the plaintext exactly once in the secret field of the response — there is no second chance to read it.

List

GET /api/api-keys returns all keys you own (no plaintext, ever). Includes last_used_at for hygiene.

Revoke

DELETE /api/api-keys/[id] sets revoked_at and disables the key immediately. In-flight requests with that key return 401 invalid_api_key on the next call.

Was this page helpful?