Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ManiFed/TTN/llms.txt

Use this file to discover all available pages before exploring further.

Node endpoints form the data backbone of The Telescope Net. Every Seestar telescope running the node agent communicates exclusively through these routes — from the one-time registration that provisions its identity, through nightly heartbeats and plan downloads, to the photometry measurements and FITS images that flow back to the cloud after each observation. All endpoints except POST /api/v1/nodes/register, GET /api/v1/nodes/pair/{token}, and GET /api/v1/aavso-files require the X-Node-Id and X-Api-Key headers issued at registration.

POST /api/v1/nodes/pair

Submit an activation code to a waiting node via a shared pairing token. The member app calls this endpoint after the user creates an activation code; the unregistered node polls GET /api/v1/nodes/pair/{token} to receive it.
Auth: Authorization: Bearer <token> (member)
pairing_token
string
required
The pairing token displayed by the unregistered node agent (format WORD-NNNN, e.g. NOVA-4821).
activation_code
string
required
The activation code in BS-YYYY-XXXXXXXX format to deliver to the node.

GET /api/v1/nodes/pair/

Poll for an activation code that the member app has pushed to this pairing token. The node agent calls this endpoint on a 30-second loop before it is registered. When a code is available it is returned and the entry is consumed — subsequent calls return {"code": null}.
Auth: None
token
string
required
The pairing token shown by the node agent (e.g. NOVA-4821). Case-insensitive.

POST /api/v1/nodes/register

Register a new node and obtain its permanent API credentials. This endpoint is called once during first-boot setup and requires an activation code rather than existing node credentials.
After registration succeeds, the node agent saves the returned node_id and api_key to data/cloud_state.json. All subsequent calls use those credentials. You should not call this endpoint again unless the state file is lost — if the same activation code is re-presented within 15 minutes of first use, the server will return the same credentials idempotently.
Auth: None — activation code in request body
activation_code
string
required
Single-use code in BS-YYYY-XXXXXXXX format obtained from a member’s account or an admin bulk-generation call.
latitude
float
required
Observatory latitude in decimal degrees. Must not be exactly 0.0 — the server rejects the null island.
longitude
float
required
Observatory longitude in decimal degrees.
telescope_model
string
Model name, e.g. "ZWO Seestar S50". Used to seed hardware spec defaults when not overridden by the activation code.
aperture_mm
float
Telescope aperture in millimetres (default 50.0 for Seestar S50).
focal_length_mm
float
Focal length in millimetres (default 250.0).
filter_set
string
JSON array string of photometric filter names, e.g. '["CV"]' or '["B","V","R","I"]'.
tier
integer
Capability tier: 1 = Seestar (default), 2 = filtered, 3 = spectroscopy.
owner_name
string
Human-readable name for the observatory or owner. Falls back to the activation code’s stored value if omitted.
portable
boolean
true if the telescope moves between sites. Portable nodes start in sleeping status and activate when a session begins.

POST /api/v1/nodes/heartbeat

Send a 60-second liveness signal to the cloud. The node agent calls this endpoint on a fixed interval throughout the night. The server updates last_heartbeat on the node record, which drives the online/offline indicator visible to members. Nodes that have not heartbeated within 15 minutes are considered offline.
Auth: X-Node-Id + X-Api-KeyThe request body is optional. When included, conditions are stored against the node record and made available to the scheduler for weather-aware planning.
conditions
object
Current local observing conditions snapshot.

GET /api/v1/nodes/me

Retrieve the full registry entry for the authenticated node, including all hardware fields and performance metrics computed by the nightly maintenance loop.
Auth: X-Node-Id + X-Api-KeyNo request body or query parameters.

GET /api/v1/plan

Download the current nightly observation plan for this node. The plan is generated by the CHORUS scheduler each evening based on target scores, node location, weather forecast, and network-wide coverage balance. If no current plan exists the server generates one on demand.
Auth: X-Node-Id + X-Api-KeyNo request body or query parameters.

