For sellers Β· Automate your store

API reference

Everything you need to manage your listings, orders, wallet and stock programmatically. Each endpoint accepts and returns JSON. You authenticate exactly like the storefront does - with a Bearer token issued by the login endpoint.

BASE URLhttps://market-api.gydrus.net/api

Authentication

Every authenticated endpoint expects a Bearer JWT in the Authorization header. Get a token from /auth/login using your account email + password - the same credentials you use on the storefront. Tokens last 7 days.

POST/auth/login

Exchange email + password for a JWT bearer token.

Request body
{
  "email": "[email protected]",
  "password": "yourpassword"
}
Response
{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "user": { "_id": "...", "username": "youruser", "email": "...", "role": "user" }
}

Pass the token as a Bearer header on every subsequent request:

curl https://market-api.gydrus.net/api/listings/mine \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
GET/auth/meπŸ”’ auth

Returns the currently authenticated user. Useful to verify your token works.

Response
{
  "user": { "_id": "...", "username": "youruser", "email": "...", "role": "user", "coins": 0 }
}

Treat your token like a password - anyone holding it can act on your account until it expires. Rotate tokens regularly: log in again to get a fresh one, copy it into your script's secrets store, and discard the old one.

Errors

Every error response shares the same shape. The HTTP status is also set appropriately (400, 401, 403, …) so a basic HTTP client can branch on it without parsing JSON:

{
  "error": {
    "status": 400,
    "message": "Listing slug already in use",
    "details": null,
    "i18n": { "key": "apierr.slugTaken", "vars": null }
  }
}

Status codes you can expect:

  • 400 β€” Validation error or business rule violation (missing field, slug already in use, insufficient funds, etc.)
  • 401 β€” Missing, invalid or expired Bearer token
  • 403 β€” The token is valid but your account does not have permission for this action
  • 404 β€” The resource does not exist
  • 409 β€” You are trying to create something that already exists (duplicate slug, duplicate verification submission, etc.)
  • 429 β€” Rate limit exceeded - the response body includes retryAfterSec

Rate limits

Per-user limits apply on every write-heavy endpoint. When you hit one you get HTTP 429 with retryAfterSec in the body - wait that many seconds and retry.

  • Listing creation: 20 per day
  • Image uploads: 100 per day
  • Order messages: 200 per day
  • Disputes opened: 5 per day, max 5 open at once
  • Wallet deposits: 10 per hour
  • Reviews submitted: 50 per day

These are anti-abuse caps, not commercial limits - if your use case needs higher throughput (high-volume stock, bulk migration), contact support and we can raise your individual cap.

Listings

Listings are the core marketplace object. Every listing belongs to one game and one service category, has a price in minor units (cents), and may carry stock items (instant-delivery listings) or be a "service" listing the seller delivers manually. Title and description are localized maps - populate at least the default locale and you can add translations later.

GET/listings

Public marketplace search. Query params: page, limit (max 50), game (slug or id), category, seller, q, minPrice, maxPrice, sort (newest|cheapest|priciest), featured.

Response
{
  "items": [
    {
      "_id": "...",
      "slug": "ultimate-fortnite-account-3f9a",
      "title": { "en": "Ultimate Fortnite Account" },
      "description": { "en": "Includes 50 skins, full BP..." },
      "price": 4500,
      "stock": 3,
      "game": { "_id": "...", "name": "Fortnite", "slug": "fortnite", "imageUrl": "..." },
      "seller": { "_id": "...", "username": "progamer", "seller": { "rating": 4.9 } },
      "images": ["https://cdn.gydrus.net/..."]
    }
  ],
  "page": 1, "limit": 20, "total": 312, "pages": 16
}
GET/listings/mineπŸ”’ auth

Your own listings, including paused and removed.

GET/listings/:idOrSlug

Single listing detail.

POST/listingsπŸ”’ auth

Create a new listing. Each game has its own required attributes β€” fetch /games/:slug first to see them. price is in minor units (cents). title and description accept multiple languages at once; empty languages are dropped.

Request body
{
  "game": "<game id>",
  "category": "account",
  "title": { "en": "Smurf account, Diamond rank" },
  "description": { "en": "EU server. Full mastery on top 10 champions..." },
  "defaultLocale": "en",
  "price": 3500,
  "stock": 5,
  "minQuantity": 1,
  "images": ["https://cdn.gydrus.net/abc.webp"],
  "attributes": { "server": "EUW", "rank": "diamond" },
  "deliveryType": "inventory",
  "deliveryTime": "instant",
  "deliveryInstructions": { "en": "Login details will be delivered automatically." }
}
Response
{
  "_id": "...",
  "slug": "smurf-account-diamond-rank-3f9a1c",
  ...
}
PUT/listings/:idπŸ”’ auth

Update any subset of fields. Anything you omit stays as it was.

Request body
{
  "price": 4000,
  "stock": 8
}
POST/listings/:id/featureπŸ”’ auth

Pay the feature fee (see /public-settings) from your wallet to feature this listing. Calling it again while already featured extends the window.

DELETE/listings/:idπŸ”’ auth

Remove your listing. Existing orders for it remain unaffected.

Stock items

Stock items are the credentials (account login, gift card code, etc.) attached to an instant-delivery listing. They are encrypted at rest with AES-256-GCM and revealed to the buyer only at the moment of purchase. The shape of each item is free-form JSON - your script decides what fields a buyer needs.

GET/listings/:id/stockπŸ”’ auth

