Build withTalkify API
Integrate cloud telephony, AI voice agents, and broadcasting into your application with our REST API, webhooks, and real-time WebSocket events.
# 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 KeysBuilt 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/v12. 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.
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.
/api/v1/outbound/call/api/v1/outbound/bulk/api/v1/outbound/bulk-file/api/v1/outbound/call/:id/api/v1/outbound/callsWebhook Events
Subscribe to real-time events and react to platform activity.
call.completedA call finished — direction, duration, billsec and outcome
call.missedAn inbound call was not answered
campaign.startedA broadcasting campaign began dialling
campaign.completedA broadcasting campaign finished
voicemail.newA voicemail was recorded and stored
contact.createdA contact was added, by hand or by import
payment.receivedAn invoice was settled
subscription.expiringA 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