Rentora

REST API · v1 · sayt va veb-ilova uchun

Rentora API: sayt uchun

Sayt yoki veb-ilovangizda NFT'larni rasm va animatsiya bilan ko'rsating va ijaraga bering. Kalit serveringizda qoladi, brauzer esa faqat sizning serveringiz bilan gaplashadi.

Boshlash Documentatsiya.md yuklab olish Butun hujjat bitta faylda. AI yordamchiga bering, u API'ni to'liq tushunadi.
  • Bazaviy manzilhttps://user299.hostx.uz/v1
  • KirishAuthorization: Bearer
  • Narxso'mda (UZS), balansdan
AI yordamchi bilan yozyapsizmi? Docs MCP orqali Claude, ChatGPT, Cursor va boshqalar bu hujjatni o'zi o'qiydi.
Docs MCP

So'rov GET /v1/nft

curl https://user299.hostx.uz/v1/nft \
  -H "Authorization: Bearer YOUR_API_KEY"

Parametr majburiy emas. Standart: katalog + market; faqat katalog uchun ?source=catalog. Batafsil

Javob 200 OK

  • Scared Cat60 000 so'mBo'sh
  • Vintage Cigar45 000 so'mBand
  • Lol Pop80 000 so'mBo'sh

Boshlash

Barcha so'rovlar shu manzildan boshlanadi:

https://user299.hostx.uz/v1
  1. API kalit oling. Bosh sahifadagi «API olish» tugmasi orqali ro'yxatdan o'ting va kalitni nusxalang.
  2. Kalitni shu yerga kiriting. Pastdagi barcha namunalarda kalit o'zi almashadi.

    Kalit serverga yuborilmaydi va brauzer yorlig'ini yopsangiz o'chib ketadi.

  3. Birinchi so'rovni yuboring. Barcha NFT'lar ro'yxatini oling:
    curl https://user299.hostx.uz/v1/nft \
      -H "Authorization: Bearer YOUR_API_KEY"
    const res = await fetch("https://user299.hostx.uz/v1/nft", {
      headers: { Authorization: "Bearer YOUR_API_KEY" },
    });
    const { count, items } = await res.json();
    $ch = curl_init("https://user299.hostx.uz/v1/nft");
    curl_setopt_array($ch, [
        CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_KEY"],
        CURLOPT_RETURNTRANSFER => true,
    ]);
    $data = json_decode(curl_exec($ch), true);
    import requests
    
    r = requests.get(
        "https://user299.hostx.uz/v1/nft",
        headers={"Authorization": "Bearer YOUR_API_KEY"},
    )
    data = r.json()

Javobda count va items keladi. To'liq shakli GET /v1/nft bo'limida. Sayt uchun tayyor namuna Saytda ko'rsatish bo'limida.

Autentifikatsiya

Har bir so'rovda kalitni Authorization sarlavhasida yuboring:

Authorization: Bearer YOUR_API_KEY

Kalit yo'q yoki noto'g'ri bo'lsa, API 401 qaytaradi.

Kalitni brauzerda ishlaydigan kodga (HTML, frontend JavaScript) qo'ymang, uni sahifani ochgan har kim ko'ra oladi. Kalit faqat serveringizda turadi: brauzer sizning serveringizga so'rov yuboradi, server esa kalit bilan Rentora'ga murojaat qiladi. Shu hujjatdagi curl, JavaScript, PHP va Python namunalari server tomon uchun.

Tezkor ma'lumotnoma

Butun API bir joyda. Qatorni bosing: tegishli bo'limda to'liq tavsif, parametrlar va kod namunalari bor.

Umumiy qoidalar

Bazaviy manzil
https://user299.hostx.uz/v1
Kirish
Authorization: Bearer <API kalit> har so'rovda. Kalit yo'q yoki noto'g'ri bo'lsa 401.
Format
So'rov va javob JSON (UTF-8). POST da Content-Type: application/json.
Pul
Butun son, so'mda (UZS). Kasr yo'q.
Xato shakli
{"error": {"code": "...", "message": "..."}}. Kodlar jadvali: Xatolar.
Limit
Kalit bo'yicha kunlik limit bor. Market: GET daqiqada 120, POST daqiqada 10 (GET /v1/nft ning market qismi ham GET hisobiga kiradi). Oshsa 429 rate_limited va Retry-After (soniya). Istisno: GET /v1/nft da source berilmasa 429 emas, katalog qaytadi.
Takrordan himoya
Market POST larida Idempotency-Key (16–64 belgi) majburiy: tarmoq uzilsa ham pul ikki marta yechilmaydi.
Uzun id
emoji_id matn (string) bo'lib keladi. Songa aylantirmang: JavaScript oxirgi raqamlarni buzadi.

Odatiy ketma-ketlik

  1. BalansGET /v1/balance
  2. NFT tanlashGET /v1/nft
  3. Ijaraga olishPOST /v1/rentals
  4. Fragment'ga ulashPOST …/connect
  5. Holatni bilishGET /v1/rentals/{id} yoki webhook

Barcha endpointlar

Katalog

NFT ro'yxati va ma'lumotnomalar. Pul yechilmaydi.

