REST API · WebRTC · self-hosted engines

Put a companion in your product

REST and WebRTC, server-side keys with scopes and quotas, short-lived session tokens so a secret never reaches a browser, and HMAC-signed webhooks.

Plain REST over HTTPS · server keys and browser tokens · no SDK required

Two calls

Start a session, or just make her speak

Endpoint-by-endpoint detail is in the reference; task-shaped guides are in the documentation. These two calls are most of an integration.

Start a live session
// Server side — your secret key never reaches a browser.
const session = await arapulse.sessions.create({
  characterId: "rissa",
  voice: "cloned:rissa-v2",
  realtime: true          // WebRTC video + audio
});

// Hand the browser a short-lived token, not your key.
res.json({ token: session.clientToken });
Synthesise speech
curl -X POST https://api.arapulse.com/api/v1/text-to-speech \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "text": "I was hoping you would call.",
    "voiceId": "en_US-lessac-high"
  }' --output reply.wav
Credentials

Your secret key never meets a browser

Two credentials with different lifespans. The sk_ key lives on your server and signs everything; the st_ token is minted per session, handed to the browser, and expires on its own.

  • Scopes gate every route. A valid key without the required scope is refused with a 403.
  • Quotas refuse rather than bill. Rate limits apply per key across the whole /api/v1 surface; past the daily allowance, requests return a 429.
  • Tokens expire and revoke. Session tokens are listable and revocable server-side, and expire on their own if you forget.
  • Test is not live. sk_test_ keys are scoped separately from live traffic, so development cannot spend production quota.
30 fpsLive loop in a sessionPer-frame keypoints
~10 sOf reference to clone a voiceZero-shot · over the API
7Signed webhook eventsHMAC · replay window
0Third-party AI callsNothing leaves your stack
The surface

What the API gives you

  • Scoped server keys

    Keys carry scopes and per-key quotas. A valid key without the required scope is refused with a 403, not a silent success.

    sk_live_ · sk_test_
  • Short-lived browser tokens

    Mint a session token server-side and hand that to the client. Your secret key never touches a browser, and the token expires on its own.

    st_ tokens
  • Live sessions over WebRTC

    Create a session, get a room, publish the companion into it. Additional viewer tokens can be issued for the same room.

    LiveKit
  • Speech in both directions

    Transcription and synthesis are plain REST. Synthesis can stream in chunks and return word-level timings alongside the audio.

    Whisper · Piper
  • Voice cloning over the API

    Submit a reference clip and poll the voice until it reports active or failed. About ten seconds of clean audio is enough.

    GPT-SoVITS · zero-shot
  • Characters as first-class objects

    Create, update and list characters over the API. A character carries its appearance, personality and bound voice together.

    REST CRUD
  • Organisations and shared quota

    Group keys under an organisation with roles and a shared allowance, rather than one key per developer with no oversight.

    Roles · shared quota
  • Signed webhooks

    Seven events — session start and end, character created, updated and deleted, speech generated, voice created. Each signed with a timestamped HMAC over the body, with a replay window and retries on failure.

    7 events · HMAC-signed
  • Usage analytics

    Every call is recorded per key and per endpoint, so usage attributes to the feature or customer that generated it.

    Per key · per endpoint
Straight answers

Integration status, stated plainly

CapabilityStatusDetail
Text to speechShippedGenerate, chunked streaming, and word-level timings.
Speech to textShippedMultipart or raw audio. The stream endpoint returns one response rather than a live stream.
Live avatar sessionsShippedReal LiveKit room and publisher. Concurrency is capped per deployment; idle sessions are reclaimed.
Characters, keys, analytics, organisationsShippedFull CRUD, backed by real queries rather than fixtures.
Voice cloning over the APIShippedSubmit a reference URL and the job runs: fetched, transcribed and registered. Poll the voice until it reports active, or failed with a reason.
WebhooksShippedAll seven events emit from production paths. Timestamped HMAC with a replay window and constant-time comparison, plus retries with backoff.
Account erasureShippedDeleting an account unlinks the user’s files and removes their records. Supports a dry run.
OpenAPI coveragePartialThe specification documents a subset of the mounted routes. The reference is ahead of the spec file.
Questions

What integrators ask first

Is there an SDK?

Not an official one yet. The API is plain REST and works with any HTTP client — the examples in the reference use curl for that reason. The code samples on this page show the calls an SDK would wrap.

Can the browser call the API directly?

With a session token, yes. Mint an st_ token server-side and hand it over; it expires on its own and can be revoked. A secret key must never ship to a client — that is what the token exists to prevent.

What frame rate does an embedded session run at?

Embedded sessions default to 12 fps; pass target_fps to raise it. The portal’s own live session runs at 30.

How many API calls do I get?

5,000 a month on the free tier, 50,000 on Pro, unlimited on Enterprise — the full comparison is on the pricing page. Requests past the daily allowance are refused with a 429 rather than silently billed.

How do I know a webhook came from you?

Every delivery is signed: a timestamped HMAC-SHA256 over the raw body in the X-AraPulse-Signature-V2 header. Reject anything older than five minutes and compare in constant time — the reference has a complete verifier you can paste.

Build with it

Test keys on the free tier. No card.