Documentation

API reference and guides for the Resync.club platform.

📋 Overview

The Reseller API allows approved partners to programmatically redeem licenses and deliver accounts to their customers. Authentication is done via a unique API key provided upon onboarding.

⚠️Your API key is secret — never expose it in client-side code or public repos. Compromised keys will be revoked immediately.
Preview
Resync.club documentation preview
🗺️ Quick Start
1

Get your API key

Contact us on Discord to register as a reseller and receive your key. Optionally have it linked to a dashboard account so you can use /purchase directly from your balance.

2

Queue a delivery

POST to /api/reseller/redeem (with a license code) or /api/reseller/purchase (with game/type/quantity). You'll get back a claim_id.

3

Poll until ready

Hit /api/reseller/claim-status every 15s with the claim_id. Once status is approved, the validated credentials are in accounts[] — deliver them to your customer.

Authentication

🔑 API Key Required

Three ways to send your API key — pick whichever fits your integration.

1️⃣ X-API-Key Header RECOMMENDED

Best for server-to-server integrations. Send the key in a custom header — keeps it out of URLs and access logs.

Header
X-API-Key: rsk_a9f159737eb3a28e321d5d67...
cURL
curl -X POST https://nfa.resync.club/api/reseller/purchase \
  -H "X-API-Key: rsk_..." \
  -H "Content-Type: application/json" \
  -d '{"game":"CS2","type":"premier","quantity":1}'
2️⃣ Authorization Bearer Header

Standard REST pattern. Use this if your HTTP client or framework expects an Authorization header.

Header
Authorization: Bearer rsk_a9f159737eb3a28e321d5d67...
cURL
curl -X POST https://nfa.resync.club/api/reseller/purchase \
  -H "Authorization: Bearer rsk_..." \
  -H "Content-Type: application/json" \
  -d '{"game":"CS2","type":"premier","quantity":1}'
3️⃣ Key-in-URL WEBHOOK MODE

Paste a single fixed URL anywhere — Komerza, SellAuth, SellHub, Shoppex, dashboards, cron jobs, browser bookmarks. Method GET is accepted with query-string parameters so no body is needed.

URL Pattern
https://nfa.resync.club/api/<api_key>/reseller/<endpoint>
Purchase via GET
# Paste this URL into any HTTP-aware tool:
https://nfa.resync.club/api/rsk_a9f159.../reseller/purchase?game=CS2&type=premier&quantity=1
Check stock
https://nfa.resync.club/api/rsk_a9f159.../reseller/stock
⚠️API keys in URLs appear in server access logs, browser history, and referer headers. Use this mode only for trusted server-to-server triggers (e.g. your private webhook receiver). For browser-side calls or shared scripts, use the header methods above.
📋 Resolution Order

When multiple methods are present, the server picks in this priority:

  1. X-API-Key header
  2. Authorization: Bearer ... header
  3. <api_key> URL path segment
⚠️Missing or invalid API keys return 401 UNAUTHORIZED regardless of which method was attempted.

Redeem License

Queue a license key for Steam-validated delivery. Poll Claim Status → to receive the credentials once validation completes.

🚀 Endpoint
POST/api/reseller/redeem

Request Body

FieldTypeDescription
license REQUIREDstring28-character license key
Request
{
  "license": "ABCD1234EFGH5678IJKL9012MNOP"
}
✅ Queued Response
200 OK
{
  "success": true,
  "queued": true,
  "claim_id": 1842,
  "license": "ABCD1234EFGH5678IJKL9012MNOP",
  "game": "CS2",
  "type": "Premier",
  "quantity": 1,
  "queue_position": 3,
  "message": "Queued for Steam validation. Poll /api/reseller/claim-status to get the delivered accounts."
}

Field Reference

FieldTypeDescription
claim_idintegerOpaque ID for polling /claim-status. Save this.
queue_positionintegerPosition in the system queue. 1 = next to be processed.
licensestringEcho of the redeemed license code.
game / type / quantityvariousEcho of the product details for confirmation.
💡Each account is Steam-validated by our system (login + ban check) before delivery. Typical end-to-end time: 30–60 s. Poll /api/reseller/claim-status every 15 s with the claim_id.
💻 cURL Example
cURL
curl -X POST https://nfa.resync.club/api/reseller/redeem \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{"license": "ABCD1234EFGH5678IJKL9012MNOP"}'

