English
Quick Start
Here we'll send your first Telegram message through Zate, from scratch. It takes about 5 minutes, not even long enough for a serving of sate to go cold.
What You Need
- A phone with an active Telegram account. If the account uses two-step verification, have the password ready too.
- A terminal with
curl.jqmakes it even nicer. - Or Node.js 18+, if you'd rather jump straight to the full script below.
Every request on this page goes to the base URL:
text
https://api-zate.azickri.comCreate a Session
Call Create Session. No headers or body needed.
bash
curl -X POST "https://api-zate.azickri.com/session"The response looks like this:
json
{
"id": "68b3f0a2c1d4e5f6a7b8c9d0",
"sessionId": "0b2f7059-8a90-4f6d-8684-b0e1ce6f0310"
}Keep both values: they become the id and session-id headers on every request after this. To make life easier, put them in terminal variables:
bash
export ZATE_ID="68b3f0a2c1d4e5f6a7b8c9d0"
export ZATE_SESSION_ID="0b2f7059-8a90-4f6d-8684-b0e1ce6f0310"Don't wait too long
You have 3 minutes to scan the QR code. After that the session is deleted automatically and you'll need a new one. So get your phone ready now.
Get the QR Code
The QR code is generated in the background, so wait 2–3 seconds, then call Get Session:
bash
curl "https://api-zate.azickri.com/session" \
-H "id: $ZATE_ID" \
-H "session-id: $ZATE_SESSION_ID"json
{
"id": "68b3f0a2c1d4e5f6a7b8c9d0",
"generatedId": "",
"name": "",
"username": "",
"phone": "",
"sessionId": "0b2f7059-8a90-4f6d-8684-b0e1ce6f0310",
"isConnected": false,
"qrcode": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAAB...",
"isPasswordRequired": false,
"passwordHint": "",
"picture": "",
"webhook": { "url": "", "token": "" }
}The qrcode field is a base64 PNG image (without a data: prefix). The easiest ways to view it:
bash
curl -s "https://api-zate.azickri.com/session" \
-H "id: $ZATE_ID" \
-H "session-id: $ZATE_SESSION_ID" \
| jq -r '.qrcode' | base64 -d > qr.png
# Open qr.png in your favorite image viewerhtml
<!-- Add the data URL prefix, then show it as an image -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAAB..." />The QR changes every 30 seconds
Telegram only hands out short-lived login tokens, so Zate makes a new QR roughly every 30 seconds. If qrcode is still empty, wait a moment and call again. Always use the newest QR.
Scan It from Telegram
- Open Telegram on your phone.
- Go to Settings → Devices.
- Tap Link Desktop Device, then scan the QR code.
Telegram will send a "new login" notification to your account. That's expected: Zate just logged in as a new device.
Then call Get Session again. Once connected, isConnected becomes true, and name, username, phone, and picture are filled in:
json
{
"id": "68b3f0a2c1d4e5f6a7b8c9d0",
"generatedId": "123456789",
"name": "Cak Zate",
"username": "cakzate",
"phone": "6281234567890",
"sessionId": "0b2f7059-8a90-4f6d-8684-b0e1ce6f0310",
"isConnected": true,
"qrcode": "",
"isPasswordRequired": false,
"passwordHint": "",
"picture": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...",
"webhook": { "url": "", "token": "" }
}Does your account use two-step verification?
After the scan, qrcode turns empty and isPasswordRequired becomes true (your password hint is in passwordHint). Send the password with Submit Password:
bash
curl -X POST "https://api-zate.azickri.com/session/password" \
-H "id: $ZATE_ID" \
-H "session-id: $ZATE_SESSION_ID" \
-H "Content-Type: application/json" \
-d '{"password":"your-cloud-password"}'If it's correct, isConnected becomes true right away.
Send Your First Message
The moment you've been waiting for. Replace @target_username with a Telegram username, then call Send Message:
bash
curl -X POST "https://api-zate.azickri.com/message" \
-H "id: $ZATE_ID" \
-H "session-id: $ZATE_SESSION_ID" \
-H "Content-Type: application/json" \
-d '{"username":"@target_username","type":"text","text":"Hello from Zate! 🍢"}'json
{
"messageId": "1024"
}No one to test with?
Use your own username. The message lands in your Saved Messages, safe and bothering nobody.
Check Telegram. If the message is there, congratulations, you're officially a Zate regular! 🎉
Full Version with Node.js
Don't feel like copy-pasting each step? This script runs all of the steps above in one go: it creates a session, saves the QR to qr.png whenever it changes, asks for the password if the account uses two-step verification, waits until you're connected, then sends a message.
js
// quick-start.mjs
// Run: node quick-start.mjs @target_username
import { writeFile } from 'node:fs/promises';
import { createInterface } from 'node:readline/promises';
const BASE_URL = 'https://api-zate.azickri.com';
const username = process.argv[2];
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function zate(method, path, { headers = {}, body } = {}) {
const response = await fetch(BASE_URL + path, {
method,
headers: { 'Content-Type': 'application/json', ...headers },
body: body ? JSON.stringify(body) : undefined,
});
const data = await response.json();
if (!response.ok) throw new Error(`${data.statusCode}: ${data.message}`);
return data;
}
// 1. Create a session
const { id, sessionId } = await zate('POST', '/session');
const auth = { 'id': id, 'session-id': sessionId };
console.log('Session created:', auth);
// 2 & 3. Save the QR to qr.png, wait for the scan, ask for the password if needed
let lastQrcode = '';
while (true) {
const session = await zate('GET', '/session', { headers: auth });
if (session.isConnected) {
console.log(`Connected as ${session.name}!`);
break;
}
if (session.isPasswordRequired) {
const rl = createInterface({ input: process.stdin, output: process.stdout });
const hint = session.passwordHint ? ` (hint: ${session.passwordHint})` : '';
const password = await rl.question(`Two-step verification password${hint}: `);
rl.close();
try {
await zate('POST', '/session/password', { headers: auth, body: { password } });
} catch (error) {
console.log(error.message); // 400: invalid password, try again
}
continue;
}
if (session.qrcode && session.qrcode !== lastQrcode) {
lastQrcode = session.qrcode;
await writeFile('qr.png', Buffer.from(session.qrcode, 'base64'));
console.log('New QR saved to qr.png, scan it from Telegram!');
}
await sleep(3000);
}
// 4. Send the first message
const { messageId } = await zate('POST', '/message', {
headers: auth,
body: { username, type: 'text', text: 'Hello from Zate! 🍢' },
});
console.log('Message sent:', messageId);If the script stops with 404: session not found while waiting, the QR expired before you scanned it. Just run it again and scan a bit faster. 😄
What's Next?
- Read Core Concepts to understand the session lifecycle and how receivers work.
- Set up a webhook so your server hears about incoming messages.
- Try sending images, documents, locations, or contacts.
- Send to a group or post a story.
- Hit an error? Check Errors & Fixes.