API Reference
REST API for the AT1AS v2 server (Rust / Axum / Postgres). All responses are JSON.
- Base URL (dev):
http://127.0.0.1:8080(use127.0.0.1, notlocalhost) - Auth: session-token bearer header on protected routes:
Authorization: Bearer <token>(obtained from register/login) - Bodies:
Content-Type: application/json :idparams marked (id|code) accept either a numeric id or a text code (e.g./api/station/terraor/api/station/1).
Error formatโ
Every handler error returns:
{ "error": { "code": "...", "message": "..." } }
| code | HTTP | meaning |
|---|---|---|
bad_request | 400 | invalid input / rule violation |
unauthorized | 401 | missing/invalid token or bad credentials |
not_found | 404 | resource (or owned ship) doesn't exist |
conflict | 409 | uniqueness clash (email/username) |
internal | 500 | unexpected server/DB error |
Note: an unmatched path currently returns a bare
404with empty body (no global JSON fallback yet).
Legendโ
๐ public ยท ๐ requires auth ยท ๐ค requires auth and ownership of the ship ยท โ ship must be docked ยท ๐ญ station must offer the noted service
Auth & accountโ
POST /api/user/register ๐โ
Create an account. Bootstraps a full starting state in one transaction: user + player character + wallet (50,000 โก) + a starter shuttle docked at Terra + 3 NPC crew (pilot/engineer/gunner).
// body
{ "email": "pilot@at1as.test", "password": "min8chars" }
// 200
{ "token","user_id","expires_at","character_id","credits":50000,
"ship": { "ship_id","name","hull","hp","station" },
"crew": [ { "character_id","name","role" } ] }
409 if the email is already registered.
POST /api/user/login ๐โ
{ "email","password" } // body
{ "token","user_id","expires_at" } // 200 ยท 401 on bad credentials
POST /api/user/logout ๐โ
Deletes the presented session token. โ { "ok": true, "ended": <n> }
POST /api/user/forgot ๐โ
{ "email" } โ { "ok": true, "reset_token"? } (token returned only in dev; never reveals whether the account exists).
GET /api/user/oauth?provider=google ๐โ
Stub. Returns { provider, configured:false, status:"not_configured", authorize_url, redirect_uri }.
GET /api/user/me ๐โ
The account: user + each character with wallet + ship count.
{ "user": { "id","email","username","status","created_at","last_login_at" },
"characters": [ { "character_id","name","kind","archetype",
"wallet": { "credits","tokens" }, "ship_count" } ] }
POST /api/user/username ๐โ
{ "username" } (3โ32 chars) โ { "ok":true, "username" } ยท 409 if taken.
POST /api/user/password ๐โ
{ "current_password","new_password" } (new โฅ 8). Verifies the current password, then revokes all sessions. โ { "ok":true, "sessions_revoked":true } ยท 401 if the current password is wrong.
GET /api/wallet ๐โ
โ { "character_id","credits","tokens" }
GET /api/standing ๐โ
Faction reputation (signed; 0 = neutral). โ { "standing": [ { "faction","name","value" } ] }
GET /api/transactions ๐โ
The caller's ledger, most-recent first (capped 100). Each row: { id, ts, kind, item, qty, unit_price, credits_amount, station_id, role } (role = buyer/seller/party).
Shipsโ
GET /api/ship/list ๐โ
Every ship owned by the caller. โ { "count", "ships": [ <ship object> ] }
GET /api/ship/:id ๐โ
Full ship object (see Ship object). 404 if missing.
POST /api/ship/buy ๐ โ๐ญshipyardโ
Buy a hull from a colony's shipyard stock; the new ship docks at that colony.
{ "colony":"pallas", "hull":"gunship" } // body
{ "ship_id","hull","name","station","credits_spent","wallet_credits" }
400 if the colony has no shipyard service, no stock, or you can't afford it.
POST /api/ship/:id/rename ๐คโ
{ "name" } (โค48) โ { "ship_id","name" }
POST /api/ship/:id/dock ๐คโ
{ "station": "(id|code)" } โ { "ship_id","status":"docked","station":{id,code,name} }
POST /api/ship/:id/undock ๐คโ
โ { "ship_id","status":"flying" }
POST /api/ship/:id/refuel ๐ค โ๐ญrefuelโ
Buy reaction mass / fusion fuel into the ship's tanks. Priced per-kg from item_types.base_price รท mass_kg_per_unit.
{ "remass_kg"?: 2000, "fusion_kg"?: 0 }
{ "ship_id","remass_kg","fusion_kg","credits_spent","wallet_credits" }
POST /api/ship/:id/provision ๐ค โ๐ญmarketโ
Stock the food / water tanks (life-support stores, separate from cargo/fuel); capped by the hull's food_cap_kg/water_cap_kg.
{ "food_kg"?: 4000, "water_kg"?: 5000 }
{ "ship_id","food_kg","water_kg","credits_spent","wallet_credits" }
POST /api/ship/:id/repair ๐ค โ๐ญrepairโ
Restore hp to max (50 โก/hp). โ { "ship_id","hp","max_hp","credits_spent","wallet_credits" }
POST /api/ship/:id/transfer ๐ค โโ
Move cargo between the ship hold and the station hangar. Loading enforces the hull's cargo_cap_kg.
{ "item_type":"(id|code)", "qty":50, "direction":"hangar_to_hold"|"hold_to_hangar" }
{ "ship_id","item_type_id","qty","direction" }
POST /api/ship/:id/sell ๐ค โ๐ญshipyardโ
Sell the ship for 60% of hull base price. Requires an empty hold. Hull returns to the local yard's stock if the station backs a colony. โ { "sold_ship_id","hull","credits_gained","wallet_credits","returned_to_yard","fleet_remaining" }
Outfittingโ
All mutating refits are ๐ค โ๐ญshipyard.
GET /api/ship/:id/loadout ๐คโ
โ { ship_id, drive, drive_name, armor, hp, max_hp, hull, hull_size, slots, used_slots, weapons:[ { slot, weapon_id, name, class, damage, tier } ] }
Hull-size ladder: shuttle < light < gunship < cruiser < capital. Hardpoints by size: 1 / 2 / 3 / 4 / 6.
POST /api/ship/:id/armorโ
{ "tiers"?: 1 } โ each tier +500 hp & max_hp, costs 5,000 โก. โ { ship_id, armor, hp, max_hp, credits_spent, wallet_credits }
POST /api/ship/:id/driveโ
{ "drive_type":"fusion_torch" } โ cost = 20,000 ร drive tier. โ { ship_id, drive, drive_name, credits_spent, wallet_credits }
POST /api/ship/:id/mountโ
{ "weapon_id":"torpedo", "slot"?: 0 } โ cost = 10,000 ร weapon tier. The weapon's min_hull must fit the hull; omit slot to use the lowest free hardpoint. โ { ship_id, weapon_id, slot, credits_spent, wallet_credits }
POST /api/ship/:id/unmountโ
{ "slot": 0 } โ refunds 5,000 ร tier. โ { ship_id, weapon_id, slot, refund, wallet_credits }
Crew & life supportโ
GET /api/ship/:id/lifesupport ๐คโ
Age-scaled per-cycle ration need and how long the tanks last. โ { ship_id, crew, food_kg, food_cap_kg, water_kg, water_cap_kg, food_need_per_cycle, water_need_per_cycle, cycles_of_supply, starve_cycles, starving } (cycles_of_supply = -1 when there's no crew.)
GET /api/ship/:id/crew ๐คโ
โ { ship_id, crew:[ { character_id, name, role, age, status, wage_credits, share_bps } ] }
POST /api/ship/:id/crew ๐ค โ (hire)โ
Mints an NPC and berths them. Roles: pilot|engineer|gunner|medic|quartermaster|scientist|deckhand. Cap 8 active crew.
{ "role":"medic", "name"?: "Doc", "wage_credits"?: 0, "share_bps"?: 0 }
{ "character_id","name","role","ship_id" }
DELETE /api/ship/:id/crew/:character_id ๐ค (fire)โ
โ { ship_id, character_id, fired:true }
POST /api/ship/:id/crew/:character_id/role ๐คโ
{ "role" } โ { ship_id, character_id, role }
Stations & marketsโ
GET /api/station/list ๐โ
โ { count, stations:[ <station object> ] }
GET /api/station/:id ๐ (id|code)โ
Full station object: { id, code, name, faction, sec_level, parent_body, orbit_radius_km, position, services[], fees{tax_bp,broker_fee_bp}, colony, ships_docked, open_order_count }.
GET /api/market/list ๐โ
Stations offering a market, with summaries. โ { count, markets:[ { station, fees, open_order_count, items_traded } ] }
GET /api/market/:id ๐ (id|code)โ
A station's full order book, grouped per item with bids/asks and best bid/ask. โ { station, fees, open_order_count, book:[ { item_type_id, code, name, base_price, best_bid, best_ask, bids[], asks[] } ] }
GET /api/market/resource/:id ๐ (item id|code)โ
Cross-market view for one commodity: where to buy (cheapest sells) and sell (highest buys). โ { resource, best_buy_price, best_sell_price, buy_from:[ { station, best_price, total_qty, orders } ], sell_to:[ { station, best_price, total_qty, orders } ] }
GET /api/market/orders ๐โ
The caller's own open resting orders. โ { orders:[ { order_id, station, item, side, price, qty_remaining, qty_original, status, created_at } ] }
POST /api/market/buy ๐ ๐ญmarketโ
Instantly buy, crossing the cheapest asks (โค limit_price if given). Goods land in your hangar at that station.
{ "station":"(id|code)", "item":"(id|code)", "qty":100, "limit_price"?: 50 }
{ "filled","requested","credits_spent","avg_price","wallet_credits","delivered_to" }
POST /api/market/sell ๐ ๐ญmarketโ
Instantly sell from your hangar, crossing the highest bids (โฅ limit_price). โ { filled, requested, credits_gained, avg_price, wallet_credits }
POST /api/market/order ๐ ๐ญmarketโ
Place a resting limit order with escrow (sell escrows goods, buy escrows credits).
{ "station","item","side":"buy"|"sell","price","qty" }
{ "order_id","side","price","qty","station","item","status":"open" }
POST /api/market/order/:id/cancel ๐โ
Cancel your open order; refunds the escrow. โ { ok:true, order_id, refunded_qty }
Inventoryโ
GET /api/inventory/ship/:id ๐คโ
โ { ship_id, name, cargo_cap_kg, used_mass_kg, items:[ { item_id, item_type_id, code, name, qty, unit, mass_kg } ] }
GET /api/inventory/station/:id ๐ (id|code)โ
The caller's goods stored at a station hangar. โ { station, items:[ โฆ ] }
World (reads) ๐โ
GET /api/character/:idโ
{ id, user_id, kind, name, archetype, religion, status, sex, age, home_colony, home_station, wallet, ship_count, crew_berth, created_at } ยท 404 if missing.
GET /api/colony/listโ
{ count, colonies:[ { code, name, body, type, owner_corp, population, security, food_stock, station, corp } ] } (population desc).
GET /api/colony/:codeโ
A colony plus trade: { produces:[], needs:[] }.
GET /api/faction/listโ
{ count, factions:[ { id, code, name, description } ] }
GET /api/corp/list ยท GET /api/corp/:codeโ
Corps; the fetch adds relations[] (corp_relations) and colonies[] owned.
Catalogs (reference data) ๐โ
| Endpoint | Returns |
|---|---|
GET /api/catalog/items | every item_types row (goods + hull stats) |
GET /api/catalog/hulls | ships only โ hp, weapon, dry mass, cargo/food/water caps, price |
GET /api/catalog/weapons | weapon catalog (class, tier, damage, range, guided, cooldown, ammo, min_hull) |
GET /api/catalog/drives | drives + their fuels[] and refuel_sources[] |
GET /api/catalog/fuels | fuels + sources[] |
Contracts (jobs)โ
GET /api/contract/list?status=&type= ๐โ
Open contracts by default; filter by status/type. โ { count, contracts:[ โฆ ] }
POST /api/contract ๐โ
Post a job. Escrows reward_credits from your wallet. Types: haul|mine|bounty|escort|salvage|supply.
{ "type","target"?,"pickup_location"?,"dropoff_location"?,"reward_credits","expires_at"? }
{ "contract_id","type","reward_credits","status":"open" }
POST /api/contract/:id/accept ๐โ
Take an open contract (not your own). โ { contract_id, status:"taken" }
POST /api/contract/:id/complete ๐โ
Taker marks done and is paid the escrowed reward. โ { contract_id, status:"done", reward_paid, wallet_credits }
Simplified: does not yet verify actual delivery (needs movement).
POST /api/contract/:id/abandon ๐โ
Taker drops it; resets to open (escrow stays). โ { contract_id, status:"open" }
Miscโ
GET /healthz ๐ โ { ok:true, db:true }โ
GET /ws ๐ โ WebSocket upgrade (echo/hello for now; not yet a real channel)โ
Ship objectโ
Returned by GET /api/ship/:id and each entry of GET /api/ship/list. Keys are alphabetised (serialised from Postgres jsonb).
{
"id", "name", "status", // docked|flying|destroyed
"owner": { "character_id","name","kind","user_id" } | null,
"hull": { "id","code","name","category","base_price","hp","weapon" },
"station": { "id","code","name" } | null,
"position": { "x","y" }, "velocity": { "x","y" }, // FixedCoord mm, mm/s
"mass": { "dry_mass_kg","cargo_cap_kg" },
"propulsion": { "drive_type","remass_kg","fusion_kg","dv_used" },
"provisions": { "food_kg","food_cap_kg","water_kg","water_cap_kg" },
"combat": { "hp","max_hp","armor","last_aggro_at" },
"starve_cycles",
"crew": [ { "character_id","name","role","age","status","wage_credits","share_bps" } ],
"weapons": [ { "slot","weapon_id","name","class","damage" } ],
"created_at", "updated_at"
}
Not yet implementedโ
Movement / flight (set-course, telemetry) ยท mining & prospecting ยท combat (attack, kill-feed) ยท refine/manufacture ยท NPC market-maker (books are hand-seeded) ยท life-support consume tick ยท real WebSocket channels + WS auth ยท OAuth callback ยท password-reset completion ยท pagination / idempotency / TLS.