API Reference

Complete reference for all Svara API endpoints — send voice notes, check status, and query usage.

Base URL

https://svarapi.io/api/v1

All endpoints require a Bearer token in the Authorization header. See Authentication for details.


POST /v1/send

Send a voice note. LinkedIn is the primary platform; Telegram is also supported.

Request body

| Parameter | Type | Required | Description | |---|---|---|---| | platform | string | Yes | Target platform: linkedin or telegram. The API also accepts whatsapp, messenger, instagram, slack, discord, viber and wechat, but these are coming soon and not yet available for production use. | | recipient | string | Yes | LinkedIn: the person's profile URL (or the name after /in/). Telegram: the chat ID. | | audio_url | string | Yes | Publicly accessible URL to the audio file | | session | object | Telegram only | { "bot_token": "..." } — your Telegram bot token. Not used for LinkedIn. | | duration | number | No | Audio duration in seconds. Auto-detected if omitted. | | caption | string | No | Text caption sent alongside the voice note (Telegram only) |

LinkedIn

No session is needed. Install the Svara Chrome extension and stay signed in to LinkedIn in Chrome; your voice notes are sent from your LinkedIn account.

Telegram

{
  "bot_token": "7000000000:AAH..."
}

Response

{
  "id": "msg_a1b2c3d4e5f6",
  "status": "queued",
  "platform": "linkedin",
  "recipient": "john-doe-12345",
  "created_at": "2026-03-14T12:00:00Z"
}

Returns 202 Accepted on success.

Example: LinkedIn voice note

curl -X POST https://svarapi.io/api/v1/send \
  -H "Authorization: Bearer $SVARA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "linkedin",
    "recipient": "https://www.linkedin.com/in/john-doe-12345",
    "audio_url": "https://cdn.example.com/notes/outreach.m4a",
    "duration": 14
  }'

LinkedIn notes are sent by the Svara Chrome extension, so no session is needed — keep Chrome open and signed in to LinkedIn. recipient is the person's profile URL or just the name after /in/; messaging-thread, Sales Navigator and company links are rejected with a 400.

Example: Telegram voice note

curl -X POST https://svarapi.io/api/v1/send \
  -H "Authorization: Bearer $SVARA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "telegram",
    "recipient": "123456789",
    "audio_url": "https://cdn.example.com/notes/hello.m4a",
    "session": {
      "bot_token": "7000000000:AAHxyz..."
    },
    "caption": "Hey, listen to this update!"
  }'

Example: JavaScript

const response = await fetch("https://svarapi.io/api/v1/send", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SVARA_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    platform: "telegram",
    recipient: "123456789",
    audio_url: "https://cdn.example.com/notes/hello.m4a",
    session: {
      bot_token: process.env.TELEGRAM_BOT_TOKEN,
    },
  }),
});

const result = await response.json();
console.log(result.id); // "msg_a1b2c3d4e5f6"

Example: Python

import requests

response = requests.post(
    "https://svarapi.io/api/v1/send",
    headers={"Authorization": f"Bearer {api_key}"},
    json={
        "platform": "telegram",
        "recipient": "123456789",
        "audio_url": "https://cdn.example.com/notes/hello.m4a",
        "session": {
            "bot_token": bot_token,
        },
    },
)

result = response.json()
print(result["id"])  # "msg_a1b2c3d4e5f6"

POST /v1/audio

Upload a voice note and get an audio_url you can pass to POST /v1/send on any platform. Use this instead of hosting the file yourself — a hosted URL is always downloadable.

Send the file as a multipart/form-data field named file, or as the raw request body with an audio Content-Type.

| Limit | Value | |---|---| | Formats | MP3, M4A/AAC, OGG/Opus, WAV, WebM (browser recordings), FLAC | | Max size | 4 MB per file (larger uploads get 413) | | Retention | 30 days — send the same audio_url as often as you like until expires_at | | Uploads | 100 per account per rolling 24 hours (then 429 with Retry-After) | | Storage | 500 MB of hosted audio per account — the total size of your uploads that haven't expired yet (then 413). Space frees up as uploads reach 30 days |

Uploading never sends anything and never uses notes; sk_test_ keys can upload too.

Response 201 Created

| Field | Type | Description | |---|---|---| | id | string | Upload id | | audio_url | string | https://svarapi.io/api/v1/audio/{id} — pass this to /v1/send | | content_type | string | Detected audio type, e.g. audio/mp4, audio/webm | | size | integer | Bytes stored | | expires_at | string | ISO 8601 time after which the URL stops working |

{
  "id": "Xq3v9KdPz0bW7mYtR2cLfA",
  "audio_url": "https://svarapi.io/api/v1/audio/Xq3v9KdPz0bW7mYtR2cLfA",
  "content_type": "audio/mp4",
  "size": 48213,
  "expires_at": "2026-10-26T12:00:00.000Z",
  "request_id": "req_a1b2c3d4e5f6a1b2c3d4e5f6"
}

Errors

