Decentralized Space Network API

Overview

The Decentralized Space Network API provides programmatic access to satellite pass prediction, reservation management, mission profile management, and file-transfer metadata for ground-station operations.

The API is intended for server-to-server integrations. File payloads are exchanged through S3 buckets; the API stores and reports metadata, ownership, reservation status, and delivery state.

Base path:

/orbapi

Authentication

All operational endpoints use API-token authentication.

Authorization: Bearer dsn_live_...

API tokens are scoped. A request is rejected if the token does not include the scope required by the endpoint.

Common scopes:

ScopePurpose
passes:readSearch satellite passes
bookings:createCreate bookings and attach uplink files
bookings:cancelCancel bookings
mission-profile:createCreate, read, and delete mission profiles

Conventions

All request and response bodies are JSON unless otherwise stated.

Timestamps use ISO 8601 UTC format:

2026-05-06T10:00:00Z

Errors use the following general shape:

{
  "error": "Human-readable error message"
}

Common status codes:

StatusMeaning
200Request completed successfully
201Resource created successfully
400Invalid request
401Missing or invalid API token
403API token does not have the required scope
404Resource not found or not visible to the caller
500Internal server error

Satellite Pass Search

Searches predicted visibility passes for one satellite across one or more ground stations.

POST /orbapi/passes/search
Authorization: Bearer dsn_live_...

Purpose: Calculate upcoming visibility windows for a satellite from one or more ground stations.

Required scope:

passes:read

The request is per satellite. The satellite may be identified by NORAD ID or by raw TLE.

Search by NORAD ID:

{
  "noradId": 25544,
  "days": 7,
  "groundStationIds": ["1", "2"],
  "minElevationDeg": 10
}

Search by TLE:

{
  "tle": {
    "name": "SATELLITE NAME",
    "line1": "1 ...",
    "line2": "2 ..."
  },
  "days": 7,
  "groundStationIds": ["1"],
  "minElevationDeg": 10
}

Request fields:

FieldRequiredDescription
noradIdConditionalSatellite NORAD catalog ID. Required if tle is not provided.
tleConditionalRaw TLE object. Required if noradId is not provided or if a custom TLE should be used.
daysNoNumber of days to search. Defaults to 7, maximum 14.
startNoSearch start timestamp. Defaults to current time.
endNoSearch end timestamp. Capped to start + 14 days.
groundStationIdsNoGround stations to include. If omitted, all configured stations with coordinates are used.
minElevationDegNoMinimum pass elevation in degrees. Defaults to 10.
stepSecondsNoCalculation step size. Allowed range is 15-300 seconds. Defaults to 60.

Response:

{
  "satellite": {
    "noradId": 25544,
    "name": "ISS",
    "tle": {
      "name": "ISS",
      "line1": "1 ...",
      "line2": "2 ..."
    }
  },
  "groundStations": [
    {
      "id": "1",
      "description": "Ground Station",
      "latitude": 42.0,
      "longitude": 23.0,
      "altitude": 500
    }
  ],
  "passes": [
    {
      "groundStationId": "1",
      "rise_time": "2026-05-06T10:00:00.000Z",
      "set_time": "2026-05-06T10:10:00.000Z",
      "aos": "2026-05-06T10:00:00.000Z",
      "los": "2026-05-06T10:10:00.000Z",
      "aos_azimuth": 183.1,
      "los_azimuth": 31.8,
      "max_elevation": 42.3,
      "max_elevation_time": "2026-05-06T10:05:00.000Z",
      "slant_range_km": 1250.4,
      "polar_track": [
        {
          "azimuth": 183.1,
          "elevation": 0,
          "time": "2026-05-06T10:00:00.000Z"
        }
      ]
    }
  ],
  "total": 1,
  "generated_at": "2026-05-05T12:00:00.000Z"
}

Bookings

Bookings reserve one or more pass windows for a satellite and mission type.

Create Booking

POST /orbapi/bookings
Authorization: Bearer dsn_live_...

Purpose: Reserve one or more ground-station pass windows for a satellite mission.

Required scope:

bookings:create

Request:

{
  "norad_cat_id": 25544,
  "type": "data",
  "slots": [
    {
      "start": "2026-05-06T10:00:00Z",
      "end": "2026-05-06T10:10:00Z",
      "gs_id": "1"
    }
  ],
  "uplinkFile": {
    "key": "clients/client_123/bookings/42/uplink.bin",
    "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
  }
}

Request fields:

FieldRequiredDescription
norad_cat_idYesSatellite NORAD catalog ID.
typeYesMission type. Currently data or lora.
slotsYesRequested reservation windows.
slots[].startYesSlot start timestamp.
slots[].endYesSlot end timestamp.
slots[].gs_idYesGround station ID.
uplinkFileNoOptional uplink object metadata to attach during booking creation.
uplinkFile.keyYes, if uplinkFile is presentObject key in the DSN S3 bucket.
uplinkFile.sha256NoOptional SHA-256 checksum as 64 hexadecimal characters.

