Skip to main content

Migration Guide: v1 → v2

TL;DR

Five things to change, in order of priority:

#Whatv1v2
1AuthAPI key in URL /{apikey}/...Header: x-api-key: YOUR_KEY
2URLs/{apikey}/{mode}/endpoint/v2/endpoint
3Refreshlive mode in path?refresh=true query param
4ErrorsAlways HTTP 200, check success === 0Real HTTP status codes (401, 404, 429…)
5json_pathSupportedRemoved — filter client-side

If you're in a hurry, jump straight to the checklist or the before/after examples.


If you can't migrate everything at once:

Phase 1 — Authentication

Everything else depends on it.

  • Move the API key from the URL to the x-api-key header
  • Update error handling to check HTTP status codes instead of success === 0

Phase 2 — URL paths (can iterate)

Old paths stay working via legacy middleware — temporarily. Migrate one endpoint at a time.

  • /{apikey}/{mode}/endpoint/v2/endpoint
  • Replace live with ?refresh=true, drop everything else

Phase 3 — Response parsing (safe to defer)

  • success === 1success === true (or just if (response.success) — works for both)
  • Handle 400 / 401 / 403 / 404 / 429 / 500 properly

Phase 4 — Optional polish

  • Add If-None-Match / ETag support to reduce bandwidth on polling
  • Use updatedAt / expiresAt to drive smarter cache invalidation

Migration Checklist

[ ] Move API key from URL to x-api-key header
[ ] Update request URLs: /{apikey}/{mode}/... → /v2/...
[ ] Replace {mode} path segment with ?refresh=true, or drop it entirely
[ ] Update success checks: success 1/0 → true/false
[ ] Update error handling: check HTTP status codes, not the success field
[ ] Remove json_path query params — filter client-side
[ ] Update progress-tracker path: /progress-tracker → /progress-tracker/teams
[ ] Update starmap routes to new sub-paths (see endpoint reference below)
[ ] Handle HTTP 429 (new rate-limit status)
[ ] Remove If-Match header usage (no longer supported)

Quick Before/After Examples

# v1
GET /myapikey1234/live/user/SomeHandle

# v2
GET /v2/users/SomeHandle?refresh=true
x-api-key: myapikey1234

Detailed Reference

1. Authentication

v1 — API key in URL

GET /{apikey}/live/user/SomeHandle

v2 — API key in header

GET /v2/users/SomeHandle
x-api-key: YOUR_API_KEY

Action required: Remove the API key from the URL. Pass it as the x-api-key request header on every request.

2. Base URL & path structure

v1 pattern

/{apikey}/{mode}/{endpoint}
/{apikey}/v1/{mode}/{endpoint} ← optional v1 prefix, identical behaviour

v2 pattern

/v2/{endpoint}

All v1 paths are automatically rewritten to v2 by the legacy compatibility middleware — but only temporarily. Migrate explicitly to avoid breakage when legacy support is removed.

3. Fetch mode → ?refresh parameter

v1 exposed a {mode} path segment controlling cache behaviour. v2 replaces this with a single boolean query parameter.

v1 modev2 equivalentDescription
live?refresh=trueScrape RSI in real time. Costs quota.
cache?refresh=false (default)Return cached data. Free.
auto?refresh=false (default)Server auto-refreshes behind the scenes
eager?refresh=trueForce live scrape — same as ?refresh=true

In v2, the API manages cache freshness automatically server-side. Clients simply omit ?refresh for cached data, or pass ?refresh=true when live data is needed.

caution

Only ?refresh=true consumes your daily quota. Omitting ?refresh or setting ?refresh=false is always free.

4. Endpoint URL mapping

Users

v1v2
GET /{apikey}/{mode}/user/{handle}GET /v2/users/{handle}
(no separate endpoint)GET /v2/users/{handle}/profile
(no separate endpoint)GET /v2/users/{handle}/organization

Organizations

v1v2
GET /{apikey}/{mode}/organization/{sid}GET /v2/organizations/{sid}
GET /{apikey}/{mode}/organization_members/{sid}GET /v2/organizations/searchMembers?sid={sid}
(no v1 endpoint)GET /v2/organizations/search?...

Ships

v1v2
GET /{apikey}/{mode}/shipsGET /v2/ships

Query parameters are largely compatible. page and page_max are preserved.

Versions

v1v2
GET /{apikey}/{mode}/versionsGET /v2/versions
GET /{apikey}/{mode}/versions?filter=latestGET /v2/versions?filter=latest
(no v1 endpoint)GET /v2/versions?version=X.Y.Z

Roadmap

v1v2
GET /{apikey}/{mode}/roadmap/{board}GET /v2/roadmap/{board}

board values unchanged: starcitizen or squadron42. date_min, date_max, version query params are preserved.

