Token API’si

Cihazı gönderin, hemen bir request_id alın ve onu kilit açma token’ına kadar takip edin.

Türkçe
Başlarken

01Nasıl çalışır

Telefonu kendi aracınızla okur ve okuduğunuzu gönderirsiniz. Hemen bir request_id alırsınız. Onu status.php’ye geri gönderirsiniz; bu, işi seçtiğiniz sunucuda başlatır. Aynı çağrı daha sonra işin durumunu söyler ve telefona yazmanız için kilit açma token’ını verir. Biz telefona asla dokunmayız, siz de sunucuyla hiç uğraşmazsınız.

1Gönder

token.php her şeyi kontrol eder ve hemen WT-API-6AF684545B gibi bir request_id ile yanıt verir. Henüz hiçbir sunucuya bir şey gönderilmez ve ücret alınmaz.

230 saniye içinde onaylayın

request_id değerini status.php’ye gönderin. Bu ilk çağrı sizin makbuzunuzdur: iş ancak şimdi başlar. 30 saniye içinde kimsenin onaylamadığı bir request_id iptal edilir.

3Token’ı alın

Birkaç saniyede bir status.php’ye tekrar sorun; ta ki state değeri done — token ile — ya da error olsun: nedeni yazar ve krediniz iade edilir.

Uç noktalar

POST token.phpToken isteği gönder: request_id hemen döner.
POST status.phpBir request_id’yi onayla (bu işi başlatır) ve token’a kadar takip et.
POST history.phpİşleriniz, tarihe ve hizmete göre, ve her birinin nasıl sonuçlandığı.
POST balance.phpKrediniz ve nereye harcandığı.
POST servers.phpKullanabileceğiniz sunucular ve her birindeki fiyatınız.

https://xiaomi.source.af/api/reseller/v1/…

02Kimlik bilgileri

Sizi dört bilgi tanımlar ve dördü de aynı hesabı göstermelidir. Token başlıkta, diğer üçü gövdede gönderilir. Herhangi biri yanlışsa aynı unauthorized yanıtı döner — hangisi olduğunu asla söylemeyiz, çünkü bu, bir saldırgana hangisini koruyacağını söylemiş olurdu.

AlanNedir
AuthorizationHesap tokenı — Yalnızca size aittir. Panelinizde Kimlik bilgileriniz bölümünden oluşturun veya bizden isteyin. Sadece hash’ini saklarız; bu yüzden bir kez gösterilir ve geri alınamaz — yenisini oluşturmak eskisini anında geçersiz kılar.
api_keyAPI anahtarı — Her istekte, gövdede.
emailE-posta — Hesabınızdaki adres. Değişirse bize bildirin, aksi takdirde çağrılar durur.
passwordAPI şifresi — Hesabınızın API şifresi. Varsayılan olarak giriş şifrenizin ta kendisidir. Ayrı bir şifre istiyorsanız panelinizde Hesap → API şifresi bölümünden belirleyin; Giriş şifremi kullan düğmesi önceki duruma döndürür ve ayrı şifre hemen geçersiz olur. Bunu sizin için biz de ayarlayabiliriz. Her iki durumda da günlüklerimize asla yazılmaz ve işle birlikte asla saklanmaz.

Her uç nokta POST yöntemiyle, HTTPS üzerinden çalışır. GET isteği method_not_allowed ile reddedilir; JSON olmayan bir gövde bad_json ile reddedilir.

Bölüm 1 · Token isteği gönderme

03İstek

POSThttps://xiaomi.source.af/api/reseller/v1/token.php
isteğin tamamı
POST /api/reseller/v1/token.php HTTP/1.1
Host: xiaomi.source.af
Content-Type: application/json; charset=utf-8
Accept: application/json
Authorization: Bearer rst_YOUR_ACCOUNT_TOKEN

{
  "api_key":      "YOUR_API_KEY",
  "email":        "you@example.com",
  "password":     "YOUR_PASSWORD",
  "soc":          "frp",
  "serverid":     "server1",
  "configblob":   "eyJ0b2tlbiI6IjhmMjFjMGI0ZTlkNyIsImRldmljZU5hbWUiOiJm…",
  "request_date":     "2026-09-21T14:51:51.980Z",
  "request_language": "English"
}

Aşağıdaki tüm alanlar JSON gövdesinde gönderilir.

AlanTürZorunluNedir
api_keystringevetAPI anahtarınız.
emailstringevetHesabınızdaki e-posta.
passwordstringevetAPI şifreniz — panelinizde Hesap → API şifresi bölümünden ayrı bir şifre belirlemediyseniz, varsayılan olarak giriş şifrenizle aynıdır. Bkz. Kimlik bilgileri.
socstringevetHangi hizmet. frp = FRP kaldırma, fdl = Fastboot’tan EDL’ye. Varsayılan değer yoktur — göndermemek, sizi yanlış hizmet için ücretlendirebilecek bir tahmin yerine hata olarak döner.
configblobstringevetCihazdan okunan bilgilerin tamamı, base64 ile kodlanmış bir JSON nesnesi olarak. Neleri içermesi gerektiği soc değerine bağlıdır — bkz. Cihaz blob’u.
serveridstringhayırİşi çalıştırması gereken sunucunun genel kimliği, ör. server1 — servers.php listesinden veya panelinizde Sunucular altından. Katıdır: o sunucu işi çalıştırır ya da çağrı nedeniyle birlikte reddedilir. Göndermezseniz iş alan en ucuz sunucuyu biz seçeriz. Araç sahipleri: her zaman gönderin. Bkz. Sunucu seçimi.
request_datestringhayırİsteğe bağlı. Sizin sunucunuzun bu isteği gönderdiği zaman; Z veya bir saat farkıyla ISO-8601 biçiminde. Dokunulmadan client_sent olarak geri döndürülür ve hesaplamalarımızda asla kullanılmaz. Göndermezseniz hiçbir şey değişmez; yalnızca client_sent ve client_clock_offset_seconds değerleri null olarak döner.
request_languagestringhayırOptional. The language for the customer-facing message of a refusal: one of English, Persian, Spanish, French, Turkish, Arabic (or a 2-letter code like en/fa). Omitted or unrecognised → the reply is in English. Send it on every call (token.php, status.php and the reads). The structured fields (such as flash_status, region, takes_on) come back regardless, so you can also build your own sentence in any language.

04Cihaz blob’u

Blob, cihazdan okunan bilgilerin tamamını taşıyan bir JSON nesnesinin base64 halidir — yalnızca token değil, aracınızın o modda okuduğu her şey. Neyin zorunlu olduğu soc değerine bağlıdır: frp için telefon Mi Assistant modundadır (sideload / recovery), fdl için Fastboot modundadır. Her değeri telefonun verdiği yanıtla birebir aynı gönderin — kısaltmadan, biçimini değiştirmeden.

frp — telefon Mi Assistant modunda (sideload / recovery)

AlanOkuma komutuZorunluNedirÖrnek
tokengetmitoken:evet — null reddedilirFRP challenge değeri, aynen okunduğu gibi8f21c0b4e9d7…
deviceNamegetdevice:evet — null reddedilirBölge ekiyle birlikte kod adıfleur_global
versiongetversion:evet — null reddedilirROM derlemesiOS2.0.207.0.VMTMIXM
serialgetsn:evet — null reddedilirSeri numarasıfb4d921c
codebasegetcodebase:evet — okunamazsa nullAndroid sürümü15
regiongetregion:evet — okunamazsa nullROM bölgesiIR
cpuidgetcpuid:evet — okunamazsa nullCPU ID’si, telefon yanıt verirse0x000460E1
recoverygetrecoveryversion:evet — okunamazsa nullRecovery sürümü — yalnızca desteklenmeyen cihazlar listemiz kullanır2
branchgetbranch:hayır — null sorun değilROM dalıF
languagegetlanguage:hayır — null sorun değilCihazın dili — yalnızca desteklenmeyen cihazlar listemiz kullanırfa
romzonegetromzone:hayır — null sorun değilROM zone — yalnızca desteklenmeyen cihazlar listemiz kullanır2
frp · base64’ten önce
{
  "token":      "8f21c0b4e9d7…",
  "deviceName": "fleur_global",
  "version":    "OS2.0.207.0.VMTMIXM",
  "serial":     "fb4d921c",
  "codebase":   "15",
  "region":     "IR",
  "cpuid":      "0x000460E1",
  "recovery":   "2",
  "branch":     "F",
  "language":   "fa"
}

frp için productName göndermeyin. Yok sayılır: ürünü, tıpkı kendi aracımızın yaptığı gibi, deviceName değerinden türetiriz (fleur_global → fleur). ROM derlemesi version alanına yazılır. Bu sayfanın önceki bir sürümü ROM derlemesinin productName alanına yazılmasını söylüyordu — istemciniz bunu yapıyorsa değeri version alanına taşıyın.

fdl — telefon Fastboot modunda

AlanOkuma komutuZorunluNedirÖrnek
tokenoem get_token
(getvar:token)
evet — null reddedilirFastboot tokenı, aynen okunduğu gibiVQHzN2Ib…
productgetvar:productevet — null reddedilirBölge eki olmadan kod adıfleur
serialgetvar:serialnoevet — null reddedilirSeri numarasıfb4d921c
cpuidgetvar:cpuidevet — okunamazsa nullCPU ID’si, telefon yanıt verirse0x000460E1
fdl · base64’ten önce
{
  "token":   "VQHzN2Ib…",
  "product": "fleur",
  "serial":  "fb4d921c",
  "cpuid":   "0x000460E1"
}

Telefon okuyamadığında her alan null olarak gönderilebilir (JSON null veya "null" metni) — asla unknown, N/A veya boş metin göndermeyin. Sonrası alana bağlıdır: evet — null reddedilir olarak işaretli alan, sunucuların işi kurduğu alandır; bu yüzden istek incomplete_configblob ile reddedilir, alan nulls içinde belirtilir ve hiçbir ücret alınmaz — telefonu yeniden okuyun ve eksiksiz bilgiyi gönderin; evet — okunamazsa null olarak işaretli alan her zaman blob’da bulunmalıdır ve null ile iş her zamanki gibi çalışır (hiç gönderilmezse reddedilir); hayır — null sorun değil olarak işaretli alanı null gönderin ya da hiç göndermeyin — iş çalışır. null alanlarla gönderilen bir iş, gönderdiğinizle çalışır: bir alan okunamadığı için token daha sonra telefonda çalışmazsa iade edilemez. Telefonun yanıt verdiği her alanı gönderin.

cpuid, bazı sunucuların cihazın bölgesini kontrol etmesi için gereklidir. Telefon verdiğinde her zaman gönderin (Mi Assistant modunda 0x… seri numarası CPU ID’dir). Gönderilmezse null kabul edilir ve iş devam eder.

frp · region null
{
  "token":      ",VQEBHQEQNzczMmNmNjE0MzcxMTgwZAIE1UIc…",
  "deviceName": "fog",
  "version":    "V13.0.8.0.SGEMIXM",
  "serial":     "0xd5421c9d",
  "codebase":   "12",
  "region":     null,
  "cpuid":      "0xd5421c9d",
  "recovery":   "2",
  "branch":     "F",
  "language":   "fa-IR"
}

Aynı alanlar için kabul ettiğimiz diğer adlar: token için authKey veya auth_key; deviceName için devicename veya device_name; version için osVersion veya os_version; serial için serial_number veya serialNumber (fdl için ayrıca serialno); product için productName veya productname; cpuid için cpu_id.

Ücret alınmadan önce kontrol edilir