| Status | error.code | Meaning | |---|---|---| | 400 | invalid_audio | The file isn't playable audio (a web page, document, video or corrupted file) | | 400 | missing_parameter | No file field, or an empty body | | 401 | unauthorized | Missing or invalid API key | | 413 | file_too_large | Over 4 MB — send a shorter or more compressed recording | | 413 | storage_limit_exceeded | This upload would take your account over 500 MB of hosted audio. Wait for older uploads to expire (30 days after upload), or host the file yourself and pass its URL as audio_url. error.details has limit_bytes, used_bytes and file_bytes | | 429 | rate_limit_exceeded | 100 uploads in the last 24 hours — reuse an existing audio_url |

Example

curl -X POST https://svarapi.io/api/v1/audio \
  -H "Authorization: Bearer $SVARA_API_KEY" \
  -F file=@note.m4a

Raw body instead of multipart:

curl -X POST https://svarapi.io/api/v1/audio \
  -H "Authorization: Bearer $SVARA_API_KEY" \
  -H "Content-Type: audio/mpeg" \
  --data-binary @note.mp3

GET /v1/audio/:id

Download an uploaded file. No API key needed — the audio_url itself is the access link, so treat it like a secret if the recording is private. Returns the audio with its Content-Type, or 404 (not_found) once it has expired or if it doesn't exist.

curl -o note.m4a https://svarapi.io/api/v1/audio/Xq3v9KdPz0bW7mYtR2cLfA

GET /v1/status/:message_id

Check the delivery status of a previously sent voice note.

Path parameters

| Parameter | Type | Description | |---|---|---| | message_id | string | The message ID returned from the /v1/send endpoint |

Response

{
  "id": "msg_a1b2c3d4e5f6",
  "status": "delivered",
  "platform": "telegram",
  "recipient": "123456789",
  "created_at": "2026-03-14T12:00:00Z",
  "delivered_at": "2026-03-14T12:00:02Z",
  "error": null
}

If delivery failed, error says what went wrong and what to do, and error_code is a stable code you can branch on:

{
  "id": "msg_a1b2c3d4e5f6",
  "status": "failed",
  "platform": "linkedin",
  "recipient": "john-doe-12345",
  "created_at": "2026-03-14T12:00:00Z",
  "delivered_at": null,
  "error": "Your audio_url returned HTTP 404. Check that the link is correct, public (no login or expiring signature) and points directly at the audio file. This note was not counted against your quota.",
  "error_code": "audio_http_error"
}

Failed notes never count against your quota.

| error_code | What to do | |---|---| | audio_unreachable | Make audio_url a public https link our servers can download (not localhost or a signed-in link), then resend. | | audio_expired | The audio_url from POST /v1/audio is past its 30 days (or doesn't exist). Upload again and resend with the new URL. | | audio_http_error | The audio_url host returned an HTTP error. Fix the link (4xx) or retry shortly (5xx). | | audio_invalid | The file isn't playable audio (often a web page or share link). Link directly to an MP3, M4A, OGG, WAV or WebM file. | | audio_too_large | Send a file under 10 MB. | | recipient_not_found | Use the person's profile URL (linkedin.com/in/<name>) or <name>. | | linkedin_session | Sign in to LinkedIn in the Chrome profile where the Svara extension is installed, then resend. | | linkedin_rejected | You can only voice-note people you can already message (1st-degree connections or an open conversation). | | agent_connection_lost | Chrome went offline mid-send. Keep it open and online, then resend. | | agent_not_running | Status expired: no extension/CLI picked the note up within 24 hours. Install and run it, then resend. | | delivery_unconfirmed | Status expired: the extension started but never reported back. Check LinkedIn before resending. | | platform_auth | The credentials in session were rejected. Refresh the token. | | rate_limited | The platform is throttling you. Wait and send more slowly. | | temporary_error | A temporary error on our side. Resend. | | unknown | Resend; if it keeps failing, email hello@svarapi.io with the message id. |

The same message and code are returned in the body of a failed POST /v1/send (error.message, error.details.reason).

Example

curl https://svarapi.io/api/v1/status/msg_a1b2c3d4e5f6 \
  -H "Authorization: Bearer $SVARA_API_KEY"

GET /v1/usage

Get usage statistics for your account in the current billing period.

Response

{
  "plan": "growth",
  "period_start": "2026-03-01T00:00:00Z",
  "period_end": "2026-03-31T23:59:59Z",
  "usage": {
    "total_sent": 153,
    "total_delivered": 148,
    "total_failed": 5,
    "by_platform": {
      "linkedin": 92,
      "telegram": 61
    }
  },
  "limits": {
    "monthly_quota": 2000,
    "remaining": 1847,
    "rate_limit_per_minute": 500
  }
}

Example

curl https://svarapi.io/api/v1/usage \
  -H "Authorization: Bearer $SVARA_API_KEY"
import requests

response = requests.get(
    "https://svarapi.io/api/v1/usage",
    headers={"Authorization": f"Bearer {api_key}"},
)

usage = response.json()
print(f"Used {usage['usage']['total_sent']} of {usage['limits']['monthly_quota']} this month")

Coming soon

WhatsApp, Messenger, Instagram, Slack, Discord, Viber and WeChat are coming soon — not yet available for production use. Their session endpoints and request formats may change before launch. Want early access? Email hello@svarapi.io.

Ask Svara

Hey! I'm the Svara assistant. Ask me anything about integrating voice notes into your product.

Powered by Svara