Purchase Account

Buy accounts directly from stock using your prepaid balance. No license code required — balance is reserved up-front and each account is Steam-validated before delivery. Poll Claim Status → to receive credentials once validation completes.

💰 Endpoint
POST/api/reseller/purchase

Specify the game and type you want and how many. The total cost is debited from your balance and the stock is reserved atomically. If validation later fails for any reserved row, the system auto-refunds the corresponding amount and re-queues from fresh stock.

Request Body

FieldTypeDescription
game REQUIREDstringGame name (e.g. CS2, Rust, ARC Raiders)
type REQUIREDstringProduct type (e.g. premier, medals, not premier, skins, knifeglove, rating, NFA)
quantityintegerHow many accounts to buy. Default 1, max 50.
Request
{
  "game": "CS2",
  "type": "premier",
  "quantity": 3
}
✅ Queued Response
200 OK
{
  "success": true,
  "queued": true,
  "claim_id": 1843,
  "game": "CS2",
  "type": "Premier",
  "quantity": 3,
  "base_price": 0.60,
  "discount_pct": 40,
  "unit_price": 0.36,
  "total_cost": 1.08,
  "balance_after": 48.92,
  "queue_position": 2,
  "message": "Queued for Steam validation. Poll /api/reseller/claim-status to get the delivered accounts."
}

Field Reference

FieldTypeDescription
claim_idintegerOpaque ID for polling /claim-status. Save this.
queue_positionintegerPosition in the system queue. 1 = next to be processed.
base_pricenumberCatalog price per account (from products table).
discount_pctintegerEffective discount applied (0–65; capped at 25 for CS2 Skins / Knife & Glove).
unit_pricenumberEffective price per account after discount: base_price × (1 - discount_pct/100).
total_costnumberunit_price × quantity, debited from your balance at queue time.
balance_afternumberYour remaining balance immediately after the debit.
💡Each account is Steam-validated by our system (login + ban check) before delivery. Typical end-to-end time: 30–60 s. Poll /api/reseller/claim-status every 15 s with the claim_id.
💡Same discount tier as dashboard Store — driven by your lifetime deposit. Top up more on the dashboard to unlock higher tiers (5% at $15, 65% at $1,500).
⚠️Premium inventory has a hard 25 % discount cap: CS2 Skins and CS2 Knife & Glove. Even at the 65 % tier (or with an admin override), these two products max out at 25 % off — applied automatically server-side.
❌ Insufficient Balance
402 Payment Required
{
  "success": false,
  "error": "Insufficient balance. Required $1.80, available $0.50.",
  "error_code": "INSUFFICIENT_BALANCE",
  "required": 1.80,
  "available": 0.50
}
503 Out of Stock
{
  "success": false,
  "error": "Insufficient stock. Requested 3, available 1.",
  "error_code": "OUT_OF_STOCK",
  "available": 1
}
💡Your API key is linked to a Resync.club dashboard account. Top up there with crypto (NOWPayments) — balance is shared between dashboard Store and reseller API. Contact admin if your key isn't linked yet.
💻 Examples
cURL — header auth
curl -X POST https://nfa.resync.club/api/reseller/purchase \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{"game": "CS2", "type": "premier", "quantity": 3}'
Webhook GET
https://nfa.resync.club/api/rsk_yourkey/reseller/purchase?game=CS2&type=premier&quantity=3

Paste the webhook URL into any storefront / automation tool that hits HTTP endpoints (Komerza, SellAuth, SellHub, Shoppex, cron, custom dashboards). See Authentication → for details.

⚠️ Notes
💳Balance is the same wallet as your Resync.club dashboard. Top up there with crypto (NOWPayments) — updates apply instantly to both. No separate reseller wallet.
All accounts are Steam-validated before delivery (login check + ban check by the system). You only receive credentials that passed validation — failed rows are auto-refunded.
💡Standard warranty (3 h / 10 min for valued inventory) applies from delivered_at. Use /warranty-check + /warranty-claim to replace banned accounts.

Purchase License

Create pre-paid redeem license codes — with an optional custom prefix — for your own customers to redeem later. Balance is charged now; codes are returned immediately. Use this when you're running your own storefront and want to issue branded vouchers instead of delivering accounts directly.

🎟️ Endpoint
POST/api/reseller/purchase-license