POST /api/v1/measurements

Upload a single photometry measurement. The cloud validates the measurement against physical bounds, stores it, and runs cross-validation against co-temporal observations from other nodes. Measurements that pass cross-validation and meet quality thresholds are queued for AAVSO submission.
Auth: X-Node-Id + X-Api-Key
measurement
object
required
The photometry result from photometry.run_pipeline().
conditions
object
Observing conditions at the time of this measurement. Stored alongside the measurement for quality analysis.

POST /api/v1/images

Upload a raw FITS frame. The server stores the file under cloud_data/images/ and returns a storage path. File size is capped at the server’s 128 MB content limit.
Auth: X-Node-Id + X-Api-KeyContent-Type: multipart/form-data
file
file
required
The FITS file to upload. Attach as a multipart form field named file.

POST /api/v1/aavso-files

Upload an AAVSO Extended Format text file (.txt) generated by the node’s photometry pipeline. Files are stored under cloud_data/aavso_files/<date>/ and can be downloaded by an operator to email to observations@aavso.org. File size is capped at 512 KB.
Auth: X-Node-Id + X-Api-KeyContent-Type: multipart/form-data
file
file
required
The AAVSO .txt file. Filenames are sanitised server-side; a .txt extension is appended automatically if missing.

GET /api/v1/aavso-files

List all uploaded AAVSO Extended Format text files, newest first. No authentication required — the list is public so operators can locate files to email to AAVSO.
Auth: NoneNo query parameters.

GET /api/v1/aavso-files/download/

Download a specific AAVSO text file by its relative path. Returns the file as an attachment. Path traversal is blocked server-side.
Auth: None
path
string
required
Relative path from the AAVSO file listing, e.g. 2026-06-15/SS_Cyg_20260615.txt.

POST /api/v1/incidents

Report a structured reliability incident from the node agent. The cloud stores it in the reliability_incidents table, making hardware faults, slew failures, emergency parks, and similar events visible to remote operators the moment they occur.
Auth: X-Node-Id + X-Api-Key
incident_type
string
required
Machine-readable event name, e.g. "slew_failure", "emergency_park", "disk_full".
severity
string
One of "info", "warning", "error", or "critical". Defaults to "info".
target_name
string
Target being observed when the incident occurred, if applicable.
detail
object
Structured detail dict (max 4 KB after serialisation). Any extra fields beyond incident_type should go here.

GET /api/v1/interrupts

Poll for unexpired high-priority target interrupts broadcast by the cloud. The node agent calls this endpoint regularly alongside its heartbeat to detect urgent retargeting requests — for example, a supernova alert or gamma-ray burst follow-up that takes precedence over the nightly plan.
Auth: X-Node-Id + X-Api-KeyNo request body or query parameters.

POST /api/v1/interrupts//ack

Acknowledge receipt of an interrupt. Once acknowledged, the acked field is set to true for this node on subsequent polls. Acknowledgment does not remove the interrupt — it remains visible to all other eligible nodes until it expires.
Auth: X-Node-Id + X-Api-Key
id
integer
required
The interrupt ID from the GET /api/v1/interrupts response.

GET /api/v1/nodes/config-patches

Retrieve pending config.yaml patches queued by the help assistant for this node. The node agent polls this endpoint alongside plan and interrupt polling to pick up any configuration changes pushed remotely.
Auth: X-Node-Id + X-Api-KeyNo request body or query parameters.

POST /api/v1/nodes/config-patches//ack

Acknowledge a config patch after applying it. Reports success or failure back to the cloud so the help assistant knows whether the change took effect.
Auth: X-Node-Id + X-Api-Key
patch_id
integer
required
The patch ID from the config-patches list.
ok
boolean
true when the patch was applied successfully. Defaults to true if omitted.
error
string
Error message (up to 500 characters) when ok is false.

Build docs developers (and LLMs) love