Tüm kontroller, herhangi bir kredi ayrılmadan veya ücret alınmadan önce yapılır. Gönderilmeyen zorunlu bir alan (evet — null reddedilir) missing içinde; null gönderilen nulls içinde; başarısız bir okuma — N/A, unknown, none, bir hata metni — içeren ise invalid içinde belirtilir. Her biri HTTP 400 incomplete_configblob ile reddedilir; telefonun bulunması gereken mod mode içinde verilir: Mi Assistant veya Fastboot. İsteğe bağlı alanları telefon yanıt verdiği sürece gönderin; eksik, null veya başarısız okuma içeren bir alan yalnızca dışarıda bırakılır ve hiçbir yere iletilmez — işi durdurmaz. Tokeni eksik veya null olan bir blob missing_token ile yanıtlanır.

incomplete_configblob
HTTP/1.1 400 Bad Request

{
  "status":  400,
  "error":   "incomplete_configblob",
  "message": "The field deviceName (null) is required and must be sent filled in — the server needs it to run this job. Read the device again and send the complete information. Nothing was charged. (configblob is not complete for frp (device in Mi Assistant mode) -- null: deviceName; missing: region. A field the phone does not report is sent as null, e.g. \"region\": null.)",
  "missing": ["region"],
  "invalid": [],
  "nulls":   ["deviceName"],
  "mode":    "Mi Assistant",
  "data":    { "state":"error", "start_date":{ … }, "end_date":{ … }, "response_date":{ … } }
}

# No request_id was given: nothing was created, held or charged.

Her sunucunun beklediği kendine özgü biçimi bu alanlardan kendimiz oluştururuz; böylece hiçbir zaman belirli bir sunucuya ait bir yapı göndermezsiniz — farklı bir serverid da gönderdiğiniz şeyi asla değiştirmez.

Ne gönderdiğiniz ve ne geri aldığınız:

GönderdiğinizDöndürdüğümüzAnlamı
deviceNamedevice_nameBölge ekiyle birlikte kod adı (frp)
—product_modelBölge eki olmadan kod adı — bunu deviceName değerinden biz türetiriz (frp)
productproduct_model
device_name
Bölge eki olmadan kod adı (fdl)
versiondevice_versionROM derlemesi (frp)
serialserial_numberSeri numarası
codebasecodebaseAndroid sürümü (frp)
branchbranchROM dalı (frp)
regionregionROM bölgesi (frp)
cpuidcpu_idCPU ID’si, telefon yanıt verirse
token—device içinde tekrarlanmaz

O hizmet için geçerli olmayan bir alan, yanıttan çıkarılmak yerine null olarak döner; böylece tek bir ayrıştırıcı her iki hizmeti de okur.

05Desteklenen cihazlar

Bazı build numaraları desteklenmez ve bazı ülkeler de desteklenmeyebilir. Hangileri olduğunu öğrenmek için araç sahibi API’nizi aldıktan sonra yöneticiye Telegram veya WhatsApp üzerinden sorun.

Kendi desteklenmeyen cihazlar listemizdeki bir cihaz token.php tarafından hemen unsupported (422) ile reddedilir: request_id yok, hiçbir sunucuya bir şey gönderilmez, hiçbir ücret alınmaz. Liste configblob’un her alanını sınayabilir — model, firmware, Android sürümü, dal, dil, bölge, recovery sürümü, ROM zone, seri no ve CPU id — bu yüzden aracınızın okuduğu her şeyi gönderin.

Dikkat: desteklenmeyen bir model göndermek size kredisine mal olur — iade edilmez — ve bazen hesabınızın yasaklanmasına yol açabilir.

Aynı desteklenmeyen cihaz tekrar tekrar: bir cihazın desteklenmeyen olarak her reddi (unsupported) hesabınız ve o cihaz için 5 dakika boyunca sayılır. 4. ret, message alanında bir uyarı ve true değerinde strike.warning taşır (strike = {count, max, window_seconds, warning} bu tür her retde bulunur): bu cihazı yeniden göndermek hesabınızı engeller. Bu 5 dakika içinde bir ret daha hesabınızı 5 dakika kısıtlar: her yeni istek account_restricted (403) ile yanıtlanır. Uyarıda durun ve müşterinize cihazı kabul eden bir sunucu önerin.

Bir cihaz bölgesi nedeniyle reddedildiğinde ve sunucularınızdan biri o bölge için premium olduğunda, unsupported reddi region, suggested, premium (check.php’deki gibi) ve takes_on taşır ve message o sunucuyu adlandırır: “Cihazınızın bölgesi CN. Bu cihaz Server 6.3 ile yapılmalıdır — premium bir sunucu: bu cihaz için FRP kaldırma başarı oranı çok yüksektir.” Hiçbir ücret alınmadı.

Bölgenin premium sunucularının hepsi kapalıysa veya boş yuvası yoksa hiçbir şey önerilmez (suggested null olur), slots_full true olur ve message bunu söyler: “★ Server 6.3 cihazınızın AE bölgesini destekliyor, ancak yuvaları şu an geçici olarak dolu. Lütfen biraz sonra tekrar bakın veya Telegram kanalımızı takip edin …” Bunu gösterin ve cihazı bölgesini kabul etmeyen bir sunucuya göndermek yerine müşterinizin daha sonra tekrar denemesine izin verin. Premium bir sunucu her zaman yıldızıyla (★) anılır.

Seçtiğiniz sunucu bir cihazı kendisi reddettiğinde, status.php’nin unsupported yanıtı server_message taşır: sunucunun kendi cümlesi, hiçbir tedarikçi adı olmadan, örn. “This device is not supported (China Device Not Supported) · CPUID: 0xe4f01f4c · Product: star · IMEI: 867869053687315”; message de bununla biter. data.amount_charged işin ücretlendirilip ücretlendirilmediğini söyler: bir cihazı işi çalıştırmadan önce reddeden sunucu hiçbir ücret almaz, biz de almayız.

Yöneticiye sorun: Telegram: @RaminGSM WhatsApp: +93799691689

06Sunucu seçimi

Her sunucunun, bizim verdiğimiz herkese açık bir ID’si — server1, server2… — ve Server 1 gibi bir adı vardır. İkisi de servers.php tarafından serverid ve name olarak listelenir; ayrıca panelinizdeki Sunucular bölümünde de yer alır. Bir işi bunlardan birinde çalıştırmak için ID’sini serverid olarak gönderin.

iki durum
# 1. name the server -- exactly this one, or an error saying why not
{ "soc":"frp", "configblob":"…", "serverid":"server1" }

# 2. leave it out -- we take the cheapest server taking jobs
{ "soc":"frp", "configblob":"…" }

# every answer names the server that runs the job
-> { "data": { "request_id":"WT-API-6AF684545B", "serverid":"server1", "server_name":"Server 1", … } }

serverid göndermezseniz sizin için seçeriz: hesabınızın kullanabileceği, iş alan en ucuz sunucu. Bir sunucu belirtirseniz bu kesin uygulanır: işi ya o sunucu çalıştırır ya da çağrı reddedilir — o ID’ye sahip bir sunucu yoksa unknown_serverid (404), sunucu hesabınız için etkin değilse server_not_allowed (403), sunucu bu hizmeti şu anda alamıyorsa server_offline (503). Sizi asla haberiniz olmadan başka bir sunucuya geçirmeyiz.

Bazı sunucular tek tek seçilebilen birkaç makineden oluşur. servers.php her makineyi kendi fiyatıyla ayrı bir sunucu olarak listeler — örneğin serverid server6-2, name Server 6.2. O serverid değerini gönderin; iş tam olarak o makinede, onun fiyatıyla çalışır ya da gerekçesiyle reddedilir. Sunucunun kendi kimliğini (server6) gönderirseniz, iş kabul eden makineleri içinden en ucuzunu kullanırız.

Herhangi bir şey ayrılmadan veya ücretlendirilmeden önce sunucuyu kontrol ederiz. İşi alamıyorsa server_offline alırsınız ve hiçbir şey harcanmaz — servers.php listesinden başka birini seçip yeniden gönderin ya da serverid göndermeyerek seçimi bize bırakın.

server_offline
{ "soc":"frp", "configblob":"…", "serverid":"server2" }

-> HTTP 503
   {
     "status":  503,
     "error":   "server_offline",
     "message": "The selected server is off right now (FRP). Use one of the other servers (servers.php lists them) or try again later.",
     "data":    { "state":"error", … }
   }

# No request_id was given: nothing was created, held or charged.
# We never move the request to another server for you.

Araç sahipleri: serverid değerini her zaman gönderin. Listeyi servers.php ile (veya panelinizde Sunucular altında) okuyun, müşterinizin seçmesine izin verin ve o kimliği gönderin. Token o zaman o sunucudan gelir ya da yanıt tam olarak neden gelmediğini söyler — asla başka bir sunucudan alınmaz.

Her yanıt işi çalıştıran sunucuyu serverid ve server_name olarak adlandırır — seçimi bize bıraktığınızda da — böylece yavaş bir sunucu, yavaş bir cihazdan ayırt edilebilir.

07request_id almadan önce

token.php, request_id değerini yalnızca aşağıdaki tüm kontroller bu sırayla geçtiğinde verir. Geçemeyen ilk kontrol sizin yanıtınızdır — kendi error koduyla — ve request_id yoktur: hiçbir şey oluşturulmadı, ayrılmadı veya ücretlendirilmedi.

#Neyi kontrol ediyoruzGeçemezse
1İstek, en fazla 256 KB JSON gövdesi olan bir POST’tur.method_not_allowed 405
bad_json 400
body_too_large 413
2Dört kimlik bilginiz aynı etkin hesabı gösteriyor: hesap token’ı, api_key, email ve password.unauthorized 401
too_many_failures 429
3İstek, tanımladıysanız hesabınızın izin verilen listesindeki bir adresten geliyor.ip_not_allowed 403
4Saatlik istek sınırınızın içindesiniz.rate_limited 429
Hesap, desteklenmeyen bir cihazı tekrar tekrar gönderdiği için kısıtlanmamış olmalı (bkz. Desteklenen cihazlar).account_restricted 403
5soc değeri frp veya fdl, bu hizmet hesabınıza satılıyor ve açık.missing_soc 400
bad_service 400
not_entitled 403
disabled 503
6configblob geçerli ve telefonun modunun gerektirdiği tam okumayı taşıyor.missing_configblob 400
bad_configblob 400
missing_token 400
incomplete_configblob 400
7Cihaz, hizmet vermediğimiz cihazlar listemizde değil.unsupported 422
8serverid ile belirttiğiniz sunucu var, hesabınız için etkin ve şu anda iş alıyor: açık, fiyatı belli, çevrimiçi ve bizim tarafımızda hazır.unknown_serverid 404
server_not_allowed 403
server_offline 503
Sunucu belirtmediniz: hesabınızın kullanabileceği, iş alan en ucuz sunucuyu seçeriz ve yanıt onun adını verir.service_not_allowed 403
service_offline 503
Seçilen sunucuda bir cihaz bilgisi ön kontrolü: cihazın kendi bölgesi okunur ve listemizle karşılaştırılır; seçilen sunucunun desteklemediği bir bölge unsupported ile reddedilir (yanıt cihazın region, takes_on, suggested ve premium alanlarını taşır). Flaş durumu da okunur, ancak hiçbir şeye karar vermez. Bu, bir request_id verilmeden önce olur, bu yüzden hiçbir ücret alınmaz. Ön kontrole ulaşılamazsa atlanır ve yukarıdaki cihaz listesi geçerli olmaya devam eder.unsupported 422
9Aynı cihaz — aynı hizmet ve aynı sunucu için aynı cihaz token’ı — son 30 dakikada gönderilmemiş olmalı. Gönderildiyse ve o iş başladıysa, o işi geri alırsınız: request_id değerini ve durumunu ya da token’ını — asla ikinci bir iş ya da ikinci bir ücret değil. Başarısız olmuş ya da request_id değeri hiç onaylanmamış bir işin yerine yenisi açılır.—
10Krediniz o sunucudaki bir işin fiyatını karşılıyor — servers.php listesinde onun için gösterilen price. Burada kontrol edilir; fiyat yalnızca iş başladığında ayrılır.no_credit 402
Tüm kontroller geçti: request_id değerini hemen, state waiting olarak alırsınız. Hiçbir sunucuya bir şey gönderilmedi ve siz status.php ile onaylayana kadar hiçbir tutar ayrılmaz.