Same pricing as Purchase Account (your lifetime-deposit discount tier applies). Unlike Purchase Account, no stock is reserved and no validation queue runs — you just get a list of 28-char redeem codes back. Each code is redeemed individually later via /redeem.

Request Body

FieldTypeDescription
game REQUIREDstringGame name (e.g. CS2, Rust, ARC Raiders)
type REQUIREDstringProduct type (e.g. premier, medals, NFA)
quantityintegerHow many license codes to create. Default 1, max 100.
prefixstringOptional custom prefix baked into every code. Uppercase A–Z / 0–9 only, max 20 chars. Codes are always 28 chars total — random alphanumeric fills the rest.
Request
{
  "game": "CS2",
  "type": "premier",
  "quantity": 3,
  "prefix": "ACME"
}
✅ Success Response
200 OK
{
  "success": true,
  "game": "CS2",
  "type": "Premier",
  "quantity": 3,
  "prefix": "ACME",
  "base_price": 0.60,
  "discount_pct": 40,
  "unit_price": 0.36,
  "total_cost": 1.08,
  "balance_after": 48.92,
  "licenses": [
    "ACMEH7K2P9XQRT3M5W8YZ4N6JCBV",
    "ACME3L9TQRYK2N7XPMBVH8C4WJZ5",
    "ACMEZ5XQMK7TLN9BVH3RJ4WPC8Y6"
  ],
  "message": "Licenses created. Each code can be redeemed via /api/reseller/redeem (or the public /api/redeem) for one account."
}

Field Reference

FieldTypeDescription
licenses[]array<string>The newly created 28-char codes. Save these — they aren't re-shown anywhere.
prefixstringEcho of the prefix you supplied, normalized to uppercase. Empty string if none provided.
base_pricenumberCatalog price per license (from products table).
discount_pctintegerYour effective discount tier (0–65, capped at 25 for CS2 Skins / Knife & Glove).
unit_pricenumberbase_price × (1 - discount_pct/100).
total_costnumberunit_price × quantity, debited from your balance immediately.
balance_afternumberWallet balance after the debit.
⚠️Premium inventory has a hard 25 % discount cap: CS2 Skins and CS2 Knife & Glove. Even at the 65 % tier these two products max out at 25 % off.
❌ Error Responses
400 Invalid Prefix
{
  "success": false,
  "error": "Prefix must be alphanumeric (A-Z, 0-9 only).",
  "error_code": "INVALID_PREFIX"
}
402 Payment Required
{
  "success": false,
  "error": "Insufficient balance. Required $36.00, available $5.00.",
  "error_code": "INSUFFICIENT_BALANCE",
  "required": 36.00,
  "available": 5.00
}
💻 Examples
cURL — bulk create
curl -X POST https://nfa.resync.club/api/reseller/purchase-license \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{"game":"CS2","type":"premier","quantity":5,"prefix":"ACME"}'
Webhook GET
https://nfa.resync.club/api/rsk_yourkey/reseller/purchase-license?game=CS2&type=premier&quantity=1&prefix=ACME

Headers, Bearer auth, or in-URL key all work — see Authentication →.

⚠️ Notes
⚠️The licenses[] array is only returned once in this response — we never re-display created codes. Store them in your DB / email / Discord before discarding the response.
💡No stock check at create time. A license is just a voucher; stock is checked when it's redeemed. Use /stock first if you want to confirm the product is available before bulk-creating.
💡Prefix collisions are fine. Random filler guarantees uniqueness across the full code; two licenses sharing the same prefix is expected. If you re-use a prefix across orders, all of those codes will sort together — useful for grouping.
🔁Each license has accounts_per_key = 1. To deliver N accounts per voucher, create N licenses instead — keeps refund + warranty accounting clean (one license = one account = one warranty window).

Claim Status

Poll a queued Redeem or Purchase claim until validation finishes and the accounts are ready.

⏳ Endpoint
POST/api/reseller/claim-status
GET/api/reseller/claim-status?claim_id=1842

Lookup by claim_id (any endpoint) OR license (redeem only). Each claim is scoped to the API key that created it — keys cannot read each other's claims.

Request Fields