Response:

{
  "status": "success",
  "bookingId": 42,
  "missionId": 42,
  "uplinkFile": {
    "id": 1,
    "missionId": 42,
    "direction": "uplink",
    "s3Key": "clients/client_123/bookings/42/uplink.bin",
    "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
    "status": "pending",
    "createdAt": "2026-05-05T12:00:00.000Z",
    "updatedAt": "2026-05-05T12:00:00.000Z"
  }
}

If no uplink file is supplied, uplinkFile is null.

List Bookings

GET /orbapi/bookings
Authorization: Bearer dsn_live_...

Purpose: Return the caller's current and historical bookings, including reserved slots.

Response:

{
  "bookings": [
    {
      "id": 42,
      "bookingId": 42,
      "missionId": 42,
      "ownerId": "client_123",
      "ownerType": "api_token",
      "noradId": "25544",
      "type": "data",
      "status": "Pending",
      "requestedAt": "2026-05-05T12:00:00.000Z",
      "slots": [
        {
          "id": 100,
          "missionId": 42,
          "gsId": "1",
          "start": "2026-05-06T10:00:00.000Z",
          "end": "2026-05-06T10:10:00.000Z",
          "status": "Pending"
        }
      ]
    }
  ]
}

Cancel Booking

DELETE /orbapi/bookings/:bookingId
Authorization: Bearer dsn_live_...

Purpose: Cancel a booking owned by the authenticated API-token caller.

Required scope:

bookings:cancel

Response:

{
  "status": "success",
  "message": "Booking cancelled successfully",
  "bookingId": 42,
  "missionId": 42
}

Mission Profiles

Mission profiles store arbitrary JSON configuration for a satellite. Because satellite ownership is not assumed by the API, multiple clients may create independent profiles for the same satellite.

Create Mission Profile

POST /orbapi/satellites/id/:noradId/profiles
Authorization: Bearer dsn_live_...

Purpose: Store a caller-owned mission configuration profile for a satellite.

Required scope:

mission-profile:create

Request:

{
  "name": "Primary data profile",
  "profile": {
    "radio": {
      "frequencyHz": 437000000,
      "modulation": "GMSK",
      "baud": 9600
    }
  }
}

The profile wrapper is optional. If omitted, the full request body is stored as profile JSON.

Response:

{
  "status": "success",
  "profile": {
    "id": 12,
    "satelliteNoradId": 25544,
    "name": "Primary data profile",
    "profile": {
      "radio": {
        "frequencyHz": 437000000,
        "modulation": "GMSK",
        "baud": 9600
      }
    },
    "createdBy": "client_123",
    "createdByType": "api_client",
    "createdAt": "2026-05-05T12:00:00.000Z",
    "updatedAt": "2026-05-05T12:00:00.000Z"
  }
}

List Mission Profiles For Satellite

GET /orbapi/satellites/id/:noradId/profiles
Authorization: Bearer dsn_live_...

Purpose: List mission profiles for the requested satellite that are visible to the caller.

Response:

{
  "noradId": 25544,
  "profiles": [
    {
      "id": 12,
      "satelliteNoradId": 25544,
      "name": "Primary data profile",
      "profile": {},
      "createdAt": "2026-05-05T12:00:00.000Z",
      "updatedAt": "2026-05-05T12:00:00.000Z"
    }
  ]
}

Get Mission Profile

GET /orbapi/satellites/profiles/:profileId
Authorization: Bearer dsn_live_...

Purpose: Fetch one mission profile by its profile ID.

Response:

{
  "profile": {
    "id": 12,
    "satelliteNoradId": 25544,
    "name": "Primary data profile",
    "profile": {}
  }
}

Delete Mission Profile

DELETE /orbapi/satellites/profiles/:profileId
Authorization: Bearer dsn_live_...

Purpose: Delete a mission profile owned by the caller, or any profile when using a service token.

Response:

{
  "status": "success",
  "message": "Mission profile deleted successfully",
  "profileId": 12
}

Uplink File Metadata

The API does not accept file uploads directly. Uplink payloads are delivered to the DSN S3 bucket by the client-side transfer process. The API records the S3 object key and marks the file as pending.

Attach Uplink File After Booking

POST /orbapi/bookings/:bookingId/uplink-files
Authorization: Bearer dsn_live_...

Purpose: Attach uplink S3 object metadata to an existing booking.

Required scope:

bookings:create

Request:

{
  "key": "clients/client_123/bookings/42/uplink.bin",
  "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
}

Response:

