{"openapi":"3.1.0","info":{"title":"SMS Platform API","version":"1.0.0","description":"Virtual number / OTP receiving platform API.\n\nAll money is **integer USD cents**. Public API (`/v1`) is authenticated with\n`Authorization: Bearer sk_live_…` (or `sk_test_…` for the sandbox, which never\nspends money or calls an upstream provider), uses the envelope\n`{ success: true, data }` / `{ success: false, error: { code, message } }`,\nand supports `Idempotency-Key` on order creation with a 24 h replay window."},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key: `Authorization: Bearer sk_live_…` or `sk_test_…` (sandbox)."},"sessionCookie":{"type":"apiKey","in":"cookie","name":"sms_session","description":"Dashboard session cookie (httpOnly, SameSite=Lax, 30 days)."}},"schemas":{"ErrorEnvelope":{"type":"object","required":["success","error"],"properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["UNAUTHORIZED","FORBIDDEN","NOT_FOUND","VALIDATION_ERROR","INSUFFICIENT_BALANCE","NO_NUMBERS","PRICE_EXCEEDED","RATE_LIMITED","IDEMPOTENCY_CONFLICT","PROVIDER_ERROR","INTERNAL_ERROR"]},"message":{"type":"string"},"details":{"description":"Optional machine-readable details"}}}}},"Order":{"type":"object","properties":{"id":{"type":"integer"},"publicId":{"type":"string","example":"ord_0a1b2c3d4e5f6071"},"countryId":{"type":"integer"},"countryIso2":{"type":"string"},"countryName":{"type":"string"},"serviceId":{"type":"integer"},"serviceSlug":{"type":"string"},"serviceName":{"type":"string"},"operator":{"type":["string","null"]},"phone":{"type":["string","null"]},"costCents":{"type":"integer"},"priceCents":{"type":"integer"},"status":{"type":"string","enum":["created","waiting_sms","sms_received","completed","canceled","expired","failed"]},"otpCode":{"type":["string","null"]},"smsText":{"type":["string","null"]},"provider":{"type":"string"},"providerOrderId":{"type":["string","null"]},"canCancel":{"type":"boolean"},"canResend":{"type":"boolean"},"canFinish":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"finishedAt":{"type":["string","null"],"format":"date-time"},"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"sender":{"type":["string","null"]},"text":{"type":"string"},"otpCode":{"type":["string","null"]},"receivedAt":{"type":"string","format":"date-time"}}}}}},"Country":{"type":"object","properties":{"id":{"type":"integer"},"iso2":{"type":"string"},"name":{"type":"string"},"dialCode":{"type":"string"},"emoji":{"type":"string"},"active":{"type":"boolean"},"priceFromCents":{"type":"integer"},"stock":{"type":"integer"}}},"Service":{"type":"object","properties":{"id":{"type":"integer"},"slug":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"active":{"type":"boolean"},"priceFromCents":{"type":"integer"},"stock":{"type":"integer"}}},"Product":{"type":"object","properties":{"id":{"type":"integer"},"countryId":{"type":"integer"},"serviceId":{"type":"integer"},"operator":{"type":"string"},"costCents":{"type":"integer"},"priceCents":{"type":"integer"},"stock":{"type":"integer"}}},"LedgerEntry":{"type":"object","properties":{"id":{"type":"integer"},"kind":{"type":"string","enum":["topup","spend","refund","adjust"]},"amountCents":{"type":"integer","description":"Signed cents: negative = spend, positive = credit"},"balanceAfterCents":{"type":"integer"},"refType":{"type":["string","null"]},"refId":{"type":["string","null"]},"note":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}}},"Deposit":{"type":"object","properties":{"id":{"type":"integer"},"userId":{"type":"integer"},"method":{"type":"string","enum":["usdt_trc20","btc","manual"]},"amountCents":{"type":"integer"},"txRef":{"type":["string","null"]},"status":{"type":"string","enum":["pending","approved","rejected"]},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":["string","null"],"format":"date-time"}}},"ApiKey":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"prefix":{"type":"string","example":"sk_live_AbCdEfGhIjKl"},"mode":{"type":"string","enum":["live","sandbox"]},"scopes":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time"}}},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"integer"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"CursorPage":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}}}}},"paths":{"/":{"get":{"summary":"Service metadata","tags":["system"],"description":"Public API root.","responses":{"200":{"description":"Default Response"}}}},"/health":{"get":{"summary":"Health check (Postgres + Redis)","tags":["system"],"responses":{"200":{"description":"Healthy","content":{"application/json":{"schema":{"description":"Healthy","type":"object","properties":{"ok":{"type":"boolean"},"db":{"type":"boolean"},"redis":{"type":"boolean"}}}}}},"503":{"description":"Unhealthy (db and/or redis unreachable)","content":{"application/json":{"schema":{"description":"Unhealthy (db and/or redis unreachable)","type":"object","properties":{"ok":{"type":"boolean"},"db":{"type":"boolean"},"redis":{"type":"boolean"}}}}}}}}},"/api/auth/signup":{"post":{"summary":"Create an account","tags":["auth"],"description":"Creates a user + wallet, signs the user in (sms_session cookie).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8}}}}}},"responses":{"201":{"description":"Account created","content":{"application/json":{"schema":{"description":"Account created","type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"integer"},"email":{"type":"string"},"role":{"type":"string"}}},"balance_cents":{"type":"integer"}}}}}}}}},"/api/auth/login":{"post":{"summary":"Sign in","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/auth/logout":{"post":{"summary":"Sign out","tags":["auth"],"description":"Deletes the current session row and clears the sms_session cookie.","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/auth/me":{"get":{"summary":"Current user + wallet balance","tags":["auth"],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/wallet/":{"get":{"summary":"Wallet balance","tags":["wallet"],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/wallet/transactions":{"get":{"summary":"Ledger statement (append-only, newest first)","tags":["wallet"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false}],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/wallet/deposits":{"get":{"summary":"My deposit requests","tags":["wallet"],"parameters":[{"schema":{"type":"string","enum":["pending","approved","rejected"]},"in":"query","name":"status","required":false}],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Create a pending deposit (USDT TRC-20 / BTC / manual)","tags":["wallet"],"description":"Deposits stay pending until an admin approves them; approval credits the wallet ledger with kind=topup.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount_cents","method"],"properties":{"amount_cents":{"type":"integer","minimum":50},"method":{"type":"string","enum":["usdt_trc20","btc","manual"]},"tx_ref":{"type":"string","maxLength":200}}}}}},"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/catalog/countries":{"get":{"summary":"List active countries with cheapest price + live stock","tags":["catalog"],"responses":{"200":{"description":"Country list","content":{"application/json":{"schema":{"description":"Country list","type":"array","items":{"$ref":"#/components/schemas/Country"}}}}}}}},"/api/catalog/services":{"get":{"summary":"List services/platforms (optionally filtered by country stock)","tags":["catalog"],"parameters":[{"schema":{"type":"integer"},"in":"query","name":"country_id","required":false}],"responses":{"200":{"description":"Service list","content":{"application/json":{"schema":{"description":"Service list","type":"array","items":{"$ref":"#/components/schemas/Service"}}}}}}}},"/api/catalog/products":{"get":{"summary":"Buyable products for a country and/or service","tags":["catalog"],"parameters":[{"schema":{"type":"integer"},"in":"query","name":"country_id","required":false},{"schema":{"type":"integer"},"in":"query","name":"service_id","required":false}],"responses":{"200":{"description":"Product list","content":{"application/json":{"schema":{"description":"Product list","type":"array","items":{"$ref":"#/components/schemas/Product"}}}}}}}},"/api/catalog/summary":{"get":{"summary":"Catalog counters for landing pages / admin dashboards","tags":["catalog"],"responses":{"200":{"description":"Default Response"}}}},"/api/orders/":{"post":{"summary":"Create an order (deducts wallet, worker buys the number)","tags":["orders"],"description":"Validates product availability + stock, checks the wallet balance, writes the order row and the spend ledger entry atomically. Optional Idempotency-Key header.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"product_id":{"type":"integer"},"country_id":{"type":"integer"},"service_id":{"type":"integer"},"max_price_cents":{"type":"integer"},"metadata":{"type":"object"}}}}}},"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}},"get":{"summary":"List my orders (cursor paginated, newest first)","tags":["orders"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false},{"schema":{"type":"string"},"in":"query","name":"status","required":false}],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/orders/active":{"get":{"summary":"My active orders (created / waiting_sms / sms_received)","tags":["orders"],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/orders/{publicId}":{"get":{"summary":"One order with its SMS messages","tags":["orders"],"parameters":[{"schema":{"type":"string","example":"ord_0a1b2c3d4e5f6071"},"in":"path","name":"publicId","required":true}],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/orders/{publicId}/cancel":{"post":{"summary":"Cancel an order","tags":["orders"],"description":"Before the provider purchase the API refunds immediately; afterwards the worker cancels upstream and refunds.","parameters":[{"schema":{"type":"string"},"in":"path","name":"publicId","required":true}],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/orders/{publicId}/finish":{"post":{"summary":"Finish an order (idempotent)","tags":["orders"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"publicId","required":true}],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/orders/{publicId}/resend":{"post":{"summary":"Request another SMS window on the same number","tags":["orders"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"publicId","required":true}],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/keys/":{"post":{"summary":"Create an API key (returns the plaintext key once)","tags":["api-keys"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":80},"mode":{"type":"string","enum":["live","sandbox"],"default":"live"}}}}}},"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}},"get":{"summary":"List my API keys (hashes are never returned)","tags":["api-keys"],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/keys/{id}":{"delete":{"summary":"Revoke an API key","tags":["api-keys"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/admin/stats":{"get":{"summary":"Platform stats: users, orders, revenue, cost, margin","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/api/admin/orders":{"get":{"summary":"All orders (newest first, optional status filter)","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false},{"schema":{"type":"string"},"in":"query","name":"status","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/admin/users":{"get":{"summary":"All users with wallet balance and order count","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/admin/deposits":{"get":{"summary":"Deposit requests (default: pending)","tags":["admin"],"parameters":[{"schema":{"type":"string","enum":["pending","approved","rejected"]},"in":"query","name":"status","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/admin/deposits/{id}/approve":{"post":{"summary":"Approve a deposit: credit wallet + topup ledger entry + audit log","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/admin/deposits/{id}/reject":{"post":{"summary":"Reject a deposit (no wallet change) + audit log","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/admin/catalog/sync":{"post":{"summary":"Flags a catalog sync (worker picks it up on its next tick)","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/api/admin/providers":{"get":{"summary":"Configured upstream providers + health","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/api/admin/ledger":{"get":{"summary":"Global ledger tail (admin)","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/webhooks/smsbower":{"get":{"summary":"SMSBower webhook reachability check","tags":["webhooks-in"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Receive an inbound SMS from SMSBower","tags":["webhooks-in"],"description":"Body: {activationId, service, text, code, country, receivedAt}. Matches the order by provider_order_id, stores the message, flips the order to sms_received and enqueues user webhook deliveries.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["activationId"],"properties":{"activationId":{"type":["string","number"]},"service":{"type":["string","null"]},"text":{"type":["string","null"]},"code":{"type":["string","number","null"]},"country":{"type":["string","number","null"]},"receivedAt":{"type":["string","null"]}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/v1/catalog/countries":{"get":{"summary":"List countries (with cheapest price + stock)","tags":["v1-catalog"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Countries","content":{"application/json":{"schema":{"description":"Countries","type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Country"}}}}}}}}}},"/v1/catalog/services":{"get":{"summary":"List services/platforms, optionally in stock for a country","tags":["v1-catalog"],"parameters":[{"schema":{"type":"integer"},"in":"query","name":"country_id","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/catalog/products":{"get":{"summary":"List buyable products (operator, price_cents, stock)","tags":["v1-catalog"],"parameters":[{"schema":{"type":"integer"},"in":"query","name":"country_id","required":false},{"schema":{"type":"integer"},"in":"query","name":"service_id","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/catalog/summary":{"get":{"summary":"Catalog counters","tags":["v1-catalog"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/balance":{"get":{"summary":"Wallet balance in integer USD cents","tags":["v1-wallet"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/me/transactions":{"get":{"summary":"Ledger statement (newest first, cursor paginated)","tags":["v1-wallet"],"parameters":[{"schema":{"type":"integer"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/orders/create":{"post":{"summary":"Create an order","tags":["v1-orders"],"description":"Requires `Idempotency-Key` for safe retries (24 h replay window). Sandbox keys create mock orders that never spend money or call a provider.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"product_id":{"type":"integer"},"country_id":{"type":"integer"},"service_id":{"type":"integer"},"max_price_cents":{"type":"integer"},"metadata":{"type":"object"}}}}}},"parameters":[{"schema":{"type":"string","maxLength":255},"in":"header","name":"idempotency-key","required":false}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Order created","content":{"application/json":{"schema":{"description":"Order created","type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Order"}}}}}},"401":{"description":"Missing or invalid credentials (UNAUTHORIZED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Insufficient wallet balance (INSUFFICIENT_BALANCE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found (NOT_FOUND / NO_NUMBERS)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Idempotency conflict (IDEMPOTENCY_CONFLICT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation error or price exceeded (VALIDATION_ERROR / PRICE_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/orders":{"get":{"summary":"List my orders (cursor paginated, newest first)","tags":["v1-orders"],"parameters":[{"schema":{"type":"integer"},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false},{"schema":{"type":"string"},"in":"query","name":"status","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/orders/active":{"get":{"summary":"Active orders (created / waiting_sms / sms_received)","tags":["v1-orders"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/orders/{id}":{"get":{"summary":"One order (public id or numeric id) with SMS messages + capabilities","tags":["v1-orders"],"parameters":[{"schema":{"type":"string","example":"ord_0a1b2c3d4e5f6071"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"404":{"description":"Not found (NOT_FOUND / NO_NUMBERS)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/orders/cancel":{"post":{"summary":"Cancel an order (refund rules: see docs)","tags":["v1-orders"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string","example":"ord_0a1b2c3d4e5f6071"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/orders/finish":{"post":{"summary":"Finish an order (idempotent)","tags":["v1-orders"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/orders/resend":{"post":{"summary":"Request another SMS on the same number","tags":["v1-orders"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/webhooks":{"post":{"summary":"Create a webhook endpoint (secret is returned once)","tags":["v1-webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["order.created","order.sms_received","order.completed","order.canceled","order.expired"]}}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}},"get":{"summary":"List my webhook endpoints","tags":["v1-webhooks"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/webhooks/{id}":{"get":{"summary":"Get one webhook endpoint","tags":["v1-webhooks"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Disable a webhook endpoint","tags":["v1-webhooks"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}}},"servers":[{"url":"https://smsapi.muneebs.space"}],"tags":[{"name":"system","description":"Health, docs and metadata"},{"name":"auth","description":"Email + password accounts and cookie sessions"},{"name":"wallet","description":"Balance, ledger and deposit requests"},{"name":"catalog","description":"Countries, services and live products (prices in integer USD cents)"},{"name":"orders","description":"Number orders and their SMS lifecycle"},{"name":"api-keys","description":"Create and revoke public API keys"},{"name":"v1-catalog","description":"Public API v1 — catalog (Bearer auth)"},{"name":"v1-wallet","description":"Public API v1 — balance and transactions"},{"name":"v1-orders","description":"Public API v1 — order lifecycle"},{"name":"v1-webhooks","description":"Public API v1 — webhook endpoint management"},{"name":"admin","description":"Admin operations (session + admin role)"},{"name":"webhooks-in","description":"Inbound supplier webhooks"}]}