Video — entry 026 of 37
SWAPI
SWAPI.tech is an actively maintained REST rebuild of the classic SWAPI dataset, covering the same Star Wars people/films/planets/starships/vehicles but with its own schema (wrapped result/properties objects, stable uid identifiers) and ongoing support via Discord and GitHub. Unlike the frozen original swapi.dev, this one ships fixes and additions over time.
SWAPI.tech is an actively maintained REST rebuild of the classic SWAPI dataset -- Star Wars people, films, planets, starships, and vehicles -- wrapped in its own `{message, result}` envelope with stable `uid` identifiers, unlike the frozen original swapi.dev. No key is required for any read endpoint.
GreatAPIs Score
Auth quickstart
- No API key required. A live `GET /people/1` with no credentials or headers returned full character data this run, along with real `x-ratelimit-*` headers (see gotcha below) that only ever appear on unauthenticated, keyless traffic here.
Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.
Look up a person by ID
GEThttps://www.swapi.tech/api/people/1
{"message":"ok","result":{"properties":{"created":"2026-07-28T08:45:43.014Z","edited":"2026-07-28T08:45:43.014Z","name":"Luke Skywalker","gender":"male","skin_color":"fair","hair_color":"blond","height":"172","eye_color":"blue","mass":"77","homeworld":"https://www.swapi.tech/api/planets/1","birth_year":"19BBY","vehicles":["https://www.swapi.tech/api/vehicles/14","https://www.swapi.tech/api/vehicles/30"],"starships":["https://www.swapi.tech/api/starships/12","https://www.swapi.tech/api/starships/22"],"films":["https://www.swapi.tech/api/films/1","https://www.swapi.tech/api/films/2","https://www.swapi.tech/api/films/3","https://www.swapi.tech/api/films/6"],"url":"https://www.swapi.tech/api/people/1"},"_id":"5f63a36eee9fd7000499be42","description":"A person within the Star Wars universe","uid":"1","__v":4},"apiVersion":"1.0","timestamp":"2026-07-28T16:13:11.966Z","support":{"contact":"admin@swapi.tech","donate":"https://www.paypal.com/donate/?business=2HGAUVTWGR5T2&no_recurring=0&item_name=Support+Swapi+and+keep+the+galaxy%27s+data+free%21+Your+donation+fuels+open-source+innovation+and+helps+us+grow.+Thank+you%21+%F0%9F%9A%80¤cy_code=USD","partnerDiscounts":{"saberMasters":{"link":"https://www.swapi.tech/partner-discount/sabermasters-swapi","details":"Use this link to automatically get $10 off your purchase!"},"heartMath":{"link":"https://www.heartmath.com/ryanc","details":"Looking for some Jedi-like inner peace? Take 10% off your heart-brain coherence tools from the HeartMath Institute!"}}},"social":{"discord":"https://discord.gg/zWvA6GPeNG","reddit":"https://www.reddit.com/r/SwapiOfficial/","github":"https://github.com/semperry/swapi/blob/main/CONTRIBUTORS.md"}}Try it
Developer reference
https://www.swapi.tech/api- GET/people/{id}
- GET/films
Gotchas & limits
- Every response, including 404s, carries real, measured rate-limit headers -- `x-ratelimit-limit: 100`, `x-ratelimit-remaining`, and `x-ratelimit-reset` (a Unix timestamp). `x-ratelimit-remaining` does NOT count down monotonically across sequential calls this run -- it read 99, 99, 99, 99, then 97, 98, 96 across seven back-to-back probes, and the `x-ratelimit-reset` value jumped between two different timestamps rather than climbing smoothly. Combined with the `via: 2.0 heroku-router` header on every response, this is consistent with each request landing on one of several backend replicas that each track their own counter rather than one shared global count -- but that mechanism is an inference from the pattern, not something confirmed directly. A live `OPTIONS` preflight got no `x-ratelimit-*` headers at all. No documented request-per-window figure was found on the site itself; the `limit: 100` figure is measured behaviour, not a documented spec.
- Every JSON response, success or 404, is padded with unrelated marketing fields -- `support.donate` (a PayPal link), `support.partnerDiscounts`, and a `social` block of Discord/Reddit/GitHub links -- appended after the actual `result` payload. Code that does `Object.keys(response)` expecting just `message`/`result` will see 4-5 extra top-level keys on every single call.
- A nonexistent-but-well-formed numeric ID (`/people/999999`) and a non-numeric path segment (`/people/abc`) are both HTTP 404 with the identical body `{"message":"not found",...}` (plus the same marketing padding above) -- there is no distinction in the error body between "doesn't exist" and "malformed ID".
- `access-control-allow-origin: *` is sent unconditionally on every response this run, with or without an Origin header, including on 404s -- unlike several other keyless APIs in this catalogue whose CORS header only appears when the request itself carries an Origin.
- Plain `http://www.swapi.tech` is not redirected or blocked: a live `GET http://www.swapi.tech/api/people/1` returned the same HTTP 200 JSON (plus the same rate-limit headers) as the https:// version this run.