MetodEndpointVazifasi
GET/v1/nftNFT'lar: katalog + market (standart); ?source=catalog faqat katalog. Rasm, animatsiya, narx, bo'shligi
GET/v1/nft/{id}Bitta NFT: raqam, @username yoki manzil (EQ...; ?address= ham)
GET/v1/giftsTelegram gift kolleksiyalari va fonlari, katalogda nechtadan borligi
GET/v1/catalog/typesNFT turlari (username, number, gift, other) va soni
GET/v1/catalog/colorsGift fonlari (ranglar)
GET/v1/catalog/collectionsGift kolleksiyalari; bittasi: /{slug}
GET/v1/catalog/linksBarcha NFT havolalari: Telegram, sayt, Fragment
GET/v1/balanceBalansingiz (so'm)

Ijara (katalogdagi NFT)

Narx balansdan so'mda yechiladi.

MetodEndpointVazifasi
POST/v1/rentalsNFT'ni ijaraga olish: nft_id va days
GET/v1/rentalsShu kalit bilan olingan ijaralar
GET/v1/rentals/{id}Bitta ijara holati (status, status_message)
POST/v1/rentals/{id}/connectFragment TON Connect havolasini yuborish (ko'pi bilan 3 marta)
POST/v1/rentals/{id}/extendFaol ijarani uzaytirish

Market (NFT manzili bilan)

POST so'rovlarda Idempotency-Key sarlavhasi majburiy.

MetodEndpointVazifasi
GET/v1/market/quoteNarxni so'rash: address va days
POST/v1/market/ordersBuyurtma berish (balansdan yechiladi)
GET/v1/market/ordersBuyurtmalar ro'yxati; bittasi: /{id}
GET/v1/market/rentalsMening ijaralarim
GET/v1/market/rentals/{address}/extend/quoteUzaytirish narxi
POST/v1/market/rentals/{address}/extendIjarani uzaytirish

NFT egasi

O'z NFT'ingizni ijaraga berish.

MetodEndpointVazifasi
GET/v1/ownerHolat: hamyon, faollashtirish, daromad
POST/v1/owner/walletHamyon yaratish (24 so'z faqat shu javobda)
POST/v1/owner/activateFaollashtirish (0.10 TON)
GET/v1/owner/nftsHamyondagi NFT'lar va ularning holati
POST/v1/owner/nftsKatalogga qo'shish so'rovi
POST/v1/owner/nfts/{id}Savdodan olish yoki qaytarish
GET/v1/owner/requestsSo'rovlar va holati
POST/v1/owner/requests/{id}/cancelSo'rovni bekor qilish
GET/v1/owner/statsQaysi NFT qancha ishladi (?days=7|30|90|0)
GET/v1/owner/earningsDaromad balansi va tarixi
GET/v1/owner/withdrawalsYechish so'rovlari
POST/v1/owner/withdrawalsDaromadni yechish

Webhook: ijara holati o'zgarganda Rentora sizning manzilingizga POST qiladi (batafsil). Bu ro'yxatdagi endpoint emas, kabinetda manzilni ko'rsatasiz.

Endpointlar

Katalog uchun ikkita GET endpoint bor. NFT'ni ijaraga olish uchun Ijara bo'limiga qarang.

Barcha NFT'lar

GET/v1/nft

NFT'lar ro'yxatini qaytaradi: nomi, rasmi (.webp) va animatsiyasi (Lottie). Parametr majburiy emas. Standart source=all: source berilmasa avval katalogdagi NFT'lar, keyin Marketdagi (katalogda yo'q) ijaraga qo'yilgan NFT'lar keladi. ?source= bilan tanlang:

sourceNatija
berilmasa yoki allKatalog + market. Katalog faqat 1-sahifada (cursor yo'q yoki 0), keyingi sahifalarda faqat market.
catalogEski holat: faqat katalog, javob shakli o'zgarmagan: {"count", "items"} (market va next_cursor yo'q; elementlarda source va address: null qo'shilgan).
marketFaqat Market NFT'lari.

Har bir elementda source ("catalog" yoki "market") va address bor. Katalog elementida id bor, address esa null: ijaraga id bilan POST /v1/rentals orqali olinadi. Market elementida id: null, address — NFT manzili: ijaraga address bilan olinadi (narxni so'rang, keyin buyurtma bering). Bir NFT ikki marta chiqmaydi: katalogda bor bo'lsa, market nusxasi tashlanadi. Eski kodingiz items ni faqat id bilan ishlatsa, ?source=catalog yuboring.

Filtrlar ikkala manbada bir xil ishlaydi: kind (username, number, gift, other), collection, backdrop, available (market NFT'lari doim bo'sh, filtr ularni olib tashlamaydi), q (nom bo'yicha qidiruv, @ va harf kattaligi e'tiborsiz, 64 belgigacha). Market uchun qo'shimcha: category (gifts (standart), usernames, numbers; kind berilsa kind ustun), limit (1–100, standart 50), cursor (javobdagi next_cursor, o'zgartirmasdan). Katalog sahifalanmaydi: u hammasi 1-sahifada keladi.

Qat'iylik. Noto'g'ri source har doim 400. source aniq berilganda (catalog, market, all) noto'g'ri q, limit, cursor yoki category ham 400. source berilmasa (standart) ular e'tiborsiz qoldiriladi: masalan limit=500 100 ga qisiladi, noto'g'ri cursor 1-sahifani beradi.

market obyekti (source=catalog dan boshqa hamma holatda keladi):

MaydonMa'nosi
availabletrue bo'lsa market ro'yxati qo'shildi. false bo'lsa javob xatosiz 200, items da faqat katalog (source=market da bo'sh).
reasonFaqat available: false da: disabled (xizmat o'chiq), rate_limited (kalit limiti), unavailable (market vaqtincha javob bermayapti yoki kurs noma'lum), preparing (ro'yxat tayyorlanmoqda).
category, totalTanlangan bo'lim (all yoki bittasi) va filtrdan keyin market NFT'lari soni.
updated_at, completeRo'yxat yangilangan vaqt (unix) va to'liqmi. Market mavjud bo'lmasa null va false.
{
  "count": 1,
  "items": [
    { "id": null, "address": "EQ...", "source": "market", "name": "@nomoz", "kind": "username", "type": "username",
      "image": "https://nft.fragment.com/username/nomoz.webp", "lottie": null,
      "price": 20000, "fee": 3000, "currency": "UZS", "available": true, "min_days": 1, "max_days": 180,
      "attributes": [], "links": { "telegram": "https://t.me/nomoz", "site": null, "fragment": "https://fragment.com/username/nomoz" }, "gift": null }
  ],
  "next_cursor": "1",
  "market": { "available": true, "category": "usernames", "total": 3625, "updated_at": 1793932877, "complete": true }
}
{
  "count": 1,
  "items": [ { "id": 1, "address": null, "source": "catalog", "name": "Scared Cat" } ],
  "next_cursor": null,
  "market": { "available": false, "reason": "disabled", "category": "all", "total": 0, "updated_at": null, "complete": false }
}

Market ro'yxati bir necha daqiqa eskirgan bo'lishi mumkin (updated_at): NFT band bo'lib qolsa, narx so'raganda yoki buyurtmada 409 rejected qaytadi. price — mijozga ko'rsatiladigan kunlik narx; to'lov: price × days + fee.

Limit. Bitta API kalit bo'yicha daqiqasiga 120 so'rov (barcha GET /v1/market/* bilan birga). source=market yoki all aniq berilganda oshsa 429 rate_limited va Retry-After. source berilmasa (standart) 429 qaytmaydi: javob 200, katalog bilan, market.available: false, reason: "rate_limited". source=catalog limitga sanalmaydi. API kalit mijozga bog'lanmagan bo'lsa ham katalog (va market) olinadi.

curl https://user299.hostx.uz/v1/nft \
  -H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch("https://user299.hostx.uz/v1/nft", {
  headers: { Authorization: "Bearer YOUR_API_KEY" },
});
const { count, items } = await res.json();
$ch = curl_init("https://user299.hostx.uz/v1/nft");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_KEY"],
    CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
import requests

r = requests.get(
    "https://user299.hostx.uz/v1/nft",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
)
data = r.json()
{
  "count": 4,
  "items": [
    {
      "id": 1,
      "name": "Scared Cat",
      "image": "https://nft.fragment.com/gift/scaredcat-14805.webp",
      "lottie": "https://nft.fragment.com/gift/scaredcat-14805.lottie.json",
      "price": 60000,
      "fee": 3000,
      "currency": "UZS",
      "available": true
    },
    {
      "id": 2,
      "name": "Vintage Cigar",
      "image": "https://nft.fragment.com/gift/vintagecigar-2681.webp",
      "lottie": "https://nft.fragment.com/gift/vintagecigar-2681.lottie.json",
      "price": 45000,
      "fee": 3000,
      "currency": "UZS",
      "available": false
    },
    {
      "id": 3,
      "name": "Lol Pop",
      "image": "https://nft.fragment.com/gift/lolpop-19592.webp",
      "lottie": "https://nft.fragment.com/gift/lolpop-19592.lottie.json",
      "price": 80000,
      "fee": 3000,
      "currency": "UZS",
      "available": true
    },
    {
      "id": 4,
      "name": "Santa Hat",
      "image": "https://nft.fragment.com/gift/santahat-61419.webp",
      "lottie": "https://nft.fragment.com/gift/santahat-61419.lottie.json",
      "price": 120000,
      "fee": 3000,
      "currency": "UZS",
      "available": true
    }
  ]
}

Namuna qisqartirilgan: har bir elementda NFT obyektining hamma maydonlari keladi (kind, type, links, gift).

Bitta NFT

GET/v1/nft/{id}

Bitta NFT'ning ma'lumotini qaytaradi: raqam, @username yoki NFT manzili bo'yicha. Javob shakli ro'yxatdagi bitta element bilan bir xil.

ParametrTurMa'nosi
idyo'ldaNFT raqami (masalan 1), @username yoki nom (Turlar va izlash) yoki NFT manzili: EQ..., UQ..., 0:... (raw)
addressso'rovdaManzilni yo'lga yozmasdan: GET /v1/nft?address=EQ.... Noto'g'ri manzil: 400
sourceso'rovdaIxtiyoriy: catalog, market, all (standart). Manzil bo'yicha qidiruvni cheklaydi. Noto'g'ri qiymat: 400
curl https://user299.hostx.uz/v1/nft/1 \
  -H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch("https://user299.hostx.uz/v1/nft/1", {
  headers: { Authorization: "Bearer YOUR_API_KEY" },
});
const nft = await res.json();
$ch = curl_init("https://user299.hostx.uz/v1/nft/1");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_KEY"],
    CURLOPT_RETURNTRANSFER => true,
]);
$nft = json_decode(curl_exec($ch), true);
import requests

r = requests.get(
    "https://user299.hostx.uz/v1/nft/1",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
)
nft = r.json()
{
  "id": 1,
  "name": "Scared Cat",
  "kind": "other",
  "image": "https://nft.fragment.com/gift/scaredcat-14805.webp",
  "lottie": "https://nft.fragment.com/gift/scaredcat-14805.lottie.json",
  "price": 60000,
  "fee": 3000,
  "currency": "UZS",
  "available": true,
  "type": "gift",
  "links": {
    "telegram": "https://t.me/nft/ScaredCat-14805",
    "site": "https://user299.hostx.uz/n/scaredcat",
    "fragment": "https://fragment.com/gift/scaredcat-14805"
  },
  "gift": {
    "collection": "scaredcat",
    "collection_name": "Scared Cats",
    "collection_known": true,
    "number": 14805,
    "backdrop": { "name": "Sapphire", "colors": ["#58a3c8", "#5379c2"] },
    "model": "Model nomi",
    "symbol": "Belgi nomi"
  }
}

Manzil bo'yicha qidiruv tartibi: avval katalog (source: "catalog"; EQ, UQ va raw yozilishidan qat'i nazar bir xil NFT topiladi), topilmasa Market (source: "market", id: null, address bor). ?source=catalog faqat katalogda, ?source=market faqat marketda izlaydi. Raqam va @username faqat katalogdan izlanadi.

HolatJavob
Topilmadi; yoki source=market bilan raqam/@nom; yoki market o'chiq404 not_found
?address= bo'sh yoki manzil noto'g'ri; source noto'g'ri400 bad_request
NFT katalogda yo'q, Market ro'yxati hozir mavjud emas (vaqtincha nosoz, tayyorlanmoqda, kurs yo'q)502 upstream_unavailable
Market izlanganda kalit limiti (daqiqasiga 120) oshdi429 rate_limited + Retry-After

Katalogdagi NFT market holatiga qaramasdan topiladi. Bunday NFT yo'q bo'lsa, 404 qaytadi. Namunadagi qiymatlar shartli; maydonlar ma'nosi NFT obyekti jadvalida.

NFT obyekti

Ro'yxatdagi har bir element va bitta NFT javobi shu maydonlardan iborat:

MaydonTurMa'nosi
idsonNFT raqami
namematnNFT nomi
kindmatnNFT turi: username (Telegram username), number (anonim raqam) yoki other (boshqa NFT)
imagematnRasm (.webp) manzili
lottiematnAnimatsiya (Lottie JSON) manzili
pricesonIjaraning 1 kunlik narxi (so'm)
feesonHar bir ijaraga bir marta qo'shiladigan xizmat haqi (so'm). NFT qaysi bo'lishidan qat'i nazar bir xil
giftobyektGift bo'lsa: kolleksiya, raqam, fon (nomi va ranglari), model, belgi. Aks holda null. Batafsil
typematnKo'rinish turi: username, number, gift yoki other
linksobyekttelegram, site (/n/nom sahifasi), fragment havolalari. Batafsil
currencymatnValyuta, hozircha UZS
availablemantiqiytrue bo'lsa NFT hozir bo'sh va ijaraga olish mumkin

Orqa fon alohida maydon emas, u animatsiya (lottie) ichida keladi. image va lottie manzillari ochiq, ularni yuklash uchun kalit kerak emas.

Turlar va username bo'yicha izlash

Har bir NFT'ning kind maydoni bor. U blokcheyndagi kolleksiya manziliga qarab avtomatik aniqlanadi — qo'lda belgilanmaydi:

QiymatMa'nosi
usernameTelegram username, masalan @nomoz
numberTelegram anonim raqami, masalan +888 ...
otherBoshqa NFT: gift, oddiy kolleksiya

Faqat username'larni olish

GET/v1/nft?kind=username

Javob ko'rinishi GET /v1/nft bilan bir xil: count va items (source berilmasa market ham keladi). kind filtri katalogga ham, marketga ham qo'llanadi. Noma'lum qiymat berilsa 400 qaytadi.

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://user299.hostx.uz/v1/nft?kind=username"

Username bo'yicha bitta NFT

GET/v1/nft/{username}

Raqam o'rniga nomni ham berish mumkin. Quyidagilar bir xil natija beradi:

GET /v1/nft/@nomoz
GET /v1/nft/nomoz
GET /v1/nft/NOMOZ
GET /v1/nft/%40nomoz     // URL-kodlangan ko'rinishi ham ishlaydi

Katta-kichik harf farq qilmaydi, @ ixtiyoriy. Slug bo'yicha ham topiladi. Topilmasa yoki NFT o'chirilgan bo'lsa 404 qaytadi.

Raqam va @username bo'yicha bitta NFT faqat katalogdan izlanadi. Fragment'dagi istalgan username emas — faqat ijaraga qo'yilganlari. Market NFT'i uchun uning manzilini (EQ...) ishlating (Bitta NFT).

Gift bo'limlari: kolleksiya va fon bo'yicha

Telegram gift'lari kolleksiyalarga (Plush Pepe, Durov's Cap, Loot Bag…) bo'linadi, har birining o'z foni (backdrop: Sapphire, Onyx Black, Pure Gold…) bor. Rentora katalogga qo'shilgan har bir gift'ni o'zi tegishli bo'limga joylaydi: kolleksiya NFT havolasidan, fon esa blokcheyndagi metadata'dan olinadi. Siz qo'shimcha hech narsa qilmaysiz.

GET/v1/gifts

Telegram'dagi barcha kolleksiyalar va fonlar ro'yxati, har birida katalogda hozir nechta NFT borligi (count). count: 0 — bu bo'limga NFT hali qo'shilmagan: botingizda "tez orada" deb ko'rsating. Telegram yangi kolleksiya chiqarsa, ro'yxat avtomatik yangilanadi; hali ro'yxatda bo'lmagan yangi kolleksiya "soon": true bilan keladi.

{
  "collections": [
    { "slug": "plushpepe", "name": "Plush Pepes", "count": 4, "thumb": "https://fragment.com/file/gifts/plushpepe/thumb.webp" },
    { "slug": "durovscap", "name": "Durov's Caps", "count": 0, "thumb": "…" }
  ],
  "backdrops": [
    { "name": "Sapphire", "colors": ["#58a3c8", "#5379c2"], "count": 3 },
    { "name": "Onyx Black", "colors": ["#4d5154", "#333638"], "count": 0 }
  ],
  "updated_at": "2026-10-01 18:00:00"
}
GET/v1/nft?collection=plushpepe&backdrop=Sapphire

Katalogni bo'lim bo'yicha saralash. Ikkala parametr ixtiyoriy va bir-biri bilan, kind bilan ham birga ishlaydi. collection — kolleksiya kodi (slug), backdrop — fon nomi (katta-kichik harf farq qilmaydi). Noma'lum fon berilsa 400 qaytadi.

Har bir NFT javobida endi gift maydoni bor (gift bo'lmasa null):

"gift": {
  "collection": "plushpepe",
  "collection_name": "Plush Pepes",
  "collection_known": true,
  "number": 12,
  "backdrop": { "name": "Sapphire", "colors": ["#58a3c8", "#5379c2"] },
  "model": "Emerald Pepe",
  "symbol": "Crown"
}

backdrop.colors — Telegram'dagi radial gradient ranglari (markaz, chet). Kartani fon rangida chizish uchun: background: radial-gradient(circle, colors[0], colors[1]). Saytdagi katalogda ham shu bo'limlar bor: /katalog, havola bilan: /katalog?collection=plushpepe&backdrop=Sapphire.

Ma'lumotnomalar: turlar, ranglar, kolleksiyalar, havolalar

Bot menyusi yoki sayt filtrlari uchun tayyor ro'yxatlar. Hammasi GET, API kalit bilan (Autentifikatsiya). Ro'yxatlar katalogning hozirgi holatini qaytaradi — NFT qo'shilsa yoki ijaraga berilsa, sonlar darhol o'zgaradi.

GET/v1/catalog/types

NFT turlari va har birida nechta NFT bor (count) va hozir nechtasi bo'sh (available). filter — shu turni olish uchun tayyor parametr, url — shu turning o'z sahifasi. Katalogda hali yo'q turlar ham "count": 0 bilan qaytadi.

{
  "count": 42,
  "items": [
    { "kind": "username", "label": "Telegram username",   "count": 12, "available": 9,  "filter": "?kind=username" },
    { "kind": "number",   "label": "Anonim raqam (+888)", "count": 4,  "available": 4,  "filter": "?kind=number" },
    { "kind": "gift",     "label": "Telegram gift",       "count": 25, "available": 20, "filter": "?kind=gift" },
    { "kind": "other",    "label": "Boshqa NFT",          "count": 1,  "available": 1,  "filter": "?kind=other" }
  ]
}
GET/v1/catalog/types/{kind}

Bitta tur (username, number, gift, other): soni, nechtasi bo'sh va shu turdagi NFT'lar havolalari bilan. gift uchun qo'shimcha collections — Telegram'dagi kolleksiyalar soni. ?collection=, ?backdrop=, ?available=1 bilan filtrlanadi. Noma'lum tur — 404.

{
  "kind": "username", "label": "Telegram username", "count": 12, "available": 9,
  "items": [ { "id": 3, "name": "@nomoz", "type": "username", "available": true, "price": 60000, "currency": "UZS",
               "telegram": "https://t.me/nomoz", "site": "https://…/n/nomoz", "fragment": "https://fragment.com/username/nomoz", "...": "..." } ]
}
GET/v1/catalog/colors

NFT ranglari — Telegram gift fonlari (backdrop). Har birida rang nomi, center va edge (hex), tayyor css gradient va katalogda shu rangdagi NFT soni. Telegram'dagi barcha 60+ rang qaytadi (katalogda yo'qlari "count": 0); ?nonempty=1 — faqat katalogda bor ranglar.

{
  "count": 2,
  "items": [
    { "name": "Sapphire",   "center": "#58a3c8", "edge": "#5379c2",
      "css": "radial-gradient(circle, #58a3c8, #5379c2)", "count": 3, "filter": "?backdrop=Sapphire" },
    { "name": "Onyx Black", "center": "#4d5154", "edge": "#333638",
      "css": "radial-gradient(circle, #4d5154, #333638)", "count": 1, "filter": "?backdrop=Onyx%20Black" }
  ]
}
GET/v1/catalog/collections

Telegram'dagi barcha gift kolleksiyalari: kod (slug), nomi, rasmi (thumb), nechta NFT (count, katalogda yo'q bo'lsa 0) va kolleksiya sahifasi (url). ?nonempty=1 — faqat katalogda NFT'i borlari. "soon": true — Telegram yangi chiqargan, ro'yxatga tez qo'shiladigan kolleksiya.

GET/v1/catalog/collections/{slug}

Bitta kolleksiya: nomi, rasmi, Fragment sahifasi, sayt katalogidagi havola, shu kolleksiyadagi ranglar va NFT'lar (har biri /v1/catalog/links dagi ko'rinishda). ?backdrop= va ?available=1 bilan filtrlanadi. Noma'lum kod — 404.

{
  "slug": "plushpepe", "name": "Plush Pepe", "thumb": "https://fragment.com/file/gifts/plushpepe/thumb.webp",
  "count": 3, "soon": false,
  "fragment": "https://fragment.com/gifts/plushpepe", "site": "/katalog?collection=plushpepe", "filter": "?collection=plushpepe",
  "colors": [ { "name": "Sapphire", "count": 2, "filter": "?backdrop=Sapphire" } ],
  "items":  [ { "id": 12, "name": "Plush Pepe #77", "type": "gift", "available": true, "price": 15000, "...": "..." } ]
}
GET/v1/catalog/links

Barcha NFT'larning havolalari ro'yxati — bitta so'rovda: Telegram, sayt sahifasi, Fragment, rasm, animatsiya, custom emoji, rang. Filtrlar: ?kind=, ?collection=, ?backdrop=, ?available=1 (faqat bo'shlar) — birga ham ishlaydi.

{
  "count": 1,
  "items": [{
    "id": 12, "name": "Plush Pepe #77", "type": "gift", "available": true, "price": 15000, "currency": "UZS",
    "telegram": "https://t.me/nft/PlushPepe-77",
    "site":     "https://user299.hostx.uz/n/plushpepe-77",
    "fragment": "https://fragment.com/gift/plushpepe-77",
    "image":    "https://nft.fragment.com/gift/plushpepe-77.webp",
    "lottie":   "https://nft.fragment.com/gift/plushpepe-77.lottie.json",
    "emoji_id": null,
    "color":    { "name": "Sapphire", "colors": ["#58a3c8", "#5379c2"] }
  }]
}

Username uchun fragment — fragment.com/username/nom, raqam uchun — fragment.com/number/888…. Har bir NFT javobida (/v1/nft) ham endi type va links maydonlari bor — alohida so'rov shart emas.

const colors = await api("/v1/catalog/colors");
colorsEl.innerHTML = colors.items.map(c =>
  `<button data-bd="${c.name}" title="${c.name} — ${c.count}"
     style="background:${c.css};width:28px;height:28px;border-radius:50%"></button>`).join("");

colorsEl.onclick = async (e) => {
  const bd = e.target.dataset.bd;
  const list = await api("/v1/catalog/links?backdrop=" + encodeURIComponent(bd));
  grid.innerHTML = list.items.map(n => `
    <a href="${n.site}" class="card" style="background:${n.color ? `radial-gradient(${n.color.colors[0]}, ${n.color.colors[1]})` : "#222"}">
      <img src="${n.image}" alt=""><b>${n.name}</b><span>${n.price} so'm/kun</span>
    </a>`).join("");
};
ParametrQayerdaMa'nosi
kind/v1/nft, /v1/catalog/linksusername, number, gift, other. Noma'lum qiymat — 400
collection/v1/nft, /v1/catalog/linksGift kolleksiyasi kodi, masalan plushpepe
backdrop/v1/nft, /v1/catalog/linksRang (fon) nomi, katta-kichik harf farq qilmaydi. Noma'lum — 400
available/v1/nft, /v1/catalog/links1 — faqat hozir bo'sh NFT'lar
nonempty/v1/catalog/colors, /collectionsEndi standart: hammasi qaytadi. ?nonempty=1 — faqat katalogda borlari

Ijara

Saytingiz foydalanuvchiga NFT'ni ijaraga bera oladi. Narx (price × days + fee) sizning Rentora balansingizdan so'mda yechiladi. NFT Rentora'ning alohida ijara hamyoniga o'tadi: foydalanuvchi undan Fragment orqali foydalanadi, lekin sota olmaydi va boshqa hamyonga o'tkaza olmaydi, chunki hamyon kaliti faqat Rentora serverida. Muddat tugagach NFT avtomatik qaytadi.

Kalit brauzerga chiqmasin. Ijara so'rovlarini faqat o'z serveringizdan yuboring. Brauzerdagi JavaScript sizning serveringizga murojaat qiladi, server esa Rentora'ga.

Balans

GET/v1/balance

Balansingiz so'mda. Uni admin to'ldiradi; kabinetning «Balans» bo'limida ham ko'rinadi.

{
  "balance": 250000,
  "currency": "UZS"
}

Ijaraga olish

POST/v1/rentals

Body (JSON): nft_id, days (1 dan 365 gacha), link (ixtiyoriy, lekin tavsiya etiladi) — ijarachining Fragment'dagi TON Connect havolasi, va ixtiyoriy renter_telegram_id. Katalogda "available": true bo'lgan NFT'ni tanlang. Havolani qanday olish — Fragment'ga ulash bo'limida.

// Sizning serveringizda (masalan Node.js). Kalit shu yerda qoladi.
const res = await fetch("https://user299.hostx.uz/v1/rentals", {
  method: "POST",
  headers: { Authorization: "Bearer YOUR_API_KEY" },
  body: JSON.stringify({ nft_id: 1, days: 3, link: formdanKelganHavola }),
});
const rental = await res.json();   // 201: ijara, 400: havola yo'q/noto'g'ri, 409: sababi error.message da
$ch = curl_init("https://user299.hostx.uz/v1/rentals");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_KEY"],
    CURLOPT_POSTFIELDS => json_encode(["nft_id" => 1, "days" => 3, "link" => $_POST['link']]),
    CURLOPT_RETURNTRANSFER => true,
]);
$rental = json_decode(curl_exec($ch), true);
r = requests.post(
    "https://user299.hostx.uz/v1/rentals",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"nft_id": 1, "days": 3, "link": link},
)
rental = r.json()
curl -X POST https://user299.hostx.uz/v1/rentals \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"nft_id": 1, "days": 3, "link": "https://app.tonkeeper.com/ton-connect?v=2&id=..."}'
{
  "id": 128,
  "nft_id": 1,
  "nft_name": "@rentora",
  "days": 3,
  "price_paid": 183000,
  "rental_price": 180000,
  "fee": 3000,
  "currency": "UZS",
  "status": "transferring",
  "status_message": "NFT ijara hamyoniga yuborildi, tasdiq kutilmoqda.",
  "can_connect": false,
  "ends_at": "2026-09-28 14:02:00"
}

Balans yetmasa, NFT band bo'lsa yoki muddat noto'g'ri bo'lsa, javob 409 bo'ladi va sababi error.message da o'zbekcha yoziladi. Uni foydalanuvchiga o'zgartirmasdan ko'rsatish mumkin.

Havola: hozir yoki keyinroq

Havola bilan (tavsiya etiladi): Rentora havolani olgan zahoti darhol Fragment'ga ulanadi — havola hali yangi, Fragment sahifasi ochiq. Pul faqat ulanish muvaffaqiyatli bo'lgandan keyin yechiladi. Ulanib bo'lmasa, javob 409 bo'ladi, sababi error.message da, balansga tegilmaydi.

Havolasiz: link berilmasa ijara to'lanadi, lekin NFT yuborilmaydi — joyidan qo'zg'almaydi, gaz sarflanmaydi. Javobda "awaiting_link": true. Havolani keyin /connect orqali yuboring: ulangan zahoti NFT yo'lga chiqadi va ijara muddati shu paytdan boshlanadi. Belgilangan vaqt (standart 30 daqiqa) ichida ulanilmasa, ijara bekor bo'ladi va pul to'liq qaytadi.

Ulanish urinishlari cheklangan: bitta ijara uchun ko'pi bilan 3 marta (yaratishdagi havola ham hisoblanadi). Qolgani javobdagi connect_attempts_left da. Limit tugasa /connect 429 connect_limit qaytaradi. Ko'rinishi noto'g'ri havola (xato nusxalangan) urinish hisoblanmaydi.

Ulangach javobda connected_at to'la bo'ladi. NFT ijara hamyoniga 10–60 soniyada yetib keladi (queued → transferring → active). Shundan keyin ijarachi Fragment sahifasini yangilasa, NFT ko'rinadi. Ijara muddati ulangan paytdan boshlanadi.

Fragment ulanishni uzsa (masalan ijarachi "Disconnect" bossa), status_message da yangi havola so'raladi — uni /connect orqali yuboring.

Pul qaytishi

Fragment'ga ulanish bo'lmasa — ya'ni ijaradan umuman foydalanilmasa — to'lov to'liq qaytariladi. Ijara obyektida "refunded": true va "connected_at": null bo'ladi. Ulangan ijarada pul qaytarilmaydi.

Fragment'ga ulash

POST/v1/rentals/{id}/connect

Havolani ijaraga olishdan oldin so'rang va POST /v1/rentals ga qo'shing. Saytingizda foydalanuvchiga shu yo'riqnomani ko'rsating:

  1. fragment.com'ni oching va Telegram akkauntingiz bilan kiring.
  2. Connect TON tugmasini bosing, hamyonlar ro'yxatidan Tonkeeperni tanlang.
  3. QR kod ostidagi havolani nusxalang (https://app.tonkeeper.com/ton-connect?v=2&id=...) va sayt formasiga qo'ying.

Sayt havolani darhol Rentora'ga uzatadi: havola faqat Fragment sahifasi ochiq turganda ishlaydi. /connect endpointi havola eskirgan bo'lsa yoki foydalanuvchi boshqa qurilmadan kirmoqchi bo'lsa, yangi havola yuborish uchun:

await fetch(`https://user299.hostx.uz/v1/rentals/${rental.id}/connect`, {
  method: "POST",
  headers: { Authorization: "Bearer YOUR_API_KEY" },
  body: JSON.stringify({ link: formdanKelganHavola }),
});
$ch = curl_init("https://user299.hostx.uz/v1/rentals/{$rental['id']}/connect");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_KEY"],
    CURLOPT_POSTFIELDS => json_encode(["link" => $_POST['link']]),
    CURLOPT_RETURNTRANSFER => true,
]);
$rental = json_decode(curl_exec($ch), true);

Ulangach holat active bo'ladi: Fragment'da NFT foydalanuvchiniki kabi ko'rinadi va u NFT'dan foydalana oladi, masalan username'ni akkauntiga biriktiradi. Fragment sotish yoki o'tkazishni so'rasa, Rentora rad etadi. Foydalanuvchi boshqa qurilmadan kirmoqchi bo'lsa, yangi havola bilan qayta chaqiring.

Ijarani uzaytirish

POST/v1/rentals/{id}/extend

Faol (Fragment'ga ulangan) ijarani qo'shimcha kunlarga uzaytiradi. NFT qaytmaydi, Fragment ulanishi uzilmaydi — faqat ends_at suriladi. Narx: kunlik narx × kun, xizmat haqisiz, balansdan darhol yechiladi. Javob — yangilangan ijara obyekti.

curl -X POST https://user299.hostx.uz/v1/rentals/128/extend \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"days": 7}'
const res = await fetch(`https://user299.hostx.uz/v1/rentals/${rental.id}/extend`, {
  method: "POST",
  headers: { Authorization: "Bearer YOUR_API_KEY" },
  body: JSON.stringify({ days: 7 }),
});
const updated = await res.json();   // updated.ends_at — yangi tugash vaqti

Faqat status: "active" ijara uzaytiriladi va tugashiga 10 daqiqadan ko'p qolgan bo'lishi kerak. Umumiy muddat 365 kundan oshmaydi. Balans yetmasa yoki shart bajarilmasa — 409 va error.message da sababi. Foydalanuvchiga tugashdan bir kun oldin "uzaytirasizmi?" deb taklif qilish yaxshi ishlaydi.

Ijara holati

GET/v1/rentals/{id}

Bitta ijara (yuqoridagi obyekt). GET /v1/rentals esa kalitingiz bilan olingan ijaralar ro'yxatini (count, items) qaytaradi.

HolatMa'nosi
queuedTo'lov olindi. awaiting_link: true bo'lsa — havola kutilmoqda (NFT hali joyida); aks holda NFT yuborilishi kutilmoqda
transferringNFT ijara hamyoniga o'tmoqda (10–60 soniya)
readyNFT yetib keldi, lekin Fragment ulanishi yo'q (uzilgan): yangi havolani /connect orqali yuboring
activeFragment'ga ulangan, foydalanuvchi NFT'dan foydalanmoqda
returningMuddat tugadi, NFT qaytarilmoqda
completedNFT qaytdi, ijara yakunlandi
cancelledNFT yuborilmasdan bekor qilindi, pul balansga qaytdi

Har bir ijarada status_message maydoni bor: holatning o'zbekcha izohi, uni foydalanuvchiga to'g'ridan-to'g'ri ko'rsatish mumkin. Holat o'zgarishini bilish uchun sahifada har 10–15 soniyada GET /v1/rentals/{id} ni chaqirib turing.

Webhook: holat o'zgarganini o'zi xabar qiladi

Har 10 soniyada so'rov yuborib turishni istamasangiz, kabinetda webhook manzilini ko'rsating. Ijara holati o'zgarganda Rentora shu manzilga POST qiladi. Manzil https:// bilan boshlanishi shart: xabar ichida ijara ma'lumoti bo'ladi, u shifrlanmagan yo'l bilan ketmasligi kerak.

Qaysi holatlarda xabar keladi: rental.ready, rental.active, rental.completed, rental.cancelled. Oraliq bosqichlar (queued, transferring, returning) uchun xabar yuborilmaydi.

Market buyurtmalari (NFT manzili bilan olingan ijara) uchun alohida hodisalar bor: order.bought, order.extended va order.failed. Imzo va qayta urinish qoidasi bir xil.

POST /rentora HTTP/1.1
Content-Type: application/json
X-Rentora-Event: rental.ready
X-Rentora-Signature: sha256=8f2b...c41d
X-Rentora-Timestamp: 1790410442
X-Rentora-Delivery: wh_5821
X-Rentora-Signature-V2: sha256=19ac...7e02

{
  "event": "rental.ready",
  "sent_at": "2026-09-26T10:14:02+00:00",
  "rental": { "id": 128, "nft_name": "@nomoz", "status": "ready", "can_connect": true, ... }
}

rental ichidagi maydonlar GET /v1/rentals/{id} qaytaradigan obyekt bilan bir xil.

Imzoni tekshirish

Manzilingizni boshqa odam ham bilib qolishi mumkin. Shuning uchun har bir xabar kabinetdagi imzo kaliti bilan imzolanadi. Xabarni qabul qilishdan oldin imzoni tekshiring — aks holda kimdir soxta "ijara tugadi" xabarini yuborib qo'yishi mumkin.

Tavsiya etiladi — V2 imzo (replay hujumidan himoya): X-Rentora-Signature-V2 vaqt (X-Rentora-Timestamp) va xabar ID'si (X-Rentora-Delivery) bilan birga imzolanadi. Eski xabarni ushlab olib qayta yuborishning iloji qolmaydi: vaqti 5 daqiqadan eski bo'lsa yoki shu ID avval qabul qilingan bo'lsa, rad eting. Qayta urinishlarda ID o'zgarmaydi, shuning uchun u takroriy xabarni aniqlashga ham yaraydi. Eski X-Rentora-Signature moslik uchun yuborilishda davom etadi.

$secret   = 'whs_...';                    // kabinetdan olinadi
$body     = file_get_contents('php://input');
$ts       = $_SERVER['HTTP_X_RENTORA_TIMESTAMP'] ?? '';
$delivery = $_SERVER['HTTP_X_RENTORA_DELIVERY'] ?? '';
$mine     = 'sha256=' . hash_hmac('sha256', $ts . '.' . $delivery . '.' . $body, $secret);
$theirs   = $_SERVER['HTTP_X_RENTORA_SIGNATURE_V2'] ?? '';

// hash_equals: imzoni belgi-belgi solishtirish vaqt orqali sirni oshkor qilmaydi
if (!hash_equals($mine, $theirs) || abs(time() - (int)$ts) > 300) {
    http_response_code(401);
    exit;
}
// Bir xil delivery ID ikkinchi marta kelsa — qayta ishlamang (bazada saqlab tekshiring)
if (already_processed($delivery)) { http_response_code(200); exit; }

$data = json_decode($body, true);
// ... ijara holatini o'z bazangizda yangilaysiz
http_response_code(200);                   // 2xx qaytarish shart
const crypto = require('crypto');

// Imzo xom (raw) body bo'yicha hisoblanadi, shuning uchun JSON'ni o'zimiz ochamiz
app.post('/rentora', express.raw({ type: 'application/json' }), (req, res) => {
  const ts = req.get('X-Rentora-Timestamp') || '', delivery = req.get('X-Rentora-Delivery') || '';
  const mine = 'sha256=' + crypto.createHmac('sha256', process.env.RENTORA_SECRET)
                                 .update(ts + '.' + delivery + '.').update(req.body).digest('hex');
  const theirs = req.get('X-Rentora-Signature-V2') || '';

  const a = Buffer.from(mine), b = Buffer.from(theirs);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.sendStatus(401);
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return res.sendStatus(401);   // eski xabar
  // delivery ID avval kelgan bo'lsa — takror, qayta ishlamang

  const data = JSON.parse(req.body);
  // ... ijara holatini saqlaysiz
  res.sendStatus(200);
});

Qayta urinish

Serveringiz 2xx qaytarsa, xabar yetib bordi deb hisoblanadi. Boshqa javob kelsa yoki server javob bermasa, Rentora 5 martagacha qayta yuboradi: 1 daqiqa, 5 daqiqa, 30 daqiqa, so'ngra 2 soat oralig'ida. Shundan keyin ham yetib bormasa, xabar "yetib bormadi" deb belgilanadi va kabinetning Sozlamalar bo'limida ko'rinadi.

Qayta yuborish bo'lishi mumkin, shuning uchun bitta xabarni ikki marta qabul qilishga tayyor bo'ling: rental.id va event bo'yicha tekshirib, takroriy xabarni e'tiborsiz qoldiring. Rentora sizning serveringizni kutib turmaydi — xabarlar navbat orqali ketadi, shuning uchun sekin javob ijarani sekinlashtirmaydi.

Kabinetda "Sinov xabari yuborish" tugmasi bor: u "event": "test" bilan bitta xabar yuboradi, shu bilan sozlamani ishga tushirmasdan tekshirib olasiz.

Market: NFT manzili bilan ijaraga olish

Katalogda ko'rinmagan Telegram NFT'ni ham ijaraga olish mumkin, agar u hozir ijaraga qo'yilgan bo'lsa: NFT manzilini (address) berasiz, Rentora narxni hisoblaydi va ijarani rasmiylashtiradi. Narx so'mda, balansdan yechiladi (GET /v1/balance). Tartib doim bir xil: avval narxni so'rang (pul yechilmaydi), keyin shu narx bilan buyurtma bering. Ijaraga qo'yilmagan yoki band NFT uchun 409 rejected qaytadi (pul yechilmaydi).

Bu bo'limdagi barcha so'rovlar bitta API kalit bo'yicha sanaladi: GET daqiqada 120 ta, POST daqiqada 10 ta (GET /v1/nft ning market qismi ham shu GET hisobiga kiradi). Oshsa 429 rate_limited va Retry-After keladi. Ijaraga qo'yilgan NFT'larni GET /v1/nft?source=market dan toping, address ni shu javobdan oling.

Narxni so'rash

GET/v1/market/quote?address=...&days=3

Query: address (NFT manzili) va days (1 dan 365 gacha butun son). Pul yechilmaydi. Daqiqasiga 40 tagacha so'rov.

const url = "https://user299.hostx.uz/v1/market/quote?address=" + encodeURIComponent(address) + "&days=3";
const res = await fetch(url, { headers: { Authorization: "Bearer YOUR_API_KEY" } });
const quote = await res.json();   // quote.total_uzs: to'lanadigan summa
$ch = curl_init("https://user299.hostx.uz/v1/market/quote?address=" . urlencode($address) . "&days=3");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_KEY"],
    CURLOPT_RETURNTRANSFER => true,
]);
$quote = json_decode(curl_exec($ch), true);
r = requests.get(
    "https://user299.hostx.uz/v1/market/quote",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"address": address, "days": 3},
)
quote = r.json()
curl -G https://user299.hostx.uz/v1/market/quote \
  -H "Authorization: Bearer YOUR_API_KEY" \
  --data-urlencode "address=EQ..." \
  --data-urlencode "days=3"
{
  "address": "EQ...",
  "name": "@nomoz",
  "days": 3,
  "per_day_uzs": 20000,
  "fee_uzs": 3000,
  "network_uzs": 0,
  "total_uzs": 63000,
  "balance": 100000,
  "enough": true,
  "missing": 0,
  "pay_enabled": true,
  "currency": "UZS"
}

total_uzs to'lanadigan to'liq summa. enough balans yetishini, missing yana qancha so'm kerakligini ko'rsatadi. pay_enabled false bo'lsa xizmat vaqtincha o'chiq: buyurtma 409 rejected bilan qaytadi.

Buyurtma berish

POST/v1/market/orders

Sarlavha: Idempotency-Key (majburiy, 16–64 belgi: harf, raqam, _ va -). Body (JSON): address, days va shown_total (foydalanuvchiga ko'rsatgan total_uzs). Daqiqasiga 10 ta, buyurtma urinishi 10 daqiqada 5 tadan oshmasin.

// Sizning serveringizda. Har bir YANGI buyurtma uchun yangi tasodifiy kalit.
const key = crypto.randomUUID().replaceAll("-", "");   // 32 belgi
const res = await fetch("https://user299.hostx.uz/v1/market/orders", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Idempotency-Key": key,
  },
  body: JSON.stringify({ address, days: 3, shown_total: quote.total_uzs }),
});
const data = await res.json();   // 201: buyurtma, 4xx/5xx: data.error.code
$key = bin2hex(random_bytes(16));   // 32 belgi, har buyurtmaga yangi
$ch = curl_init("https://user299.hostx.uz/v1/market/orders");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer YOUR_API_KEY",
        "Idempotency-Key: " . $key,
    ],
    CURLOPT_POSTFIELDS => json_encode(["address" => $address, "days" => 3, "shown_total" => $quote['total_uzs']]),
    CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
import uuid
r = requests.post(
    "https://user299.hostx.uz/v1/market/orders",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Idempotency-Key": uuid.uuid4().hex,
    },
    json={"address": address, "days": 3, "shown_total": quote["total_uzs"]},
)
data = r.json()
curl -X POST https://user299.hostx.uz/v1/market/orders \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: 3f9c1a52b7d84e60a1c2d3e4f5a6b7c8" \
  -d '{"address": "EQ...", "days": 3, "shown_total": 63000}'
{
  "state": "processing",
  "order": {
    "id": 41,
    "status": "paid",
    "nft_name": "@nomoz",
    "address": "EQ...",
    "days": 3,
    "price_uzs": 63000,
    "created_at": "2026-11-05 10:00:00"
  },
  "balance": 37000
}

state processing bo'lsa NFT yo'lda, bought bo'lsa tayyor. Oxirgi natijani buyurtma holatidan yoki webhook orqali oling.

Idempotency-Key qanday ishlaydi

Tarmoq uzilib javob kelmasa, xuddi shu kalit va xuddi shu body bilan qayta yuboring: ikkinchi buyurtma yaratilmaydi, avvalgi natija qaytadi. Boshqa buyurtma uchun doim yangi kalit oling. Bir kalit boshqa address, days yoki shown_total bilan kelsa, 422 idempotency_mismatch. Buyurtma hozir bajarilayotgan bo'lsa, 409 idempotency_in_progress va Retry-After keladi: shuncha soniya kutib, xuddi shu so'rovni qayta yuboring.

Narx o'zgarsa: narx siz ko'rsatganidan ruxsat etilganidan ko'p oshsa, 409 price_changed keladi va javobda yangi price_uzs bo'ladi. Pul yechilmaydi. Yangi narxni foydalanuvchiga ko'rsating, tasdiqlasa shown_total ni o'zgartirib, yangi kalit bilan yuboring.

Pul yechilgan, natija noma'lum (500 order_unknown): bu kalit bilan qayta yubormang. Avval GET /v1/market/orders orqali holatni tekshiring.

Buyurtmalar ro'yxati va holati

GET/v1/market/orders

Query (ixtiyoriy): limit (1 dan 100 gacha, standart 50) va before_id (keyingi sahifa uchun). Eng yangisi birinchi keladi.

{
  "count": 1,
  "items": [
    { "id": 41, "status": "bought", "nft_name": "@nomoz", "address": "EQ...", "days": 3, "price_uzs": 63000, "created_at": "2026-11-05 10:00:00" }
  ],
  "next_before_id": null
}

next_before_id bo'sh bo'lmasa, uni before_id qilib yuborib, keyingi sahifani oling. Bitta buyurtma: GET /v1/market/orders/{id} (javob yuqoridagi items elementi bilan bir xil). Boshqa mijozning buyurtmasi yoki mavjud bo'lmagan id uchun 404 not_found.

Mening ijaralarim

GET/v1/market/rentals

Shu kalit egasining Market ijaralari, NFT bo'yicha birlashtirilgan: asl ijara va uning uzaytirishlari bitta elementda. Query (ixtiyoriy): limit (1 dan 100 gacha, standart 50) va cursor (keyingi sahifa). Tartib: avval faol ijaralar (yangisi birinchi), keyin qolganlari.

{
  "count": 1,
  "items": [
    {
      "name": "Plush Pepe #42",
      "address": "EQ...",
      "status": "active",
      "end_time": 1793917933,
      "remaining_sec": 432000,
      "days_total": 5,
      "price_uzs": 222222,
      "extending": false,
      "can_extend": true,
      "last_at": "2026-11-05 10:00:00"
    }
  ],
  "next_cursor": null
}

status: active (ijarada), processing (to'langan, NFT yo'lda), ended (muddati tugagan), failed yoki refunded (bajarilmadi, pul qaytgan). end_time Unix vaqti (soniya). extending uzaytirish hozir bajarilayotganini, can_extend hozir uzaytirish mumkinligini bildiradi. next_cursor bo'sh bo'lmasa, uni o'zgartirmasdan cursor sifatida yuborib, keyingi sahifani oling.

Ijarani uzaytirish

Faqat o'zingizning hali tugamagan ijarangizni uzaytirish mumkin. NFT qaytmaydi, ulanish uzilmaydi, faqat muddat suriladi. Tartib buyurtmadagi kabi: avval narx, keyin uzaytirish.

GET/v1/market/rentals/{address}/extend/quote?days=3

days 1 dan 365 gacha. Pul yechilmaydi. Javob narx so'rash bilan bir xil maydonlarda: address, name, days, per_day_uzs, fee_uzs, network_uzs, total_uzs, balance, enough, missing, pay_enabled, currency. Daqiqasiga 40 tagacha so'rov.

POST/v1/market/rentals/{address}/extend

Sarlavha: Idempotency-Key (majburiy, 16–64 belgi). Body (JSON): days va shown_total (foydalanuvchiga ko'rsatgan total_uzs). Urinish 10 daqiqada 5 tadan oshmasin.

const key = crypto.randomUUID().replaceAll("-", "");
const res = await fetch("https://user299.hostx.uz/v1/market/rentals/" + encodeURIComponent(address) + "/extend", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Idempotency-Key": key,
  },
  body: JSON.stringify({ days: 3, shown_total: quote.total_uzs }),
});
const data = await res.json();   // 201: { state, order, balance }
$key = bin2hex(random_bytes(16));
$ch = curl_init("https://user299.hostx.uz/v1/market/rentals/" . rawurlencode($address) . "/extend");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer YOUR_API_KEY",
        "Idempotency-Key: " . $key,
    ],
    CURLOPT_POSTFIELDS => json_encode(["days" => 3, "shown_total" => $quote['total_uzs']]),
    CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
import uuid
r = requests.post(
    f"https://user299.hostx.uz/v1/market/rentals/{address}/extend",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Idempotency-Key": uuid.uuid4().hex,
    },
    json={"days": 3, "shown_total": quote["total_uzs"]},
)
data = r.json()
curl -X POST "https://user299.hostx.uz/v1/market/rentals/EQ.../extend" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: 8d1f0c9a3b6e4f72a5c1d0e9b8a7f6e5" \
  -d '{"days": 3, "shown_total": 183600}'
{
  "state": "bought",
  "order": { "id": 42, "status": "bought", "nft_name": "Plush Pepe #42", "address": "EQ...", "days": 3, "price_uzs": 183600, "created_at": "2026-11-05 10:30:00" },
  "balance": 816400
}

state: bought (muddat uzaytirildi) yoki processing (jarayonda; natijani GET /v1/market/rentals yoki webhook orqali oling). Idempotency-Key, price_changed va order_unknown qoidalari buyurtmadagi bilan bir xil.

404 not_found: NFT begonaniki, mavjud emas yoki ijara muddati tugagan bo'lsa, javob uch holatda ham bir xil. Pul yechilmaydi, kalit va urinish qaytariladi. Muddati tugagan NFT'ni uzaytirib bo'lmaydi: uni yangi buyurtma sifatida oling.

Uzaytirish buyurtmasi GET /v1/market/orders ro'yxatida chiqmaydi. Yangi muddatni GET /v1/market/rentals dagi end_time dan oling.

Buyurtma webhook'i

Kabinetdagi webhook manzilingizga uch hodisa keladi (imzo, X-Rentora-* sarlavhalari va qayta urinish Webhook bo'limidagi bilan bir xil):

Noaniq holatlarda (paid, sending va hokazo) xabar yuborilmaydi: natija aniq bo'lgandagina keladi. Bir buyurtma uchun hodisa bir marta yuboriladi.

{
  "event": "order.bought",
  "sent_at": "2026-11-05T10:00:00+00:00",
  "order": { "id": 41, "status": "bought", "nft_name": "@nomoz", "address": "EQ...", "days": 3, "price_uzs": 63000, "created_at": "2026-11-05 10:00:00" }
}

order obyekti GET /v1/market/orders/{id} qaytaradigan bilan bir xil. order.extended dagi order.id uzaytirish buyurtmasiniki: uni GET /v1/market/orders/{id} orqali olib bo'lmaydi (404), yangi muddatni GET /v1/market/rentals dan oling.

NFT egasi: o'z NFT'ingizni ijaraga bering

Xuddi shu API kalit bilan siz ham NFT'ni ijaraga olasiz, ham o'z NFT'ingizni ijaraga berasiz. Buning uchun sizga alohida hamyon ochiladi. NFT o'sha hamyonda turadi, ijaraga berilganda undan chiqadi va muddat tugagach o'sha hamyonga qaytadi. Ijara narxidan platforma ulushi ayrilib, qolgani daromad balansingizga yoziladi. Hammasini API'siz, brauzerda ham qilish mumkin: NFT egasi paneli.

  1. POST /v1/owner/wallet — hamyon yarating. Javobda 24 so'z bir marta keladi.
  2. POST /v1/owner/activate — hamyonni faollashtiring: 0.10 TON ijaraga berish huquqi uchun Rentora'ga yechiladi.
  3. Hamyon manziliga NFT va kamida 0.2 TON yuboring.
  4. POST /v1/owner/nfts — katalogga qo'shish so'rovini yuboring. Admin ko'rib, ma'lumotini to'ldiradi, narxni belgilaydi va tasdiqlaydi.
  5. Ijara tugagach daromad yoziladi: GET /v1/owner/stats, GET /v1/owner/earnings.
  6. POST /v1/owner/withdrawals — pulni yeching.
BalansNima uchunQayerda
balanceNFT ijaraga olish uchun to'lanadigan pulGET /v1/balance
earningsNFT'laringiz ijaradan ishlab topgan pulGET /v1/owner/earnings

Faollashtirish va 0.2 TON qoidasi

Faollashtirish. Hamyon ochilgach POST /v1/owner/activate chaqiriladi: hamyondan 0.10 TON Rentora manziliga yechiladi (bir martalik, qaytarilmaydi). Buning uchun hamyonda kamida 0.12 TON bo'lishi kerak (to'lov + tarmoq to'lovi). Faollashtirilmaguncha katalogga so'rov yuborib bo'lmaydi. Holat activation.status da: none, pending (blokcheyn tasdig'i kutilmoqda) yoki active.

0.2 TON. Har ijarada NFT'ni ijara hamyoniga yuborish va qaytarish gazi sizning hamyoningizdan to'lanadi (taxminan 0.12 TON yuboriladi, ortig'i NFT bilan birga qaytadi). Shuning uchun katalogda NFT turishi uchun hamyonda kamida 0.2 TON bo'lishi shart. TON kamaysa, NFT'laringiz avtomatik katalogdan olinadi va ijaraga berilmaydi. TON to'ldirilgach bir necha daqiqada o'zi qaytadi. NFT'ni hamyondan olib chiqsangiz ham xuddi shunday.

Hamyon

POST/v1/owner/wallet
{
  "wallet": {
    "address": "UQ_YOUR_TON_ADDRESS",
    "address_raw": "0:84a76f...07fc",
    "network": "mainnet"
  },
  "mnemonic": ["word1", "word2", "...", "word24"],
  "min_ton": "0.2",
  "warning": "24 so'zni xavfsiz joyga yozib oling..."
}

24 so'z faqat shu javobda keladi, API orqali qayta olinmaydi (NFT egasi panelida Telegram orqali kirib ko'rish mumkin). Ular bilan hamyon to'liq boshqariladi — ularni hech kimga bermang. Ikkinchi marta chaqirilsa 409.

POST/v1/owner/activate
{
  "status": "active",
  "fee_ton": "0.1",
  "need_ton": "0.12",
  "to": "UQB...admin",
  "paid_ton": "0.1",
  "paid_at": "2026-09-27 11:04:00",
  "tx": "a3f1..."
}

TON yetmasa yoki allaqachon faollashtirilgan bo'lsa 409. "status": "pending" bo'lsa, bir necha soniyadan keyin GET /v1/owner bilan tekshiring.

GET/v1/owner

Umumiy holat: hamyon, activation, TON balansi, qoida bajarilyaptimi (gas_ok), so'rov yuborish mumkinmi (can_request), daromad, katalogdagi NFT'lar (listings) va so'rovlar (requests).

listings[].paused — NFT nima uchun katalogda emas: low_ton (TON yetarli emas), nft_missing (NFT hamyonda yo'q) yoki owner_blocked (admin to'xtatgan). Sababi paused_message da.

Katalogga qo'shish so'rovi

GET/v1/owner/nfts

Hamyoningizdagi NFT'lar blokcheyndan o'qiladi. Katalogdagilarida listing, so'rov yuborilganlarida request to'ldirilgan.

POST/v1/owner/nfts
curl -X POST https://user299.hostx.uz/v1/owner/nfts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"nft_address": "EQD...", "price": 40000, "note": "Qisqa username"}'
$ch = curl_init("https://user299.hostx.uz/v1/owner/nfts");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_KEY"],
    CURLOPT_POSTFIELDS => json_encode(["nft_address" => $address, "price" => 40000]),
    CURLOPT_RETURNTRANSFER => true,
]);
$request = json_decode(curl_exec($ch), true);   // 201: so'rov yuborildi, 409: sababi error.message da

price — siz taklif qilayotgan 1 kunlik narx, so'mda (0 dan 100 000 000 gacha, butun son); note ixtiyoriy. Javob — so'rov obyekti, "status": "pending". NFT darhol katalogga chiqmaydi: admin uni ko'rib, nom/rasm/narxni to'ldirib tasdiqlaydi (approved) yoki sababini yozib rad etadi (rejected, sababi admin_note da). Faollashtirilmagan bo'lsa, NFT hamyonda bo'lmasa yoki TON 0.2 dan kam bo'lsa 409.

GET/v1/owner/requests
POST/v1/owner/requests/{id}/cancel

So'rovlar ro'yxati va kutilayotgan so'rovni bekor qilish.

POST/v1/owner/nfts/{id}

Katalogdan olish {"active": false} yoki qaytarish {"active": true}. Narxni admin belgilaydi — price yuborilsa 400. Ijarada turgan NFT katalogdan olinsa, joriy ijara oxirigacha davom etadi.

Statistika: qaysi NFT qancha ishladi

GET/v1/owner/stats?days=30

days: 7, 30, 90 yoki 0 (hamma vaqt).

{
  "days": 30,
  "totals": { "rentals": 3, "days_rented": 7, "earned": 216000, "pending": 36000, "nfts": 1 },
  "items": [
    { "id": 8, "name": "@nomoz", "kind": "username", "price": 40000, "active": true,
      "rentals": 3, "days_rented": 7, "earned": 216000, "pending": 36000,
      "rented_now": true, "last_rented": "2026-09-27 11:04:00" }
  ],
  "daily": [ { "date": "2026-09-27", "amount": 72000 }, "..." ],
  "commission_pct": 10
}

earned — daromadga yozilgan pul (platforma ulushi ayrilgan). pending — ijara davom etmoqda, tugagach yoziladi. daily — kunlik yozilgan daromad (grafik uchun).

Daromad va pul yechish

GET/v1/owner/earnings

Daromad balansi va harakatlar tarixi. Har bir ijara tugagach rent_income yozuvi qo'shiladi: ijara narxi minus platforma ulushi (commission_pct). Xizmat haqi (fee) daromadga kirmaydi. Ijarachiga pul qaytarilsa (Fragment'ga ulanmagan bo'lsa), daromad yozilmaydi.

POST/v1/owner/withdrawals
methoddetailsQanday bajariladi
card16 raqamli kartaAdmin o'tkazadi va "to'landi" deb belgilaydi
tonTON manzilAdmin yuboradi va "to'landi" deb belgilaydi
balancekerak emasDarhol API balansingizga o'tadi
{ "amount": 100000, "method": "card", "details": "8600 1234 5678 9012" }

Summa so'rov paytida daromaddan ushlab turiladi. Admin rad etsa, qaytib tushadi va sababi admin_note da ko'rinadi. Holatni GET /v1/owner/withdrawals bilan kuzating: pending, paid, rejected. Eng kam summa min_withdraw da.

Saytda ko'rsatish

Sayt NFT'larni ko'rsatishi uchun ikki qism kerak: kalitni yashirib turadigan kichik server endpoint va NFT'larni chizadigan sahifa.

Brauzer  --GET /api/nft-->  Sizning server  --GET /v1/nft + kalit-->  Rentora API
Brauzer  <--JSON-----------  Sizning server  <--JSON----------------  Rentora API

1. Server: /api/nft

Server so'rovni kalit bilan Rentora'ga uzatadi va javobni o'zgartirmay qaytaradi. Kalitni kodga yozish o'rniga muhit o'zgaruvchisidan olish yaxshiroq.

<?php
// nft.php: brauzer shu faylga murojaat qiladi, kalit faqat shu yerda turadi
$apiKey = "YOUR_API_KEY";

$ch = curl_init("https://user299.hostx.uz/v1/nft");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer $apiKey"],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10,
]);
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

header("Content-Type: application/json; charset=utf-8");
if ($body === false) {
    http_response_code(502);
    exit('{"error":{"code":"server_error","message":"Rentora javob bermadi"}}');
}
http_response_code($code);
header("Cache-Control: public, max-age=60");
echo $body;
// server.js (Node.js 18+, "type": "module", npm i express)
import express from "express";

const app = express();
const API_KEY = "YOUR_API_KEY";

app.get("/api/nft", async (req, res) => {
  try {
    const r = await fetch("https://user299.hostx.uz/v1/nft", {
      headers: { Authorization: `Bearer ${API_KEY}` },
    });
    res.status(r.status).json(await r.json());
  } catch {
    res.status(502).json({ error: { code: "server_error", message: "Rentora javob bermadi" } });
  }
});

app.use(express.static("public")); // sahifa public/index.html da turadi
app.listen(3000);
# app.py (pip install flask requests)
import requests
from flask import Flask, jsonify

app = Flask(__name__, static_folder="public", static_url_path="")
API_KEY = "YOUR_API_KEY"

@app.get("/")
def home():
    return app.send_static_file("index.html")  # public/index.html

@app.get("/api/nft")
def nft():
    try:
        r = requests.get(
            "https://user299.hostx.uz/v1/nft",
            headers={"Authorization": f"Bearer {API_KEY}"},
            timeout=10,
        )
    except requests.RequestException:
        return jsonify(error={"code": "server_error", "message": "Rentora javob bermadi"}), 502
    return jsonify(r.json()), r.status_code

2. Sahifa: NFT'larni chizish

Sahifa faqat o'zingizning /api/nft manzilingizga murojaat qiladi. Bu yerda kalit yo'q.

<div id="nfts"></div>

<script>
async function loadNfts() {
  const box = document.getElementById("nfts");
  const res = await fetch("/api/nft");
  if (!res.ok) {
    box.textContent = "NFT'larni olib bo'lmadi";
    return;
  }

  const { items } = await res.json();
  for (const nft of items) {
    const card = document.createElement("figure");

    const img = document.createElement("img");
    img.src = nft.image;
    img.alt = nft.name;
    img.width = 200;

    const name = document.createElement("figcaption");
    name.textContent = nft.name;

    card.append(img, name);
    box.append(card);
  }
}
loadNfts();
</script>

Serveringiz Rentora xatosini o'zgartirmay uzatadi, shuning uchun sahifada res.ok ni tekshiring. Xato kodlari Xatolar bo'limida.

Animatsiya (Lottie)

Rasm uchun image manzilini oddiy <img>ga qo'ying. Animatsiya Lottie JSON, uni lottie-web bilan o'ynating:

// sahifada lottie-web yuklangan bo'lsin
lottie.loadAnimation({
  container: document.getElementById("nft"),
  renderer: "svg",
  loop: true,
  autoplay: true,
  path: nft.lottie,
});
Brauzer animatsiya faylini to'g'ridan-to'g'ri ola olmasa (CORS xatosi chiqsa), uni o'z serveringiz orqali bering. Shu vaqtgacha image rasmini ko'rsatib turing.

Quyida shunday proksi. Brauzer lottie.php?f=scaredcat-14805 deb so'raydi, server faylni Fragment'dan olib beradi. Nom tekshiriladi, shuning uchun bu orqali boshqa saytga so'rov yuborib bo'lmaydi.

<?php
$f = $_GET["f"] ?? "";
if (!preg_match('/^[a-z0-9]+-\d+$/', $f)) {
    http_response_code(400);
    exit("bad request");
}

$ch = curl_init("https://nft.fragment.com/gift/$f.lottie.json");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_TIMEOUT        => 10,
]);
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($body === false || $code !== 200) {
    http_response_code(502);
    exit("upstream error");
}

header("Content-Type: application/json; charset=utf-8");
header("Cache-Control: public, max-age=86400");
echo $body;

Sahifada path o'rniga shu manzilni bering: path: "lottie.php?f=" + slug. Bu yerda slug lottie manzilidagi nom, masalan scaredcat-14805.

Xatolar

Muvaffaqiyatli so'rov 200 OK (yaratishda 201 Created) bilan tugaydi. Xatoda status kodi o'zgaradi va javobda sababi yoziladi:

{
  "error": {
    "code": "unauthorized",
    "message": "API kalit noto'g'ri yoki yuborilmagan"
  }
}
StatusKodSababi va nima qilish kerak
400bad_requestSo'rov noto'g'ri: address, days, shown_total, limit yoki before_id yaroqsiz, yoki POST /v1/rentals da link buzuq. Pul yechilmaydi. error.message nimani tuzatishni aytadi.
400idempotency_key_requiredPOST /v1/market/orders yoki POST /v1/market/rentals/{address}/extend da Idempotency-Key yo'q. Har buyurtma yoki uzaytirishga yangi tasodifiy kalit yuboring.
400idempotency_key_invalidIdempotency-Key 16–64 belgidan iborat bo'lishi kerak (harf, raqam, _, -).
401unauthorizedKalit yo'q yoki noto'g'ri. Authorization sarlavhasini tekshiring.
402insufficient_balanceBalans yetarli emas. Javobda price_uzs, balance, missing bor: missing yana qancha so'm kerakligini bildiradi. Balansni to'ldirib, qayta yuboring. Pul yechilmaydi.
403forbiddenKalit bu IP manzildan ishlatilishi taqiqlangan (kabinetdagi IP ro'yxati).
403no_clientKalit kabinetdagi mijozga bog'lanmagan. Kabinetdan olingan kalit kerak.
404not_foundBunday id li NFT, ijara yoki buyurtma yo'q (boshqa mijozniki ham shu javobni beradi). Uzaytirishda: bu NFT sizda faol ijarada emas (begona, mavjud emas yoki muddati tugagan: javob bir xil).
409rejectedShart bajarilmadi: NFT hozir ijaraga berilmaydi yoki band, xizmat vaqtincha o'chiq, balans yetmaydi (/v1/rentals) va hokazo. Pul yechilmaydi. Sababi error.message da.
409price_changedNarx ko'rsatilganidan oshib ketgan. Javobda yangi price_uzs, per_day_uzs, days. Tasdiqlansa, shown_total ni o'zgartirib, yangi Idempotency-Key bilan yuboring.
409order_failedPul yechilgan, lekin buyurtma bajarilmadi. refunded: true bo'lsa pul balansga qaytgan, false bo'lsa tez orada qaytadi. Javobda balance va order_id ham bor.
409idempotency_in_progressShu kalit bilan buyurtma hozir bajarilmoqda. Retry-After soniyadan keyin xuddi shu so'rovni qayta yuboring.
422idempotency_mismatchBu Idempotency-Key boshqa parametrlar bilan ishlatilgan. Yangi buyurtma uchun yangi kalit oling.
429rate_limitedSo'rovlar juda ko'p. Retry-After sarlavhasida ko'rsatilgan soniya kutib, qayta yuboring. Sahifa har ochilganda emas, natijani serveringizda bir necha daqiqa saqlab bering.
429connect_limitPOST /v1/rentals/{id}/connect: bitta ijara uchun ulanish urinishlari tugagan. Qayta urinish foydasiz, holatni GET /v1/rentals/{id} bilan tekshiring.
429too_many_attemptsNoto'g'ri kalit bilan bitta IP'dan juda ko'p urinish. Retry-After soniyadan keyin urinib ko'ring.
500order_unknownPul yechilgan, natija hali noma'lum. Bu kalit bilan qayta yubormang: buyurtma uchun GET /v1/market/orders, uzaytirish uchun GET /v1/market/rentals orqali holatni tekshiring.
500server_errorXato Rentora tomonida. Birozdan keyin qayta urinib ko'ring.
502upstream_unavailableIjara xizmati hozir javob bermayapti. Pul yechilmadi, birozdan keyin qayta urinib ko'ring.
503unavailableXizmat vaqtincha ishlamayapti (baza ulanmadi). Birozdan keyin qayta urinib ko'ring.

AI yordamchi uchun: Docs MCP

Shu hujjatni AI yordamchingiz o'zi o'qiy oladi. Rentora Docs MCP serveri bo'limlar ro'yxati, qidiruv va endpoint tafsilotini beradi. Faqat o'qish: API kalit yoki mijoz ma'lumoti serverga umuman kirmaydi.

https://user299.hostx.uz/mcp

Claude, ChatGPT, Cursor, VS Code, Windsurf va Gemini CLI'ga ulash yo'riqnomasi: Docs MCP sahifasida.