08request_id değeriniz

Yanıt hemen gelir: state waiting ile HTTP 202. request_id, işin WorkID değeridir — aynı WT-API-6AF684545B değerini panelinizde görür ve orada arayabilirsiniz. Saklayın: işi onaylamak, takip etmek, token’ı almak ve bize onunla ilgili soru sormak hep bu request_id ile yapılır. 2026-10-17 öncesinde verilen bir request_id, örneğin Api123, her yerde çalışmaya devam eder ve aynı biçimde yanıtlanır.

token.php yanıtı
HTTP/1.1 202 Accepted

{
  "status": 202,
  "data": {
    "request_id":     "WT-API-6AF684545B",
    "soc":            "frp",
    "serverid":       "server1",
    "server_name":    "Server 1",
    "configblob":     "eyJ0b2tlbiI6IjhmMjFj…",
    "device":         { "product_model":"fleur", "device_name":"fleur_global", … },
    "state":          "waiting",
    "confirm_within": 30,
    "price":          1.2,
    "currency":       "USD",
    "response_token": null,
    "start_date":     { … },
    "end_date":       { … },
    "response_date":  { … }
  }
}

# Nothing has been sent to any server yet, and nothing is held.
# Send this request_id to status.php within 30 seconds: that starts the job.

30 saniye içinde onaylayın. status.php’ye gönderin: bu çağrı makbuzunuzdur ve işi başlatır. 30 saniye içinde kimsenin onaylamadığı bir request_id iptal edilir — hiçbir sunucuya bir şey gönderilmedi ve ücret alınmadı — ve onunla yapılan sonraki bir çağrı request_expired yanıtını alır: yeni bir request_id için isteği yeniden gönderin. Böylece bir yanıt size hiç ulaşmadıysa, takip edemeyeceğiniz hiçbir iş çalışmaz.

AlanNedir
request_idBu iş için kimliğimiz — WT-API-6AF684545B gibi WorkID değeri. İşi onunla onaylar, takip eder ve teslim alırsınız; işle ilgili her soruda bize bunu belirtin.
statewaiting
confirm_withinstatus.php ile onaylamak için kalan saniye.
priceİşin o sunucuda size maliyeti — başladığında ayrılır, yalnızca token gelirse ücretlendirilir.
serveridİşi çalıştıran sunucunun herkese açık ID’si — sizin de gönderebileceğiniz serverid ile aynı değer.
server_nameO sunucunun herkese açık adı, ör. Server 1.

Aynı cihaz — aynı hizmet ve aynı sunucu için aynı cihaz token’ı — son 30 dakikada gönderilmemiş olmalı. Gönderildiyse ve o iş başladıysa, o işi geri alırsınız: request_id değerini ve durumunu ya da token’ını — asla ikinci bir iş ya da ikinci bir ücret değil. Başarısız olmuş ya da request_id değeri hiç onaylanmamış bir işin yerine yenisi açılır.

Bölüm 2 · Bir isteği sorgulama

09Onayla ve takip et

POSThttps://xiaomi.source.af/api/reseller/v1/status.php

request_id değerini aynı dört kimlik bilgisiyle status.php’ye gönderin. 30 saniye içindeki ilk çağrı işi başlatır ve hemen pending yanıtı verir; ardından state artık pending olmayana kadar her retry_after saniyede bir tekrar sorun. Bir iş genellikle 15–25 saniye sürer.

status.php
POST /api/reseller/v1/status.php
{ "api_key":"…", "email":"…", "password":"…", "request_id":"WT-API-6AF684545B" }

# 1. the first call, within 30 seconds -- your receipt: the job starts now
-> HTTP 202  { "status":202, "data":{ "request_id":"WT-API-6AF684545B", "state":"pending", "retry_after":3, … } }

# 2. ask again every retry_after seconds
-> HTTP 202  { "status":202, "data":{ "request_id":"WT-API-6AF684545B", "state":"pending", "retry_after":3, … } }

# 3. the token
-> HTTP 200  { "status":200, "data":{ "request_id":"WT-API-6AF684545B", "state":"done",
                                      "response_token":"THE_UNLOCK_TOKEN_GOES_HERE", … } }

# Asked again later with the same request_id: the same token, at no extra cost.

state ne söyler

DurumHTTPAnlamı ve ne yapmalı
pending202İş sunucuda. retry_after saniye sonra tekrar sorun.
done200Token response_token alanındadır: telefona yazın. İş ücretlendirilir; yanıt maliyeti ve sonrasındaki kredinizi söyler.
error4xx · 5xxToken yok. Nedeni error söyler — server_offline, unsupported, server_unavailable, failed veya no_credit. Fiyat tamamen kredinize geri döner; yalnızca sunucu cihazı desteklemediğini söylediğinde (unsupported) o iş ücretlendirilir, amount_charged bunu gösterir.
expired41030 saniye içinde onaylanmadı: iptal edildi, hiçbir şey gönderilmedi, ücret alınmadı. Yeni bir request_id için isteği yeniden gönderin.
not_found404Bu request_id ile hesabınıza ait bir istek yok.

Token, işle birlikte sunucumuzda saklanır. Bir yanıt size hiç ulaşmadıysa aynı request_id ile status.php’ye tekrar sorun: iş çalışırken pending alırsınız, bittiğinde token’ı — ne kadar sorarsanız, ek ücret olmadan. Başarısız olan bir iş nedenini söyler.

request_expired
# the first status.php call came more than 30 seconds after token.php answered
-> HTTP 410
   {
     "status":  410,
     "error":   "request_expired",
     "message": "This request_id was not confirmed with status.php within 30 seconds, so it was cancelled. Nothing was sent to any server and nothing was charged. Send a new request to get a new request_id.",
     "data":    { "request_id":"WT-API-6AF684545B", "state":"expired", "response_token":null, … }
   }

status.php’nin kendi sınırı vardır — hesap başına dakikada 120 çağrı — ve saatlik kotanıza sayılmaz; böylece bir işi takip etmek token isteklerinizi asla tüketmez.

10Yanıt

Bir işle ilgili her yanıt için tek bir biçim; token.php, status.php ya da history.php fark etmez. state değeri waiting, pending, done, error veya expired olur; HTTP durumu da aynısını söyler, böylece ayrıştırmadan önce dallanabilirsiniz.

Token teslim edildi
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "status": 200,
  "data": {
    "request_id":  "WT-API-6AF684545B",
    "soc":         "frp",
    "serverid":    "server1",
    "server_name": "Server 1",
    "configblob":  "eyJ0b2tlbiI6IjhmMjFjMGI0ZTlkNyIsImRldmljZU5hbWUiOiJm…",

    "device": {
      "product_model":  "fleur",
      "serial_number":  "fb4d921c",
      "device_version": "OS2.0.207.0.VMTMIXM",
      "device_name":    "fleur_global",
      "cpu_id":         "0x000460E1",
      "codebase":       "14",
      "branch":         "F",
      "region":         "global",
      "soc":            "frp"
    },

    "state":          "done",
    "response_token": "THE_UNLOCK_TOKEN_GOES_HERE",
    "provider_ref":   "R7F3A9C21B04E",
    "amount_charged": 1.2,
    "credit":         93.8,
    "currency":       "USD",

    "start_date": {
      "client_sent":       "2026-09-21T14:51:51.980Z",
      "server_received":   "2026-09-21T14:51:52.392Z",
      "upstream_sent":     "2026-09-21T14:51:52.560Z",
      "upstream_received": "2026-09-21T14:51:57.392Z",
      "elapsed_seconds":   5.0
    },
    "end_date": {
      "upstream_answered": "2026-09-21T14:51:57.392Z",
      "server_answered":   "2026-09-21T14:52:00.392Z",
      "elapsed_seconds":   3.0
    },
    "response_date": {
      "total_seconds":               8.0,
      "client_clock_offset_seconds": 0.412
    }
  }
}

Yanıttaki tüm alanlar:

AlanNedir
request_idBu iş için kimliğimiz — WT-API-6AF684545B gibi WorkID değeri. İşi onunla onaylar, takip eder ve teslim alırsınız; işle ilgili her soruda bize bunu belirtin.
socÇalışan hizmet.
serveridİşi çalıştıran sunucunun herkese açık ID’si — sizin de gönderebileceğiniz serverid ile aynı değer.
server_nameO sunucunun herkese açık adı, ör. Server 1.
configblobGönderdiğiniz configblob, bayt bayt aynısı.
deviceÇözülmüş haliyle cihaz. Her zaman bulunur.
statewaiting, pending, done, error veya expired.
response_tokenKilit açma tokenı. Telefona yazdığınız şey budur.
provider_refSunucunun kendi iş referansı; destek soruları için.
amount_chargedBu işin size maliyeti.
creditTahsilat sonrası krediniz.
currencyHer iki tutarın para birimi.

Başarısız sonuç

HTTP 4xx / 5xx
# the job started, and the server could not take it
-> HTTP 503
   {
     "status":  503,
     "error":   "server_offline",
     "message": "The selected server is off right now (FRP). Use one of the other servers (servers.php lists them) or try again later. Nothing was charged.",
     "data":    { "request_id":"WT-API-1C93E07B2D", "serverid":"server2", "server_name":"Server 2",
                  "state":"error", "response_token":null, … }
   }

# The price is back on your credit in full. The job was not moved to another server.

Üç zaman bloğu

Üç blok vardır ve toplamları tutar: start_date.elapsed_seconds artı end_date.elapsed_seconds, tam olarak response_date.total_seconds değerine eşittir, çünkü üçü de aynı anlardan türetilir.

Aşağıdaki çözümlü örnekte işin alınması 5 saniye, geri teslim edilmesi 3 saniye sürdü; toplamda 8 saniye.

AlanNedir
start_date — tokenın alınması
client_sentsunucunuzun isteği gönderdiği zaman — tam olarak gönderdiğiniz değer
server_receivedisteğin sunucumuza ulaştığı zaman
upstream_sentisteği token sunucusuna gönderdiğimiz zaman
upstream_receivedtoken sunucusunun yanıtının bize ulaştığı zaman
elapsed_secondsisteğin varışından token elde edilene kadar — örnekte 5 saniye
end_date — geri teslim
upstream_answeredtoken sunucusunun bize yanıt verdiği zaman
server_answeredsunucumuzun size yanıt verdiği zaman
elapsed_secondsyalnızca teslim aşaması — örnekte 3 saniye
response_date — sürecin tamamı
total_seconds5 + 3 = 8 saniye
client_clock_offset_secondssizin saatinizle bizimki arasındaki fark

Süre blokları, token.php isteği aldığı andan itibaren ölçülür. end_date, token’lı yanıt bizden çıktığında biter; yani status.php çağrılarınız arasında beklediğiniz süreyi de içerir.

Kendi zaman damganız neden hesaplamalarda kullanılmaz
client_sent içinde aynen geri döndürülür ve bizim değil, sizin değerinizdir — sunucunuzun saati bir dakika ileri giderse, onu kullanan hesaplama negatif bir süre bildirir. Geçen süreye ait tüm değerler bizim saatimizden gelir ve ikisi arasındaki fark ayrıca client_clock_offset_seconds olarak bildirilir; böylece bu fark, faturalandırdığınız bir sayının içine sessizce katılmak yerine görebileceğiniz şekilde sunulur.

11Cihaz bilgisi okumaları (soc)

frp ve fdl dışında, araç sahibi hesapları bir cihazın bilgilerini de okuyabilir. Bu hizmetler aynı token.php ardından status.php akışıyla çalışır, ancak hiçbir sunucu kullanmaz ve token yerine cihaz bilgilerini alanlar (fields) olarak döndürür. Şimdilik ücretsizdir (ileride bir fiyat belirlenebilir).

soc değerleri

