Docs

One endpoint. Send what your user said, get back what to say. There is no SDK to install and nothing to keep updated — if you can make an HTTP request, you can use Vesper.

Version 1.0 Base URL vesper-api.danielflowers2505.workers.dev Status live

1Quick start

Create a key in the console, then make one request. That is the whole integration.

# Ask her something curl -X POST https://vesper-api.danielflowers2505.workers.dev/v1/say \ -H "Authorization: Bearer vsk_live_…" \ -H "Content-Type: application/json" \ -d '{"message":"what have I missed?"}' # → {"text":"Not much. A couple of messages from Sarah, and your # four o'clock reminder.","cached":false}

JavaScript

const r = await fetch("https://vesper-api.danielflowers2505.workers.dev/v1/say", { method: "POST", headers: { "Authorization": `Bearer ${process.env.VESPER_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ message: userSaid }) }); if (!r.ok) { // She is unavailable. Carry on without her rather than breaking. return fallbackReply(); } const { text } = await r.json();

2Authentication

Every request carries your key as a bearer token. Nothing else is needed — no signing, no session, no expiry to refresh.

Authorization: Bearer vsk_live_…

Keys are secrets. They belong on your server, in an environment variable. Never ship one inside a mobile app or a web page — anyone who unpacks your bundle has your key and spends your allowance.

A vsk_test_ key behaves identically but never spends and never speaks aloud. Use it in development.

3POST /v1/say

POST https://vesper-api.danielflowers2505.workers.dev/v1/say

Request body

FieldTypeNotes
messagestring Required. What your user said. Up to 2,000 characters.
voiceboolean Ask for spoken audio. Returns 501 today — see below.

Response

FieldTypeNotes
textstring What she says. One or two sentences, written to be spoken.
cachedboolean Whether the audio came from cache. Always false without voice.

She is told to answer in British English, in one or two short sentences, with no lists, markdown or emoji — because it is meant to be heard, not read. What you set under How she appears in the console shapes her name, her manner and what she knows about your users.

4Errors

Every error is JSON with an error code you can branch on and a message written for a human.

StatusCodeWhat happened
400no_messageYou did not send a message.
400message_too_longOver 2,000 characters.
400bad_jsonThe body was not valid JSON.
401no_keyNo bearer token, or it is malformed.
401bad_keyThe key is not recognised.
403key_revokedThat key was revoked. Create another.
403account_suspendedGet in touch.
429allowance_usedMonth's allowance spent. Resets on the 1st.
429upstream_quotaBusy. Retry shortly.
501voice_unavailableSpoken replies are not being served yet.
502upstreamShe could not answer. Retry once.
503unavailableWe could not check your key. Retry.

Treat any non-200 as “carry on without her”. An assistant that breaks your app when it is unavailable is a design problem we cannot fix from our side.

5Allowances

Your plan includes a monthly allowance, counted per calendar month and reset on the 1st, London time. Usage appears in the console the moment a request lands.

PlanSpokenText
Pilot5,00050,000
Studio25,000250,000
Platform75,0001,000,000
Enterprise500,0005,000,000

Past your allowance you get 429. If you have set a spend cap, she refuses rather than exceeding it — so write your integration to cope with being told no.

6Spoken replies

Sending "voice": true currently returns 501 voice_unavailable. Text generation is live; serving her synthesised audio through this endpoint is not yet.

Until it is, ask for text and speak it with the device's own voice. When spoken replies arrive, the response simply gains an audio field — base64 MP3 — and nothing you have written will break. Status says when that changes.

7Health check

GET https://vesper-api.danielflowers2505.workers.dev/v1/health

No key needed. Returns {"ok":true} when the service is up. Safe to poll from your own monitoring.

8Doing it properly

  • Call from your server, never from the client. A key in an app bundle is a key in somebody else's hands.
  • Set a timeout of about five seconds and fall back rather than leaving a user waiting.
  • Retry once on 502 and 503, with a short pause. Never retry a 4xx — it will fail identically.
  • Send only what she needs. She answers what somebody said; she does not need their name, location or payment details.
  • Do not depend on exact wording. She improves over time, and her phrasing will change.
  • Use a test key in development so your staging traffic never touches your allowance.