FieldTypeDescription
claim_idintegerThe claim_id returned by /redeem or /purchase. Preferred.
licensestring28-char license code (redeem flow only — purchases have no license).
💡At least one of claim_id or license must be provided. GET requests accept either as a query-string param.
⏳ Pending / Processing
200 OK
{
  "success": true,
  "claim_id": 1842,
  "status": "processing",
  "game": "CS2",
  "type": "Premier",
  "accounts_needed": 3,
  "queue_position": 1,
  "accounts": null,
  "message": "Validating Steam credentials..."
}

Status will be pending while waiting in the queue, then processing once the system picks it up. accounts stays null until approved.

✅ Approved (Delivered)
200 OK
{
  "success": true,
  "claim_id": 1842,
  "status": "approved",
  "game": "CS2",
  "type": "Premier",
  "accounts_needed": 3,
  "queue_position": 0,
  "accounts": [
    "username1----eyJhbGciOi...",
    "username2----eyJhbGciOi...",
    "username3----eyJhbGciOi..."
  ],
  "message": "Delivered."
}

Length of accounts matches accounts_needed. Each entry is a username----token string ready to feed into Steam / your customer.

❌ Rejected
200 OK
{
  "success": true,
  "claim_id": 1842,
  "status": "rejected",
  "game": "CS2",
  "type": "Premier",
  "accounts_needed": 3,
  "accounts": null,
  "message": "Validation failed: all candidate accounts banned or unreachable. Balance refunded."
}
💡Rejection is rare — the system retries from fresh stock multiple times before giving up. When it does happen, purchase claims auto-refund the original debit to your balance, and redeem claims release the license so you can retry.
📡 Status Values
StatusMeaningNext step
pendingIn queue, not yet picked up by the system.Keep polling.
processingThe system is validating accounts right now.Keep polling.
approvedValidation succeeded — credentials in accounts[].Deliver to your customer. Done.
rejectedValidation failed — balance refunded / license released.Retry the original call.
💻 Examples
cURL — by claim_id
curl -X POST https://nfa.resync.club/api/reseller/claim-status \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{"claim_id": 1842}'
cURL — by license
curl -X POST https://nfa.resync.club/api/reseller/claim-status \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{"license": "ABCD1234EFGH5678IJKL9012MNOP"}'
Webhook GET
https://nfa.resync.club/api/rsk_yourkey/reseller/claim-status?claim_id=1842
⚠️ Polling Guidance
⚠️Leave at least 15 seconds between polls. With a 300 req/h budget you'd burn through your quota in 75 minutes at faster cadence. Most claims finish in 30–60 s anyway.
💡If you need push-style delivery instead of polling, contact us about webhook callbacks — we can POST the final status to a URL you control.

Stock Inventory

Check live stock counts and prices for every product. Use this to power your own storefront or to know what's safe to /purchase right now.

📦 Endpoint
GET/api/reseller/stock

No request body. Auth via X-API-Key header only.

💡Results are cached for 5 minutes (300 s) server-side. Polling more frequently than that returns the same payload — no extra DB load on your end either.
✅ Success Response
200 OK
{
  "success": true,
  "total": 583,
  "cached_for_seconds": 300,
  "products": [
    {
      "game": "ARC Raiders",
      "type": "NFA",
      "type_raw": "NFA",
      "available": 72,
      "price": 1.35
    },
    {
      "game": "CS2",
      "type": "Premier",
      "type_raw": "premier",
      "available": 80,
      "price": 0.60
    },
    {
      "game": "CS2",
      "type": "Premier Medals",
      "type_raw": "medals",
      "available": 334,
      "price": 0.70
    }
  ]
}

Field Reference

FieldTypeDescription
totalintegerSum of available across all products.
cached_for_secondsintegerHow long this snapshot may be served from cache before a fresh DB query runs.
products[].gamestringGame name (e.g. CS2, Rust, ARC Raiders).
products[].typestringDisplay label for UI (e.g. Premier, Premier Medals).
products[].type_rawstringInternal type code — pass this verbatim to /purchase.
products[].availableintegerAccounts currently buyable: available + ready + cooldown-expired rows.
products[].pricenumber | nullBase unit price in USD. null if no products row exists for this game/type.
💡Products with available = 0 are omitted from the response. Treat a missing entry as "out of stock right now".
💻 cURL Example
cURL
curl https://nfa.resync.club/api/reseller/stock \
  -H "X-API-Key: your-api-key-here"

Replacement Account

Request a warranty replacement for a delivered account via API.

🔁 Workflow
1

Check Warranty