socNe yaparGirdiYanıt süresi
frpFRP kilidini açar; bir yanıt token’ı döndürür.configblob — cihazın tam okumasıHemen
fdlFDL yetkilendirmesi; bir yanıt token’ı döndürür.configblob — cihazın tam okumasıHemen
read_sideloadCihaz bilgilerini Mi Assistant modunda okur.configblob — yalnızca cihaz token’ı gerekirHemen
read_fastbootCihaz bilgilerini fastboot modunda okur.configblob — yalnızca cihaz token’ı gerekirHemen
read_imeiIMEI’yi üreticinin veritabanında arar.imei — 15 haneli IMEI1 ila 5 dakika; sormaya devam edin
read_lockcodeBir kilit kodunun arkasındaki cihaz kaydını döndürür.imei — sipariş için IMEIBirkaç dakika; sormaya devam edin

Bu okumalar araç sahibi hesapları içindir. read_imei yalnızca API’ye açık olduğu sürece listelenir; aksi halde XST aracının içinde kullanılabilir.

Bir okuma gönderme

Bir okuma tam olarak frp ve fdl gibi gönderilir ve kontrol edilir: token.php size bir request_id verir, ilk status.php çağrınız onu başlatır ve bitene kadar sorarsınız. Hiçbir sunucu kullanmaz ve sunucu ücreti almaz.

token.php · read
# A DEVICE-TOKEN READ (Mi Assistant) -- soc = read_sideload. No serverid: a read
# uses no server. Only the device token inside configblob is needed.
POST /api/reseller/v1/token.php
{ "api_key":"…", "email":"…", "password":"…",
  "soc":"read_sideload", "configblob":"eyJ0b2tlbiI6IjhmMjFj…" }

-> HTTP 202
   { "status":202, "data":{ "request_id":"WT-API-3D7B19F0A4", "soc":"read_sideload",
                            "kind":"read", "state":"waiting", "confirm_within":30,
                            "price":0, "currency":"USD" } }

# read_fastboot is the same, with the token read in fastboot mode.

# AN IMEI LOOKUP -- soc = read_imei. No configblob: the caller types the IMEI.
POST /api/reseller/v1/token.php
{ "api_key":"…", "email":"…", "password":"…", "soc":"read_imei", "imei":"862127050000000" }

-> HTTP 202
   { "status":202, "data":{ "request_id":"WT-API-B82E6C0D51", "soc":"read_imei",
                            "kind":"read", "state":"waiting", "confirm_within":30, … } }

# read_lockcode is the same shape, with the IMEI used for the shop order.

Tamamlanan bir okumanın döndürdüğü

Bir response_token yerine, bir okuma bir fields nesnesiyle yanıt verir — cihaz bilgileri etiket/değer çiftleri olarak. Etiketler hizmete bağlıdır; kaynağın boş bıraktığı bir alan atlanır.

status.php · read done
POST /api/reseller/v1/status.php
{ "api_key":"…", "email":"…", "password":"…", "request_id":"WT-API-3D7B19F0A4" }

# 1. the first call, within 30 seconds -- your receipt: the read starts now
-> HTTP 202  { "status":202, "data":{ "request_id":"WT-API-3D7B19F0A4", "soc":"read_sideload",
                                      "kind":"read", "state":"pending", "retry_after":5 } }

# 2. ask again every retry_after seconds, until state is "done"
-> HTTP 200
   {
     "status": 200,
     "data": {
       "request_id":     "WT-API-3D7B19F0A4",
       "soc":            "read_sideload",
       "kind":           "read",
       "state":          "done",
       "fields": {
         "Product":        "fleur",
         "IMEI":           "862127050000000",
         "IMEI 2":         "862127050000001",
         "Serial (SN)":    "fb4d921c",
         "Region":         "Iran (IR)",
         "Find My Device": "OFF"
       },
       "amount_charged": 0,
       "credit":         38,
       "currency":       "USD"
     }
   }

# A read answers with `fields` -- label/value pairs -- not a response_token.
# Asked again later with the same request_id: the same fields, at no extra cost.
read_imei · done
# read_imei: the answer takes about 1 to 5 minutes. Keep polling status.php until
# state is "done"; every call is "pending" with a retry_after until then.
# `fields` is a label->value map; which labels come back depends on the device and
# which info sources are enabled for your account, so treat it generically (loop
# over it) -- never assume a fixed set. Any of these may appear:
-> HTTP 200
   { "status":200, "data":{ "request_id":"WT-API-B82E6C0D51", "soc":"read_imei", "kind":"read", "state":"done",
       "fields": {
         "IMEI":            "862127050000000",
         "IMEI 2":          "862127050000001",
         "Product name":    "Xiaomi 14 12GB+512GB Black",
         "Brand":           "Xiaomi",
         "Model":           "Xiaomi 14",
         "Model code":      "2405CPX3DG",
         "Manufacturer":    "Xiaomi",
         "RAM":             "12 GB",
         "Storage":         "512 GB",
         "Color":           "Black",
         "Sold in":         "Global (MI)",
         "Region":          "Global",
         "Serial (SN)":     "fb4d921c",
         "SKU":             "MZB0ABCIN",
         "Wi-Fi MAC":       "A4:FF:9F:71:0E:EE",
         "Factory date":    "2024-02-14",
         "Activation":      "Never activated",
         "Repair":          "Available",
         "Flash status":    "Clean",
         "Production date": "2024-02-20 08:14 UTC",
         "Find My Device":  "OFF"
       },
       "amount_charged":0, "credit":38, "currency":"USD" } }
read_lockcode · done
# read_lockcode: an order placed at the shop. The answer takes a few minutes; keep
# polling status.php. Our own cron also follows the order, so it finishes even if
# you stop asking.
-> HTTP 200
   { "status":200, "data":{ "request_id":"WT-API-47A0F3E9C2", "soc":"read_lockcode", "kind":"read", "state":"done",
       "fields": {
         "Lock code":      "4YYZ-F7CO-FPDJ-GAU",
         "Product":        "fleur",
         "Serial Number":  "58583/65QU09211",
         "IMEI":           "862127050000000",
         "Find My Device": "ON"
       },
       "amount_charged":0, "credit":38, "currency":"USD" } }

servers.php lists the reads you may use in a reads array, each with its soc, name, needs and price, plus time (the delivery time; for read_lockcode the shop service's own, empty when not known) and field (the name of the input to show your customer, e.g. Lock Code). read_imei and read_lockcode are asynchronous (poll).

Bölüm 3 · Krediniz ve fiyatlar

12İş geçmişiniz

POSThttps://xiaomi.source.af/api/reseller/v1/history.php

İşleriniz, en yeniden eskiye: her birinin ne zaman, hangi sunucuya gönderildiği ve nasıl sonuçlandığı — tarihe ve hizmete göre. Aynı dört kimlik bilgisi; kredi harcamaz ve saatlik kotanıza sayılır.

AlanTürZorunluNedir
fromstringhayırBir gün, 2026-10-08 (veya 2026-Oct-08), UTC olarak: o gün veya sonrasında gönderilen işler.
tostringhayırBir gün: o gün veya öncesinde gönderilen işler, günün tamamı dahil.
socstringhayırfrp veya fdl: yalnızca o hizmetin işleri.
limitnumberhayırListelenecek iş sayısı, 1–100. Varsayılan 1.
beforestringhayırBir request_id: ondan eski işler. Sonraki sayfa için bir yanıttaki next_before değerini gönderin.
history.php
curl -X POST https://xiaomi.source.af/api/reseller/v1/history.php \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer rst_YOUR_ACCOUNT_TOKEN' \
  -d '{"api_key":"YOUR_API_KEY","email":"you@example.com","password":"YOUR_PASSWORD",
       "from":"2026-10-08","to":"2026-10-09","soc":"frp","limit":2}'

-> {
  "status": 200,
  "data": {
    "from":     "2026-10-08",
    "to":       "2026-10-09",
    "soc":      "frp",
    "total":    14,
    "counts":   { "done":11, "error":2, "expired":1, "pending":0, "waiting":0 },
    "spent":    13.2,
    "currency": "USD",
    "jobs": [
      { "request_id":"WT-API-6AF684545B", "door":"api", "soc":"frp", "serverid":"server1", "server_name":"Server 1",
        "state":"done", "error":null, "message":null, "amount":1.2, "currency":"USD",
        "device":{ "product_model":"fleur", "device_name":"fleur_global", "serial_number":"fb4d921c" },
        "created_at":"2026-10-09T14:51:52Z", "updated_at":"2026-10-09T14:52:00Z" },
      { "request_id":"WT-API-9F04A2C6E1", "door":"api", "soc":"frp", "serverid":"server2", "server_name":"Server 2",
        "state":"error", "error":"server_offline", "message":"The selected server is off right now (FRP). …",
        "amount":0, "currency":"USD", "device":{ … },
        "created_at":"2026-10-09T14:40:10Z", "updated_at":"2026-10-09T14:40:11Z" }
    ],
    "next_before": "WT-API-9F04A2C6E1"
  }
}

total ve counts yalnızca bu sayfayı değil tüm aralığı kapsar: kaç istek gönderdiğinizi ve kaçının done, error, expired, pending veya waiting olarak sonuçlandığını; spent ise size maliyetini gösterir. jobs altındaki her işin request_id değeri vardır — WorkID’si: bu API ile gönderilen iş için WT-API-6AF684545B, kendi aracımızda çalıştırılan iş için WT-WEB-…; door bunu söyler — ayrıca soc, serverid ve server_name, state, token vermediyse error ve message, amount (size maliyeti), device ve gönderilme ile son değişiklik zamanı. Token’ın kendisi listelenmez: status.php onu request_id ile verir.

13Kredi ve kullanım

POSThttps://xiaomi.source.af/api/reseller/v1/balance.php

Ne kadar kredi kaldığı ve geri kalanının nereye gittiği: panelinizin üstündeki kartlarla aynı rakamlar. Token isteğiyle aynı dört kimlik bilgisini alır, kredi harcamaz ve 10 saniyede bir yanıt verir.

balance.php
curl -X POST https://xiaomi.source.af/api/reseller/v1/balance.php \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer rst_YOUR_ACCOUNT_TOKEN' \
  -d '{"api_key":"YOUR_API_KEY","email":"you@example.com","password":"YOUR_PASSWORD"}'

-> {
  "status": 200,
  "data": {
    "username": "you",
    "credit":   38,
    "currency": "USD",
    "usage": {
      "bought":        50,
      "spent":         12,
      "spent_frp":     10.8,
      "spent_fdl":     1.2,
      "spent_api":     9,
      "spent_xst":     3,
      "sent_to_users": 0,
      "left":          38
    },
    "prices": {
      "frp": [
        { "serverid":"server1", "name":"Server 1", "online":true,  "price":1.2 },
        { "serverid":"server2", "name":"Server 2", "online":true,  "price":1.5 },
        { "serverid":"server3", "name":"Server 3", "online":false, "price":1.4 }
      ],
      "fdl": [
        { "serverid":"server1", "name":"Server 1", "online":true,  "price":0.3 }
      ]
    }
  }
}

usage altında: bought, hesabınıza eklenen tüm kredidir, yöneticinin geri aldığı düşülür; spent, işlerinizin maliyetidir, iadeler düşülür — hizmete göre spent_frp ve spent_fdl, kanala göre spent_api (bu API ile) ve spent_xst (kendi aracımızda) olarak ayrılır; sent_to_users, bir zamanlar bayi olduysanız kendi kullanıcılarınıza verdiğinizdir; left kalan miktardır, credit ile aynıdır. Toplamlar tutar: bought − sent_to_users − spent = left ve spent_frp + spent_fdl = spent. prices, hizmete göre her sunucuda bir işin size maliyetidir: serverid, name, online olup olmadığı ve price, kendi para biriminizde.

10 saniye içinde yeniden sorulursa retry_after ile birlikte 429 too_soon yanıtı verir: o kadar saniye bekleyin. Hiçbir şey engellenmez.

14Sunucular ve fiyatlar

