/api/v1Keşif belgesi
Kapsamları, kotaları, webhook olaylarını ve tam işlemler kataloğunu döner. Herhangi bir geçerli API anahtarı çalışır.
Satıcı Açık API, Discord bildirimleri, stok senkronizasyonu, Zapier tarzı otomasyon veya RMT.GG üzerinde özel bir arka ofis isteyen satıcılar içindir.
Geliştirici ayarlarında bir API anahtarı oluşturun, ardından canlı kataloğu yazdırmak için keşfi çağırın.
/api/v1Kapsamları, kotaları, webhook olaylarını ve tam işlemler kataloğunu döner. Herhangi bir geçerli API anahtarı çalışır.
Her /api/v1 isteğinde canlı gizli anahtarınızı gönderin. Sadece HTTPS tercih edin. Anahtarları kamuya açık istemcilerde veya tarayıcı paketlerinde asla gömülü olarak kullanmayın.
Tercih edilen başlık
Authorization: Bearer rmt_sk_live_<prefix>_<secret>Alternatif başlık
X-Api-Key: rmt_sk_live_<prefix>_<secret>Yeniden kullanılabilir TypeScript istemcisi (Bearer kimlik doğrulama, tipli hatalar, 429 tekrar deneme)
const API_BASE = "https://rmt.gg/api/v1";
const API_KEY = process.env.RMT_API_KEY!; // rmt_sk_live_…
export class RmtApiError extends Error {
constructor(
readonly status: number,
readonly code: string | undefined,
message: string,
readonly retryAfterSec?: number,
) {
super(message);
this.name = "RmtApiError";
}
}
type RmtFetchInit = RequestInit & { idempotencyKey?: string };
export async function rmtFetch<T>(path: string, init: RmtFetchInit = {}): Promise<T> {
const headers = new Headers(init.headers);
headers.set("Authorization", `Bearer ${API_KEY}`);
// Alternate: headers.set("X-Api-Key", API_KEY);
headers.set("Accept", "application/json");
if (init.body && !headers.has("Content-Type")) {
headers.set("Content-Type", "application/json");
}
if (init.idempotencyKey) headers.set("Idempotency-Key", init.idempotencyKey);
const res = await fetch(`${API_BASE}${path}`, { ...init, headers });
const retryAfter = Number(res.headers.get("Retry-After") ?? "");
const body = (await res.json().catch(() => ({}))) as {
error?: string;
code?: string;
retryAfter?: number;
};
if (res.status === 429) {
throw new RmtApiError(
429,
body.code ?? "RATE_LIMITED",
body.error ?? "Rate limited",
Number.isFinite(retryAfter) ? retryAfter : body.retryAfter,
);
}
if (!res.ok) {
throw new RmtApiError(res.status, body.code, body.error ?? res.statusText);
}
return body as T;
}
export async function withRetry<T>(fn: () => Promise<T>, maxAttempts = 4): Promise<T> {
let attempt = 0;
for (;;) {
try {
return await fn();
} catch (err) {
attempt += 1;
if (!(err instanceof RmtApiError) || err.status !== 429 || attempt >= maxAttempts) {
throw err;
}
const waitSec = Math.max(1, err.retryAfterSec ?? 1);
await new Promise((r) => setTimeout(r, waitSec * 1000));
}
}
}
Sızıntı durumunda döndürün
Bir anahtar sızarsa, Geliştirici ayarlarında iptal edin ve yenisini oluşturun. Canlıysanız iptal etmeden önce otomasyonunuzu güncelleyin.
Her API anahtarı, uç noktaları kontrol eden kapsamları taşır. Eksik kapsam 403 SCOPE_MISSING döner.
offers:read: Tekliflerinizi listeleyin ve alın.offers:write: Teklifleri oluşturun, güncelleyin, yayınlayın ve silin.orders:read: Satıcı siparişlerini listeleyin ve alın.orders:write: Siparişleri teslim edildi olarak işaretleyin.webhooks:manage: Gelecek Open API webhook yönetimi için ayrılmıştır. Bugün Bildirimler altında Discord/Telegram'ı ve Geliştirici ayarlarında JSON webhook'larını yapılandırın.checkout:write: Barındırılan ödeme oturumlarını oluşturma ve okuma. Yönetici onaylı ortak ödeme gerektirir.Varsayılan anahtar kapsamları
Yeni anahtarlar offers:read, offers:write, orders:read ve orders:write alır. Dışa dönük webhook CRUD, Ayarlar UI'sında kalır (oturum kimlik doğrulaması).
Teklif tanımlayıcıları, genel url slug'ını veya sayısal kimliği kabul eder. Yanıtlar içsel id ve sellerId'yi içermez.
PATCH'in henüz değiştiremeyeceği şeyler
Stok satırları, seçenek fiyatları, medya ve özellikler satıcı düzenleyicisinde (veya gelecekteki uç noktalar) yönetilir, bugün PATCH ile değil.
/api/v1/offersarchive=active (varsayılan), arşivlenmiş veya tüm ile filtreleyin.
İstek
archive| Ad | İçinde | Tür | Gerekli | Açıklama |
|---|---|---|---|---|
archive | query | string | Opsiyonel | One of "active" (default), "archived", or "all". |
/api/v1/offersKimlik doğrulaması yapılmış satıcıya ait boş bir taslak oluşturur. Gövde gerekli değildir.
/api/v1/offers/:urlOrIdGenel url slug'ı veya sayısal kimlik ile yükleyin. İlişkiler (seçenekler) dahil edilebilir; stok öğeleri dahil değildir.
İstek
urlOrId| Ad | İçinde | Tür | Gerekli | Açıklama |
|---|---|---|---|---|
urlOrId | path | string | gerekli | Offer.url slug or Offer.id. |
/api/v1/offers/:urlOrIdListeleme alanlarının güvenli bir alt kümesini PATCH yapın. Dışa dönük webhook'lar yapılandırıldığında offer.updated yayar.
İstek
urlOrIdtitledescriptionvisibilitycategoryIdofferingIdthumbnailofferTypelistingMode| Ad | İçinde | Tür | Gerekli | Açıklama |
|---|---|---|---|---|
urlOrId | path | string | gerekli | Offer.url slug or Offer.id. |
title | body | string | Opsiyonel | Listing title. |
description | body | string | Opsiyonel | Listing description. |
visibility | body | string | Opsiyonel | PUBLIC | PRIVATE | UNPUBLISHED. |
categoryId | body | number | Opsiyonel | Catalog category id. |
offeringId | body | number | Opsiyonel | Catalog offering id. |
thumbnail | body | string | Opsiyonel | Thumbnail URL or asset reference. |
offerType | body | string | Opsiyonel | Offer type string used by the listing. |
listingMode | body | string | Opsiyonel | Listing mode (for example STANDARD, RANK_BOOST, SESSION). |
/api/v1/offers/:urlOrIdSatıcı UI'si ile aynı sil/arşiv kuralları.
İstek
urlOrId| Ad | İçinde | Tür | Gerekli | Açıklama |
|---|---|---|---|---|
urlOrId | path | string | gerekli | Offer.url slug or Offer.id. |
/api/v1/offers/:urlOrId/publishBir taslağı (veya görünürlüğü değiştirir) yayınlar. Gerekli listeleme alanları eksikse 400 ile başarısız olur.
İstek
urlOrIdvisibility| Ad | İçinde | Tür | Gerekli | Açıklama |
|---|---|---|---|---|
urlOrId | path | string | gerekli | Offer.url slug or Offer.id. |
visibility | body | string | Opsiyonel | Optional. PUBLIC (default), PRIVATE, or UNPUBLISHED. |
Her seviye için satın alınabilir miktarları görün, teslimat alan adlarını doğru listeyle eşleştirin, ardından miktarı veya kaydedilmiş anahtarları ve hesapları yeniden stoklayın.
Eşlemenin nasıl çalıştığı
GET /api/v1/stock?fields=username,password, bu alanlara sahip listelemeleri bulur. Yeniden stoklamak için seçenek adlarını (veya optionId) ve alan adlarını kullanın. İçsel alan kimliklerine ihtiyacınız yok. Yanıtlar asla kimlik bilgisi değerlerini içermez.
/api/v1/stockAnahtarları ve hesapları doğru teklife eşleştirebilmeniz için seviye başına miktarları ve teslimat alan adlarını döndürür. q, fields, stockMode ve lowStock ile filtreleyin. Asla kimlik bilgisi değerlerini döndürmez.
İstek
qfieldsstockModelowStockarchive| Ad | İçinde | Tür | Gerekli | Limitler | Açıklama |
|---|---|---|---|---|---|
q | query | string | Opsiyonel | Max 80 | Filter by listing title or url slug. |
fields | query | string | Opsiyonel | Comma-separated delivery field names. The listing must have all of them (Username,Password). Names match case-insensitively. | |
stockMode | query | string | Opsiyonel | QUANTITY or COMPLEX. Listing must have at least one option in that mode. | |
lowStock | query | number | Opsiyonel | Keep listings that have a finite tier with available less than or equal to this number. | |
archive | query | string | Opsiyonel | One of "active" (default), "archived", or "all". |
/api/v1/offers/:urlOrId/stockBir url veya sayısal id için indeksle aynı StockOffer şekli. Sadece miktarları döndürür.
İstek
urlOrId| Ad | İçinde | Tür | Gerekli | Açıklama |
|---|---|---|---|---|
urlOrId | path | string | gerekli | Offer.url slug or Offer.id. |
/api/v1/offers/:urlOrId/stockMiktar seviyeleri: ekle, kaldır veya ayarla. Kaydedilmiş öğe seviyeleri: alan adıyla öğe nesneleri, bir alan olduğunda keys[], veya sınırlı metin. Bir çağrıda birden fazla seviye options[] aracılığıyla. dryRun eşleşmeyi önizler. onDuplicate varsayılan olarak atla.
{
"option": "1 Month",
"add": 50
}İstek
urlOrIdoptionoptionIdaddremovesetitemskeystextdelimiterheadersoptionsdryRunonDuplicate| Ad | İçinde | Tür | Gerekli | Limitler | Açıklama |
|---|---|---|---|---|---|
urlOrId | path | string | gerekli | Offer.url slug or Offer.id. | |
option | body | string | Koşullu | Pricing option name (case-insensitive). Omit when the listing has a single tier. | |
optionId | body | number | Koşullu | Pricing option id from GET stock. Wins over option when both are sent. Ambiguous names return 409 OPTION_AMBIGUOUS. | |
add | body | number | Koşullu | 1-1,000,000 | QUANTITY: add this many units. Fails with 400 UNLIMITED_STOCK if the tier is unlimited. |
remove | body | number | Koşullu | 1-1,000,000 | QUANTITY: withdraw this many units. Fails with 400 INSUFFICIENT_STOCK when there is not enough. |
set | body | number | null | Koşullu | QUANTITY: set an absolute count. null means unlimited. Cannot go below units held in checkout. | |
items | body | object[] | Koşullu | Max 1,000 | COMPLEX: objects keyed by delivery field name, for example { "Username": "a", "Password": "b" }. Names match case-insensitively. |
keys | body | string[] | Koşullu | Max 1,000 | COMPLEX: license keys when the listing has exactly one delivery field. Otherwise 400 FIELD_MAPPING_AMBIGUOUS. |
text | body | string | Koşullu | Max 1,000 rows | COMPLEX: delimited paste. A header row that matches field names is detected automatically. Otherwise columns map in field sort order when the column count matches. |
delimiter | body | string | Opsiyonel | Default : | Delimiter for text. Ignored unless text is sent. |
headers | body | string[] | Opsiyonel | Optional column headers for text when the first line is data, not names. | |
options | body | object[] | Koşullu | Restock several tiers in one call. Each element is the same shape as a single-option body (option, add, items, …). | |
dryRun | body | boolean | Opsiyonel | Preview matching and counts without writing. Default false. | |
onDuplicate | body | string | Opsiyonel | skip (default) or error | COMPLEX: skip existing unsold fingerprints, or fail the request with 409 DUPLICATE_ITEMS. |
Hesaplar için items[], tek alan lisans kodları için keys[] ile POST /api/v1/offers/:url/stock kullanın. Her istekte 1,000 satıra kadar bölün.
Listeyle eşleşen yükü seçin
Önce GET stock çağrısı yapın. Eğer fields[] birden fazla isim içeriyorsa, bu isimlerle anahtarlanan items nesnelerini gönderin (Kullanıcı Adı, Şifre, E-Posta). Eğer tam olarak bir alan varsa, keys[] yeterlidir. Miktar listeleri için add kullanın, items değil.
Her istekte 1.000 satır. Her seviye için 5.000 satılmamış öğe. Dakikada 300 istek. Varsayılan olarak kopyalar atlanır.
accounts.json (her hesap için bir nesne)
[
{ "Username": "player1", "Password": "secret1", "E-Mail": "[email protected]" },
{ "Username": "player2", "Password": "secret2", "E-Mail": "[email protected]" }
]accounts.csv
Username,Password,E-Mail
player1,secret1,p1@example.com
player2,secret2,p2@example.comkeys.txt (her satırda bir lisans anahtarı)
AAAA-BBBB-CCCC
DDDD-EEEE-FFFF
GGGG-HHHH-IIIIcURL
# Inspect field names and stockMode
curl -s -H "Authorization: Bearer rmt_sk_live_…" \
-H "Accept: application/json" \
https://rmt.gg/api/v1/offers/YOUR_OFFER_URL/stock
# Preview (no write)
curl -s -X POST \
-H "Authorization: Bearer rmt_sk_live_…" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
https://rmt.gg/api/v1/offers/YOUR_OFFER_URL/stock \
-d '{"dryRun":true,"onDuplicate":"skip","option":"Premium","items":[{"Username":"player1","Password":"secret1","E-Mail":"[email protected]"}]}'
# Apply accounts
curl -s -X POST \
-H "Authorization: Bearer rmt_sk_live_…" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
https://rmt.gg/api/v1/offers/YOUR_OFFER_URL/stock \
-d '{"onDuplicate":"skip","option":"Premium","items":[{"Username":"player1","Password":"secret1","E-Mail":"[email protected]"}]}'
# Apply license keys (listing must have exactly one delivery field)
curl -s -X POST \
-H "Authorization: Bearer rmt_sk_live_…" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
https://rmt.gg/api/v1/offers/YOUR_OFFER_URL/stock \
-d '{"option":"Steam","keys":["AAAA-BBBB-CCCC","DDDD-EEEE-FFFF"]}'
# Or paste CSV / colon-separated rows in text
curl -s -X POST \
-H "Authorization: Bearer rmt_sk_live_…" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
https://rmt.gg/api/v1/offers/YOUR_OFFER_URL/stock \
-d '{"option":"Premium","delimiter":",","text":"Username,Password,E-Mail\nplayer1,secret1,[email protected]"}'TypeScript toplu içe aktarma (istek başına 1,000 satır)
// Paste rmtFetch and withRetry from the Auth section first.
const CHUNK = 1000;
async function importRows(offerUrl: string, option: string, rows: Array<Record<string, string>>) {
for (let i = 0; i < rows.length; i += CHUNK) {
const items = rows.slice(i, i + CHUNK);
const preview = await rmtFetch<{
results: Array<{ wouldImport: number; skippedDuplicates: number; errors: string[] }>;
}>(`/offers/${offerUrl}/stock`, {
method: "POST",
body: JSON.stringify({ dryRun: true, onDuplicate: "skip", option, items }),
});
const row = preview.results[0];
if ((row?.errors?.length ?? 0) > 0) {
throw new Error(row.errors.join("; "));
}
await withRetry(() =>
rmtFetch(`/offers/${offerUrl}/stock`, {
method: "POST",
body: JSON.stringify({ onDuplicate: "skip", option, items }),
}),
);
}
}
// License keys: only when GET stock.fields has exactly one name
async function importKeys(offerUrl: string, option: string, keys: string[]) {
for (let i = 0; i < keys.length; i += CHUNK) {
await withRetry(() =>
rmtFetch(`/offers/${offerUrl}/stock`, {
method: "POST",
body: JSON.stringify({ option, keys: keys.slice(i, i + CHUNK) }),
}),
);
}
}
Bu API'nin koruduğu şeyler
Anahtarlar offers:write gerektirir, oran sınırlıdır ve yalnızca kendi listelemelerinizi yeniden stoklayabilir. GET asla kaydedilmiş kimlik bilgilerini döndürmez. POST yanıtları Kullanıcı Adı, Şifre veya anahtar değerlerini yansıtmaz. Üretimde gövdeyi HTTPS üzerinden gönderin ve API anahtarını bir ortam değişkeninde saklayın.
Windows'ta curl.exe kullanın (curl takma adını değil). PowerShell'in bölmemesi için -d JSON'u tırnak içine alın.
Siparişler, satıcı hesabınıza özgüdür. Alıcı fatura detayları, kayıtlı pazar gizlilik kuralları altında gizlenebilir.
/api/v1/orderslimit, offset, durum, q ve sıralama (en yeni, en eski, toplam_yüksek, toplam_düşük) destekler.
İstek
limitoffsetstatusqsort| Ad | İçinde | Tür | Gerekli | Limitler | Açıklama |
|---|---|---|---|---|---|
limit | query | number | Opsiyonel | 1-100, default 20 | Page size. |
offset | query | number | Opsiyonel | >= 0, default 0 | Skip this many rows. |
status | query | string | Opsiyonel | Max 32 | Filter by order status (for example PAID, DELIVERED, COMPLETED). |
q | query | string | Opsiyonel | Max 80 | Search reference or related text. |
sort | query | string | Opsiyonel | newest (default) | newest | oldest | total_high | total_low. |
/api/v1/orders/:uidSatır öğeleri ile siparişi döner. Genel sipariş uid'sini kullanın.
İstek
uid| Ad | İçinde | Tür | Gerekli | Açıklama |
|---|---|---|---|---|
uid | path | string | gerekli | Order.uid. |
/api/v1/orders/:uid/deliverManuel yerine getirme. COMPLEX satırları gerekli olduğunda tamamen eklenmelidir. order.delivered yayar.
İstek
uidevidence| Ad | İçinde | Tür | Gerekli | Limitler | Açıklama |
|---|---|---|---|---|---|
uid | path | string | gerekli | Order.uid. | |
evidence | body | string[] | Opsiyonel | HTTPS, max 10 | Optional screenshot or transfer-proof URLs. |
Herhangi bir onaylı partner mağaza veya arka uç, alıcıları RMT.GG ödeme sayfasına yönlendirebilir. Biz kayıtlı satıcı olarak kalıyoruz ve kilitli tutarın %4'ünü alıyoruz.
Beyaz liste ve yerine getirme
Ayarlar altında, Barındırılan ödeme sayfasına gidin, ardından burada bir API anahtarı ve JSON webhook oluşturun. Ödeme sonrası checkout.completed bildirimi gönderiyoruz. Teslimat değerleri RMT.GG onayında kalır; satıcı GET veya webhook'larda yer almaz.
/api/v1/checkout/sessionsAlıcıları kilitli bir RMT.GG ödeme sayfasına yönlendirin. Bir ürün: miktar ve itemName. Sepet: her satırda isim ve miktar ile items[]. Para birimi varsayılan olarak USD'dir. Ödeme sonrası alıcı, teslimat alanlarını kopyalamak için RMT.GG'de kalır. returnUrl, dükkana devam eder; teslimat yoksa kısa bir geri sayımdan sonra onları geri gönderiyoruz. Miktar, uzunluklar ve diğer sınırlar Limits sütunundadır.
{
amount: 10, // what the buyer pays
itemName: "Gold pack", // pay page heading
}İstek
amountcurrencyitemNametitledescriptionimageUrlitemsitems[].nameitems[].titleitems[].descriptionitems[].amountitems[].quantityitems[].imageUrlitems[].deliveryitems[].delivery[].nameitems[].delivery[].typeitems[].delivery[].valueemailreturnUrlcancelUrlinvoiceIdcategorySlugofferingmetadataIdempotency-Key| Ad | İçinde | Tür | Gerekli | Limitler | Açıklama |
|---|---|---|---|---|---|
amount | body | number | Koşullu | > 0, max 1,000,000 | What the buyer pays. Required for a single item. With items[], omit it or send the line sum. Mismatch: 400 AMOUNT_MISMATCH. |
currency | body | string | Opsiyonel | Default USD | ISO 4217 code such as USD or EUR. |
itemName | body | string | Koşullu | Max 120 | Pay page heading. Required for a single item. Alias: title. With items[], defaults to the first line name. Missing: 400 ITEM_NAME_REQUIRED. |
title | body | string | Opsiyonel | Alias of itemName. If both are sent, itemName wins. | |
description | body | string | Opsiyonel | Max 200 | Copy under the heading. If omitted, the heading is reused. |
imageUrl | body | string | Opsiyonel | HTTPS, max 2048 | Product image, or fallback for lines without imageUrl. Invalid: 400 INVALID_IMAGE_URL. |
items | body | object[] | Koşullu | 1-20 lines, JSON max 48,000 | Locked cart. Required when amount is omitted. Buyers cannot change lines. Empty: 400 INVALID_ITEMS. |
items[].name | body | string | gerekli | Max 120 | Line title. Alias: title. |
items[].title | body | string | Opsiyonel | Alias of items[].name. If both are sent, name wins. | |
items[].description | body | string | Opsiyonel | Max 200 | Line copy under the name. |
items[].amount | body | number | gerekli | > 0, max 1,000,000 | Unit price. Session total is sum(amount * quantity). |
items[].quantity | body | number | Opsiyonel | 1-99, default 1 | Locked on the pay page. |
items[].imageUrl | body | string | Opsiyonel | HTTPS, max 2048 | Line image. Falls back to top-level imageUrl. |
items[].delivery | body | object[] | Opsiyonel | Max 16 fields | Shown after payment on RMT.GG. Seller GET and webhooks omit values. |
items[].delivery[].name | body | string | gerekli | Max 80 | Field label, for example Code or Password. |
items[].delivery[].type | body | string | Opsiyonel | text, password, textarea | password is blurred until the buyer reveals it. Default text. |
items[].delivery[].value | body | string | gerekli | Max 2048 | Field value. Numbers are stored as strings. Empty: 400 INVALID_DELIVERY. |
email | body | string | Opsiyonel | Invalid values ignored | Prefills the pay page. The buyer still confirms email before paying. |
returnUrl | body | string | Opsiyonel | HTTPS, max 2048 | Continue-to-shop after payment. Delivery fields keep the buyer on RMT.GG with a button. No delivery: we send them back after a short countdown. If omitted, there is no shop button. http://localhost is allowed for local shops. |
cancelUrl | body | string | Opsiyonel | HTTPS, max 2048 | Redirect if the buyer cancels or the session expires. If omitted, they stay on the pay page. |
invoiceId | body | string | Opsiyonel | Max 128 | Your shop id. Same payload returns the existing session. A different payload: 409 INVOICE_CONFLICT. |
categorySlug | body | string | Koşullu | With offering, or omit both | Public root slug such as games. Used for card, PayPal, and crypto labels, not the pay page title. Wrong pair: 400 INVALID_PSP_CATEGORY. |
offering | body | string | Koşullu | With categorySlug, or omit both | Catalog offering such as Mods. Mapped to labels like Games · Add-ons. |
metadata | body | object | Opsiyonel | Object, max 4096 chars | Stored on the session. Not returned on seller GET. |
Idempotency-Key | header | string | Opsiyonel | Max 128 | Replay header. Same key and payload returns the existing session. A different payload: 409 IDEMPOTENCY_CONFLICT. |
Yanıt
uidstatuspaidamountcurrencyitemNamedescriptionemaillangreturnUrlcancelUrlinvoiceIdexternalInvoiceIdsourceexpiresAthostedUrlorderUiditemshosted_urlexpires_at| Ad | İçinde | Tür | Açıklama |
|---|---|---|---|
uid | response | string | Session id. Same value as in hostedUrl / hosted_url. |
status | response | string | created | pending_payment | paid | canceled | expired | refunded | error. Unpaid sessions expire after 24 hours. |
paid | response | boolean | true only when status is paid. false for refunded, expired, canceled, and unpaid states. |
amount | response | number | Locked buyer total in major units. |
currency | response | string | ISO currency code stored on the session (for example USD). |
itemName | response | string | null | Pay page heading. |
description | response | string | Longer copy under the heading. |
email | response | string | null | Prefill or confirmed buyer email. Guest checkout placeholders are returned as null. |
lang | response | string | null | Buyer locale when known. Not a create-session field. |
returnUrl | response | string | null | Continue-to-shop URL stored on the session, or null. |
cancelUrl | response | string | null | Cancel/expiry redirect, or null. |
invoiceId | response | string | null | Your invoice id. Same value as externalInvoiceId. |
externalInvoiceId | response | string | null | Same as invoiceId (legacy alias). |
source | response | string | How the session was created. API sessions are "api". |
expiresAt | response | string | ISO timestamp. Unpaid checkouts cannot be completed after this time. |
hostedUrl | response | string | Pay page URL (same target as top-level hosted_url on create). |
orderUid | response | string | null | Marketplace order uid after payment. null until the session is paid. |
items | response | object[] | Locked lines: name, description, amount, quantity, imageUrl. Seller GET never includes delivery values. |
hosted_url | response | string | Pay page URL. Send the buyer here. Same target as hostedUrl. |
expires_at | response | string | ISO timestamp. Same value as expiresAt. |
/api/v1/checkout/sessions/:uidOluşturduğunuz oturumu döndürür. checkout.completed gecikirse bunu kullanın. paid yalnızca durum paid olduğunda doğrudur. öğeler asla teslimat değerlerini içermez.
İstek
uid| Ad | İçinde | Tür | Gerekli | Açıklama |
|---|---|---|---|---|
uid | path | string | gerekli | Session uid returned at create time. |
Yanıt
uidstatuspaidamountcurrencyitemNamedescriptionemaillangreturnUrlcancelUrlinvoiceIdexternalInvoiceIdsourceexpiresAthostedUrlorderUiditems| Ad | İçinde | Tür | Açıklama |
|---|---|---|---|
uid | response | string | Session id. Same value as in hostedUrl / hosted_url. |
status | response | string | created | pending_payment | paid | canceled | expired | refunded | error. Unpaid sessions expire after 24 hours. |
paid | response | boolean | true only when status is paid. false for refunded, expired, canceled, and unpaid states. |
amount | response | number | Locked buyer total in major units. |
currency | response | string | ISO currency code stored on the session (for example USD). |
itemName | response | string | null | Pay page heading. |
description | response | string | Longer copy under the heading. |
email | response | string | null | Prefill or confirmed buyer email. Guest checkout placeholders are returned as null. |
lang | response | string | null | Buyer locale when known. Not a create-session field. |
returnUrl | response | string | null | Continue-to-shop URL stored on the session, or null. |
cancelUrl | response | string | null | Cancel/expiry redirect, or null. |
invoiceId | response | string | null | Your invoice id. Same value as externalInvoiceId. |
externalInvoiceId | response | string | null | Same as invoiceId (legacy alias). |
source | response | string | How the session was created. API sessions are "api". |
expiresAt | response | string | ISO timestamp. Unpaid checkouts cannot be completed after this time. |
hostedUrl | response | string | Pay page URL (same target as top-level hosted_url on create). |
orderUid | response | string | null | Marketplace order uid after payment. null until the session is paid. |
items | response | object[] | Locked lines: name, description, amount, quantity, imageUrl. Seller GET never includes delivery values. |
/api/v1/checkout/sessionsuid ile GET'teki aynı oturum nesnesi. Oluştururken gönderdiğiniz invoiceId'yi geçin. Eksik: 400 INVOICE_ID_REQUIRED. Bilinmeyen: 404 NOT_FOUND.
İstek
invoiceId| Ad | İçinde | Tür | Gerekli | Limitler | Açıklama |
|---|---|---|---|---|---|
invoiceId | query | string | gerekli | Max 128 | invoiceId from create. Missing: 400 INVOICE_ID_REQUIRED. Too long: 400 INVALID_INVOICE_ID. |
Yanıt
uidstatuspaidamountcurrencyitemNamedescriptionemaillangreturnUrlcancelUrlinvoiceIdexternalInvoiceIdsourceexpiresAthostedUrlorderUiditems| Ad | İçinde | Tür | Açıklama |
|---|---|---|---|
uid | response | string | Session id. Same value as in hostedUrl / hosted_url. |
status | response | string | created | pending_payment | paid | canceled | expired | refunded | error. Unpaid sessions expire after 24 hours. |
paid | response | boolean | true only when status is paid. false for refunded, expired, canceled, and unpaid states. |
amount | response | number | Locked buyer total in major units. |
currency | response | string | ISO currency code stored on the session (for example USD). |
itemName | response | string | null | Pay page heading. |
description | response | string | Longer copy under the heading. |
email | response | string | null | Prefill or confirmed buyer email. Guest checkout placeholders are returned as null. |
lang | response | string | null | Buyer locale when known. Not a create-session field. |
returnUrl | response | string | null | Continue-to-shop URL stored on the session, or null. |
cancelUrl | response | string | null | Cancel/expiry redirect, or null. |
invoiceId | response | string | null | Your invoice id. Same value as externalInvoiceId. |
externalInvoiceId | response | string | null | Same as invoiceId (legacy alias). |
source | response | string | How the session was created. API sessions are "api". |
expiresAt | response | string | ISO timestamp. Unpaid checkouts cannot be completed after this time. |
hostedUrl | response | string | Pay page URL (same target as top-level hosted_url on create). |
orderUid | response | string | null | Marketplace order uid after payment. null until the session is paid. |
items | response | object[] | Locked lines: name, description, amount, quantity, imageUrl. Seller GET never includes delivery values. |
Ayarlar → Geliştirici'de HTTPS uç noktalarını (veya Discord webhook'larını) yapılandırın. Abone olunan olaylar tetiklendiğinde RMT POST yapar.
JSON teslimat zarfı
{
"id": "whd_…",
"type": "order.paid",
"created": "2026-07-23T12:00:00.000Z",
"data": {
"order": {
"uid": "ord_…",
"reference": "RMT-…",
"status": "PAID",
"url": "https://rmt.gg/orders/ord_…",
"items": [ /* line items with offer names */ ]
}
}
}İmzalı teslimat başlıkları
{
"X-RMT-Event": "order.paid",
"X-RMT-Delivery": "whd_…",
"X-RMT-Timestamp": "1710000000",
"X-RMT-Signature": "v1=abc123…"
}ödeme.tamamlandı yükü
{
"id": "whd_…",
"type": "checkout.completed",
"created": "2026-08-14T12:00:00.000Z",
"data": {
"checkout": {
"uid": "pcs_…",
"status": "paid",
"amount": 10,
"currency": "USD",
"itemName": "Gold pack",
"description": "1000 gold for account example",
"invoiceId": "inv-12345",
"source": "api",
"orderUid": "ord_…",
"hostedUrl": "https://rmt.gg/pay/pcs_…",
"email": "[email protected]",
"paidAt": "2026-08-14T12:01:00.000Z",
"expiresAt": "2026-08-15T12:00:00.000Z",
"createdAt": "2026-08-14T12:00:00.000Z",
"reason": null,
"items": [
{
"name": "Gold pack",
"description": "1000 gold for account example",
"amount": 10,
"quantity": 1,
"imageUrl": "https://cdn.shop.example/gold.png"
}
]
}
}
}checkout.canceled yükü
{
"id": "whd_…",
"type": "checkout.canceled",
"created": "2026-08-14T12:20:00.000Z",
"data": {
"checkout": {
"uid": "pcs_…",
"status": "canceled",
"amount": 10,
"currency": "USD",
"itemName": "Gold pack",
"description": "1000 gold for account example",
"invoiceId": "inv-12345",
"source": "api",
"orderUid": null,
"hostedUrl": "https://rmt.gg/pay/pcs_…",
"email": "[email protected]",
"paidAt": null,
"expiresAt": "2026-08-15T12:00:00.000Z",
"createdAt": "2026-08-14T12:00:00.000Z",
"reason": "buyer_canceled",
"items": [
{
"name": "Gold pack",
"description": "1000 gold for account example",
"amount": 10,
"quantity": 1,
"imageUrl": "https://cdn.shop.example/gold.png"
}
]
}
}
}Bir imzalama gizli anahtarı ayarlandığında, timestamp + '.' + rawBody üzerinde HMAC-SHA256 hesaplayın ve v1= sonrası hex ile karşılaştırın.
Gizli anahtar RMT'de kalır. Her imzalı POST, X-RMT-Timestamp (Unix saniyeleri) ve X-RMT-Signature (v1= artı hex) içerir. String timestamp + '.' + rawBody üzerinde gizli anahtarınızı kullanarak HMAC-SHA256 hesaplayın, ardından v1= sonrasındaki hex ile karşılaştırın. 5 dakikadan eski zaman damgalarını reddedin.
TypeScript doğrulaması (zaman güvenli karşılaştırma ve 5 dakikalık tekrar penceresi)
import { createHmac, timingSafeEqual } from "node:crypto";
const MAX_AGE_SEC = 5 * 60; // reject replays older than 5 minutes
export function verifyRmtSignature(opts: {
secret: string;
timestamp: string | null | undefined;
signatureHeader: string | null | undefined;
rawBody: string; // exact POST bytes. Do not JSON.parse then re-stringify.
nowSec?: number;
}): boolean {
const secret = opts.secret.trim();
const timestamp = String(opts.timestamp ?? "").trim();
const provided = String(opts.signatureHeader ?? "").trim().replace(/^v1=/i, "");
if (!secret || !timestamp || !provided) return false;
const ts = Number(timestamp);
if (!Number.isInteger(ts) || ts <= 0) return false;
const nowSec = opts.nowSec ?? Math.floor(Date.now() / 1000);
if (Math.abs(nowSec - ts) > MAX_AGE_SEC) return false;
const expected = createHmac("sha256", secret)
.update(`${timestamp}.${opts.rawBody}`)
.digest("hex");
const a = Buffer.from(expected, "utf8");
const b = Buffer.from(provided.toLowerCase(), "utf8");
if (a.length !== b.length) return false;
return timingSafeEqual(a, b);
}
// Express / Node HTTP example:
// const rawBody = (req as { rawBody?: string }).rawBody
// ?? JSON.stringify(req.body); // only if you captured the raw string first
// const ok = verifyRmtSignature({
// secret: process.env.RMT_WEBHOOK_SECRET!,
// timestamp: req.headers["x-rmt-timestamp"] as string,
// signatureHeader: req.headers["x-rmt-signature"] as string,
// rawBody,
// });
// if (!ok) return res.status(401).end();
TypeScript webhook işleyici
type CheckoutCompleted = {
id: string;
type: "checkout.completed";
created: string;
data: {
checkout: {
uid: string;
status: "paid";
amount: number;
currency: string;
itemName: string | null;
description: string;
invoiceId: string | null;
source: string | null;
orderUid: string | null;
hostedUrl: string;
email: string | null;
paidAt: string | null;
expiresAt: string | null;
createdAt: string | null;
reason: null;
items: Array<{
name: string;
description: string | null;
amount: number;
quantity: number;
imageUrl: string | null;
}>;
};
};
};
type CheckoutCanceled = {
type: "checkout.canceled";
data: {
checkout: {
uid: string;
status: "canceled" | "expired";
invoiceId: string | null;
reason: "buyer_canceled" | "expired";
};
};
};
export async function handleRmtWebhook(rawBody: string, headers: Headers) {
const ok = verifyRmtSignature({
secret: process.env.RMT_WEBHOOK_SECRET!,
timestamp: headers.get("x-rmt-timestamp"),
signatureHeader: headers.get("x-rmt-signature"),
rawBody,
});
if (!ok) throw new Response("Unauthorized", { status: 401 });
const event = JSON.parse(rawBody) as { type: string; data: Record<string, unknown> };
switch (event.type) {
case "checkout.completed": {
const checkout = (event as CheckoutCompleted).data.checkout;
if (!checkout.invoiceId || !checkout.paidAt) break;
await fulfillShopOrder(checkout.invoiceId, checkout.orderUid);
break;
}
case "checkout.canceled": {
const checkout = (event as CheckoutCanceled).data.checkout;
await markShopOrderCanceled(checkout.invoiceId, checkout.reason);
break;
}
case "checkout.refunded":
case "order.paid":
case "order.delivered":
break;
default:
break;
}
}
COMPLEX (benzersiz birim) listelemeleri için, RMT, yerel stok azaldığında ödeme sonrası bir sonraki lisansı, hesabı veya anahtarı oluşturmak için HTTPS uç noktanıza POST yapabilir.
Ödeme güvenli hatalar
Eğer uç noktanız zaman aşımına uğrarsa veya geçersiz veri dönerse, sipariş PAID olarak kalır. Alıcıya ücretlendirilir; siparişte bir hata görürsünüz ve rezervi yeniden deneyebilir veya anahtarları manuel olarak ekleyebilirsiniz.
Kanonik POST gövdesi (kısaltılmış)
{
"id": "rsv_…",
"type": "reserve.item",
"order": { "uid": "ord_…", "reference": "RMT-…", "url": "https://rmt.gg/orders/ord_…" },
"offer": { "url": "my-offer", "title": "Game key", "pageUrl": "https://rmt.gg/offers/my-offer" },
"option": { "id": 1, "name": "Standard" },
"fields": [{ "id": 10, "name": "License", "type": "text", "required": true }],
"quantity": 1
}İstek başlıkları (bir imza gizli anahtarı ayarlandığında)
{
"Content-Type": "application/json",
"X-RMT-Event": "reserve.item",
"X-RMT-Delivery": "rsv_…",
"X-RMT-Timestamp": "1710000000",
"X-RMT-Signature": "v1=abc123…"
}Kolaylık yanıtı
{
"entries": [
{ "name": "License", "value": "AAAA-BBBB-CCCC" }
]
}Eşlenmiş JSON alanları (yanıtMap yolları gibi $.license)
{
"license": "AAAA-BBBB-CCCC",
"email": "[email protected]",
"password": "temporary-pass"
}Teklifte bir gizli anahtar ayarladıysanız, her reserve POST imzalanır. HMAC-SHA256(secret, timestamp + '.' + rawBody) hesaplayın ve v1= ön ekini kaldırdıktan sonra X-RMT-Signature ile karşılaştırın. Gizli anahtar istekte asla yer almaz.
Tam doğrulama örneğine bakınTypeScript rezervasyon işleyici (doğrula, ardından girişleri döndür)
type ReserveRequest = {
id: string;
type: "reserve.item";
dryRun?: boolean;
quantity: number;
fields: Array<{ name: string; required?: boolean }>;
};
export async function handleReserve(rawBody: string, headers: Headers) {
const ok = verifyRmtSignature({
secret: process.env.RMT_RESERVE_SECRET!,
timestamp: headers.get("x-rmt-timestamp"),
signatureHeader: headers.get("x-rmt-signature"),
rawBody,
});
if (!ok) return new Response("Unauthorized", { status: 401 });
const body = JSON.parse(rawBody) as ReserveRequest;
if (body.type !== "reserve.item") {
return Response.json({ error: "Unexpected event" }, { status: 400 });
}
const qty = Number(body.quantity);
if (!Number.isInteger(qty) || qty < 1) {
return Response.json({ error: "Invalid quantity" }, { status: 400 });
}
if (body.dryRun) {
return Response.json({
entries: [{ name: "License", value: "TEST-AAAA-BBBB" }],
});
}
const license = await mintLicense(); // your inventory
return Response.json({
entries: [{ name: "License", value: license }],
});
}
Ödeme öncesinde rezerv çağrısı yapmayın
RMT, yalnızca ödeme başarılı olduktan sonra uç noktanıza çağrı yapar, bu nedenle terkedilmiş alışverişler lisansları yakmaz.
Hatalar JSON { error, code? } döner. Açık API trafiği, her API anahtarı için dakikada 300 istekle sınırlıdır.
API_KEY_REQUIREDAuthorization veya X-Api-Key başlığı eksik.
API_KEY_INVALIDAnahtar bilinmiyor, iptal edilmiş, süresi dolmuş veya geliştirici erişimi askıya alınmış.
SCOPE_MISSINGAnahtar, uç noktanın gerektirdiği kapsamı taşımıyor.
RATE_LIMITEDÇok fazla istek. Retry-After ve X-RateLimit-Reset'e saygı gösterin.
CHECKOUT_PARTNER_NOT_APPROVEDBu satıcı, barındırılan ödeme için onaylanmamıştır.
INVALID_JSONİstek gövdesi JSON olmalıdır.
INVALID_AMOUNTmiktar 0'dan büyük ve en fazla 1.000.000 olmalıdır.
UNSUPPORTED_CURRENCYpara birimi desteklenen bir ISO kodu değildir.
INVALID_RETURN_URLreturnUrl ve cancelUrl https olmalıdır (http://localhost yerel mağazalar için kabul edilir).
INVALID_PSP_CATEGORYcategorySlug ve offering birlikte gönderilmeli ve bir katalog çiftini eşleştirmelidir.
INVALID_INVOICE_IDinvoiceId 128 karakterden uzun.
INVOICE_ID_REQUIREDGET /checkout/sessions, invoiceId'yi sorgu parametresi olarak gerektirir.
INVALID_IDEMPOTENCY_KEYIdempotency-Key 128 karakterden uzun.
INVALID_METADATAmetadata bir JSON nesnesi olmalıdır, dizi veya ilkel değil.
METADATA_TOO_LARGESerileştirilmiş metadata 4096 karakterden büyük.
IDEMPOTENCY_CONFLICTIdempotency-Key farklı bir miktar, para birimi veya öğe ile yeniden kullanıldı.
INVOICE_CONFLICTinvoiceId farklı bir miktar, para birimi veya öğe ile yeniden kullanıldı.
INVALID_IMAGE_URLimageUrl https URL olmalıdır.
ITEM_NAME_REQUIREDitemName (veya başlık) belirtilmediğinde gereklidir.
INVALID_ITEMSitems, kilitli satır öğelerinin boş olmayan bir dizisi olmalıdır (maks 20). Her satırın ismi ve miktarı olmalıdır.
TOO_MANY_ITEMSitems 20'den fazla satır içeremez.
AMOUNT_MISMATCHmiktar, her satır miktarının miktar ile çarpımına eşit olmalıdır.
INVALID_DELIVERYteslimat alanları geçersiz. Her alanın bir ismi (maks 80) ve değeri (maks 2048) olmalıdır. tür metin, şifre veya textarea olmalıdır (varsayılan metin). Her satırda en fazla 16 alan olabilir.
ITEMS_TOO_LARGESerileştirilmiş öğeler JSON'u 48.000 karakterden büyüktür.
NOT_FOUNDBu satıcı için o uid veya invoiceId ile eşleşen bir barındırılan ödeme oturumu yok.
RESERVE_FAILEDRezerv webhook'u zaman aşımına uğradı, geçersiz veri döndü veya gerekli alanları atladı.
OPTION_AMBIGUOUSBirden fazla fiyatlandırma seçeneği bu adı karşılıyor. GET stokundan optionId'yi geçin.
OPTION_NOT_FOUNDBu listelemede o id veya ad ile eşleşen fiyatlandırma seçeneği yok.
OPTION_REQUIREDBu listelemede birden fazla fiyatlandırma seçeneği var. Seçenek veya optionId'yi geçin.
UNKNOWN_FIELDBir alan adı bu listelemenin teslimat şemasına uymuyor.
FIELD_MAPPING_AMBIGUOUSSütunları veya anahtarları teslimat alanlarına eşleştiremedik. Başlıkları gönderin veya alan adıyla anahtarlanmış öğe nesnelerini kullanın.
STOCK_MODE_MISMATCHO yük, seçeneğin stok moduyla (miktar vs kaydedilmiş öğeler) eşleşmiyor.
IMPORT_TOO_LARGEBir yeniden stoklama isteği, her seçenek için en fazla 1.000 kaydedilmiş öğe içe aktarabilir.
OPTION_ITEM_CAPACITYBu fiyatlandırma seçeneği zaten 5.000 satılmamış kaydedilmiş öğe maksimumuna ulaştı.
DUPLICATE_ITEMSonDuplicate=error ve en az bir öğe zaten bu seçenekte mevcut.
UNLIMITED_STOCKBu seçenekte sınırsız miktar var. Önce sonlu bir sayıya geçmek için set kullanın.
INSUFFICIENT_STOCKKaldırmak için yeterli miktar stoku yok.
STOCK_HELD_IN_CHECKOUTÖdeme aşamasında rezerve edilen birimlerin altına miktarı düşüremezsiniz.
INVALID_RESTOCKYeniden stoklama gövdesinde gerekli bir eylem eksik veya bir seçenekte add/items birleştirilmiş.
| Kod | HTTP | Açıklama |
|---|---|---|
| API_KEY_REQUIRED | 401 | Authorization veya X-Api-Key başlığı eksik. |
| API_KEY_INVALID | 401 | Anahtar bilinmiyor, iptal edilmiş, süresi dolmuş veya geliştirici erişimi askıya alınmış. |
| SCOPE_MISSING | 403 | Anahtar, uç noktanın gerektirdiği kapsamı taşımıyor. |
| RATE_LIMITED | 429 | Çok fazla istek. Retry-After ve X-RateLimit-Reset'e saygı gösterin. |
| CHECKOUT_PARTNER_NOT_APPROVED | 403 | Bu satıcı, barındırılan ödeme için onaylanmamıştır. |
| INVALID_JSON | 400 | İstek gövdesi JSON olmalıdır. |
| INVALID_AMOUNT | 400 | miktar 0'dan büyük ve en fazla 1.000.000 olmalıdır. |
| UNSUPPORTED_CURRENCY | 400 | para birimi desteklenen bir ISO kodu değildir. |
| INVALID_RETURN_URL | 400 | returnUrl ve cancelUrl https olmalıdır (http://localhost yerel mağazalar için kabul edilir). |
| INVALID_PSP_CATEGORY | 400 | categorySlug ve offering birlikte gönderilmeli ve bir katalog çiftini eşleştirmelidir. |
| INVALID_INVOICE_ID | 400 | invoiceId 128 karakterden uzun. |
| INVOICE_ID_REQUIRED | 400 | GET /checkout/sessions, invoiceId'yi sorgu parametresi olarak gerektirir. |
| INVALID_IDEMPOTENCY_KEY | 400 | Idempotency-Key 128 karakterden uzun. |
| INVALID_METADATA | 400 | metadata bir JSON nesnesi olmalıdır, dizi veya ilkel değil. |
| METADATA_TOO_LARGE | 400 | Serileştirilmiş metadata 4096 karakterden büyük. |
| IDEMPOTENCY_CONFLICT | 409 | Idempotency-Key farklı bir miktar, para birimi veya öğe ile yeniden kullanıldı. |
| INVOICE_CONFLICT | 409 | invoiceId farklı bir miktar, para birimi veya öğe ile yeniden kullanıldı. |
| INVALID_IMAGE_URL | 400 | imageUrl https URL olmalıdır. |
| ITEM_NAME_REQUIRED | 400 | itemName (veya başlık) belirtilmediğinde gereklidir. |
| INVALID_ITEMS | 400 | items, kilitli satır öğelerinin boş olmayan bir dizisi olmalıdır (maks 20). Her satırın ismi ve miktarı olmalıdır. |
| TOO_MANY_ITEMS | 400 | items 20'den fazla satır içeremez. |
| AMOUNT_MISMATCH | 400 | miktar, her satır miktarının miktar ile çarpımına eşit olmalıdır. |
| INVALID_DELIVERY | 400 | teslimat alanları geçersiz. Her alanın bir ismi (maks 80) ve değeri (maks 2048) olmalıdır. tür metin, şifre veya textarea olmalıdır (varsayılan metin). Her satırda en fazla 16 alan olabilir. |
| ITEMS_TOO_LARGE | 400 | Serileştirilmiş öğeler JSON'u 48.000 karakterden büyüktür. |
| NOT_FOUND | 404 | Bu satıcı için o uid veya invoiceId ile eşleşen bir barındırılan ödeme oturumu yok. |
| RESERVE_FAILED | 400 | Rezerv webhook'u zaman aşımına uğradı, geçersiz veri döndü veya gerekli alanları atladı. |
| OPTION_AMBIGUOUS | 409 | Birden fazla fiyatlandırma seçeneği bu adı karşılıyor. GET stokundan optionId'yi geçin. |
| OPTION_NOT_FOUND | 404 | Bu listelemede o id veya ad ile eşleşen fiyatlandırma seçeneği yok. |
| OPTION_REQUIRED | 400 | Bu listelemede birden fazla fiyatlandırma seçeneği var. Seçenek veya optionId'yi geçin. |
| UNKNOWN_FIELD | 400 | Bir alan adı bu listelemenin teslimat şemasına uymuyor. |
| FIELD_MAPPING_AMBIGUOUS | 400 | Sütunları veya anahtarları teslimat alanlarına eşleştiremedik. Başlıkları gönderin veya alan adıyla anahtarlanmış öğe nesnelerini kullanın. |
| STOCK_MODE_MISMATCH | 400 | O yük, seçeneğin stok moduyla (miktar vs kaydedilmiş öğeler) eşleşmiyor. |
| IMPORT_TOO_LARGE | 400 | Bir yeniden stoklama isteği, her seçenek için en fazla 1.000 kaydedilmiş öğe içe aktarabilir. |
| OPTION_ITEM_CAPACITY | 400 | Bu fiyatlandırma seçeneği zaten 5.000 satılmamış kaydedilmiş öğe maksimumuna ulaştı. |
| DUPLICATE_ITEMS | 409 | onDuplicate=error ve en az bir öğe zaten bu seçenekte mevcut. |
| UNLIMITED_STOCK | 400 | Bu seçenekte sınırsız miktar var. Önce sonlu bir sayıya geçmek için set kullanın. |
| INSUFFICIENT_STOCK | 400 | Kaldırmak için yeterli miktar stoku yok. |
| STOCK_HELD_IN_CHECKOUT | 400 | Ödeme aşamasında rezerve edilen birimlerin altına miktarı düşüremezsiniz. |
| INVALID_RESTOCK | 400 | Yeniden stoklama gövdesinde gerekli bir eylem eksik veya bir seçenekte add/items birleştirilmiş. |
429 ile başa çıkın
Retry-After saniyelerini kullanarak geri çekilin. Limitleri aşmak için anahtarları döndürmeyin; limit her anahtar için ve tüm satıcılar için sabittir.
Başarılı yanıtlar X-RateLimit-Limit, X-RateLimit-Remaining ve X-RateLimit-Reset içerir.
Geliştirici ayarlarında bir anahtar oluşturun ve Bildirimler altında Discord veya Telegram'ı bağlayın.