Call /api/reseller/warranty-check with the account token to verify eligibility and get the current account status.

2

Claim Replacement

If eligible, call /api/reseller/warranty-claim to queue an automatic replacement. Poll the status endpoint until the new account is delivered.

🔍 Step 1 — Check Warranty
POST/api/reseller/warranty-check

Request Body

FieldTypeDescription
license_key REQUIREDstringFull credential in username----token format (same value returned by /redeem)
Request
{
  "license_key": "username----eyJhbGciOi..."
}
200 OK
{
  "success": true,
  "license_key": "username----eyJhbGciOi...",
  "game": "CS2",
  "type": "Premier",
  "steamid64": "76561198xxxxxxxxx",
  "profile": {
    "personaname": "Player Name",
    "avatar": "https://avatars.steamstatic.com/..."
  },
  "ban_check": {
    "VACBanned": false,
    "NumberOfVACBans": 0,
    "NumberOfGameBans": 0,
    "CommunityBanned": false,
    "EconomyBan": "none"
  },
  "warranty": {
    "is_within_warranty": true,
    "delivered_at": "2026-05-16 10:30:00",
    "warranty_expires_at": "2026-05-16 13:30:00",
    "time_remaining_seconds": 8742
  },
  "verdict": {
    "eligible_for_warranty": true,
    "reason": "Eligible — call /warranty-claim to request replacement.",
    "action": "REPLACE_ACCOUNT"
  }
}

verdict.action values

ActionMeaning
REPLACE_ACCOUNTEligible — proceed to claim
IN_QUEUEReplacement already pending — poll status
APPROVEDReplacement already issued for this account
REJECTEDPrevious claim rejected — check reason
EXPIREDWarranty window has passed
🔄 Step 2 — Claim Replacement
POST/api/reseller/warranty-claim
FieldTypeDescription
license_key REQUIREDstringSame account token used in check
200 OK
{
  "success": true,
  "status": "queued",
  "message": "Replacement queued. Poll /warranty-status for updates.",
  "claim_id": 42,
  "queue_position": 3
}
💡If you call /warranty-claim twice for the same account, the second call returns the existing claim_id instead of creating a duplicate. Poll /warranty-status every 15 seconds until status is approved or rejected.
📡 Status Polling
POST/api/reseller/warranty-status

Poll with the original license_key. Status will be one of pending, processing, approved, or rejected.

Approved
{
  "success": true,
  "status": "approved",
  "new_account": "new_username----eyJhbGciOi...",
  "new_account_type": "Premier Medals",
  "message": "Replacement delivered.",
  "queue_position": 0
}
Pending / Processing
{
  "success": true,
  "status": "processing",
  "new_account": null,
  "message": "Validating new account...",
  "queue_position": 2
}
Rejected
{
  "success": true,
  "status": "rejected",
  "new_account": null,
  "new_account_type": null,
  "message": "Account can still be logged into and has no bans/cooldowns.",
  "queue_position": null
}

Field Reference

FieldTypeDescription
successbooleanAlways true when the claim was found. Transport-level errors (auth, bad input, 404) return false with an error field instead.
statusstringClaim state: pending, processing, approved, or rejected. Terminal states are approved / rejected — stop polling once you see them.
messagestringHuman-readable reason / progress note. Always populated — surface this to your end customer so they understand why their claim was queued, approved, or rejected. See the Rejection Reasons table below for known patterns to match against.
new_accountstring | nullReplacement credential in username----token format. null until status is approved.
new_account_typestring | nullDisplay label of the delivered type. May differ from the original if a substitute (e.g. Premier → Premier Medals) was issued.
queue_positioninteger | nullPosition in the system queue while pending/processing; 0 once approved; null when rejected.

Rejection Reasons — message patterns

When status === "rejected", the message field contains one of the following strings. Match against the substring column for safe forward-compatibility — exact wording may evolve, but these tokens stay stable.