POSThttps://xiaomi.source.af/api/reseller/v1/servers.php

Token isteğiyle aynı dört kimlik bilgisini alır ve kredi harcamaz. Her çağrı saatlik kotanıza dahil edilir.

Neleri kullanabileceğiniz ve her işin size maliyeti.

servers.php
curl -X POST https://xiaomi.source.af/api/reseller/v1/servers.php \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer rst_YOUR_ACCOUNT_TOKEN' \
  -d '{"api_key":"YOUR_API_KEY","email":"you@example.com","password":"YOUR_PASSWORD"}'

-> {
  "status": 200,
  "data": {
    "currency": "USD",
    "services": {
      "frp": {
        "price": 1.2,
        "providers": [
          { "serverid":"server1", "name":"Server 1", "online":true,  "price":1.2, "currency":"USD",
            "region_support":[], "region_not_support":["CN","IN"] },
          { "serverid":"server6-3", "name":"Server 6.3", "online":true,  "price":1.5, "currency":"USD",
            "region_support":["CN"], "region_not_support":["IN"] },
          { "serverid":"server3", "name":"Server 3", "online":false, "price":1.4, "currency":"USD",
            "region_support":["CN","IN"], "region_not_support":[] }
        ]
      },
      "fdl": { "price":0.3, "providers":[ … ] }
    }
  }
}

providers altındaki her satır kullanabileceğiniz bir sunucudur — şu anda kapalı olanlar da dahil hepsi (online false); iş alanlar ve en ucuzlar önce. serverid ve name, gönderdiğiniz ve her yanıtın geri adlandırdığı değerlerdir; price, onda bir işin size maliyetidir; online ise ona yönelik bir isteğin şu anda kabul edilip edilmediğini söyler. Kapalı birini seçmek sizin tercihinizdir: token.php onu herhangi bir request_id vermeden server_offline ile reddeder — başka bir sunucu kullanın ya da daha sonra deneyin. Listenin yanındaki price, serverid olmadan bir isteğin maliyetidir: iş alan en ucuz sunucu.

Her satır ayrıca o sunucunun hangi ülkeleri kabul ettiğini cihazın region değerine göre söyler: region_support — bazı sunucularımız kabul etmese de bu sunucunun kabul ettiği (ya da orada kabul edildiğini belirttiğimiz) ülkeler, region_not_support — kabul etmediği ülkeler. İkisi de boşsa: tüm ülkeler. Bunları müşterinize hatırlatma olarak gösterin, ör. “Server 6.3 — Çin: evet, Hindistan: hayır”. Yalnızca ülke yayımlanır: diğer koşullarımız (bir model, bir sürüm, bir CPU ID…) listelenmez ve bizde kalır. Karar her zaman burada, hiçbir şey gönderilmeden verilir — token.php bir sunucunun kabul etmediği cihazı unsupported (422) ile reddeder ve check.php bunu tek bir cihaz için yanıtlar.

servers yanıtını kendi müşterilerinize güvenle gösterebilirsiniz: herkese açık sunucu adlarımızı ve sizin fiyatınızı içerir; asla bizim maliyetimizi ve asla üst sağlayıcıyı içermez.

15Bir cihazı hangi sunucular kabul eder

POSThttps://xiaomi.source.af/api/reseller/v1/check.php

Kuru bir kontrol: token.php ile aynı kimlik bilgileri ve aynı gövde (soc, configblob), configblob’un aynı kontrolleri ve aynı hatalar — ve sonra hiçbir şey: request_id yok, iş yok, rezerve veya ücret yok, hiçbir sunucuya bir şey gönderilmez. Bazı sunucular bazı cihazları kabul etmez (bir sürüm, bir ülke…); bu çağrı, bu cihaz için sunucularınızdan hangilerinin kabul ettiğini söyler. Kendi sınırı vardır, dakikada 60 çağrı, ve saatlik kotanızdan düşmez.

check.php
curl -X POST https://xiaomi.source.af/api/reseller/v1/check.php \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer rst_YOUR_ACCOUNT_TOKEN' \
  -d '{"api_key":"YOUR_API_KEY","email":"you@example.com","password":"YOUR_PASSWORD",
       "soc":"frp","configblob":"eyJ0b2tlbiI6IjhmMjFj…"}'

-> {
  "status": 200,
  "data": {
    "soc": "frp",
    "refused_everywhere": false,
    "suggested": "server6-3",
    "device": { "model":"fleur", "device":"fleur_global", "version":"OS2.0.207.0.VMTMIXM", "region":"US", "cpuid":"0x000460E1" },
    "servers": [
      { "serverid":"server1",   "name":"Server 1",   "online":true,  "price":1.2, "currency":"USD", "region_support":[],     "region_not_support":["CH","CN"], "takes":false, "reason":"China devices are not supported on this server" },
      { "serverid":"server6-3", "name":"Server 6.3", "online":true,  "price":2.0, "currency":"USD", "region_support":["CH","CN"], "region_not_support":[], "takes":true },
      { "serverid":"server5",   "name":"Server 5",   "online":false, "price":1.4, "currency":"USD", "region_support":[],     "region_not_support":["CH","CN"], "takes":false, "reason":"…" }
    ],
    "region": "CN",
    "region_checked": true,
    "flash_status": "CLEAN",
    "premium": [ { "serverid":"server6-3", "name":"Server 6.3", "online":true, "price":2.0, "currency":"USD" } ],
    "slots_full": false,
    "message": "Your device's region is CN. This device must be done with ★ Server 6.3 — a premium server: its FRP removal success rate for this device is very high."
  }
}

servers altındaki satırlar, servers.php’nin listelediği satırlardır; aynı sırayla, kapalı olanlar da dahil. takes, o sunucunun bu cihazı kabul edip etmediğini söyler; etmiyorsa reason nedenini söyler. Bir sunucu kapalı olabilir (online false) ve yine de cihazı kabul edebilir: müşterinize daha sonra denemesini söyleyin. suggested, cihazı kabul eden ve açık olan ilk sunucudur (en ucuz önce) ya da null; refused_everywhere, sunucularınızdan hiçbiri kabul etmediğinde true’dur. device, configblob’dan okuduğumuz şeydir. token.php bir cihazı unsupported (422) ile reddettiğinde yanıtı takes_on taşır: onu kabul eden serverid’ler.

Yanıt, cihazın kendi bölgesini de token.php’nin çalıştırdığı aynı cihaz bilgisi ön kontrolüyle okur — bir telefon ait olmadığı bir bölgeyi bildirebilir. region, sunucuların değerlendirildiği bölgedir: region_checked true ise ön kontrolün okuduğu, değilse configblob’un söylediği. flash_status okunan flaş durumudur (bilinmiyorsa boş). premium, bu cihazı kabul eden ve bölgesi için premium olan sunucularınızı listeler (o ülkenin cihazları için yapılmışlardır, bu yüzden başarı oranları çok yüksektir); o zaman suggested bunlardan biridir ve message müşterinize gösterebileceğiniz bir cümledir, örn. “Cihazınızın bölgesi CN. Bu cihaz Server 6.3 ile yapılmalıdır — premium bir sunucu …” (yoksa boş). Bu sunucuyu müşteriniz için önceden seçin, nedenini söyleyin ve sunucuyu değiştirmesine, iptal etmesine veya devam etmesine izin verin. Ön kontrolün yanıtı 15 dakika saklanır; ardından gelen token.php yeniden sormaz.

Bir cihazı okuduktan sonra, onu reddedecek sunucuları soluk göstermek için; ya da token.php müşterinizin seçtiği sunucu için unsupported yanıtı verdikten sonra, kabul edeni önermek için sorun. serverid içermeyen bir istek, cihazı kabul eden en ucuz sunucuya kendiliğinden gönderilir.

Bölüm 4 · Hata kodları

16Hata kodları

Her hata aynı biçimdedir: dallanma için bir error kodu ve insanlar için bir message. Dallanmayı mesaj metnine göre değil, her zaman koda göre yapın — ifadeler değişir, kodlar değişmez. Giriş kontrollerini geçtikten sonra oluşan token.php hataları da süre bloklarını taşır; böylece yavaş bir hata, yavaş bir başarı kadar ölçülebilir. Bazıları kendi alanlarını da ekler: incomplete_configblob, alanların adlarını missing ve invalid içinde, mode ile birlikte verir; rate_limited ise limit ve used değerlerini taşır. Kod ne olursa olsun, token teslim etmeyen bir işin maliyeti yoktur — retler herhangi bir şey ayrılmadan önce gelir, gönderildikten sonra başarısız olan bir işte ise ayrılan kredinin tamamı iade edilir.