{
  "status": "success",
  "bookingId": 42,
  "missionId": 42,
  "uplinkFile": {
    "id": 1,
    "missionId": 42,
    "direction": "uplink",
    "s3Key": "clients/client_123/bookings/42/uplink.bin",
    "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
    "status": "pending",
    "createdAt": "2026-05-05T12:00:00.000Z",
    "updatedAt": "2026-05-05T12:00:00.000Z"
  }
}

File status values:

StatusMeaning
pendingMetadata has been accepted; object verification has not completed.
availableObject is available for ground-station use.
consumedObject has been used by the ground-station workflow.
failedObject verification or use failed.
deliveredDownlink object has been delivered to the client bucket.

List Uplink Files

GET /orbapi/bookings/:bookingId/uplink-files
Authorization: Bearer dsn_live_...

Purpose: List uplink file metadata attached to a booking.

Response:

{
  "bookingId": 42,
  "missionId": 42,
  "files": [
    {
      "id": 1,
      "missionId": 42,
      "direction": "uplink",
      "s3Key": "clients/client_123/bookings/42/uplink.bin",
      "sha256": null,
      "status": "pending",
      "createdAt": "2026-05-05T12:00:00.000Z",
      "updatedAt": "2026-05-05T12:00:00.000Z"
    }
  ]
}

Downlink File Metadata

Downlink file contents are delivered to the client S3 bucket by the DSN delivery process. The API is used for status and metadata only.

List Downlink Files

GET /orbapi/bookings/:bookingId/downlink-files
Authorization: Bearer dsn_live_...

Purpose: List downlink file metadata produced for a booking.

Response:

{
  "bookingId": 42,
  "missionId": 42,
  "files": [
    {
      "id": 2,
      "missionId": 42,
      "direction": "downlink",
      "s3Key": "clients/client_123/downlink/booking-42/data.bin",
      "sha256": null,
      "status": "delivered",
      "createdAt": "2026-05-06T10:20:00.000Z",
      "updatedAt": "2026-05-06T10:21:00.000Z"
    }
  ]
}

Reference Data

Satellites

GET /orbapi/satellites

Purpose: List satellites available in the catalog.

Example:

GET /orbapi/satellites?start=0&limit=20

Result:

{
  "data": [
    {
      "norad_cat_id": 25544,
      "name": "ISS",
      "names": "ISS (ZARYA)",
      "status": "alive"
    }
  ],
  "total": 1
}
GET /orbapi/satellites/id/:noradId

Purpose: Fetch one satellite by NORAD catalog ID.

Example:

GET /orbapi/satellites/id/25544

Result:

{
  "data": [
    {
      "norad_cat_id": 25544,
      "name": "ISS",
      "names": "ISS (ZARYA)",
      "status": "alive"
    }
  ],
  "total": 1
}
GET /orbapi/satellites/name/:name

Purpose: Search satellites by name.

Example:

GET /orbapi/satellites/name/ISS

Result:

{
  "data": [
    {
      "norad_cat_id": 25544,
      "name": "ISS",
      "names": "ISS (ZARYA)",
      "status": "alive"
    }
  ],
  "total": 1
}

TLEs

GET /orbapi/tles

Purpose: List current TLE records.

Example:

GET /orbapi/tles?start=0&limit=20

Result:

{
  "data": [
    {
      "id": 25544,
      "name": "ISS",
      "tle0": "ISS (ZARYA)",
      "tle1": "1 ...",
      "tle2": "2 ..."
    }
  ],
  "total": 1
}
GET /orbapi/tles/id/:noradId

Purpose: Fetch the TLE for one satellite by NORAD catalog ID.

Example:

GET /orbapi/tles/id/25544

Result:

{
  "data": [
    {
      "id": 25544,
      "name": "ISS",
      "tle0": "ISS (ZARYA)",
      "tle1": "1 ...",
      "tle2": "2 ..."
    }
  ],
  "total": 1
}
GET /orbapi/tles/name/:name

Purpose: Search TLE records by satellite name.

Example:

GET /orbapi/tles/name/ISS

Result:

{
  "data": [
    {
      "id": 25544,
      "name": "ISS",
      "tle0": "ISS (ZARYA)",
      "tle1": "1 ...",
      "tle2": "2 ..."
    }
  ],
  "total": 1
}

Ground Stations

GET /orbapi/gs

Purpose: List ground stations in the network.

Example:

GET /orbapi/gs?start=0&limit=20

Result:

{
  "data": [
    {
      "id": "3886",
      "description": "DSN Stob W1AW 2m dish and 70GHz V-band",
      "latitude": 42.09963,
      "longitude": 23.106661,
      "altitude": 472
    }
  ],
  "total": 1
}
GET /orbapi/gs/id/:id

Purpose: Fetch one ground station by ID.

Example:

GET /orbapi/gs/id/1