CategorySubstring to matchWhat it means / what to show the customer
Still working"still be logged into"The old account still logs in cleanly with no ban/cooldown. The system could not reproduce the customer's complaint. Customer-facing: "Our system was able to log into your account successfully and detected no bans or cooldowns. If you believe this is incorrect, please contact support."
User-triggered cooldown"trigger a 20h", "trigger a 3-day", "trigger a 7-day", "trigger a 14-day", "trigger a 31-day", "trigger a 45-day", "trigger a 181-day"The cooldown's remaining time matches a fresh ladder entry — i.e. the customer triggered it themselves AFTER receiving the account. Not eligible for replacement. Customer-facing: "Your account was clean at delivery; the {ladder} cooldown was triggered by gameplay after delivery and is not covered by warranty."
User-triggered VAC ban"trigger a VAC ban"Account was clean pre-delivery, VAC banned after. Customer fault — not covered. Customer-facing: "VAC bans triggered after delivery are not eligible for replacement."
Cooldown state unverified"could not verify cooldown state"Steam GCPD page didn't render — automation can't confirm. Tell the customer to retry in a few minutes. Customer-facing: "We could not verify your account's cooldown state right now. Please submit the claim again in 5–10 minutes."
Rating unverified"could not verify the rating"csstats.gg unreachable (rate-limit / private profile / third-party outage). Customer-facing: "We could not verify the rating via our third-party stats provider. Please try again later or contact support."
Warranty expired"Warranty expired"Claim was submitted after the warranty window. Window is 10 minutes for CS2 Skins / Knife & Glove, 3 hours for everything else. Customer-facing: "The warranty window for this account has expired."
Invalid input"Invalid license key format", "Old account record not found"Malformed key or no matching record in our DB. Treat as a 4xx-style permanent failure — do not retry. Customer-facing: "We could not locate this account. Please double-check the credentials."
💡If you receive a substitute type (e.g. asked for premier but got medals), it's because the Medals stock is cross-compatible — a Medals account can still play Premier.
⚠️Always present the raw message string (or your localized equivalent) to the end customer when status is rejected. Resellers who silently swallow the rejection get more support tickets — customers want to know whether to retry, wait, or accept the verdict.
💻 Full cURL Flow
cURL
# Step 1: Check warranty
curl -X POST https://nfa.resync.club/api/reseller/warranty-check \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{"license_key": "username----eyJhbGciOi..."}'

# Step 2: Claim replacement (if eligible)
curl -X POST https://nfa.resync.club/api/reseller/warranty-claim \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{"license_key": "username----eyJhbGciOi..."}'

# Step 3: Poll status until complete
curl -X POST https://nfa.resync.club/api/reseller/warranty-status \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{"license_key": "username----eyJhbGciOi..."}'

Account Status

Check the health and ban status of a delivered account.

🛡️ Endpoint
POST/api/reseller/account-status

Returns the current status of a delivered account including ban checks, cooldown state, and profile information. Useful for building dashboards or proactively detecting issues before your customer reports them.

Request Body

FieldTypeDescription
license_key REQUIREDstringAccount token in format username----token
Request
{
  "license_key": "username----eyJhbGciOi..."
}
✅ Success Response
200 OK
{
  "success": true,
  "steamid64": "76561198xxxxxxxxx",
  "profile": {
    "personaname": "Player Name",
    "avatar": "https://avatars.steamstatic.com/..."
  },
  "bans": {
    "vac_banned": false,
    "game_banned": false,
    "community_banned": false,
    "number_of_vac_bans": 0,
    "number_of_game_bans": 0
  },
  "account_status": "active"
}

account_status values

ValueMeaning
activeNo bans detected — account is healthy.
bannedVAC ban or game ban present — eligible for warranty claim if still within window.
community_bannedSteam community ban only (no VAC/game ban). Account still works for matchmaking but flagged.
💡This is a stateless health check — it does NOT consume warranty or trigger a claim. For matchmaking cooldowns (e.g. CS2 competitive cooldown), use /warranty-check which performs deeper inspection.
💻 cURL Example
cURL
curl -X POST https://nfa.resync.club/api/reseller/account-status \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{"license_key": "username----eyJhbGciOi..."}'

Error Codes

All errors return a consistent JSON format.