KodHTTPAnlamı ve ne yapmalı
unauthorized401Dört kimlik bilgisinden biri yanlış veya hesap devre dışı. Hangisi olduğunu bilerek söylemiyoruz.
ip_not_allowed403Dört kimlik bilgisi de doğru, ancak istek hesabınızın izin listesinde olmayan bir adresten geldi. Yanıt bu adresi ip alanında bildirir. Adresi panelinizden ekleyin (Hesap → İzin verilen IP’ler) veya izin verilen bir adresten gönderin. Hiçbir şey çalıştırılmadı ve ücret alınmadı.
too_many_failures429Adresinizden çok fazla başarısız deneme yapıldı. Bekleyin, ardından yeniden denemeden önce kimlik bilgisini düzeltin.
rate_limited429Bir sınırı aştınız: saatlik kotanız (token.php, history.php, balance.php, servers.php) ya da dakikada 120 durum sorgusu. Yanıt limit, used ve per içerir.
too_soon429balance.php 10 saniye içinde yeniden sorgulandı. Yanıt, kaç saniye beklemeniz gerektiğini bildirir (retry_after ve Retry-After başlığı); hiçbir şey engellenmez.
method_not_allowed405GET kullandınız. Tüm uç noktalar POST’tur.
bad_json400Gövde bir JSON nesnesi değildi. Content-Type: application/json ayarlayın.
body_too_large413Gövde 256 KB’tan büyük.
missing_soc400soc gönderilmedi. Bilerek varsayılan bir değeri yoktur.
bad_service400soc tam olarak frp veya fdl olmalıdır.
not_entitled403Bu hizmet hesabınıza satılmıyor. Etkinleştirmemiz için bize başvurun.
disabled503Bu hizmeti şu anda kapattık. Geçicidir.
missing_configblob400configblob gönderilmedi.
bad_configblob400configblob, bir JSON nesnesinin geçerli base64 kodlaması değil.
missing_token400Blob içinde cihaz token değeri eksik.
incomplete_configblob400Sunucuların ihtiyaç duyduğu bir alan gönderilmemiş (missing), null gönderilmiş (nulls) ya da başarısız bir okuma içeriyor (invalid); mode, telefonun bulunması gereken moddur. Telefonu yeniden okuyun ve eksiksiz bilgiyi gönderin; hiçbir ücret alınmadı.
use_serverid400services veya server_id gönderdiniz; bu, sunucuyu sırasına göre seçmenin eski yoludur. Artık kabul edilmiyor: serverid gönderin (servers.php’den) ya da göndermeyip seçimi bize bırakın.
use_status400token.php’ye bir request_id gönderdiniz; o yalnızca yeni istek başlatır. request_id değerini status.php’ye gönderin.
unknown_serverid404Bu serverid değerine sahip bir sunucu yok. Liste için servers.php çağrısı yapın veya panelinizdeki Sunucular bölümüne bakın.
server_not_allowed403Belirttiğiniz sunucu hesabınız için etkin değil. Sizi başka bir sunucuya geçirmeyiz: listenizden birini seçin ya da serverid göndermeyin.
service_not_allowed403Sunucu belirtmediniz ve hesabınız için etkin bir sunucu yok. Birini etkinleştirmemizi isteyin.
server_offline503Belirttiğiniz sunucu bu hizmeti şu anda alamıyor: kapalı, çevrimdışı ya da bizim tarafımızda hazır değil. token.php bunu request_id vermeden önce kontrol eder, iş de başlarken yeniden kontrol eder; arada ya da iş çalışırken kapandıysa ayrılan kredi iade edilir. Hiçbir ücret alınmadı. servers.php listesinden başka bir sunucu kullanın ya da daha sonra tekrar deneyin.
service_offline503Sunucu belirtmediniz ve şu anda bu hizmet için iş alan sunucu yok. Hiçbir ücret alınmadı. Kısa süre sonra tekrar deneyin.
no_credit402O sunucudaki bir iş için kredi yetersiz — ya token.php herhangi bir request_id vermeden reddetti ya da krediniz bu arada düştüyse iş başlarken. Hiçbir ücret alınmadı. Kredi yükleyin ya da daha ucuz bir sunucu seçin.
bad_imei400imei eksikti veya geçersizdi: read_imei 15 haneli IMEI’ye ihtiyaç duyar; read_lockcode sipariş için kullanılan IMEI’ye ihtiyaç duyar.
read_failed502Bir okuma (read_sideload, read_fastboot, read_imei veya read_lockcode) tamamlanamadı. Ücret alınmadı. Tekrar gönderin veya daha sonra deneyin.
missing_request_id400status.php, request_id olmadan çağrıldı.
not_found404Bu request_id ile hesabınıza ait bir istek yok.
request_expired410request_id, 30 saniye içinde status.php ile onaylanmadığı için iptal edildi. Hiçbir şey gönderilmedi ve ücret alınmadı. Yeni bir request_id için isteği token.php’ye yeniden gönderin.
unsupported422Bu cihaza hizmet verilemiyor. Hizmet vermediğimiz cihazlar listemizdeyse token.php onu reddeder: request_id verilmez, ücret alınmaz. Seçtiğiniz sunucu cihazı desteklemediğini söylerse iş ücretlendirilir ve iade edilmez — göndermeden önce hangi build’lerin ve ülkelerin desteklendiğini bize sorun (bkz. Desteklenen cihazlar). Aynı sunucuda tekrar denemeyin.
account_restricted403Hesabınız birkaç dakikalığına kısıtlandı: bir cihaz 5 dakika içinde 3’ten fazla kez desteklenmeyen olarak reddedildi ve uyarıdan sonra yeniden gönderildi. O zamana kadar her yeni istek reddedilir; status.php zaten başlamış işler için yanıt vermeye devam eder. Yanıt reason (unsupported_device_repeated), retry_after (saniye), restricted_until ve panelinize yönelik bir cümle olan note taşır. Bir hata olduysa bize ulaşın.
device_reboot409Sunucu bu cihaz token’ının zaten kullanıldığını söylüyor. Ücret alınmadı. Telefonu yeniden başlatın, yeni bir token vermesi için tekrar sideload moduna alın ve yeni bir istek gönderin.
server_unavailable503Sunucu zamanında yanıt vermedi ya da — hiç sunucu belirtmediyseniz — kullanılabilir sunucu yoktu. Hiçbir ücret alınmadı. Aynı isteği yeniden gönderin.
failed400Seçtiğiniz sunucu işi çalıştırdı ancak bu cihaz için token vermedi — geç aşamada bir hata. Hiçbir ücret alınmadı: ayrılan kredinin tamamı iade edilir. Telefonun okumasını kontrol edin ya da başka bir sunucu deneyin.
bad_before400history.php içindeki before bir request_id değil.
bad_date400history.php içindeki from veya to, 2026-10-08 gibi bir gün değil ya da from, to değerinden sonra.
Bölüm 5 · Güvenlik

17Güvenlik

Her zaman HTTPS kullanın

Şifreniz ve anahtarınız her isteğin gövdesindedir. Düz HTTP üzerinden yol üzerindeki herkes bunları okuyup yeniden kullanabilir.

Hesap token’ınız yalnızca bir kez gösterilir

Bu sizin hesap token’ınızdır — Authorization başlığındaki rst_… değeri — kilit açma token’ları değil. Yalnızca bir özetini saklarız, bu yüzden size sonradan e-postayla gönderemeyiz. Diğer gizli bilgilerinizi sakladığınız yerde saklayın. Sızarsa panelinizde yenisini oluşturun — eskisi hemen çalışmaz olur. İşlerinizin getirdiği kilit açma token’ları başka bir şeydir: her biri kendi işiyle saklanır ve status.php onu request_id ile size yeniden verir.

Kimlik bilgilerini dağıttığınız yazılımın dışında tutun

Bizi son kullanıcılara verdiğiniz bir araçtan değil, kendi sunucunuzdan çağırın. Dağıttığınız her şey okunabilir.

API’yi adreslerinize kilitleyin

Panelinizden (Hesap → İzin verilen IP’ler) API’yi sunucunuzun çağrı yaptığı adreslere kilitleyebilirsiniz; böylece çalınan bir kimlik bilgisi başka hiçbir yerde işe yaramaz. Başka bir adresten gelen istek ip_not_allowed ile reddedilir. Bunu sizin için biz de ayarlayabiliriz.

Şifrenizi asla günlüğe kaydetmeyiz

İstek işle birlikte saklanmadan önce çıkarılır; bu yüzden ne veritabanımızda, ne iş günlüğümüzde ne de yönetici ekranlarımızda bulunur.

request_id sizin makbuzunuzdur

Bir request_id değerini yalnızca sizin hesabınız okuyabilir; başka her hesap not_found alır. Bir iş, ancak request_id değerini 30 saniye içinde onayladığınızda başlar; böylece yolda kaybolan bir yanıt, haberiniz olmayan ücretli bir işi asla çalışır halde bırakmaz.

Sınırlar

Saatlik kotanız token.php, history.php, balance.php ve servers.php çağrılarını kapsar; status.php kendi başına dakikada 120 çağrıya izin verir; balance.php 10 saniyede bir yanıt verir; bir adresten 15 dakikada 40’tan fazla başarısız girişten sonra o adres bir süre too_many_failures ile reddedilir.

Bölüm 6 · Kod örnekleri

18Kod örnekleri

Her iş için dört dilde eksiksiz bir program — istek gönderme, onu request_id ile sorgulama, iş geçmişiniz, krediniz, sunucular. Kendi kimlik bilgilerinizi girip çalıştırın; bir dil seçmek onu tüm bloklarda gösterir.

1Token isteği gönderme

Telefon okumasını token.php’ye gönderir ve request_id değerini yazdırır. Henüz hiçbir şey çalışmaz: o request_id değerini 30 saniye içinde sonraki programa verin.

send.sh
#!/bin/sh
# 1. Send a token request. Prints the answer with the request_id; nothing runs
#    until you confirm it with status.sh within 30 seconds.
BASE='https://xiaomi.source.af/api/reseller/v1'
TOKEN='rst_YOUR_ACCOUNT_TOKEN'
AUTH='"api_key":"YOUR_API_KEY","email":"you@example.com","password":"YOUR_PASSWORD"'
post() { curl -s -X POST "$BASE/$1" -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" -d "{$AUTH$2}"; }

# The complete Mi Assistant reading, exactly as the phone answered
DEVICE='{"token":"8f21c0b4e9d7","deviceName":"fleur_global","version":"OS2.0.207.0.VMTMIXM","serial":"fb4d921c","codebase":"15","region":"IR","cpuid":"0x000460E1","recovery":"2","branch":"F","language":"fa"}'
BLOB=$(printf '%s' "$DEVICE" | base64 | tr -d '\n')

post token.php ',"soc":"frp","serverid":"server1","configblob":"'"$BLOB"'"'
echo
# -> {"status":202,"data":{"request_id":"WT-API-6AF684545B","state":"waiting","confirm_within":30,…}}
# next, within 30 seconds:  sh status.sh WT-API-6AF684545B
send.php
<?php
/* 1. Send a token request. Prints the request_id; nothing runs until you
      confirm it with status.php within 30 seconds. */
const BASE  = 'https://xiaomi.source.af/api/reseller/v1';
const TOKEN = 'rst_YOUR_ACCOUNT_TOKEN';
const AUTH  = ['api_key' => 'YOUR_API_KEY', 'email' => 'you@example.com', 'password' => 'YOUR_PASSWORD'];

function xst(string $endpoint, array $body): array
{
    $ch = curl_init(BASE . '/' . $endpoint);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode(AUTH + $body),
        CURLOPT_HTTPHEADER     => ['Content-Type: application/json', 'Authorization: Bearer ' . TOKEN],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 30,
    ]);
    $raw = curl_exec($ch);
    curl_close($ch);
    return json_decode((string)$raw, true) ?: ['error' => 'no_answer', 'message' => 'no answer from the server'];
}

/* What your tool read in Mi Assistant mode, exactly as the phone answered. */
$device = [
    'token'      => '8f21c0b4e9d7…',          // getmitoken:
    'deviceName' => 'fleur_global',           // getdevice:
    'version'    => 'OS2.0.207.0.VMTMIXM',    // getversion:
    'serial'     => 'fb4d921c',               // getsn:
    'codebase'   => '14',                     // getcodebase:
    'branch'     => 'F',                      // getbranch:
    'region'     => 'global',                 // getregion:
    'cpuid'      => '0x000460E1',             // getcpuid:  optional
];

$r = xst('token.php', [
    'soc'        => 'frp',
    'serverid'   => 'server1',                // the server that must run it
    'configblob' => base64_encode(json_encode($device)),
]);
if (isset($r['error'])) {
    exit("refused: {$r['error']} - {$r['message']}\n");     // nothing was created or charged
}
$rid = $r['data']['request_id'];
echo "request_id $rid\n";
echo "confirm it within {$r['data']['confirm_within']} seconds:  php status.php $rid\n";
send.py
"""1. Send a token request. Prints the request_id; nothing runs until you
   confirm it with status.py within 30 seconds."""
import base64, json, sys, time, requests

BASE  = "https://xiaomi.source.af/api/reseller/v1"
TOKEN = "rst_YOUR_ACCOUNT_TOKEN"
AUTH  = {"api_key": "YOUR_API_KEY", "email": "you@example.com", "password": "YOUR_PASSWORD"}

def xst(endpoint, body):
    try:
        r = requests.post(f"{BASE}/{endpoint}", json={**AUTH, **body},
                          headers={"Authorization": f"Bearer {TOKEN}"}, timeout=30)
        return r.json()
    except (requests.RequestException, ValueError):
        return {"error": "no_answer", "message": "no answer from the server"}

# What your tool read in Mi Assistant mode, exactly as the phone answered.
device = {
    "token":      "8f21c0b4e9d7…",          # getmitoken:
    "deviceName": "fleur_global",           # getdevice:
    "version":    "OS2.0.207.0.VMTMIXM",    # getversion:
    "serial":     "fb4d921c",               # getsn:
    "codebase":   "14",                     # getcodebase:
    "branch":     "F",                      # getbranch:
    "region":     "global",                 # getregion:
    "cpuid":      "0x000460E1",             # getcpuid:  optional
}

r = xst("token.php", {"soc": "frp", "serverid": "server1",      # the server that must run it
                      "configblob": base64.b64encode(json.dumps(device).encode()).decode()})
if "error" in r:
    sys.exit(f"refused: {r['error']} - {r.get('message')}")    # nothing was created or charged
rid = r["data"]["request_id"]
print("request_id", rid)
print(f"confirm it within {r['data']['confirm_within']} seconds:  python status.py {rid}")
Program.cs
// 1. Send a token request. Prints the request_id; nothing runs until you
//    confirm it with the status program within 30 seconds.
// .NET 6 or later: dotnet new console, then replace Program.cs with this file.
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json.Nodes;

const string BASE  = "https://xiaomi.source.af/api/reseller/v1";
const string TOKEN = "rst_YOUR_ACCOUNT_TOKEN";

var http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TOKEN);

