Jump to content

SimTX API/Station endpoints

From SimTX Wiki
Revision as of 16:27, 24 October 2026 by Clanker (talk | contribs) (Protocol v25 reference)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The station endpoints of the account service create, read, edit and delete an account's persistent stations, launch satellites and deorbit them. A station belongs to the account, not to a game server; game sessions attach to it with a station-bound game ticket.

All endpoints take a bearer credential (an access credential or a personal credential) on https://auth.simtx.net. Service credentials are refused with 403 account_credential_required.

Endpoints

Method and path Scope Result
GET /api/v1/stations Any 200 {"stations": [Station]}: your stations
POST /api/v1/stations station.manage 201 Station: create a ground station
GET /api/v1/stations/{id} Any 200 Station
PATCH /api/v1/stations/{id} station.manage 200 Station
DELETE /api/v1/stations/{id} station.manage 204
POST /api/v1/stations/{id}/antennas station.manage 201 Station (ground stations only)
PATCH, DELETE /api/v1/stations/{id}/antennas/{antennaId} station.manage 200 Station
POST /api/v1/stations/{id}/rigs station.manage 201 Station (ground stations only)
PATCH, DELETE /api/v1/stations/{id}/rigs/{rigId} station.manage 200 Station
POST /api/v1/satellites station.manage 201 Station: launch a satellite
POST /api/v1/stations/{id}/deorbit/preview Any 200 Deorbit: what a burn now would do
POST /api/v1/stations/{id}/deorbit station.manage 200 Station: fire the deorbit burn
GET /api/v1/satellites None (public) 200 {"satellites": [SatelliteCatalogEntry]}; see Public endpoints

"Any" means any account credential, without a particular scope. A write with a credential whose scope lacks station.manage is refused with 403 scope_required and fieldErrors.scope = "station.manage"; sign the user in again with the wider scope. An account without the permission gets 403 permission_denied. Rate limits: 240 reads and 120 writes per minute per IP address.

The Station object

{
  "stationId": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
  "ownerAccountId": "0f8e2c4a-1b3d-4e5f-8a9b-0c1d2e3f4a5b",
  "ownerHandle": "n0call",
  "kind": "GROUND",
  "state": "ACTIVE",
  "name": "Home",
  "callsign": "N0CALL",
  "visibility": "UNLISTED",
  "revision": 3,
  "limits": { "maxSessions": 16, "maxTransmitters": 4, "maxReceivers": 16 },
  "location": { "latitudeDeg": 47.4979, "longitudeDeg": 19.0402, "altitudeMeters": 120.0 },
  "antennas": [
    {
      "antennaId": "9b2c1e47-2f0a-4c55-8d1e-6a7b8c9d0e1f",
      "name": "40 m dipole", "ordinal": 0, "revision": 1,
      "type": "DIPOLE", "heightMeters": 10.0, "azimuthDeg": 90.0,
      "feedlineLossDb": 1.0, "wireLengthMeters": 0.0, "mount": "FIXED"
    }
  ],
  "rigs": [
    {
      "rigId": "c41d7a52-0e3b-4f6a-9c8d-1b2a3c4d5e6f",
      "name": "100 W transceiver", "revision": 1,
      "paMaxWatts": 100.0, "noiseFigureDb": 6.0,
      "tx": { "carrierLeakDb": 55.0, "oppositeSidebandSuppressionDb": 50.0 }
    }
  ],
  "createdAt": "2026-10-24T12:00:00Z",
  "updatedAt": "2026-10-24T12:30:00Z"
}
Field Type Description
stationId string (UUID) Never changes.
ownerAccountId, ownerHandle string The owning account.
kind string GROUND or SATELLITE.
state string ACTIVE, DEORBITING or DEORBITED. Ground stations are always ACTIVE.
name, callsign string 1 to 64 characters each.
visibility string PUBLIC or UNLISTED. See Visibility.
revision integer Increases with every edit of the station.
limits object maxSessions, maxTransmitters, maxReceivers, each 0 to 10,000, clamped to the owner's game.station_sessions.N.
location object Ground stations: latitudeDeg (−90 to 90), longitudeDeg (−180 to 180), altitudeMeters (−500 to 10,000).
orbit, attitude object Satellites. See Orbit and attitude.
deorbit object Satellites whose deorbit burn has fired. See Deorbiting.
antennas array 1 to 8 antennas (satellites: 1 to 4). See Antennas and rigs.
rigs array 0 to 8 rigs.
createdAt, updatedAt, launchedAt, deorbitedAt string Timestamps; launchedAt and deorbitedAt for satellites.

Antennas and rigs

An antenna has antennaId, name (at most 64 characters), ordinal (its position; the first antenna is the default for tickets), revision, and the fields of the game protocol's AntennaConfig in camelCase:

Field Description
type An antenna type name.
heightMeters ≥ 0. Default 10 for ground stations, 0 for satellites.
azimuthDeg −360 to 360.
feedlineLossDb ≥ 0. Default 1 for ground stations, 0 for satellites.
wireLengthMeters ≥ 0. 0 sizes the template for the operating frequency.
necDeck Optional NEC-2 deck, at most 262,144 bytes; replaces the template. Satellite decks must not contain a GN card. Read responses add necDeckSha256, the hex SHA-256 of the deck.
mount FIXED (default), AZ or AZEL.
pointing Steerable mounts only: mode (FIXED or TRACK), azimuthDeg (−360 to 360), elevationDeg (−90 to 90), targetStationId (required for TRACK), azimuthRateDegPerSec and elevationRateDegPerSec (0 to 360; 0 = default). A FIXED mount stores no pointing. See SimTX API/Tracking and pointing.

A rig is a saved radio profile: rigId, name, revision, paMaxWatts (0 to 10,000,000; default 100), noiseFigureDb (0 to 100; default 6), and tx, an object with the fifteen transmitter imperfection values in camelCase (finalDriveDb, paHeadroomDb, audioCompressionDb, paSoftness, paAmPmDeg, carrierLeakDb, oppositeSidebandSuppressionDb, frequencyOffsetHz, mainsHumDb, mainsHumHz, amModulationIndex, paSupplySagDb, txNoiseFloorDb, oscillatorPhaseNoiseDb, cwKeyRiseMs). Values left out take the generic HF preset.

Orbit and attitude

orbit holds the mean elements of the simtx-j2-v1 model: model (simtx-j2-v1), epoch (read-only), semiMajorAxisKm, eccentricity, inclinationDeg, raanDeg, argumentOfPerigeeDeg, meanAnomalyDeg.

attitude has a mode of NADIR, INERTIAL or SPIN and the fields of that mode: yawDeg; rightAscensionDeg, declinationDeg (−90 to 90), rollDeg; or spinAxis (NADIR, ORBIT_NORMAL, VELOCITY), spinRateRpm (0 to 60), spinPhaseDeg. See Attitude.

Listing stations

GET /api/v1/stations returns the account's stations, ground and satellite, including deorbited satellites that have not been deleted.

curl -s https://auth.simtx.net/api/v1/stations -H "Authorization: Bearer $SIMTX_TOKEN"

Creating a ground station

POST /api/v1/stations

{
  "name": "Home",
  "callsign": "N0CALL",
  "visibility": "UNLISTED",
  "location": { "latitudeDeg": 47.4979, "longitudeDeg": 19.0402, "altitudeMeters": 120.0 },
  "antennas": [ { "name": "40 m dipole", "type": "DIPOLE", "heightMeters": 10.0, "azimuthDeg": 90.0 } ],
  "rigs": [ { "name": "100 W transceiver", "paMaxWatts": 100.0, "noiseFigureDb": 6.0 } ]
}

name, callsign, location and at least one antenna are required. visibility defaults to UNLISTED, limits to 16 sessions, 4 transmitters and 16 receivers before clamping. A ground station is often a real address: clients should keep the UNLISTED default unless the user chooses otherwise.

Reading, editing and deleting

  • GET /api/v1/stations/{id} returns one station. Another account's station is 404 station_not_found.
  • PATCH /api/v1/stations/{id} takes any of name, callsign, visibility, limits and, for ground stations, location. Omitted fields keep their values. There is no cooldown on location changes.
  • DELETE /api/v1/stations/{id} deletes a ground station, or a satellite that has reentered (DEORBITED). An active or deorbiting satellite is refused with 409 satellite_active.

Every edit increases the station's revision. Sessions bound to the station either continue with the new values or end; see Edits while sessions run.

Antennas and rigs

Ground stations only; a launched satellite is sealed.

  • POST /api/v1/stations/{id}/antennas adds an antenna (at most 8). PATCH .../antennas/{antennaId} changes one; omitted fields keep their values. DELETE .../antennas/{antennaId} removes one; the last antenna cannot be removed (409 last_antenna).
  • POST /api/v1/stations/{id}/rigs adds a rig (at most 8). PATCH .../rigs/{rigId} changes one; a tx object replaces the stored imperfection values as a whole. DELETE .../rigs/{rigId} removes one.

Each returns the whole station.

Launching a satellite

POST /api/v1/satellites

{
  "name": "SimSat-1",
  "callsign": "SSAT1",
  "visibility": "PUBLIC",
  "orbit": {
    "model": "simtx-j2-v1",
    "semiMajorAxisKm": 6921.0, "eccentricity": 0.001, "inclinationDeg": 97.6,
    "raanDeg": 120.0, "argumentOfPerigeeDeg": 90.0, "meanAnomalyDeg": 10.0
  },
  "attitude": { "mode": "NADIR", "yawDeg": 0.0 },
  "antennas": [ { "name": "70 cm turnstile", "type": "TURNSTILE" } ],
  "rigs": [ { "name": "Beacon", "paMaxWatts": 2.0, "noiseFigureDb": 2.0 } ]
}
  • name, callsign, orbit and 1 to 4 antennas are required; up to 8 rigs.
  • The orbit is sent without epoch. The account service sets the epoch to the launch instant and interprets the elements at that instant.
  • The orbit must pass validation: model simtx-j2-v1, perigee at least 200 km and apogee at most 40,000 km above the 6,371 km sphere, 0 ≤ e < 1, 0 ≤ i ≤ 180°, finite angles, spin rate 0 to 60 rpm.
  • Satellite antennas are modelled in free space; their NEC decks must not contain a GN card.
  • After launch the satellite is sealed: only name, callsign, visibility and limits can change. Changes to the orbit, attitude, antennas or rigs are refused with 409 station_sealed.

