StagecraftStagecraft
FeaturesHow it worksRankingsPricingVerifiedReportsMCPDocsChangelog
Sign inStart free
FeaturesHow it worksRankingsPricingVerifiedReportsMCPDocsChangelogSign in
Stagecraft · © 2026
APITermsPrivacyChangeloghelp@stagecraft.gg
Stagecraft is an independent analytics tool and is not affiliated with Rockstar Games, Take-Two, Cfx.re, FiveM, RedM, or Tebex.
On this page
  • Authentication
  • Rate limiting
  • Endpoints
  • Webhooks
  • Response shape
  • Compliance
  • Versioning
Reference · v1

Public read API

Programmatic access to the same data the dashboard reads. Available on the Agency plan. JSON over HTTPS, Bearer-token auth, 60 requests/min.

Authentication

Pass your API key in the Authorization header. Generate keys from the API Keys settings page. Keys look like sk_live_….

curl https://stagecraft.gg/api/v1/listings?limit=5 \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxx"

Rate limiting

Each request returns standard headers so you can pace yourself:X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. When you exceed your quota you get a 429 with a Retry-After header.

Endpoints

GET/api/v1

Returns your org context, plan, and rate-limit info. Useful for verifying your key works.

GET/api/v1/listings

Search and filter listings. Mirrors the in-app /search filters.

ParamTypeNotes
qstringFull-text search
frameworkscsvqbcore,qbox,esx,standalone,redm
categorystringExact category match
sourcestringcfx_marketplace | tebex
min_price / max_pricenumberPrice band (USD)
is_freebooltrue|false
min_ratingnumber0-5
has_videobooltrue|false
sortstringrating | newest | oldest | price_asc | price_desc | quality
limitnumber1-200, default 50
offsetnumberdefault 0
GET/api/v1/listings/{id}

Full listing detail with quality breakdown, daily snapshots (default 90 days), and recent events.

ParamTypeNotes
history_daysnumber1-365, default 90
GET/api/v1/opportunities

Ranked (category × framework) clusters with the same six sub-scores the dashboard exposes (demand / supply gap / price attractiveness / comp weakness / framework gap / momentum).

ParamTypeNotes
categorystringFilter to one category
frameworkstringFilter to one framework
include_emergingboolInclude sub-threshold clusters (default false)
limitnumber1-100, default 30
GET/api/v1/creators/{id}

Seller profile + their full portfolio (up to 100 listings).

GET/api/v1/sellers/{id}/history

Time-series view of a seller's catalog: listing count, average price, and quality score per day. Useful for tracking competitor expansion or pricing changes over time.

ParamTypeNotes
daysnumber1-365, default 90
GET/api/v1/categories/{slug}/timeline

Daily timeline of a category — listing count, average price, and median quality. Powers the category-level reports.

ParamTypeNotes
daysnumber1-365, default 90
GET/api/v1/exports/listings.csv

Bulk CSV dump of listings (Agency only — same data as the listings endpoint, paginated up to 50k rows). Streams gzip; pass `since` to slice by last_seen.

ParamTypeNotes
sinceISO 8601 datetimeOnly listings updated since (default: 30 days ago)
limitnumber1-50000, default 10000

Webhooks

Subscribe a URL to receive real-time events when listings change. Each delivery includes an HMAC-SHA256 signature so you can verify Stagecraft sent it. Available event types: listing.created, listing.removed, price.changed, sale.event.

GET/api/v1/webhooks

List your active webhook subscriptions.

POST/api/v1/webhooks

Create a new subscription. Returns the signing secret once — store it; it isn't retrievable later.

curl -X POST https://stagecraft.gg/api/v1/webhooks \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.example.com/hooks/stagecraft",
    "event_types": ["price.changed", "listing.created"]
  }'
GET|DELETE/api/v1/webhooks/{id}

Fetch or revoke a subscription. DELETE marks it inactive — past deliveries remain auditable.

Verifying signatures

Every POST to your webhook URL carries two headers: X-Stagecraft-Timestamp (unix seconds) and X-Stagecraft-Signature (format t=<ts>,v1=<hex>). Compute HMAC_SHA256(secret, "{ts}.{raw_body}") and compare in constant time. Reject if the timestamp is more than 5 minutes off.

// Node.js receiver
import { createHmac, timingSafeEqual } from 'node:crypto';

function verify(rawBody, header, secret) {
  const m = /^t=(\d+),v1=([a-f0-9]+)$/.exec(header || '');
  if (!m) return false;
  const ts = Number(m[1]);
  if (Math.abs(Date.now() / 1000 - ts) > 300) return false;
  const expected = createHmac('sha256', secret)
    .update(`${ts}.${rawBody}`).digest('hex');
  const a = Buffer.from(m[2]);
  const b = Buffer.from(expected);
  return a.length === b.length && timingSafeEqual(a, b);
}

Respond with any 2xx within 10 seconds. Non-2xx responses are retried with exponential backoff; subscriptions disable themselves after sustained failures.

Response shape

Every successful response wraps the payload in a data field:

{
  "data": [ ... ],
  "pagination": { "total": 487, "limit": 50, "offset": 0, "has_more": true }
}

Errors use a consistent shape:

{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Retry in 17s.",
    "retry_after": 17
  }
}

Compliance

The API exposes the same public data the marketplace already publishes — never paid asset files, never buyer emails, never login-walled content. Don't redistribute bulk listing dumps; that violates Cfx PLA §3.1(6) and your Terms of Service. If you need a bulk export for analysis, email help@stagecraft.gg.

Versioning

The API is versioned in the URL (/v1/…). Breaking changes ship as /v2/… with overlap; v1 stays available for at least 12 months after v2 GA.