List your stock items for one listing.

Response
{
  "items": [
    { "_id": "...", "status": "available", "createdAt": "2026-...", "preview": "Account #1" }
  ]
}
POST/listings/:id/stockπŸ”’ auth

Add stock items in bulk. Each item is a JSON object with the credentials the buyer needs to receive β€” pick whatever field names make sense for your listing. The platform encrypts every item at rest and only reveals it to the buyer at purchase.

Request body
{
  "items": [
    { "username": "[email protected]", "password": "...", "extra": "Recovery code abc123" },
    { "username": "[email protected]", "password": "...", "extra": "Recovery code def456" }
  ]
}
DELETE/stock/:idπŸ”’ auth

Delete an unsold stock item. Items already delivered to a buyer cannot be deleted.

Orders

Orders represent a completed purchase. The buyer pays into escrow; you (the seller) deliver; after the escrow window closes the funds release to your wallet. You can communicate with the buyer through the order conversation thread.

GET/orders/salesπŸ”’ auth

Your sales (orders where you are the seller). Query params: page, limit, status, q (searches the listing title), minAmount, maxAmount, from, to (ISO dates), sort.

GET/orders/purchasesπŸ”’ auth

Your purchases (orders where you are the buyer). Same query params as /orders/sales.

GET/orders/:idπŸ”’ auth

Single order detail. Includes a snapshot of the listing at the moment of purchase, so the order page always shows what was bought even if you later edit or remove the listing.

POST/orders/:id/messagesπŸ”’ auth

Send a message in the order's conversation thread. The other party receives an in-app notification.

Request body
{
  "body": "Hi! Just to confirm, the account is ready and will be delivered tonight."
}
POST/orders/:id/deliverπŸ”’ auth

Manually mark a service-type order as delivered. For inventory-type instant orders, delivery is automatic at purchase and this endpoint is a no-op.

POST/orders/:id/completeπŸ”’ auth

Buyer-side: confirm the order is satisfactory. Releases escrow to the seller immediately (no wait for the dispute window to expire).

Wallet

Your wallet holds your platform balance - earnings released from escrow, refunds received, manual top-ups. All amounts are in minor units (USD cents). Withdraw via the dedicated withdrawal flow.

GET/walletπŸ”’ auth

Wallet snapshot: balance, recent 20 transactions, escrow summary (held + released-pending). Amounts in minor units.

Response
{
  "wallet": { "_id": "...", "balance": 125000, "currency": "USD" },
  "transactions": [
    { "_id": "...", "type": "sale", "amount": 4500, "balanceAfter": 125000, "description": "Sale: ...", "createdAt": "..." }
  ],
  "escrow": { "held": 8000, "released": 0 }
}
GET/wallet/transactionsπŸ”’ auth

Paginated ledger of every wallet movement. Query params: page, limit (max 100). The description field is the human-readable label for each entry.

Withdrawals

Withdrawals require an approved ID verification on file. You register a destination wallet once and then request withdrawals against it; an admin reviews each request before funds move.

GET/withdrawals/quoteπŸ”’ auth

Preview the platform fee for a given withdrawal amount before submitting.

POST/withdrawals/walletsπŸ”’ auth

Register a payout destination (crypto address or bank account). You can add multiple; each subsequent withdrawal picks one.

Request body
{
  "method": "crypto",
  "crypto": { "currency": "USDT_TRC20", "address": "T...." }
}
GET/withdrawals/walletsπŸ”’ auth

List your registered payout destinations.

POST/withdrawalsπŸ”’ auth

Request a withdrawal. Amount is in minor units. Admin must approve before funds move.

Request body
{
  "amount": 50000,
  "walletId": "<id from /withdrawals/wallets>"
}
GET/withdrawalsπŸ”’ auth

List your withdrawal requests, all statuses.

Image uploads

Use this endpoint to upload listing photos and avatars. The server validates the image, strips all metadata (EXIF/GPS/device), resizes to fit 2000Γ—2000, and re-encodes to WebP. The returned URL is permanent - put it into Listing.images or User.avatarUrl.

POST/uploadsπŸ”’ auth

multipart/form-data with a single 'file' field. JPEG, PNG, WebP or GIF, max 5MB. The platform re-encodes the image, strips all metadata (GPS, device info), and caps the dimensions at 2000Γ—2000. Returns a permanent URL you can put straight into Listing.images.

Response
{
  "url": "https://cdn.gydrus.net/1779286476998-c2dadb980629ce0a.webp"
}

For ID-verification documents (private), append ?visibility=private. The response then includes a key (the persistent reference to store) and a short-lived signed url for immediate preview.

Reference data

Read-mostly endpoints your scripts will hit for catalogue + config data. None of these mutate; some are cacheable for hours on your side.

GET/games

Game catalogue. For each game you get the supported categories, the required attributes for new listings, the commission percent, and the escrow window.

GET/games/:idOrSlug

Single game detail. Read this before building a Create-Listing payload to know which attributes are required.

GET/public-settings

Platform-wide values your script may need: loyalty-coin reward percent, minimum deposit, dispute window, tier ladders, listing length caps, affiliate reward rate, coin redemption rate, social links.

GET/dispute-reasonsπŸ”’ auth

Preset dispute reasons grouped by service category β€” what your UI would show in a 'pick a reason' dropdown.

Support

Spotted a missing endpoint or unclear field? We'd rather hear about it - drop a note via our feedback form.