📦 Error Response Format
Error
{
  "success": false,
  "error": "Human-readable error message",
  "error_code": "MACHINE_READABLE_CODE"
}
⚡ Error Reference
HTTPerror_codeMeaning
401UNAUTHORIZEDInvalid or missing API key
429RATE_LIMITEDExceeded 300 requests per hour for this API key
429BUSYConcurrent claim on same license — retry after 1s
400MISSING_PARAMclaim-status: neither claim_id nor license provided
400INVALID_PARAMclaim-status: claim_id is not a valid integer
400MISSING_LICENSEMissing license field (redeem only)
400INVALID_KEYMissing or invalid license_key (warranty / account-status)
400INVALID_FORMATNot 28 alphanumeric chars (redeem) or not username----token (account-status)
400INVALID_TOKENCould not extract Steam ID from token (account-status)
400NOT_ELIGIBLEAccount status is not delivered — cannot warranty-check
400NOT_COVEREDValued inventory (CS2 Skins / Knife & Glove / Rust / ARC) — no warranty
400EXPIREDWarranty window has passed (3h normal, 10min CS2 Skins/Knife)
400MISSING_FIELDSPurchase: missing game or type
400INVALID_QUANTITYPurchase: quantity must be 1–50 (Purchase Account) or 1–100 (Purchase License)
400INVALID_PREFIXPurchase License: prefix not alphanumeric, or longer than 20 chars
500GENERATION_FAILEDPurchase License: could not generate enough unique codes — try a different prefix
403NO_LINKED_ACCOUNTPurchase: API key not linked to a dashboard account. Contact admin to link.
402INSUFFICIENT_BALANCEPurchase: dashboard balance lower than total cost. Top up via dashboard.
404NOT_FOUNDclaim-status: no claim matches the given id/license under this API key
404INVALID_LICENSELicense key not found in DB
404PRODUCT_NOT_FOUNDPurchase: no product matches the given game / type
404NO_CLAIMNo warranty claim exists for this license (warranty-status)
409ALREADY_REDEEMEDLicense already used (redeem)
503OUT_OF_STOCKNo accounts available (or insufficient quantity for the request)
500SERVER_ERRORInternal error — retry later
500SERVICE_ERRORDB connection failure — retry later

Rate Limits

Limits to ensure fair usage across all resellers.

⏱️ Limits
LimitValue
Requests per API key300 requests / hour (rolling window)
Request body size16 MB max
💡That's 5 requests per minute on average — plenty for normal operations. For higher throughput, distribute calls across multiple API keys or contact us about a custom tier.
⚠️When polling /warranty-status, leave at least 15 seconds between polls to stay under the limit. System validation typically completes in under 1 minute.

Account Replacement

How the automated warranty replacement system works.

🔄 How It Works
1

Check Warranty

Enter your account token (username----token) in the Replacement tab. The system checks if your account is still within the warranty period.

2

Auto Validation

The system automatically verifies your old account status — checking for bans (VAC, Game, Community), cooldowns, and revocation.

3

Get Replacement

If your account qualifies, click "Request Replacement" and the system will validate a new account and deliver it to you automatically.

📋 Warranty Coverage
IssueCovered?Notes
VAC Ban✅ YesAutomatic replacement
Game Ban✅ YesAutomatic replacement
Community Ban✅ YesAutomatic replacement
Account Revoked✅ YesAutomatic replacement
Competitive Cooldown✅ YesAutomatic replacement
No Prime✅ YesAutomatic replacement
Deranked (Rating)✅ YesRating type only — if rating drops below threshold
Lost credentials❌ NoSave your token after redeem
Someone is playing❌ NoIt's the account owner, please wait patiently — this can keep the account alive for days or weeks. If you fight with the owner for access, the credentials will be changed in a minute. Also note: the account is still functional in this case, so it does not qualify as a non-working account and no replacement will be issued.
Valued Inventory❌ NoThese accounts only offer first-login warranty and are fully validated before being delivered for redeem, so they are not eligible for replacement after delivery (e.g. CS2 Skins, CS2 Knife & Glove).
Refresh while in queue❌ NoPlease do not refresh! Refreshing will cancel your claim and you will lose the account & license.
⚠️ Important Notes
⚠️Save your account token immediately after redeeming. We cannot recover lost tokens — this is your responsibility.
💡Replacement requests are processed automatically by our backend system. Processing time depends on the current queue — typically under 5 minutes.

Known Issues

Common problems you may hit after delivery — and how to resolve each one.

1🔑 After logging in, Steam asks for a password

Symptom — You sign in with the delivered token, but Steam immediately prompts for the account password instead of logging you straight in.

⚠️Cause — The original account owner has reclaimed the account: they revoked the active session or changed the password.
💡Solution — If you are still within the warranty window, open the Replacement tab → and submit your token there. The system will validate and deliver a fresh working account to you.
Need help? Contact us on Discord