Skip to content
Developer Hub

Build withTalkify API

Integrate cloud telephony, AI voice agents, and broadcasting into your application with our REST API, webhooks, and real-time WebSocket events.

Quick Start
# Your first API call — speak a line of Bengali down the phone
curl -X POST https://app.talkify.com.bd/api/v1/outbound/call \
  -H "X-API-Key: $TALKIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone": "8801712345678", "text": "আপনার অর্ডারটি পাঠানো হয়েছে।"}'

# Create the key in the dashboard: Developers → API Keys

Built for Developers

Everything you need to integrate Talkify into your stack.

JWT Authentication

Secure API access with JSON Web Tokens. Role-based scoping for platform and tenant operations.

Swagger / OpenAPI

Auto-generated interactive API documentation. Try endpoints directly from the browser.

Real-Time Webhooks

Get notified on call events, voicemail, transcription, agent status, and campaign outcomes.

RESTful JSON API

Clean, predictable REST endpoints. Consistent error handling, pagination, and filtering.

Rate Limiting & Security

Built-in rate limiting, CORS configuration, IP whitelisting, and request signing.

WebSocket Events

Live extension presence, call status updates, and dashboard metrics via WebSocket.

Quickstart

Five steps from an API key to a ringing phone. Copy, paste your key, run.

1. Authenticate

Create a key under Developers → API Keys in the dashboard. Send it as a header on every request — either form works.

# Either header is accepted
X-API-Key: tk_live_xxxxxxxxxxxxxxxxxxxx
Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx

# Base URL
https://app.talkify.com.bd/api/v1

2. Place your first call

Speak a line of text to one number. Bengali works as-is — pick a voice and it is read in Bengali.

curl -X POST https://app.talkify.com.bd/api/v1/outbound/call \
  -H "X-API-Key: $TALKIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "8801712345678",
    "text": "আপনার অর্ডারটি পাঠানো হয়েছে। ধন্যবাদ।",
    "externalId": "order-10482"
  }'

3. Personalise it

Send a template with variables and each recipient hears their own version. Add dtmfOptions and the call becomes a one-question survey.

curl -X POST https://app.talkify.com.bd/api/v1/outbound/call \
  -H "X-API-Key: $TALKIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "8801712345678",
    "template": "{{name}}, আপনার বিল {{amount}} টাকা বকেয়া আছে।",
    "variables": { "name": "রহিম", "amount": "১,২৫০" },
    "dtmfOptions": { "1": "এখনই পরিশোধ", "2": "পরে মনে করিয়ে দিন" },
    "webhookUrl": "https://your-app.com/talkify/webhook"
  }'

4. Call a list

Up to a batch per request, each with its own variables. The response returns an id per call.

curl -X POST https://app.talkify.com.bd/api/v1/outbound/bulk \
  -H "X-API-Key: $TALKIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "calls": [
      { "phone": "8801712345678", "text": "প্রথম বার্তা", "externalId": "a-1" },
      { "phone": "8801812345678", "text": "দ্বিতীয় বার্তা", "externalId": "a-2" }
    ]
  }'

5. Check what happened

Poll by id, or filter the list by status and your own externalId. Or skip polling and let the webhook tell you.

# One call
curl https://app.talkify.com.bd/api/v1/outbound/call/CALL_ID \
  -H "X-API-Key: $TALKIFY_API_KEY"

# Everything you sent for one order
curl "https://app.talkify.com.bd/api/v1/outbound/calls?externalId=order-10482" \
  -H "X-API-Key: $TALKIFY_API_KEY"

The Interactive Calls API is included with Professional and Enterprise. Keys carry per-permission scopes — outbound:call to place calls, outbound:status to read them back.

Copy and paste

In your language

No package to install — Node uses the built-in fetch, PHP uses cURL. The webhook example is the one worth reading twice: the signature covers the raw bytes, so parsing the body before verifying it makes every check fail.

Place a call

No dependencies — fetch is built in from Node 18. Reusing an externalId returns the original call instead of dialling twice.

const BASE = 'https://app.talkify.com.bd/api/v1';

async function talkify(path, options = {}) {
  const res = await fetch(BASE + path, {
    ...options,
    headers: {
      'X-API-Key': process.env.TALKIFY_API_KEY,
      'Content-Type': 'application/json',
      ...options.headers,
    },
  });

  const body = await res.json();
  if (!res.ok) {
    // A validation failure returns message as an array of strings;
    // an auth failure returns a single string.
    const detail = Array.isArray(body.message) ? body.message.join('; ') : body.message;
    throw new Error(`Talkify ${res.status}: ${detail}`);
  }
  return body;
}

const { data } = await talkify('/outbound/call', {
  method: 'POST',
  body: JSON.stringify({
    phone: '8801712345678',
    text: 'আপনার অর্ডারটি পাঠানো হয়েছে। ধন্যবাদ।',
    externalId: 'order-10482',      // your id — send it again and you get the
    webhookUrl: 'https://your-app.com/talkify/webhook',
  }),                                // same call back, never a second dial
});

console.log(data.callId, data.status);   // '…-…' 'QUEUED'

Check what happened

Poll one call by id, or fetch everything you sent under one of your own ids. Note the list endpoint has no success wrapper.

// One call
const { data: call } = await talkify('/outbound/call/' + callId);
console.log(call.status, call.dtmfPressed, call.duration);

// Everything for one order — this endpoint returns { data, pagination }
const { data: calls, pagination } = await talkify(
  '/outbound/calls?externalId=order-10482'
);
console.log(`${calls.length} of ${pagination.total}`);

Verify a webhook

Sign-and-compare on the RAW body. Parsing the JSON first and re-serialising it changes the bytes and every signature fails.

import express from 'express';
import crypto from 'node:crypto';

const app = express();

// express.raw, not express.json — the signature covers the exact bytes sent.
app.post('/talkify/webhook',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const expected = 'sha256=' + crypto
      .createHmac('sha256', process.env.TALKIFY_WEBHOOK_SECRET)
      .update(req.body)                       // the Buffer, untouched
      .digest('hex');

    const got = req.get('X-Talkify-Signature') || '';
    // Constant-time: a plain === leaks the answer one byte at a time.
    const ok = got.length === expected.length &&
      crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected));

    if (!ok) return res.status(401).send('bad signature');

    const event = JSON.parse(req.body.toString());
    console.log(event.externalId, event.status, event.dtmfLabel);

    res.sendStatus(200);   // anything else and Talkify retries: 2s, 4s, 8s
  });

API Endpoints

Everything an API key opens, in full.

POST/api/v1/outbound/call
POST/api/v1/outbound/bulk
POST/api/v1/outbound/bulk-file
GET/api/v1/outbound/call/:id
GET/api/v1/outbound/calls

Webhook Events

Subscribe to real-time events and react to platform activity.

call.completed

A call finished — direction, duration, billsec and outcome

call.missed

An inbound call was not answered

campaign.started

A broadcasting campaign began dialling

campaign.completed

A broadcasting campaign finished

voicemail.new

A voicemail was recorded and stored

contact.created

A contact was added, by hand or by import

payment.received

An invoice was settled

subscription.expiring

A subscription period is about to end

Ready to Integrate?

Get your API key and start building. Full documentation, code samples, and a sandbox environment included.

Get Started