Result:

{
  "data": [
    {
      "id": "1",
      "description": "Ground Station",
      "latitude": 42.0,
      "longitude": 23.0,
      "altitude": 500
    }
  ],
  "total": 1
}
GET /orbapi/gs/id/:id/status

Purpose: Report command-broker heartbeat status for a ground station.

Example:

GET /orbapi/gs/id/1/status

Result:

{
  "groundStation": {
    "id": "1",
    "description": "Ground Station"
  },
  "host": "1",
  "online": true,
  "status": "online",
  "lastSeenAt": "2026-05-05T12:00:00.000Z",
  "lastSeenAgeMs": 1200,
  "queueDepth": 0
}
GET /orbapi/gs/description/:description

Purpose: Search ground stations by description.

Example:

GET /orbapi/gs/description/Sofia

Result:

{
  "data": [
    {
      "id": "4567",
      "description": "DSN Sofia Tech Park LoRa and X-band/V-band reflector",
      "latitude": 42.667693,
      "longitude": 23.373397,
      "altitude": 630
    }
  ],
  "total": 1
}

Ground-station status is based on the command-broker heartbeat. Each time a station polls the broker for pending commands, the station lastSeenAt timestamp is updated.

{
  "groundStation": {
    "id": "1",
    "description": "Ground Station"
  },
  "host": "1",
  "online": true,
  "status": "online",
  "lastSeenAt": "2026-05-05T12:00:00.000Z",
  "lastSeenAgeMs": 1200,
  "queueDepth": 0
}

Transmitters

GET /orbapi/transmitters

Purpose: List transmitter records.

Example:

GET /orbapi/transmitters?start=0&limit=20

Result:

{
  "data": [
    {
      "uuid": "ZzPz4gcsNBPKPKAFPmer7g",
      "description": "DSN Stob LoRa(868MHz) band",
      "mode": "LoRa",
      "mode_id": 89,
      "gs_id": "3886",
      "status": "active"
    }
  ],
  "total": 1
}
GET /orbapi/transmitters/id/:noradCatId

Purpose: List transmitters associated with a satellite NORAD catalog ID.

Example:

GET /orbapi/transmitters/id/25544

Result:

{
  "data": [
    {
      "uuid": "sat-transmitter-uuid",
      "norad_cat_id": 25544,
      "description": "Satellite downlink",
      "mode": "LoRa",
      "mode_id": 89,
      "gs_id": null
    }
  ],
  "total": 1
}
GET /orbapi/transmitters/uuid/:uuid

Purpose: Fetch one transmitter by UUID.

Example:

GET /orbapi/transmitters/uuid/550e8400-e29b-41d4-a716-446655440000

Result:

{
  "data": [
    {
      "uuid": "550e8400-e29b-41d4-a716-446655440000",
      "description": "Transmitter",
      "mode": "LoRa",
      "mode_id": 89,
      "gs_id": "1"
    }
  ],
  "total": 1
}
GET /orbapi/transmitters/mode/:modeId

Purpose: List transmitters that support a mode such as lora or a numeric mode ID.

Example:

GET /orbapi/transmitters/mode/lora

Result:

{
  "data": [
    {
      "uuid": "ZzPz4gcsNBPKPKAFPmer7g",
      "description": "DSN Stob LoRa(868MHz) band",
      "mode": "LoRa",
      "mode_id": 89,
      "gs_id": "3886"
    }
  ],
  "total": 1
}
GET /orbapi/transmitters/id/:noradCatId/mode/:modeId

Purpose: List transmitters for one satellite filtered by mode.

Example:

GET /orbapi/transmitters/id/25544/mode/lora

Result:

{
  "data": [
    {
      "uuid": "sat-transmitter-uuid",
      "norad_cat_id": 25544,
      "description": "Satellite LoRa downlink",
      "mode": "LoRa",
      "mode_id": 89
    }
  ],
  "total": 1
}
GET /orbapi/transmitters/gs/:gsId

Purpose: List transmitters associated with a ground station.

Example:

GET /orbapi/transmitters/gs/1

Result:

{
  "data": [
    {
      "uuid": "ground-station-transmitter-uuid",
      "description": "Ground station transmitter",
      "mode": "LoRa",
      "mode_id": 89,
      "gs_id": "1"
    }
  ],
  "total": 1
}
GET /orbapi/transmitters/gs/:gsId/mode/:modeId

Purpose: List ground-station transmitters filtered by mode.

Example:

GET /orbapi/transmitters/gs/1/mode/lora

Result:

{
  "data": [
    {
      "uuid": "ground-station-transmitter-uuid",
      "description": "Ground station LoRa transmitter",
      "mode": "LoRa",
      "mode_id": 89,
      "gs_id": "1"
    }
  ],
  "total": 1
}