Session dosyası
Telethon ya da Pyrogram ile doğrudan açılır. Giriş adımı yok, oturum zaten kurulu.
Numarayı biz alıyoruz, doğrulamayı biz geçiyoruz. Siz siparişi açıyorsunuz; session ve tdata dosyaları iş bittiğinde sizi bekliyor.
SDK yok, düz HTTPsession · tdata · JSON künyeTR · GB · US numaraları
◇ örnek kod
Kurulacak SDK yok. Aşağıdaki örnekler baştan sona çalışır: siparişi açar, iş bitene kadar bekler, hazır dosyayı diske yazar.
dil seç
Python örneği requests paketini, Node.js örneği 18+ sürümü ister. Anahtarı ortam değişkeninden okuyun.
import os
import time
import requests
BASE = "https://create-session.cerceyn.com"
# Anahtarı koda gömmeyin, ortam değişkeninden okuyun.
HEAD = {"Authorization": "Bearer " + os.environ["CREATE_SESSION_API_KEY"]}
# 1) Siparişi aç. Boş gövde = sunucu varsayılanları.
created = requests.post(BASE + "/accounts", json={}, headers=HEAD, timeout=30)
created.raise_for_status()
job_id = created.json()["id"]
print("iş sıraya girdi:", job_id)
# 2) Bitene kadar takip et.
while True:
time.sleep(5)
job = requests.get(BASE + "/accounts/jobs/" + job_id, headers=HEAD, timeout=30).json()
print(job["status"], "-", job["state"])
if job["status"] in ("succeeded", "failed", "cancelled"):
break
if job["status"] != "succeeded":
raise SystemExit("iş bitmedi: " + str(job.get("error")))
# 3) Hazır hesabın session dosyasını indir.
phone = job["phone"]
session = requests.get(BASE + "/accounts/" + phone + "/session", headers=HEAD, timeout=60)
session.raise_for_status()
with open(phone + ".session", "wb") as handle:
handle.write(session.content)
print("hesap hazır:", phone)import os
import time
import requests
BASE = "https://create-session.cerceyn.com"
# Never hardcode the key, read it from the environment.
HEAD = {"Authorization": "Bearer " + os.environ["CREATE_SESSION_API_KEY"]}
# 1) Place the order. An empty body means "use server defaults".
created = requests.post(BASE + "/accounts", json={}, headers=HEAD, timeout=30)
created.raise_for_status()
job_id = created.json()["id"]
print("job queued:", job_id)
# 2) Poll until it settles.
while True:
time.sleep(5)
job = requests.get(BASE + "/accounts/jobs/" + job_id, headers=HEAD, timeout=30).json()
print(job["status"], "-", job["state"])
if job["status"] in ("succeeded", "failed", "cancelled"):
break
if job["status"] != "succeeded":
raise SystemExit("job did not finish: " + str(job.get("error")))
# 3) Download the session file of the finished account.
phone = job["phone"]
session = requests.get(BASE + "/accounts/" + phone + "/session", headers=HEAD, timeout=60)
session.raise_for_status()
with open(phone + ".session", "wb") as handle:
handle.write(session.content)
print("account ready:", phone)using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("CREATE_SESSION_API_KEY");
using var http = new HttpClient { BaseAddress = new Uri("https://create-session.cerceyn.com") };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
// 1) Siparişi aç. Boş gövde = sunucu varsayılanları.
var body = new StringContent("{}", Encoding.UTF8, "application/json");
var created = await http.PostAsync("/accounts", body);
created.EnsureSuccessStatusCode();
var job = JsonDocument.Parse(await created.Content.ReadAsStringAsync()).RootElement;
var jobId = job.GetProperty("id").GetString();
Console.WriteLine("iş sıraya girdi: " + jobId);
// 2) Bitene kadar takip et.
string status;
while (true)
{
await Task.Delay(TimeSpan.FromSeconds(5));
var raw = await http.GetStringAsync("/accounts/jobs/" + jobId);
job = JsonDocument.Parse(raw).RootElement;
status = job.GetProperty("status").GetString();
Console.WriteLine(status + " - " + job.GetProperty("state").GetString());
if (status == "succeeded" || status == "failed" || status == "cancelled")
{
break;
}
}
if (status != "succeeded")
{
throw new Exception("iş bitmedi");
}
// 3) Hazır hesabın session dosyasını indir.
var phone = job.GetProperty("phone").GetString();
var bytes = await http.GetByteArrayAsync("/accounts/" + phone + "/session");
await File.WriteAllBytesAsync(phone + ".session", bytes);
Console.WriteLine("hesap hazır: " + phone);using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("CREATE_SESSION_API_KEY");
using var http = new HttpClient { BaseAddress = new Uri("https://create-session.cerceyn.com") };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
// 1) Place the order. An empty body means "use server defaults".
var body = new StringContent("{}", Encoding.UTF8, "application/json");
var created = await http.PostAsync("/accounts", body);
created.EnsureSuccessStatusCode();
var job = JsonDocument.Parse(await created.Content.ReadAsStringAsync()).RootElement;
var jobId = job.GetProperty("id").GetString();
Console.WriteLine("job queued: " + jobId);
// 2) Poll until it settles.
string status;
while (true)
{
await Task.Delay(TimeSpan.FromSeconds(5));
var raw = await http.GetStringAsync("/accounts/jobs/" + jobId);
job = JsonDocument.Parse(raw).RootElement;
status = job.GetProperty("status").GetString();
Console.WriteLine(status + " - " + job.GetProperty("state").GetString());
if (status == "succeeded" || status == "failed" || status == "cancelled")
{
break;
}
}
if (status != "succeeded")
{
throw new Exception("job did not finish");
}
// 3) Download the session file of the finished account.
var phone = job.GetProperty("phone").GetString();
var bytes = await http.GetByteArrayAsync("/accounts/" + phone + "/session");
await File.WriteAllBytesAsync(phone + ".session", bytes);
Console.WriteLine("account ready: " + phone);import { writeFile } from "node:fs/promises";
const BASE = "https://create-session.cerceyn.com";
// Anahtarı koda gömmeyin, ortam değişkeninden okuyun.
const HEAD = {
Authorization: `Bearer ${process.env.CREATE_SESSION_API_KEY}`,
"Content-Type": "application/json"
};
const bekle = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// 1) Siparişi aç. Boş gövde = sunucu varsayılanları.
const created = await fetch(`${BASE}/accounts`, { method: "POST", headers: HEAD, body: "{}" });
if (!created.ok) {
throw new Error(`sipariş açılamadı: ${created.status}`);
}
const { id } = await created.json();
console.log("iş sıraya girdi:", id);
// 2) Bitene kadar takip et.
let job;
do {
await bekle(5000);
job = await (await fetch(`${BASE}/accounts/jobs/${id}`, { headers: HEAD })).json();
console.log(job.status, "-", job.state);
} while (!["succeeded", "failed", "cancelled"].includes(job.status));
if (job.status !== "succeeded") {
throw new Error(`iş bitmedi: ${job.error}`);
}
// 3) Hazır hesabın session dosyasını indir.
const file = await fetch(`${BASE}/accounts/${job.phone}/session`, { headers: HEAD });
await writeFile(`${job.phone}.session`, Buffer.from(await file.arrayBuffer()));
console.log("hesap hazır:", job.phone);import { writeFile } from "node:fs/promises";
const BASE = "https://create-session.cerceyn.com";
// Never hardcode the key, read it from the environment.
const HEAD = {
Authorization: `Bearer ${process.env.CREATE_SESSION_API_KEY}`,
"Content-Type": "application/json"
};
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// 1) Place the order. An empty body means "use server defaults".
const created = await fetch(`${BASE}/accounts`, { method: "POST", headers: HEAD, body: "{}" });
if (!created.ok) {
throw new Error(`could not queue the job: ${created.status}`);
}
const { id } = await created.json();
console.log("job queued:", id);
// 2) Poll until it settles.
let job;
do {
await wait(5000);
job = await (await fetch(`${BASE}/accounts/jobs/${id}`, { headers: HEAD })).json();
console.log(job.status, "-", job.state);
} while (!["succeeded", "failed", "cancelled"].includes(job.status));
if (job.status !== "succeeded") {
throw new Error(`job did not finish: ${job.error}`);
}
// 3) Download the session file of the finished account.
const file = await fetch(`${BASE}/accounts/${job.phone}/session`, { headers: HEAD });
await writeFile(`${job.phone}.session`, Buffer.from(await file.arrayBuffer()));
console.log("account ready:", job.phone);import os
import time
import requests
BASE = "https://create-session.cerceyn.com"
HEAD = {"Authorization": "Bearer " + os.environ["CREATE_SESSION_API_KEY"]}
# Yerel mod: Android tarafını biz kurarız, Desktop girişini siz kendi
# makinenizde yaparsınız. Kalıcı oturum hiçbir zaman sunucuya uğramaz.
created = requests.post(
BASE + "/accounts",
json={"relogin_mode": "local"},
headers=HEAD,
timeout=30,
)
created.raise_for_status()
job_id = created.json()["id"]
# 1) İş, devir noktasına gelene kadar bekleyin.
while True:
time.sleep(5)
job = requests.get(BASE + "/accounts/jobs/" + job_id, headers=HEAD, timeout=30).json()
if job["state"] == "awaiting_local_relogin":
break
if job["status"] in ("failed", "cancelled"):
raise SystemExit("iş düştü: " + str(job.get("error")))
# 2) Devri üstlenin. handoff içinde telefon, api_id/api_hash, app_version,
# layer ve cihaz kimliği gelir; proxy yayınlanmaz, ağ sizin işiniz.
started = requests.post(
BASE + "/accounts/jobs/" + job_id + "/relogin/start",
json={"client": "benim-uygulamam/1.0"},
headers=HEAD,
timeout=30,
)
started.raise_for_status()
handoff = started.json()["handoff"]
# 3) Bu kimlikle kendi makinenizde auth.sendCode çağırın (Telethon, TDLib,
# fark etmez). Telegram kodu Android oturumuna düşürür, biz size aktarırız.
while True:
time.sleep(3)
relay = requests.get(
BASE + "/accounts/jobs/" + job_id + "/relogin/code", headers=HEAD, timeout=30
).json()
if relay["status"] == "ok":
code = relay["code"]
break
if relay["status"] == "timeout":
raise SystemExit("kod gelmedi: " + str(relay.get("error")))
# 4) Girişi bitirin ve sonucu bildirin; iş ancak bundan sonra kapanır.
requests.post(
BASE + "/accounts/jobs/" + job_id + "/relogin/complete",
json={"success": True, "dc_id": 2, "user_id": 123456789, "tdata_written": True},
headers=HEAD,
timeout=30,
).raise_for_status()
print("tdata sizde, hesap hazır:", handoff["phone"])import os
import time
import requests
BASE = "https://create-session.cerceyn.com"
HEAD = {"Authorization": "Bearer " + os.environ["CREATE_SESSION_API_KEY"]}
# Local mode: we set up the Android side, you run the Desktop sign-in on
# your own machine. The permanent session never touches our servers.
created = requests.post(
BASE + "/accounts",
json={"relogin_mode": "local"},
headers=HEAD,
timeout=30,
)
created.raise_for_status()
job_id = created.json()["id"]
# 1) Wait until the job parks at the handoff point.
while True:
time.sleep(5)
job = requests.get(BASE + "/accounts/jobs/" + job_id, headers=HEAD, timeout=30).json()
if job["state"] == "awaiting_local_relogin":
break
if job["status"] in ("failed", "cancelled"):
raise SystemExit("job dropped: " + str(job.get("error")))
# 2) Claim the handoff. It carries the phone, api_id/api_hash, app_version,
# layer and device identity. No proxy is published: your network, your call.
started = requests.post(
BASE + "/accounts/jobs/" + job_id + "/relogin/start",
json={"client": "my-app/1.0"},
headers=HEAD,
timeout=30,
)
started.raise_for_status()
handoff = started.json()["handoff"]
# 3) Call auth.sendCode locally with that identity (Telethon, TDLib, anything).
# Telegram pushes the code into the Android session and we relay it to you.
while True:
time.sleep(3)
relay = requests.get(
BASE + "/accounts/jobs/" + job_id + "/relogin/code", headers=HEAD, timeout=30
).json()
if relay["status"] == "ok":
code = relay["code"]
break
if relay["status"] == "timeout":
raise SystemExit("no code arrived: " + str(relay.get("error")))
# 4) Finish the sign-in and report back; the job only closes after this.
requests.post(
BASE + "/accounts/jobs/" + job_id + "/relogin/complete",
json={"success": True, "dc_id": 2, "user_id": 123456789, "tdata_written": True},
headers=HEAD,
timeout=30,
).raise_for_status()
print("tdata is yours, account ready:", handoff["phone"])Her uç noktanın ayrıntısı, gövde şemaları ve deneme alanı dokümanda: /docs
◇ ne alıyorsunuz
İş bittiğinde elinizde giriş yapılmış bir oturum ve onu taşımak için gereken her şey oluyor.
Telethon ya da Pyrogram ile doğrudan açılır. Giriş adımı yok, oturum zaten kurulu.
Zip'i açıp Telegram Desktop'ın veri klasörüne koyun; hesap açılmış olarak gelir.
Model, Android sürümü, app_version, api_id — oturumu taşırken aynı parmak izini kullanabilmeniz için.
◇ uçlar
Hepsi Authorization: Bearer ister. Tam liste, gövde alanları ve hata kodları dokümanda.
| metot | yol | ne yapar |
|---|---|---|
| POST | /accounts | Tek hesap siparişi açar |
| POST | /accounts/batch | Aynı şablonla toplu sipariş açar |
| GET | /accounts/jobs/{id} | Tek işin durumunu verir |
| GET | /accounts/jobs?ids=… | Birden çok işi tek istekte sorar |
| GET | /accounts/{phone}/session | Session dosyasını indirir |
| GET | /accounts/{phone}/tdata | tdata klasörünü zip olarak indirir |
| GET | /accounts/{phone}/export.json | Hesabın künyesini verir |
| GET | /billing/pricing | Hesap başına güncel fiyatı verir |
| GET | /billing/balance | Kalan ve bloke bakiyeyi verir |
◇ sorular
Bunlar entegrasyondan önce en çok sorulan dört şey.
İş başarıyla bittiğinde. Sipariş anında tutar bloke edilir, iş düşerse blokaj geri açılır. Bakiye yetmiyorsa istek 402 döner.
Evet. Gövdeye sms_provider (herosms veya grizzlysms) ve sms_api_key ekleyin; bu işler daha düşük olan kendi-anahtar fiyatından işlenir.
Desktop girişini sizin makinenizde yaparsınız; kalıcı oturum anahtarı hiç sunucuya düşmez. Biz sadece Telegram'ın Android oturumuna gönderdiği kodu aktarırız.
Birkaç saniyede bir GET /accounts/jobs/{id} çağırın, ya da /accounts/jobs/ws websocket'ine bağlanıp değişiklikleri canlı dinleyin.
Bot üzerinden yazın, anahtarınızı ve bakiyenizi tanımlayalım. Gerisi yukarıdaki otuz satır.
API Key Al