async Task<JsonNode> Xst(string endpoint, JsonObject body)
{
    body["api_key"]  = "YOUR_API_KEY";
    body["email"]    = "you@example.com";
    body["password"] = "YOUR_PASSWORD";
    try
    {
        var res = await http.PostAsync($"{BASE}/{endpoint}",
            new StringContent(body.ToJsonString(), Encoding.UTF8, "application/json"));
        return JsonNode.Parse(await res.Content.ReadAsStringAsync())!;
    }
    catch (Exception)
    {
        return new JsonObject { ["error"] = "no_answer", ["message"] = "no answer from the server" };
    }
}

// What your tool read in Mi Assistant mode, exactly as the phone answered.
var device = new JsonObject
{
    ["token"]      = "8f21c0b4e9d7…",          // getmitoken:
    ["deviceName"] = "fleur_global",           // getdevice:
    ["version"]    = "OS2.0.207.0.VMTMIXM",    // getversion:
    ["serial"]     = "fb4d921c",               // getsn:
    ["codebase"]   = "14",                     // getcodebase:
    ["branch"]     = "F",                      // getbranch:
    ["region"]     = "global",                 // getregion:
    ["cpuid"]      = "0x000460E1",             // getcpuid:  optional
};
var blob = Convert.ToBase64String(Encoding.UTF8.GetBytes(device.ToJsonString()));

var r = await Xst("token.php", new JsonObject { ["soc"] = "frp", ["serverid"] = "server1", ["configblob"] = blob });
if (r["error"] is not null)
{
    Console.WriteLine($"refused: {r["error"]} - {r["message"]}");   // nothing was created or charged
    return;
}
var rid = (string)r["data"]!["request_id"]!;
Console.WriteLine($"request_id {rid}");
Console.WriteLine($"confirm it within {r["data"]!["confirm_within"]} seconds:  dotnet run -- {rid}");

2Bir isteği sorgulama ve token’ı alma

İlk programdan request_id değerini alır. status.php’ye ilk çağrısı işi başlatır; ardından token gelene kadar her 3 saniyede bir sorar — ya da gelmeme nedeni gelene kadar.

status.sh
#!/bin/sh
# 2. Confirm a request and follow it to the token:  sh status.sh WT-API-6AF684545B
#    The first call starts the job (within 30 seconds of send.sh).
BASE='https://xiaomi.source.af/api/reseller/v1'
TOKEN='rst_YOUR_ACCOUNT_TOKEN'
AUTH='"api_key":"YOUR_API_KEY","email":"you@example.com","password":"YOUR_PASSWORD"'
post() { curl -s -X POST "$BASE/$1" -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" -d "{$AUTH$2}"; }
RID="${1:-WT-API-6AF684545B}"

while :; do
  ANSWER=$(post status.php ',"request_id":"'"$RID"'"')
  echo "$ANSWER"
  case "$ANSWER" in
    *'"state":"pending"'*|*'"state":"waiting"'*) sleep 3 ;;
    *) break ;;
  esac
done
# The last answer: "state":"done" with "response_token" -- write it to the phone --
# or "error" with the reason ("expired": send a new request).
status.php
<?php
/* 2. Confirm a request and follow it to the token:  php status.php WT-API-6AF684545B
      The first call starts the job (within 30 seconds of send.php). */
const BASE  = 'https://xiaomi.source.af/api/reseller/v1';
const TOKEN = 'rst_YOUR_ACCOUNT_TOKEN';
const AUTH  = ['api_key' => 'YOUR_API_KEY', 'email' => 'you@example.com', 'password' => 'YOUR_PASSWORD'];

function xst(string $endpoint, array $body): array
{
    $ch = curl_init(BASE . '/' . $endpoint);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode(AUTH + $body),
        CURLOPT_HTTPHEADER     => ['Content-Type: application/json', 'Authorization: Bearer ' . TOKEN],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 30,
    ]);
    $raw = curl_exec($ch);
    curl_close($ch);
    return json_decode((string)$raw, true) ?: ['error' => 'no_answer', 'message' => 'no answer from the server'];
}

$rid = $argv[1] ?? 'WT-API-6AF684545B';        // the request_id token.php gave you

for ($i = 0; $i < 100; $i++) {
    $r = xst('status.php', ['request_id' => $rid]);
    if (($r['error'] ?? '') === 'no_answer') { sleep(3); continue; }   // the network, not the job: ask again
    $state = $r['data']['state'] ?? 'error';
    if ($state !== 'pending' && $state !== 'waiting') { break; }
    echo "pending...\n";
    sleep((int)($r['data']['retry_after'] ?? 3));
}

if (($r['data']['state'] ?? '') === 'done') {
    $d = $r['data'];
    echo "token {$d['response_token']}\n";              // write this to the phone
    echo "from {$d['server_name']}, charged {$d['amount_charged']} {$d['currency']}, credit left {$d['credit']}\n";
} else {
    echo 'no token: ' . ($r['error'] ?? '?') . ' - ' . ($r['message'] ?? '') . "\n";
}
status.py
"""2. Confirm a request and follow it to the token:  python status.py WT-API-6AF684545B
   The first call starts the job (within 30 seconds of send.py)."""
import base64, json, sys, time, requests

BASE  = "https://xiaomi.source.af/api/reseller/v1"
TOKEN = "rst_YOUR_ACCOUNT_TOKEN"
AUTH  = {"api_key": "YOUR_API_KEY", "email": "you@example.com", "password": "YOUR_PASSWORD"}

def xst(endpoint, body):
    try:
        r = requests.post(f"{BASE}/{endpoint}", json={**AUTH, **body},
                          headers={"Authorization": f"Bearer {TOKEN}"}, timeout=30)
        return r.json()
    except (requests.RequestException, ValueError):
        return {"error": "no_answer", "message": "no answer from the server"}

rid = sys.argv[1] if len(sys.argv) > 1 else "WT-API-6AF684545B"     # the request_id token.php gave you

for _ in range(100):
    r = xst("status.php", {"request_id": rid})
    if r.get("error") == "no_answer":
        time.sleep(3)                    # the network, not the job: ask again
        continue
    if r.get("data", {}).get("state") not in ("pending", "waiting"):
        break
    print("pending...")
    time.sleep(r["data"].get("retry_after", 3))

d = r.get("data", {})
if d.get("state") == "done":
    print("token", d["response_token"])  # write this to the phone
    print("from", d["server_name"], "charged", d["amount_charged"], d["currency"], "credit left", d["credit"])
else:
    print("no token:", r.get("error"), "-", r.get("message"))
Program.cs
// 2. Confirm a request and follow it to the token:  dotnet run -- WT-API-6AF684545B
//    The first call starts the job (within 30 seconds of sending).
// .NET 6 or later: dotnet new console, then replace Program.cs with this file.
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json.Nodes;

const string BASE  = "https://xiaomi.source.af/api/reseller/v1";
const string TOKEN = "rst_YOUR_ACCOUNT_TOKEN";

var http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TOKEN);

async Task<JsonNode> Xst(string endpoint, JsonObject body)
{
    body["api_key"]  = "YOUR_API_KEY";
    body["email"]    = "you@example.com";
    body["password"] = "YOUR_PASSWORD";
    try
    {
        var res = await http.PostAsync($"{BASE}/{endpoint}",
            new StringContent(body.ToJsonString(), Encoding.UTF8, "application/json"));
        return JsonNode.Parse(await res.Content.ReadAsStringAsync())!;
    }
    catch (Exception)
    {
        return new JsonObject { ["error"] = "no_answer", ["message"] = "no answer from the server" };
    }
}

var rid = args.Length > 0 ? args[0] : "WT-API-6AF684545B";      // the request_id token.php gave you

JsonNode r = new JsonObject();
for (var i = 0; i < 100; i++)
{
    r = await Xst("status.php", new JsonObject { ["request_id"] = rid });
    if ((string?)r["error"] == "no_answer") { await Task.Delay(3000); continue; }   // the network: ask again
    var state = (string?)r["data"]?["state"];
    if (state != "pending" && state != "waiting") break;
    Console.WriteLine("pending...");
    await Task.Delay(3000);
}

var d = r["data"];
if ((string?)d?["state"] == "done")
{
    Console.WriteLine($"token {d!["response_token"]}");   // write this to the phone
    Console.WriteLine($"from {d["server_name"]}, charged {d["amount_charged"]} {d["currency"]}, credit left {d["credit"]}");
}
else
{
    Console.WriteLine($"no token: {r["error"]} - {r["message"]}");
}

3İş geçmişiniz

İki gün arasındaki işlerinizi bir hizmet için listeler: kaç tane gönderdiğinizi, her birinin nasıl sonuçlandığını ve maliyetini.

history.sh
#!/bin/sh
# 3. Your job history: the FRP jobs sent from 8 to 9 October, newest first.
BASE='https://xiaomi.source.af/api/reseller/v1'
TOKEN='rst_YOUR_ACCOUNT_TOKEN'
AUTH='"api_key":"YOUR_API_KEY","email":"you@example.com","password":"YOUR_PASSWORD"'
post() { curl -s -X POST "$BASE/$1" -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" -d "{$AUTH$2}"; }

post history.php ',"from":"2026-10-08","to":"2026-10-09","soc":"frp","limit":20'
echo
history.php
<?php
/* 3. Your job history: the FRP jobs sent from 8 to 9 October, newest first. */
const BASE  = 'https://xiaomi.source.af/api/reseller/v1';
const TOKEN = 'rst_YOUR_ACCOUNT_TOKEN';
const AUTH  = ['api_key' => 'YOUR_API_KEY', 'email' => 'you@example.com', 'password' => 'YOUR_PASSWORD'];

function xst(string $endpoint, array $body): array
{
    $ch = curl_init(BASE . '/' . $endpoint);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode(AUTH + $body),
        CURLOPT_HTTPHEADER     => ['Content-Type: application/json', 'Authorization: Bearer ' . TOKEN],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 30,
    ]);
    $raw = curl_exec($ch);
    curl_close($ch);
    return json_decode((string)$raw, true) ?: ['error' => 'no_answer', 'message' => 'no answer from the server'];
}

$r = xst('history.php', ['from' => '2026-10-08', 'to' => '2026-10-09', 'soc' => 'frp', 'limit' => 20]);
if (isset($r['error'])) { exit("refused: {$r['error']} - {$r['message']}\n"); }

$d = $r['data'];
echo "{$d['total']} requests: {$d['counts']['done']} done, {$d['counts']['error']} failed, "
   . "{$d['counts']['expired']} expired; spent {$d['spent']} {$d['currency']}\n";
foreach ($d['jobs'] as $j) {
    printf("#%-9s %s %s %-10s %-8s %-6s %s\n", $j['request_id'], $j['created_at'], strtoupper($j['soc']),
           $j['server_name'], $j['state'], $j['amount'], $j['error'] ?? '');
}
history.py
"""3. Your job history: the FRP jobs sent from 8 to 9 October, newest first."""
import base64, json, sys, time, requests

BASE  = "https://xiaomi.source.af/api/reseller/v1"
TOKEN = "rst_YOUR_ACCOUNT_TOKEN"
AUTH  = {"api_key": "YOUR_API_KEY", "email": "you@example.com", "password": "YOUR_PASSWORD"}

def xst(endpoint, body):
    try:
        r = requests.post(f"{BASE}/{endpoint}", json={**AUTH, **body},
                          headers={"Authorization": f"Bearer {TOKEN}"}, timeout=30)
        return r.json()
    except (requests.RequestException, ValueError):
        return {"error": "no_answer", "message": "no answer from the server"}

r = xst("history.php", {"from": "2026-10-08", "to": "2026-10-09", "soc": "frp", "limit": 20})
if "error" in r:
    sys.exit(f"refused: {r['error']} - {r.get('message')}")

d = r["data"]
c = d["counts"]
print(f"{d['total']} requests: {c['done']} done, {c['error']} failed, {c['expired']} expired; spent {d['spent']} {d['currency']}")
for j in d["jobs"]:
    print(f"#{j['request_id']:<9} {j['created_at']} {j['soc'].upper()} {j['server_name']:<10} {j['state']:<8} {j['amount']:<6} {j['error'] or ''}")