Progress Tracker

v1v2
GET /{apikey}/{mode}/progress-trackerGET /v2/progress-tracker/teams
GET /{apikey}/{mode}/progress-tracker/{team_slug}GET /v2/progress-tracker/deliverables/{slug}
warning

/progress-tracker/progress-tracker/teams — the path suffix is required in v2.

Stats

v1v2
GET /{apikey}/{mode}/statsGET /v2/stats

New v2 query param: ?chart=hour|day|week|month.

Telemetry

v1v2
GET /{apikey}/{mode}/telemetry/{version}GET /v2/telemetry/{version}

timetable query param (DAY, WEEK, MONTH) is preserved.

Starmap

v1 used a single /{field} segment. v2 splits this into dedicated sub-routes.

v1v2
starmap/search?name=XGET /v2/starmap/search?q=X
starmap/systemsGET /v2/starmap/systems
starmap/star-system?code=XGET /v2/starmap/star-systems/{code}
starmap/object?code=XGET /v2/starmap/systems/{code}
starmap/affiliationsGET /v2/starmap/affiliations
starmap/speciesGET /v2/starmap/species
starmap/tunnelsGET /v2/starmap/tunnels

New v2-only endpoint: GET /v2/starmap/routes?from=SYS1&to=SYS2&ship_size=small

Me (API key info)

v1v2
GET /{apikey}/meGET /v2/me with x-api-key header
5. Response format

Success response

// v1
{
"success": 1,
"message": "ok",
"data": { ... },
"source": "live"
}

// v2
{
"success": true,
"message": "ok",
"data": { ... },
"updatedAt": "2024-01-15T12:00:00.000Z",
"expiresAt": "2024-01-15T13:00:00.000Z"
}
  • success is now a boolean (true/false), not an integer (1/0)
  • source is removed — replaced by updatedAt (when data was scraped) and expiresAt (when cache expires)
  • Both fields are ISO 8601 strings or null

Error response

// v1 — HTTP 200, success: 0
{
"success": 0,
"message": "Apikey is not correct.",
"data": null,
"source": null
}

// v2 — HTTP 401
{
"success": false,
"message": "Unauthorized",
"code": 401
}
  • v2 uses proper HTTP status codes — do not rely on HTTP 200 for all responses
  • Error body uses code (integer) instead of data: null + source: null

HTTP status codes

CodeMeaning
200Success
304Not Modified — If-None-Match matched ETag (see §8)
400Bad Request — invalid query params
401Unauthorized — missing or invalid API key
403Forbidden — account blocked or insufficient permissions
404Not Found
429Too Many Requests — quota or scrape rate limit exceeded
500Internal Server Error
6. Removed features

json_path query parameter

v1 supported ?json_path=$.data.some.path on all endpoints.

v2 does not support json_path. Filter client-side instead.

// v1
GET /apikey/live/ships?json_path=$.data[0].name

// v2 — simple case
const { data } = await res.json();
const name = data[0].name;

// v2 — complex filtering (use a library like jsonpath-plus)
import { JSONPath } from 'jsonpath-plus';
const names = JSONPath({ path: '$.data[?(@.size=="large")].name', json: body });

Gamedata endpoints

/gamedata/... routes were deprecated in v1 and are not present in v2.

7. Rate limiting changes
v1v2
Quota trackedPer live mode requestPer ?refresh=true request
Quota exceededHTTP 200, "success": 0HTTP 429
Global scrape limitNone60 scrapes/minute (shared, Redis-backed)
Privileged accountsSkip quota checksSame (handled server-side)

When you receive HTTP 429, back off and retry after the current minute window resets.

8. Conditional request headers

ETag support is preserved but semantics changed slightly.

Headerv1v2
ETagReturned on successReturned on success
If-None-MatchSupported → 304Supported → 304
If-MatchSupported → 412 on mismatchNot supported
Last-ModifiedNot returnedReturned
ExpiresNot returnedReturned

Send If-None-Match with the ETag from a previous response — if the data hasn't changed, the server returns 304 Not Modified with no body. Useful for polling without re-downloading unchanged data.

9. New features in v2

These endpoints did not exist in v1:

EndpointDescription
GET /v2/me/profileExtended profile including block status
DELETE /v2/meSoft-delete your account — preserves historical data
DELETE /v2/me/unregisterFull unregister — removes all personal data
POST /auth/renewRotate your API key without visiting the dashboard
GET /v2/starmap/routesRoute search between star systems
GET /health/checkPublic health check (MongoDB + Redis)
GET /statusQuota status and cache refresh info
GET /swaggerInteractive API explorer (Swagger UI)

All responses now include updatedAt and expiresAt — use these to drive smarter cache invalidation instead of guessing TTLs.


info

Need help? Join the community Discord server.