Deorbiting

  • POST /api/v1/stations/{id}/deorbit/preview returns the Deorbit object that a burn fired now would produce, without changing anything. It needs no particular scope. Use it to show the user when and where the satellite would reenter before they confirm.
  • POST /api/v1/stations/{id}/deorbit fires the burn and returns the station, now DEORBITING, with its orbit replaced by the post-burn elements (epoch = burn time) and deorbit set. The burn is irreversible.
{
  "burnAt": "2026-10-24T12:00:00Z",
  "reentryAt": "2026-10-24T12:29:00Z",
  "reentryLocation": { "latitudeDeg": -12.3, "longitudeDeg": 101.7, "altitudeMeters": 80000.0 },
  "deltaVMps": 189.0,
  "orbit": {
    "model": "simtx-j2-v1", "epoch": "2026-10-24T12:00:00Z",
    "semiMajorAxisKm": 6596.0, "eccentricity": 0.0493, "inclinationDeg": 97.6,
    "raanDeg": 120.4, "argumentOfPerigeeDeg": 270.0, "meanAnomalyDeg": 180.0
  }
}
Field Description
burnAt When the burn fires (or fired).
reentryAt The first time after the burn that the height drops below 80 km. Sessions on the satellite end then, and it becomes DEORBITED.
reentryLocation The sub-satellite point at reentryAt; altitudeMeters is the 80 km interface.
deltaVMps Velocity change of the burn, m/s.
orbit The exact post-burn elements (epoch = burnAt) that the service stores, or would store. Draw the fall from them; do not re-plan the burn.

The values in the example are illustrative. Deorbiting a satellite that is already deorbiting is refused with 409 already_deorbiting, one that has reentered with 409 station_inactive, and a ground station with 400 station_invalid. See Deorbit.

Quotas

The number of stations an account may own is capped by numeric capabilities of the account: game.owned_stations.N for all active stations, ground and satellite, and game.owned_satellites.N for active satellites. Deorbiting satellites count until they reenter. game.station_sessions.N caps a station's session limits. Defaults: members 100, 25 and 16; supporters 500, 100 and 64. There are no cooldowns. A creation over a quota is refused with 409 station_quota_exceeded, with fieldErrors.capability and fieldErrors.limit.

Errors

HTTP code Meaning
400 station_invalid A field is invalid; message and fieldErrors name it.
403 scope_required The credential's scope lacks station.manage.
403 permission_denied The account lacks station.manage.
403 account_credential_required A service credential was used.
404 station_not_found Unknown station, or not yours.
409 station_sealed The change would modify a launched satellite.
409 station_inactive The satellite has reentered.
409 last_antenna A station keeps at least one antenna.
409 station_quota_exceeded fieldErrors name the capability and its limit.
409 satellite_active Delete refused; deorbit the satellite and wait for its reentry first.
409 already_deorbiting The burn has already fired.
413 request_too_large The body is over 2 MiB.
SimTX API reference (protocol v25)
Start OverviewQuick startFramingData typesPacket listSchemaLimits and errorsCompatibility and versioning
Account service OverviewDevice loginServer directoryStation endpointsGame ticketsPermissionsPublic endpoints
Game protocol Connection and handshakeSession statusReceiver sessionTransmitter sessionControl sessionCatalogModeration
Stations StationsSatellitesTracking and pointing
Connection ClientHelloPingServerHelloPongErrorBanner
Session AntennaPointingUpdateSessionStatus
Receiver ForwardedClientAddressReceiverStartReceiverRetuneIqStreamDescriptorIqBlock
Transmitter TransmitterStartSampleBlockTxUpdateTxModeInfoTxQueueTxAcceptTxTelemetryTxUpdateAck
Control ListStationsStartMonitorStopMonitorWeatherMapRequestServerHealthRequestCoverageMapRequestEphemerisRequestPassPredictionRequestStationListMonitorBlockMonitorEndWeatherMapResponseServerHealthReportCoverageMapResponseEphemerisResponsePassPredictionResponseMonitorAck
Catalog CatalogListRequestCatalogFetchCatalogUploadCatalogDeleteCatalogListCatalogEntryCatalogUploadResultCatalogDeleteResult
Moderation KickRequestIpModerationRequestBroadcastBannerKickResultIpModerationResultStationImpactList
Archive Protocol v24 reference