Program.cs
// 3. Your job history: the FRP jobs sent from 8 to 9 October, newest first.
// .NET 6 or later: dotnet new console, then replace Program.cs with this file.
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json.Nodes;

const string BASE  = "https://xiaomi.source.af/api/reseller/v1";
const string TOKEN = "rst_YOUR_ACCOUNT_TOKEN";

var http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TOKEN);

async Task<JsonNode> Xst(string endpoint, JsonObject body)
{
    body["api_key"]  = "YOUR_API_KEY";
    body["email"]    = "you@example.com";
    body["password"] = "YOUR_PASSWORD";
    try
    {
        var res = await http.PostAsync($"{BASE}/{endpoint}",
            new StringContent(body.ToJsonString(), Encoding.UTF8, "application/json"));
        return JsonNode.Parse(await res.Content.ReadAsStringAsync())!;
    }
    catch (Exception)
    {
        return new JsonObject { ["error"] = "no_answer", ["message"] = "no answer from the server" };
    }
}

var r = await Xst("history.php", new JsonObject { ["from"] = "2026-10-08", ["to"] = "2026-10-09", ["soc"] = "frp", ["limit"] = 20 });
if (r["error"] is not null) { Console.WriteLine($"refused: {r["error"]} - {r["message"]}"); return; }

var d = r["data"]!;
var c = d["counts"]!;
Console.WriteLine($"{d["total"]} requests: {c["done"]} done, {c["error"]} failed, {c["expired"]} expired; spent {d["spent"]} {d["currency"]}");
foreach (var j in d["jobs"]!.AsArray())
    Console.WriteLine($"#{j!["request_id"],-9} {j["created_at"]} {((string)j["soc"]!).ToUpper()} {j["server_name"],-10} {j["state"],-8} {j["amount"],-6} {j["error"]}");

4Krediniz

Kredinizi, FRP ve FDL için harcadığınızı ve her sunucudaki fiyatınızı yazdırır.

balance.sh
#!/bin/sh
# 4. Your credit, what you spent on FRP and FDL, and your price on each server.
BASE='https://xiaomi.source.af/api/reseller/v1'
TOKEN='rst_YOUR_ACCOUNT_TOKEN'
AUTH='"api_key":"YOUR_API_KEY","email":"you@example.com","password":"YOUR_PASSWORD"'
post() { curl -s -X POST "$BASE/$1" -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" -d "{$AUTH$2}"; }

post balance.php ''
echo
balance.php
<?php
/* 4. Your credit, what you spent on FRP and FDL, and your price on each server. */
const BASE  = 'https://xiaomi.source.af/api/reseller/v1';
const TOKEN = 'rst_YOUR_ACCOUNT_TOKEN';
const AUTH  = ['api_key' => 'YOUR_API_KEY', 'email' => 'you@example.com', 'password' => 'YOUR_PASSWORD'];

function xst(string $endpoint, array $body): array
{
    $ch = curl_init(BASE . '/' . $endpoint);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode(AUTH + $body),
        CURLOPT_HTTPHEADER     => ['Content-Type: application/json', 'Authorization: Bearer ' . TOKEN],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 30,
    ]);
    $raw = curl_exec($ch);
    curl_close($ch);
    return json_decode((string)$raw, true) ?: ['error' => 'no_answer', 'message' => 'no answer from the server'];
}

$r = xst('balance.php', []);
if (isset($r['error'])) { exit("refused: {$r['error']} - {$r['message']}\n"); }

$d = $r['data'];
$u = $d['usage'];
echo "credit {$d['credit']} {$d['currency']}\n";
echo "spent {$u['spent']}: FRP {$u['spent_frp']}, FDL {$u['spent_fdl']}\n";
foreach ($d['prices'] as $soc => $servers) {
    foreach ($servers as $s) {
        printf("  %s %-10s %-12s %-7s %s\n", strtoupper($soc), $s['serverid'], $s['name'], $s['online'] ? 'online' : 'offline', $s['price']);
    }
}
balance.py
"""4. Your credit, what you spent on FRP and FDL, and your price on each server."""
import base64, json, sys, time, requests

BASE  = "https://xiaomi.source.af/api/reseller/v1"
TOKEN = "rst_YOUR_ACCOUNT_TOKEN"
AUTH  = {"api_key": "YOUR_API_KEY", "email": "you@example.com", "password": "YOUR_PASSWORD"}

def xst(endpoint, body):
    try:
        r = requests.post(f"{BASE}/{endpoint}", json={**AUTH, **body},
                          headers={"Authorization": f"Bearer {TOKEN}"}, timeout=30)
        return r.json()
    except (requests.RequestException, ValueError):
        return {"error": "no_answer", "message": "no answer from the server"}

r = xst("balance.php", {})
if "error" in r:
    sys.exit(f"refused: {r['error']} - {r.get('message')}")

d = r["data"]
u = d["usage"]
print("credit", d["credit"], d["currency"])
print(f"spent {u['spent']}: FRP {u['spent_frp']}, FDL {u['spent_fdl']}")
for soc, servers in d["prices"].items():
    for s in servers:
        print(f"  {soc.upper()} {s['serverid']:<10} {s['name']:<12} {'online' if s['online'] else 'offline':<7} {s['price']}")
Program.cs
// 4. Your credit, what you spent on FRP and FDL, and your price on each server.
// .NET 6 or later: dotnet new console, then replace Program.cs with this file.
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json.Nodes;

const string BASE  = "https://xiaomi.source.af/api/reseller/v1";
const string TOKEN = "rst_YOUR_ACCOUNT_TOKEN";

var http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TOKEN);

async Task<JsonNode> Xst(string endpoint, JsonObject body)
{
    body["api_key"]  = "YOUR_API_KEY";
    body["email"]    = "you@example.com";
    body["password"] = "YOUR_PASSWORD";
    try
    {
        var res = await http.PostAsync($"{BASE}/{endpoint}",
            new StringContent(body.ToJsonString(), Encoding.UTF8, "application/json"));
        return JsonNode.Parse(await res.Content.ReadAsStringAsync())!;
    }
    catch (Exception)
    {
        return new JsonObject { ["error"] = "no_answer", ["message"] = "no answer from the server" };
    }
}

var r = await Xst("balance.php", new JsonObject());
if (r["error"] is not null) { Console.WriteLine($"refused: {r["error"]} - {r["message"]}"); return; }

var d = r["data"]!;
var u = d["usage"]!;
Console.WriteLine($"credit {d["credit"]} {d["currency"]}");
Console.WriteLine($"spent {u["spent"]}: FRP {u["spent_frp"]}, FDL {u["spent_fdl"]}");
foreach (var (soc, servers) in d["prices"]!.AsObject())
    foreach (var s in servers!.AsArray())
        Console.WriteLine($"  {soc.ToUpper()} {s!["serverid"],-10} {s["name"],-12} {((bool)s["online"]! ? "online" : "offline"),-7} {s["price"]}");

5Sunucular

Kullanabileceğiniz sunucuları, her birindeki fiyatınızı ve şu anda iş alıp almadığını listeler.

servers.sh
#!/bin/sh
# 5. The servers you may use, your price on each, and whether they take jobs now.
BASE='https://xiaomi.source.af/api/reseller/v1'
TOKEN='rst_YOUR_ACCOUNT_TOKEN'
AUTH='"api_key":"YOUR_API_KEY","email":"you@example.com","password":"YOUR_PASSWORD"'
post() { curl -s -X POST "$BASE/$1" -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" -d "{$AUTH$2}"; }

post servers.php ''
echo
servers.php
<?php
/* 5. The servers you may use, your price on each, and whether they take jobs now. */
const BASE  = 'https://xiaomi.source.af/api/reseller/v1';
const TOKEN = 'rst_YOUR_ACCOUNT_TOKEN';
const AUTH  = ['api_key' => 'YOUR_API_KEY', 'email' => 'you@example.com', 'password' => 'YOUR_PASSWORD'];

function xst(string $endpoint, array $body): array
{
    $ch = curl_init(BASE . '/' . $endpoint);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode(AUTH + $body),
        CURLOPT_HTTPHEADER     => ['Content-Type: application/json', 'Authorization: Bearer ' . TOKEN],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 30,
    ]);
    $raw = curl_exec($ch);
    curl_close($ch);
    return json_decode((string)$raw, true) ?: ['error' => 'no_answer', 'message' => 'no answer from the server'];
}

$r = xst('servers.php', []);
if (isset($r['error'])) { exit("refused: {$r['error']} - {$r['message']}\n"); }

foreach ($r['data']['services'] as $soc => $svc) {
    echo strtoupper($soc) . " -- without serverid: {$svc['price']}\n";
    foreach ($svc['providers'] as $s) {
        printf("  %-10s %-12s %-7s %s %s\n", $s['serverid'], $s['name'], $s['online'] ? 'online' : 'offline', $s['price'], $s['currency']);
    }
}
servers.py
"""5. The servers you may use, your price on each, and whether they take jobs now."""
import base64, json, sys, time, requests

BASE  = "https://xiaomi.source.af/api/reseller/v1"
TOKEN = "rst_YOUR_ACCOUNT_TOKEN"
AUTH  = {"api_key": "YOUR_API_KEY", "email": "you@example.com", "password": "YOUR_PASSWORD"}

def xst(endpoint, body):
    try:
        r = requests.post(f"{BASE}/{endpoint}", json={**AUTH, **body},
                          headers={"Authorization": f"Bearer {TOKEN}"}, timeout=30)
        return r.json()
    except (requests.RequestException, ValueError):
        return {"error": "no_answer", "message": "no answer from the server"}

r = xst("servers.php", {})
if "error" in r:
    sys.exit(f"refused: {r['error']} - {r.get('message')}")

for soc, svc in r["data"]["services"].items():
    print(f"{soc.upper()} -- without serverid: {svc['price']}")
    for s in svc["providers"]:
        print(f"  {s['serverid']:<10} {s['name']:<12} {'online' if s['online'] else 'offline':<7} {s['price']} {s['currency']}")
Program.cs
// 5. The servers you may use, your price on each, and whether they take jobs now.
// .NET 6 or later: dotnet new console, then replace Program.cs with this file.
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json.Nodes;

const string BASE  = "https://xiaomi.source.af/api/reseller/v1";
const string TOKEN = "rst_YOUR_ACCOUNT_TOKEN";

var http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TOKEN);

async Task<JsonNode> Xst(string endpoint, JsonObject body)
{
    body["api_key"]  = "YOUR_API_KEY";
    body["email"]    = "you@example.com";
    body["password"] = "YOUR_PASSWORD";
    try
    {
        var res = await http.PostAsync($"{BASE}/{endpoint}",
            new StringContent(body.ToJsonString(), Encoding.UTF8, "application/json"));
        return JsonNode.Parse(await res.Content.ReadAsStringAsync())!;
    }
    catch (Exception)
    {
        return new JsonObject { ["error"] = "no_answer", ["message"] = "no answer from the server" };
    }
}

var r = await Xst("servers.php", new JsonObject());
if (r["error"] is not null) { Console.WriteLine($"refused: {r["error"]} - {r["message"]}"); return; }

foreach (var (soc, svc) in r["data"]!["services"]!.AsObject())
{
    Console.WriteLine($"{soc.ToUpper()} -- without serverid: {svc!["price"]}");
    foreach (var s in svc["providers"]!.AsArray())
        Console.WriteLine($"  {s!["serverid"],-10} {s["name"],-12} {((bool)s["online"]! ? "online" : "offline"),-7} {s["price"]} {s["currency"]}");
}

Bir şey çalışmıyor mu?

Bize request_id değerini ve error kodunu gönderin. Bu ikisiyle o işe tam olarak ne olduğunu görebiliriz; onlar olmadan yalnızca tahmin yürütürüz.

Xiaomi Source Tool · Token API’si · 2026-10-27