Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

API Endpoints

This page lists the HTTP routes currently declared across backend/blueprints/*.py (registered in backend/app.py), including backend/blueprints/skytonight_api.py.

Web & PWA Routes

  • GET /
  • GET /login
  • GET /manifest.webmanifest
  • GET /manifest.<lang>.webmanifest
  • GET /sw.js
  • GET /offline.html
  • GET /robots.txt

Authentication

  • POST /api/auth/login
  • POST /api/auth/login/verify-2fa
  • POST /api/auth/logout
  • GET /api/auth/status
  • POST /api/auth/change-password
  • GET /api/auth/preferences
  • PUT /api/auth/preferences
  • POST /api/auth/2fa/setup
  • POST /api/auth/2fa/confirm
  • POST /api/auth/2fa/disable
  • GET /api/auth/security-settings (admin)
  • POST /api/auth/security-settings (admin)

Push Notifications

  • GET /api/push/vapid-public-key
  • GET /api/push/vapid-config-status
  • POST /api/push/subscribe
  • GET /api/push/subscriptions
  • DELETE /api/push/subscriptions
  • DELETE /api/push/unsubscribe
  • POST /api/push/test
  • POST /api/push/test/<trigger_id>

User Management (admin)

  • GET /api/users
  • POST /api/users
  • PUT /api/users/<user_id>
  • DELETE /api/users/<user_id>
  • DELETE /api/users/<user_id>/2fa
  • GET /api/users/<user_id>/export (admin) - personal data ZIP of any user
  • GET /api/users/me/export - personal data ZIP of the signed-in user

Administration (admin)

  • GET /api/admin/app-settings
  • POST /api/admin/app-settings
  • POST /api/admin/restart

Configuration

  • GET /api/config
  • POST /api/config
  • GET /api/config/export
  • GET /api/skyquality

Locations (multi-location profiles, see docs/LOCATIONS.md)

  • GET /api/locations (admin)
  • POST /api/locations (admin, capped at MAX_LOCATIONS)
  • PUT /api/locations/<location_id> (admin)
  • DELETE /api/locations/<location_id>?plans=cascade|orphan (admin)
  • GET /api/locations/<location_id>/references (admin)
  • POST /api/locations/<location_id>/attribute (admin)
  • GET /api/locations/mine
  • POST /api/locations/active

Backup & Restore

  • GET /api/backup/download - Download a ZIP archive (config.json, app_settings.json, users.json, astrodex/, equipments/, observation_sessions/, wishlist/), built from the database
  • POST /api/backup/restore - Restore from a previously created backup ZIP (multipart/form-data, field file)
  • POST /api/admin/database/integrity-check (admin) - Run SQLite’s integrity and foreign key checks ({ok, problems})
  • GET /api/admin/migration-backups (admin) - What the 1.7 upgrade left in data/backups/ (archive, reports, files set aside, size)
  • GET /api/admin/migration-backups/report (admin) - Download the newest import report
  • DELETE /api/admin/migration-backups (admin) - Delete the upgrade archive, reports and files set aside (irreversible)

Platform & Utility

  • GET /api/metrics
  • GET /api/logs
  • GET /api/logs/level - Active levels: {"level": <log file>, "console_level": <console>}. They are set through POST /api/admin/app-settings (log_level, console_log_level); the LOG_LEVEL / CONSOLE_LOG_LEVEL environment variables override them when set
  • POST /api/logs/clear
  • GET /api/logs/export - Download a ZIP archive of all log files (myastroboard.log + skytonight/logs/)
  • POST /api/convert-coordinates
  • GET /api/timezones
  • POST /api/translate/on-demand
  • GET /api/health
  • GET /health
  • GET /api/cache
  • GET /api/version
  • GET /api/version/check-updates - latest GitHub release (cached 4 h). When an update is available, changes lists the CHANGELOG.md sections between the installed and the latest version (version, date, features, fixes, breaking; newest first), or is null when the changelog could not be fetched.
  • GET /api/catalogues
  • GET /api/map-tiles/vector/<z>/<x>/<y>.mvt, GET /api/map-tiles/fonts/<font>/<range>.pbf, GET /api/map-tiles/sprites/<file>, GET /api/map-tiles/raster/<z>/<x>/<y>.png - OpenStreetMap map resources served through the server’s cache, so the browser never contacts the map servers (vector tiles and glyphs are gzip-encoded; 404 for an invalid tile, font, glyph block or sprite file, 429 with Retry-After past the per-user download budget, 502 when the resource is neither cached nor downloadable); see CACHE_SYSTEM.md

Scheduler

  • GET /api/scheduler/status (legacy alias mapped to SkyTonight scheduler status)
  • POST /api/scheduler/trigger (legacy alias mapped to SkyTonight scheduler trigger)

SkyTonight

  • GET /api/skytonight/scheduler/status
  • POST /api/skytonight/scheduler/trigger
  • GET /api/skytonight/dataset/status
  • POST /api/skytonight/dataset/rebuild
  • GET /api/skytonight/log
  • GET /api/skytonight/reports
  • GET /api/skytonight/reports/<catalogue>
  • GET /api/skytonight/alttime/<target_id>
  • POST /api/skytonight/combination-recommendations
  • GET /api/skytonight/visibility-calendar - 12-month “best months to image this target” calendar for a fixed deep-sky object at the active location. Params: target (catalogue id or name, required), year (4-digit, defaults to the current year, clamped to [current-1, current+5]). Returns supported: false for solar-system bodies and comets.
  • GET /api/skytonight/framing - Framing simulator data for a fixed deep-sky object: resolved target (coordinates, apparent size), allowed background fields of view, and one frame (field of view, image scale, fit verdict, mosaic estimate) per enabled and valid equipment combination that has a camera sensor and a focal length. Param: target (catalogue id or name, required). Returns supported: false for solar-system bodies and comets. See SKYTONIGHT.md.
  • GET /api/skytonight/framing/image/<filename> - DSS2 colour background image of the framing simulator, <ra>_<dec>_<fov>.jpg in degrees (fov must be one of the allowed fields of view). Fetched once from CDS hips2fits by the server, then served from the on-disk cache; 502 when CDS is unavailable.
  • GET /api/skytonight/skymap
  • GET /api/skytonight/data/dso - Optional catalogue filter, plus the v1.4 advanced filters applied server-side before the result-set truncation: size_min, size_max, sb_max, alt_window_min_deg, alt_window_start, alt_window_end, combination_id, fov_fit, max_integration_h. Malformed values are ignored rather than rejected. See SKYTONIGHT.md.
  • GET /api/skytonight/data/bodies
  • GET /api/skytonight/data/comets
  • GET /api/skytonight/logs/<catalogue>
  • GET /api/skytonight/logs/<catalogue>/exists
  • GET /api/skytonight/target-debug
  • GET /api/skytonight/recommendations - Difficulty-aware “what to shoot tonight” recommendations, filtered by the user’s experience_level preference. Params: limit (default 5, max 10), lang (mandatory for translated content).

Weather, Moon, Sun, and Astronomy

  • GET /api/weather/forecast
  • GET /api/weather/astro-analysis
  • GET /api/weather/astro-current
  • GET /api/weather/alerts
  • GET /api/seeing-forecast
  • GET /api/moon/report
  • GET /api/moon/dark-window
  • GET /api/moon/next-7-nights
  • GET /api/moon/phase-calendar - Full calendar month of Moon phases (illumination, waxing/waning, near-new-moon flag) plus the month’s principal phase timestamps, for the active location. Params: year, month (1-12); both are clamped to the allowed 2-month window (current month and the next one), and missing or malformed values fall back to the current month. Response includes is_current_month, can_go_prev, can_go_next, today, days, principal_phases.
  • GET /api/aurora/predictions
  • GET /api/iss/passes - Returns ISS passes, solar transits, and lunar transits; all times in configured local TZ. Response includes passes, solar_transits, lunar_transits, next_visible_passage, next_solar_transit, next_lunar_transit, total_passes, total_solar_transits, total_lunar_transits.
  • GET /api/iss/location
  • POST /api/iss/celestrak/restart - Admin only. Clears the Celestrak block flag so the next crawl may query Celestrak again.
  • GET /api/css/passes - Returns CSS (China Space Station, NORAD 48274/Tiangong) passes, solar transits, and lunar transits. Same response structure as ISS; includes station: "CSS" field.
  • GET /api/css/location
  • POST /api/css/celestrak/restart - Admin only. Same as the ISS one, for the CSS TLE crawl.
  • GET /api/sun/today
  • GET /api/sun/next-eclipse
  • GET /api/moon/next-eclipse
  • GET /api/events/upcoming
  • GET /api/events/planetary
  • GET /api/events/phenomena
  • GET /api/events/solarsystem
  • GET /api/astro/sidereal-time
  • GET /api/astro/horizon-graph
  • GET /api/tonight/best-window
  • GET /api/sky-widget - Current sky status for the sky status widget in the header: period of the night, sky score, active location name

Spaceflight

  • GET /api/spaceflight/launches
  • GET /api/spaceflight/astronauts
  • GET /api/spaceflight/events
  • GET /api/spaceflight/img/<filename>
  • GET /api/spaceflight/launch/<launch_id>/vidurls

Connectors

  • GET /api/connectors - List all registered connectors with installed/enabled state, module config, target_modules (app tabs the connector surfaces in), and a config block whose SECRET_FIELDS are masked (**** + last 4, plus a has_<field> boolean). A connector on a shared MQTT connection also carries connection_field and connection_options ([{id, name}])
  • POST /api/connectors/<name>/config (admin) - Save one connector’s config; merged server-side, int / bool fields coerced to their declared type, and a blank or still-masked secret means “keep current”. Secrets are written to the connector secrets store, never to the configuration. A connector on a shared MQTT connection: 400 for an unknown connection id, or for a client_id another connector already uses on the same connection
  • GET /api/connectors/allsky/status - AllSky sensor data: the variables of the last MQTT message from AllSky’s Publish Data module, plus _received_at (when the board received it); {} while none arrived or the last one is older than 15 min. Requires the sensor_data module enabled
  • GET /api/connectors/allsky/health - Run a per-module health check against the AllSky instance with the saved configuration (cached 2 minutes); accepts ?fresh=1 to bypass the cache
  • POST /api/connectors/allsky/health - Quick reachability probe of {"url": "..."} before saving (the card’s test button); http(s) only
  • GET /api/connectors/allsky/urls - Return proxy URLs for all enabled AllSky modules; accepts ?date=YYYYMMDD
  • GET /api/connectors/allsky/proxy - Proxy an AllSky resource through the backend; params: module=<slug> and optional date=YYYYMMDD
  • GET /api/connectors/mqtt/health (admin) - One real MQTT connect against the saved connector’s connection, with the module toggles (a connection picked on the card is tested through POST /api/mqtt-connections/health). A failed probe is a 200 with reachable: false and an error string
  • GET /api/connectors/mqtt/status - What the publisher thread is doing: enabled, connected, broker, last_publish_at, last_error, devices[], messages_total (read from the status file the thread writes, so any worker can answer)
  • POST /api/connectors/mqtt/publish (admin) - Ask the publisher for a full republish (discovery + every state) on its next tick
  • POST /api/connectors/mqtt/remove (admin) - Switch the connector off and purge every retained MyAstroBoard topic from the broker (Home Assistant drops the devices)

MQTT connections

Brokers shared by the MQTT connectors (App settings -> Configuration). All admin-only; the password is never returned, not even in part: a fixed ******** mask and a has_password flag.

  • GET /api/mqtt-connections (admin) - Every connection: id, name, url, username, tls_insecure, password (******** when one is stored, nothing of it revealed), has_password, used_by (connector names)
  • POST /api/mqtt-connections (admin) - Create from {name, url, username?, password?, tls_insecure?}; 201, or 400 with the reason (name required or taken, invalid URL…)
  • PUT /api/mqtt-connections/<connection_id> (admin) - Edit; a blank or still-masked password keeps the stored one, a blank username drops it. 404 for an unknown id
  • DELETE /api/mqtt-connections/<connection_id> (admin) - Delete; 409 {error, used_by} while a connector uses it
  • POST /api/mqtt-connections/health (admin) - One real MQTT connect with {url, username?, password?, tls_insecure?, id?} as typed; a blank or masked password uses the stored one of connection id only when url is that connection’s saved URL. {id} alone probes that saved connection (the connectors’ picker). A failed probe is a 200 with reachable: false and an error string

Object Lookup

  • GET /api/object/<path:identifier>
  • GET /api/object-image/<filename> - Serve a locally cached DSS2 sky image (object thumbnails, framing backgrounds), e.g. 10.684000_41.269000.jpg; see SKYTONIGHT.md

Beginner Catalog

  • GET /api/beginner-catalog - Curated beginner-friendly DSO catalog, enriched with visible_tonight/astro_score/in_astrodex/in_plan. Params: lang (mandatory), visible_only (default true; ignored if no SkyTonight results are cached yet).

Astrodex

  • GET /api/astrodex
  • GET /api/astrodex/map - Flat list of geotagged pictures for the Photo Map sub-tab, gated by its own map_private config flag (independent from the general private sharing flag)
  • POST /api/astrodex/items
  • POST /api/astrodex/items/<item_id>/catalogue-name
  • GET /api/astrodex/items/<item_id>
  • PUT /api/astrodex/items/<item_id>
  • DELETE /api/astrodex/items/<item_id>
  • POST /api/astrodex/items/<item_id>/pictures
  • PUT /api/astrodex/items/<item_id>/pictures/<picture_id>
  • DELETE /api/astrodex/items/<item_id>/pictures/<picture_id>
  • POST /api/astrodex/items/<item_id>/pictures/<picture_id>/main
  • POST /api/astrodex/upload
  • GET /api/astrodex/images/<filename>
  • GET /api/astrodex/check/<item_name>
  • GET /api/astrodex/constellations
  • GET /api/astrodex/catalogue-lookup
  • GET /api/astrodex/collection/catalogues
  • GET /api/astrodex/collection

Astrodex Stream (see docs/ASTRODEX_STREAM.md)

  • GET /api/astrodex/stream/urls - The caller’s personal stream URL and, unless the Astrodex is private, the shared one; external_base_url_required: true under Home Assistant ingress with no external base URL set
  • GET /api/astrodex/stream/<user_id>/<token>/current.jpg - No session cookie. Current frame of one user’s slideshow; the signed token is the credential. 404 when the connector is off or the token is wrong, 429 when rate limited
  • GET /api/astrodex/stream/shared/<token>/current.jpg - No session cookie. Current frame of the slideshow of every user’s pictures; 404 while the Astrodex is private
  • POST /api/connectors/astrodex_stream/rotate (admin) - Rotate the signing secret: every stream URL handed out so far stops working

MyAstroShine integration (see docs/MYASTROSHINE.md)

Astrodex <-> MyAstroShine image round-trip. Not a BaseConnector - config lives under config.connectors.myastroshine but the routes and UI are Astrodex-side.

  • GET /api/astrodex/integration/status - { enabled: bool } - drives the per-photo “Send to MyAstroShine” button
  • GET|POST /api/connectors/myastroshine/health - Best-effort reachability probe of <url>/api/health (loopback / link-local / unspecified / multicast refused). GET probes the saved URL, POST the one in the body. The card’s config is served by the shared connector routes above
  • POST /api/astrodex/integration/handoff - Mint a signed, single-use handoff token for one of the caller’s own pictures; returns { handoff, myastroshine_url, open_url }
  • GET /api/astrodex/integration/source?handoff=<token> - No session cookie (MyAstroShine container calls it). Source picture metadata for a valid handoff
  • GET /api/astrodex/integration/source/image?handoff=<token> - No session cookie. Source image bytes
  • POST /api/astrodex/integration/enhanced - No session cookie. multipart/form-data (handoff, payload, image) + X-Webhook-Signature: sha256=<hex>. Creates a duplicated picture on the same item; 201 / 401 bad signature or handoff / 409 handoff already consumed / 404 item or picture gone / 413 image too large

Plan My Night

  • GET /api/plan-my-night/list
  • GET /api/plan-my-night
  • PATCH /api/plan-my-night
  • POST /api/plan-my-night/targets
  • PUT /api/plan-my-night/targets/<entry_id>
  • POST /api/plan-my-night/targets/<entry_id>/reorder
  • DELETE /api/plan-my-night/targets/<entry_id>
  • DELETE /api/plan-my-night/clear
  • DELETE /api/plan-my-night/clear-all
  • POST /api/plan-my-night/targets/<entry_id>/add-to-astrodex
  • GET /api/plan-my-night/export.csv
  • GET /api/plan-my-night/export.pdf
  • GET /api/plan-my-night/optimize - Preview a reordering and initial delay that maximize each target’s overlap with its real visibility window for the night
  • POST /api/plan-my-night/optimize/apply - Apply a previewed optimized order and initial delay to the plan

Observation Log (see docs/OBSERVATION_LOG.md)

  • GET /api/observation-sessions - Own sessions (newest observation date first) + minimal stats
  • POST /api/observation-sessions
  • GET /api/observation-sessions/<session_id>
  • PUT /api/observation-sessions/<session_id>
  • DELETE /api/observation-sessions/<session_id> - Deletes the session and its entries; linked Astrodex items/pictures are never touched
  • POST /api/observation-sessions/from-plan - Seed/merge a session from a Plan My Night plan (works on current and previous plans); reuses an existing night of the same date, or appends a new one
  • POST /api/observation-sessions/<session_id>/nights - Add another night to a multi-night session (v1.3.1)
  • PUT /api/observation-sessions/<session_id>/nights/<night_id> - Update one night’s conditions/notes (v1.3.1)
  • DELETE /api/observation-sessions/<session_id>/nights/<night_id> - Refused while it’s the session’s last remaining night, or while any entry still points at it (v1.3.1)
  • POST /api/observation-sessions/<session_id>/entries - Side effect: auto-registers the target in Astrodex when frame_count > 0
  • PUT /api/observation-sessions/<session_id>/entries/<entry_id> - Same auto-registration whenever frame_count newly becomes > 0
  • DELETE /api/observation-sessions/<session_id>/entries/<entry_id>
  • POST /api/observation-sessions/<session_id>/entries/<entry_id>/astrodex-picture - Manual attach of an image already uploaded through POST /api/astrodex/upload
  • POST /api/observation-sessions/<session_id>/attachments - Upload + record a generic session attachment (image/PDF/text/Word) in one step (v1.3.1)
  • GET /api/observation-sessions/attachments/<filename> - Serve an attachment file, ownership-checked (v1.3.1)
  • PUT /api/observation-sessions/<session_id>/attachments/<attachment_id> - Set/clear an attachment’s custom display name (v1.3.1)
  • DELETE /api/observation-sessions/<session_id>/attachments/<attachment_id> - Remove an attachment’s record and file (v1.3.1)
  • GET /api/observation-sessions/<session_id>/export.pdf - One session as a PDF (common info + every logged target, with its attached photo when there is one)
  • GET /api/observation-sessions/export.pdf - Every own session as one PDF (cover + summary + per-session pages); optional from_date/to_date/order (asc/desc, default asc)

Session Analytics and Wishlist (see docs/SESSION_ANALYTICS.md)

All self-scoped: a user only ever sees aggregates of their own Observation Log and Astrodex.

  • GET /api/session-analytics/summary - Integration hours (lifetime/year/month), monthly series, distinct objects, object-type and constellation breakdowns, equipment usage, top targets, plus the separately-labelled Astrodex collection size; optional year
  • GET /api/session-analytics/sky-coverage - Captured objects placed on an RA/Dec grid, the count and names of those that could not be placed, and the never-visible declination bound for the active location
  • GET /api/session-analytics/conditions - Rated entries joined to their night’s seeing/transparency/SQM/Moon, plus bucketed averages carrying their own sample counts
  • GET /api/session-analytics/best-months - Dark and moonless-dark hours available per month at the active location, next to the hours the user actually logged; not a weather statistic; optional year
  • GET /api/wishlist - Wishlist items with derived captured state, progress counters and next-visibility figures; optional sort (visibility/priority/name) and visibility=0 to skip the ephemeris pass
  • POST /api/wishlist (user) - Add targets; body is always {"targets": [...]}; returns the added items plus duplicate/invalid/full skip counts
  • PATCH /api/wishlist/<item_id> (user) - Update priority or notes
  • DELETE /api/wishlist/<item_id> (user) - Remove one item
  • POST /api/wishlist/archive-captured (user) - Remove every item currently derived as captured

Equipment

  • GET /api/equipment/telescopes
  • POST /api/equipment/telescopes
  • GET /api/equipment/telescopes/<telescope_id>
  • PUT /api/equipment/telescopes/<telescope_id>
  • DELETE /api/equipment/telescopes/<telescope_id>
  • GET /api/equipment/cameras
  • POST /api/equipment/cameras
  • GET /api/equipment/cameras/<camera_id>
  • PUT /api/equipment/cameras/<camera_id>
  • DELETE /api/equipment/cameras/<camera_id>
  • GET /api/equipment/mounts
  • POST /api/equipment/mounts
  • GET /api/equipment/mounts/<mount_id>
  • PUT /api/equipment/mounts/<mount_id>
  • DELETE /api/equipment/mounts/<mount_id>
  • GET /api/equipment/filters
  • POST /api/equipment/filters
  • GET /api/equipment/filters/<filter_id>
  • PUT /api/equipment/filters/<filter_id>
  • DELETE /api/equipment/filters/<filter_id>
  • GET /api/equipment/accessories
  • POST /api/equipment/accessories
  • GET /api/equipment/accessories/<accessory_id>
  • PUT /api/equipment/accessories/<accessory_id>
  • DELETE /api/equipment/accessories/<accessory_id>
  • GET /api/equipment/combinations
  • POST /api/equipment/combinations
  • GET /api/equipment/combinations/<combination_id>
  • PUT /api/equipment/combinations/<combination_id>
  • DELETE /api/equipment/combinations/<combination_id>
  • POST /api/equipment/fov-calculator
  • GET /api/equipment/summary

Last updated 2026-11-13