simforever

API

The leaderboard routes are public and allow cross-origin reads. Everything else needs a key.

Envelope

Every response is JSON. Successful responses wrap the payload:

{"data": ..., "meta": {"game": "classic_era", "build": "1.15.9.69722", "engineVersion": "...", "generatedAt": "..."}}

Errors:

{"error": {"code": "spec_mismatch", "message": "the export is a Mage, this spec is warrior"}}

Lists paginate with ?page=&perPage= (max 500) and carry page, perPage and total in meta.

Public leaderboard routes

No key. Writes are limited per address.

GET /v1/games/{game}/profileActive encounter profile, phase and notes.

GET /v1/games/{game}/specsEvery spec with role, ranked flag, engine status, current champion summary and co-champion count.

GET /v1/games/{game}/championsCurrent champions across specs, full records.

GET /v1/games/{game}/specs/{spec}Spec, profile, current champions, past champions and the last 50 challenges.

GET /v1/games/{game}/specs/{spec}/apl-presetsRotation presets for the spec: [{name, apl}].

GET /v1/games/{game}/specs/{spec}/bisLatest generated sets with DPS, intervals, ties and stat weights, or {"status":"not_generated"}.

POST /v1/games/{game}/specs/{spec}/submissionsSubmit a build. 202 with {submissionId, status, queuePosition, poll}.

GET /v1/games/{game}/submissions/{id}Status, queue position, stage results, verdict and the build. Always public.

GET /v1/games/{game}/submissions?spec=&status=Recent submissions, the queue view.

Keys and limits

Send the key as X-API-Key: sf_<prefix>.<secret>. A missing or invalid key returns 401. Each key has a token bucket per minute; when it runs out you get 429 with Retry-After. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining.

POST /v1/keysCreate a key: {"email","name"} returns {"key"} once. Free tier, 60 requests per minute.

GET /v1/gamesGames the API knows.

POST /v1/games/{game}/simsRun one sim from a wowsims link or settings export, up to 25,000 iterations. 202 with a job id.

GET /v1/sims/{id}Sim job status and summary.

GET /v1/jobs/{id}Any job by id.

Examples

Current champions:

curl https://forever.howtoguides.online/v1/games/classic_era/champions

One spec with history:

curl https://forever.howtoguides.online/v1/games/classic_era/specs/warrior

Submit a build from the WoWSims Exporter addon string, using a preset rotation:

curl -X POST https://forever.howtoguides.online/v1/games/classic_era/specs/warrior/submissions \
  -H 'Content-Type: application/json' \
  -d '{
    "source": "addon",
    "addon": "{\"class\":\"Warrior\",\"race\":\"Orc\",\"talents\":\"30305001302-05050005525010051\",\"gear\":{\"items\":[...]}}",
    "aplPreset": "dps_reck",
    "finderName": "Thrandor"
  }'

Submit from a wowsims link with your own rotation and talents:

curl -X POST https://forever.howtoguides.online/v1/games/classic_era/specs/warrior/submissions \
  -H 'Content-Type: application/json' \
  -d '{"source": "link", "link": "https://wowsims.github.io/classic/warrior/#...", "talents": "30305001302-05050005525010051", "apl": {"type": "TypeAPL", "priorityList": [...]}, "finderName": "Thrandor", "finderContact": "thrandor@example.org"}'

Poll a submission:

curl https://forever.howtoguides.online/v1/games/classic_era/submissions/101

Create a key for the keyed routes:

curl -X POST https://forever.howtoguides.online/v1/keys -H 'Content-Type: application/json' -d '{"email": "you@example.org", "name": "my tool"}'