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.
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.
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.
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.php | Token isteği gönder: request_id hemen döner. |
| POST status.php | Bir 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.php | Krediniz ve nereye harcandığı. |
| POST servers.php | Kullanabileceğ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.
| Alan | Nedir |
|---|---|
| Authorization | Hesap 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_key | API anahtarı — Her istekte, gövdede. |
| E-posta — Hesabınızdaki adres. Değişirse bize bildirin, aksi takdirde çağrılar durur. | |
| password | API ş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.
03İstek
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.
| Alan | Tür | Zorunlu | Nedir |
|---|---|---|---|
| api_key | string | evet | API anahtarınız. |
| string | evet | Hesabınızdaki e-posta. | |
| password | string | evet | API şifreniz — panelinizde Hesap → API şifresi bölümünden ayrı bir şifre belirlemediyseniz, varsayılan olarak giriş şifrenizle aynıdır. Bkz. Kimlik bilgileri. |
| soc | string | evet | Hangi 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. |
| configblob | string | evet | Cihazdan 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. |
| serverid | string | hayı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_date | string | hayı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_language | string | hayır | Optional. 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)
| Alan | Okuma komutu | Zorunlu | Nedir | Örnek |
|---|---|---|---|---|
| token | getmitoken: | evet — null reddedilir | FRP challenge değeri, aynen okunduğu gibi | 8f21c0b4e9d7… |
| deviceName | getdevice: | evet — null reddedilir | Bölge ekiyle birlikte kod adı | fleur_global |
| version | getversion: | evet — null reddedilir | ROM derlemesi | OS2.0.207.0.VMTMIXM |
| serial | getsn: | evet — null reddedilir | Seri numarası | fb4d921c |
| codebase | getcodebase: | evet — okunamazsa null | Android sürümü | 15 |
| region | getregion: | evet — okunamazsa null | ROM bölgesi | IR |
| cpuid | getcpuid: | evet — okunamazsa null | CPU ID’si, telefon yanıt verirse | 0x000460E1 |
| recovery | getrecoveryversion: | evet — okunamazsa null | Recovery sürümü — yalnızca desteklenmeyen cihazlar listemiz kullanır | 2 |
| branch | getbranch: | hayır — null sorun değil | ROM dalı | F |
| language | getlanguage: | hayır — null sorun değil | Cihazın dili — yalnızca desteklenmeyen cihazlar listemiz kullanır | fa |
| romzone | getromzone: | hayır — null sorun değil | ROM zone — yalnızca desteklenmeyen cihazlar listemiz kullanır | 2 |
{
"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
| Alan | Okuma komutu | Zorunlu | Nedir | Örnek |
|---|---|---|---|---|
| token | oem get_token (getvar:token) | evet — null reddedilir | Fastboot tokenı, aynen okunduğu gibi | VQHzN2Ib… |
| product | getvar:product | evet — null reddedilir | Bölge eki olmadan kod adı | fleur |
| serial | getvar:serialno | evet — null reddedilir | Seri numarası | fb4d921c |
| cpuid | getvar:cpuid | evet — okunamazsa null | CPU ID’si, telefon yanıt verirse | 0x000460E1 |
{
"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.
{
"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.
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ğiniz | Döndürdüğümüz | Anlamı |
|---|---|---|
| deviceName | device_name | Bölge ekiyle birlikte kod adı (frp) |
| — | product_model | Bölge eki olmadan kod adı — bunu deviceName değerinden biz türetiriz (frp) |
| product | product_model device_name | Bölge eki olmadan kod adı (fdl) |
| version | device_version | ROM derlemesi (frp) |
| serial | serial_number | Seri numarası |
| codebase | codebase | Android sürümü (frp) |
| branch | branch | ROM dalı (frp) |
| region | region | ROM bölgesi (frp) |
| cpuid | cpu_id | CPU 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.
# 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.
{ "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 ediyoruz | Geçemezse |
|---|---|---|
| 1 | İstek, en fazla 256 KB JSON gövdesi olan bir POST’tur. | method_not_allowed 405bad_json 400body_too_large 413 |
| 2 | Dört kimlik bilginiz aynı etkin hesabı gösteriyor: hesap token’ı, api_key, email ve password. | unauthorized 401too_many_failures 429 |
| 3 | İstek, tanımladıysanız hesabınızın izin verilen listesindeki bir adresten geliyor. | ip_not_allowed 403 |
| 4 | Saatlik 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 | |
| 5 | soc değeri frp veya fdl, bu hizmet hesabınıza satılıyor ve açık. | missing_soc 400bad_service 400not_entitled 403disabled 503 |
| 6 | configblob geçerli ve telefonun modunun gerektirdiği tam okumayı taşıyor. | missing_configblob 400bad_configblob 400missing_token 400incomplete_configblob 400 |
| 7 | Cihaz, hizmet vermediğimiz cihazlar listemizde değil. | unsupported 422 |
| 8 | serverid 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 404server_not_allowed 403server_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 403service_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 | |
| 9 | 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. | — |
| 10 | Krediniz 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.
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.
| Alan | Nedir |
|---|---|
| request_id | Bu 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. |
| state | waiting |
| confirm_within | status.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_name | O 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.
09Onayla ve takip et
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.
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
| Durum | HTTP | Anlamı ve ne yapmalı |
|---|---|---|
pending | 202 | İş sunucuda. retry_after saniye sonra tekrar sorun. |
done | 200 | Token response_token alanındadır: telefona yazın. İş ücretlendirilir; yanıt maliyeti ve sonrasındaki kredinizi söyler. |
error | 4xx · 5xx | Token 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. |
expired | 410 | 30 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_found | 404 | Bu 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.
# 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.
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:
| Alan | Nedir |
|---|---|
| request_id | Bu 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_name | O sunucunun herkese açık adı, ör. Server 1. |
| configblob | Gönderdiğiniz configblob, bayt bayt aynısı. |
| device | Çözülmüş haliyle cihaz. Her zaman bulunur. |
| state | waiting, pending, done, error veya expired. |
| response_token | Kilit açma tokenı. Telefona yazdığınız şey budur. |
| provider_ref | Sunucunun kendi iş referansı; destek soruları için. |
| amount_charged | Bu işin size maliyeti. |
| credit | Tahsilat sonrası krediniz. |
| currency | Her iki tutarın para birimi. |
Başarısız sonuç
# 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.
| Alan | Nedir |
|---|---|
| start_date — tokenın alınması | |
| client_sent | sunucunuzun isteği gönderdiği zaman — tam olarak gönderdiğiniz değer |
| server_received | isteğin sunucumuza ulaştığı zaman |
| upstream_sent | isteği token sunucusuna gönderdiğimiz zaman |
| upstream_received | token sunucusunun yanıtının bize ulaştığı zaman |
| elapsed_seconds | isteğin varışından token elde edilene kadar — örnekte 5 saniye |
| end_date — geri teslim | |
| upstream_answered | token sunucusunun bize yanıt verdiği zaman |
| server_answered | sunucumuzun size yanıt verdiği zaman |
| elapsed_seconds | yalnızca teslim aşaması — örnekte 3 saniye |
| response_date — sürecin tamamı | |
| total_seconds | 5 + 3 = 8 saniye |
| client_clock_offset_seconds | sizin 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ılmazclient_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
| soc | Ne yapar | Girdi | Yanıt süresi |
|---|---|---|---|
| frp | FRP kilidini açar; bir yanıt token’ı döndürür. | configblob — cihazın tam okuması | Hemen |
| fdl | FDL yetkilendirmesi; bir yanıt token’ı döndürür. | configblob — cihazın tam okuması | Hemen |
| read_sideload | Cihaz bilgilerini Mi Assistant modunda okur. | configblob — yalnızca cihaz token’ı gerekir | Hemen |
| read_fastboot | Cihaz bilgilerini fastboot modunda okur. | configblob — yalnızca cihaz token’ı gerekir | Hemen |
| read_imei | IMEI’yi üreticinin veritabanında arar. | imei — 15 haneli IMEI | 1 ila 5 dakika; sormaya devam edin |
| read_lockcode | Bir kilit kodunun arkasındaki cihaz kaydını döndürür. | imei — sipariş için IMEI | Birkaç 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.
# 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.
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: 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: 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).
12İş geçmişiniz
İş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.
| Alan | Tür | Zorunlu | Nedir |
|---|---|---|---|
| from | string | hayır | Bir gün, 2026-10-08 (veya 2026-Oct-08), UTC olarak: o gün veya sonrasında gönderilen işler. |
| to | string | hayır | Bir gün: o gün veya öncesinde gönderilen işler, günün tamamı dahil. |
| soc | string | hayır | frp veya fdl: yalnızca o hizmetin işleri. |
| limit | number | hayır | Listelenecek iş sayısı, 1–100. Varsayılan 1. |
| before | string | hayır | Bir request_id: ondan eski işler. Sonraki sayfa için bir yanıttaki next_before değerini gönderin. |
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
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.
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
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.
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
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.
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.
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.
| Kod | HTTP | Anlamı ve ne yapmalı |
|---|---|---|
| unauthorized | 401 | Dört kimlik bilgisinden biri yanlış veya hesap devre dışı. Hangisi olduğunu bilerek söylemiyoruz. |
| ip_not_allowed | 403 | Dö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_failures | 429 | Adresinizden çok fazla başarısız deneme yapıldı. Bekleyin, ardından yeniden denemeden önce kimlik bilgisini düzeltin. |
| rate_limited | 429 | Bir 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_soon | 429 | balance.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_allowed | 405 | GET kullandınız. Tüm uç noktalar POST’tur. |
| bad_json | 400 | Gövde bir JSON nesnesi değildi. Content-Type: application/json ayarlayın. |
| body_too_large | 413 | Gövde 256 KB’tan büyük. |
| missing_soc | 400 | soc gönderilmedi. Bilerek varsayılan bir değeri yoktur. |
| bad_service | 400 | soc tam olarak frp veya fdl olmalıdır. |
| not_entitled | 403 | Bu hizmet hesabınıza satılmıyor. Etkinleştirmemiz için bize başvurun. |
| disabled | 503 | Bu hizmeti şu anda kapattık. Geçicidir. |
| missing_configblob | 400 | configblob gönderilmedi. |
| bad_configblob | 400 | configblob, bir JSON nesnesinin geçerli base64 kodlaması değil. |
| missing_token | 400 | Blob içinde cihaz token değeri eksik. |
| incomplete_configblob | 400 | Sunucuları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_serverid | 400 | services 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_status | 400 | token.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_serverid | 404 | Bu 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_allowed | 403 | Belirttiğ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_allowed | 403 | Sunucu belirtmediniz ve hesabınız için etkin bir sunucu yok. Birini etkinleştirmemizi isteyin. |
| server_offline | 503 | Belirttiğ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_offline | 503 | Sunucu 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_credit | 402 | O 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_imei | 400 | imei eksikti veya geçersizdi: read_imei 15 haneli IMEI’ye ihtiyaç duyar; read_lockcode sipariş için kullanılan IMEI’ye ihtiyaç duyar. |
| read_failed | 502 | Bir okuma (read_sideload, read_fastboot, read_imei veya read_lockcode) tamamlanamadı. Ücret alınmadı. Tekrar gönderin veya daha sonra deneyin. |
| missing_request_id | 400 | status.php, request_id olmadan çağrıldı. |
| not_found | 404 | Bu request_id ile hesabınıza ait bir istek yok. |
| request_expired | 410 | request_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. |
| unsupported | 422 | Bu 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_restricted | 403 | Hesabı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_reboot | 409 | Sunucu 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_unavailable | 503 | Sunucu 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. |
| failed | 400 | Seç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_before | 400 | history.php içindeki before bir request_id değil. |
| bad_date | 400 | history.php içindeki from veya to, 2026-10-08 gibi bir gün değil ya da from, to değerinden sonra. |
17Güvenlik
Şifreniz ve anahtarınız her isteğin gövdesindedir. Düz HTTP üzerinden yol üzerindeki herkes bunları okuyup yeniden kullanabilir.
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.
Bizi son kullanıcılara verdiğiniz bir araçtan değil, kendi sunucunuzdan çağırın. Dağıttığınız her şey okunabilir.
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.
İ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.
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.
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.
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.
#!/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<?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";"""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}")// 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.
#!/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).<?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";
}"""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"))// 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.
#!/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<?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'] ?? '');
}"""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 ''}")// 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.
#!/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<?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']);
}
}"""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']}")// 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.
#!/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<?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']);
}
}"""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']}")// 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.