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 /loginGET /manifest.webmanifestGET /manifest.<lang>.webmanifestGET /sw.jsGET /offline.htmlGET /robots.txt
Authentication
POST /api/auth/loginPOST /api/auth/login/verify-2faPOST /api/auth/logoutGET /api/auth/statusPOST /api/auth/change-passwordGET /api/auth/preferencesPUT /api/auth/preferencesPOST /api/auth/2fa/setupPOST /api/auth/2fa/confirmPOST /api/auth/2fa/disableGET /api/auth/security-settings(admin)POST /api/auth/security-settings(admin)
Push Notifications
GET /api/push/vapid-public-keyGET /api/push/vapid-config-statusPOST /api/push/subscribeGET /api/push/subscriptionsDELETE /api/push/subscriptionsDELETE /api/push/unsubscribePOST /api/push/testPOST /api/push/test/<trigger_id>
User Management (admin)
GET /api/usersPOST /api/usersPUT /api/users/<user_id>DELETE /api/users/<user_id>DELETE /api/users/<user_id>/2faGET /api/users/<user_id>/export(admin) - personal data ZIP of any userGET /api/users/me/export- personal data ZIP of the signed-in user
Administration (admin)
GET /api/admin/app-settingsPOST /api/admin/app-settingsPOST /api/admin/restart
Configuration
GET /api/configPOST /api/configGET /api/config/exportGET /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/minePOST /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 databasePOST /api/backup/restore- Restore from a previously created backup ZIP (multipart/form-data, fieldfile)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 indata/backups/(archive, reports, files set aside, size)GET /api/admin/migration-backups/report(admin) - Download the newest import reportDELETE /api/admin/migration-backups(admin) - Delete the upgrade archive, reports and files set aside (irreversible)
Platform & Utility
GET /api/metricsGET /api/logsGET /api/logs/level- Active levels:{"level": <log file>, "console_level": <console>}. They are set throughPOST /api/admin/app-settings(log_level,console_log_level); theLOG_LEVEL/CONSOLE_LOG_LEVELenvironment variables override them when setPOST /api/logs/clearGET /api/logs/export- Download a ZIP archive of all log files (myastroboard.log + skytonight/logs/)POST /api/convert-coordinatesGET /api/timezonesPOST /api/translate/on-demandGET /api/healthGET /healthGET /api/cacheGET /api/versionGET /api/version/check-updates- latest GitHub release (cached 4 h). When an update is available,changeslists the CHANGELOG.md sections between the installed and the latest version (version,date,features,fixes,breaking; newest first), or isnullwhen the changelog could not be fetched.GET /api/cataloguesGET /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;404for an invalid tile, font, glyph block or sprite file,429withRetry-Afterpast the per-user download budget,502when 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/statusPOST /api/skytonight/scheduler/triggerGET /api/skytonight/dataset/statusPOST /api/skytonight/dataset/rebuildGET /api/skytonight/logGET /api/skytonight/reportsGET /api/skytonight/reports/<catalogue>GET /api/skytonight/alttime/<target_id>POST /api/skytonight/combination-recommendationsGET /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]). Returnssupported: falsefor 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). Returnssupported: falsefor 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>.jpgin degrees (fovmust be one of the allowed fields of view). Fetched once from CDS hips2fits by the server, then served from the on-disk cache;502when CDS is unavailable.GET /api/skytonight/skymapGET /api/skytonight/data/dso- Optionalcataloguefilter, 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/bodiesGET /api/skytonight/data/cometsGET /api/skytonight/logs/<catalogue>GET /api/skytonight/logs/<catalogue>/existsGET /api/skytonight/target-debugGET /api/skytonight/recommendations- Difficulty-aware “what to shoot tonight” recommendations, filtered by the user’sexperience_levelpreference. Params:limit(default 5, max 10),lang(mandatory for translated content).
Weather, Moon, Sun, and Astronomy
GET /api/weather/forecastGET /api/weather/astro-analysisGET /api/weather/astro-currentGET /api/weather/alertsGET /api/seeing-forecastGET /api/moon/reportGET /api/moon/dark-windowGET /api/moon/next-7-nightsGET /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 includesis_current_month,can_go_prev,can_go_next,today,days,principal_phases.GET /api/aurora/predictionsGET /api/iss/passes- Returns ISS passes, solar transits, and lunar transits; all times in configured local TZ. Response includespasses,solar_transits,lunar_transits,next_visible_passage,next_solar_transit,next_lunar_transit,total_passes,total_solar_transits,total_lunar_transits.GET /api/iss/locationPOST /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; includesstation: "CSS"field.GET /api/css/locationPOST /api/css/celestrak/restart- Admin only. Same as the ISS one, for the CSS TLE crawl.GET /api/sun/todayGET /api/sun/next-eclipseGET /api/moon/next-eclipseGET /api/events/upcomingGET /api/events/planetaryGET /api/events/phenomenaGET /api/events/solarsystemGET /api/astro/sidereal-timeGET /api/astro/horizon-graphGET /api/tonight/best-windowGET /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/launchesGET /api/spaceflight/astronautsGET /api/spaceflight/eventsGET /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 whoseSECRET_FIELDSare masked (****+ last 4, plus ahas_<field>boolean). A connector on a shared MQTT connection also carriesconnection_fieldandconnection_options([{id, name}])POST /api/connectors/<name>/config(admin) - Save one connector’s config; merged server-side,int/boolfields 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 aclient_idanother connector already uses on the same connectionGET /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 thesensor_datamodule enabledGET /api/connectors/allsky/health- Run a per-module health check against the AllSky instance with the saved configuration (cached 2 minutes); accepts?fresh=1to bypass the cachePOST /api/connectors/allsky/health- Quick reachability probe of{"url": "..."}before saving (the card’s test button); http(s) onlyGET /api/connectors/allsky/urls- Return proxy URLs for all enabled AllSky modules; accepts?date=YYYYMMDDGET /api/connectors/allsky/proxy- Proxy an AllSky resource through the backend; params:module=<slug>and optionaldate=YYYYMMDDGET /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 throughPOST /api/mqtt-connections/health). A failed probe is a 200 withreachable: falseand anerrorstringGET /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 tickPOST /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 idDELETE /api/mqtt-connections/<connection_id>(admin) - Delete; 409{error, used_by}while a connector uses itPOST /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 connectionidonly whenurlis that connection’s saved URL.{id}alone probes that saved connection (the connectors’ picker). A failed probe is a 200 withreachable: falseand anerrorstring
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 withvisible_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/astrodexGET /api/astrodex/map- Flat list of geotagged pictures for the Photo Map sub-tab, gated by its ownmap_privateconfig flag (independent from the generalprivatesharing flag)POST /api/astrodex/itemsPOST /api/astrodex/items/<item_id>/catalogue-nameGET /api/astrodex/items/<item_id>PUT /api/astrodex/items/<item_id>DELETE /api/astrodex/items/<item_id>POST /api/astrodex/items/<item_id>/picturesPUT /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>/mainPOST /api/astrodex/uploadGET /api/astrodex/images/<filename>GET /api/astrodex/check/<item_name>GET /api/astrodex/constellationsGET /api/astrodex/catalogue-lookupGET /api/astrodex/collection/cataloguesGET /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: trueunder Home Assistant ingress with no external base URL setGET /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 limitedGET /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 privatePOST /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” buttonGET|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 abovePOST /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 handoffGET /api/astrodex/integration/source/image?handoff=<token>- No session cookie. Source image bytesPOST /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/401bad signature or handoff /409handoff already consumed /404item or picture gone /413image too large
Plan My Night
GET /api/plan-my-night/listGET /api/plan-my-nightPATCH /api/plan-my-nightPOST /api/plan-my-night/targetsPUT /api/plan-my-night/targets/<entry_id>POST /api/plan-my-night/targets/<entry_id>/reorderDELETE /api/plan-my-night/targets/<entry_id>DELETE /api/plan-my-night/clearDELETE /api/plan-my-night/clear-allPOST /api/plan-my-night/targets/<entry_id>/add-to-astrodexGET /api/plan-my-night/export.csvGET /api/plan-my-night/export.pdfGET /api/plan-my-night/optimize- Preview a reordering and initial delay that maximize each target’s overlap with its real visibility window for the nightPOST /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 statsPOST /api/observation-sessionsGET /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 touchedPOST /api/observation-sessions/from-plan- Seed/merge a session from a Plan My Night plan (works oncurrentandpreviousplans); reuses an existing night of the same date, or appends a new onePOST /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 whenframe_count > 0PUT /api/observation-sessions/<session_id>/entries/<entry_id>- Same auto-registration wheneverframe_countnewly becomes> 0DELETE /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 throughPOST /api/astrodex/uploadPOST /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); optionalfrom_date/to_date/order(asc/desc, defaultasc)
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; optionalyearGET /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 locationGET /api/session-analytics/conditions- Rated entries joined to their night’s seeing/transparency/SQM/Moon, plus bucketed averages carrying their own sample countsGET /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; optionalyearGET /api/wishlist- Wishlist items with derived captured state, progress counters and next-visibility figures; optionalsort(visibility/priority/name) andvisibility=0to skip the ephemeris passPOST /api/wishlist(user) - Add targets; body is always{"targets": [...]}; returns the added items plus duplicate/invalid/full skip countsPATCH /api/wishlist/<item_id>(user) - UpdatepriorityornotesDELETE /api/wishlist/<item_id>(user) - Remove one itemPOST /api/wishlist/archive-captured(user) - Remove every item currently derived as captured
Equipment
GET /api/equipment/telescopesPOST /api/equipment/telescopesGET /api/equipment/telescopes/<telescope_id>PUT /api/equipment/telescopes/<telescope_id>DELETE /api/equipment/telescopes/<telescope_id>GET /api/equipment/camerasPOST /api/equipment/camerasGET /api/equipment/cameras/<camera_id>PUT /api/equipment/cameras/<camera_id>DELETE /api/equipment/cameras/<camera_id>GET /api/equipment/mountsPOST /api/equipment/mountsGET /api/equipment/mounts/<mount_id>PUT /api/equipment/mounts/<mount_id>DELETE /api/equipment/mounts/<mount_id>GET /api/equipment/filtersPOST /api/equipment/filtersGET /api/equipment/filters/<filter_id>PUT /api/equipment/filters/<filter_id>DELETE /api/equipment/filters/<filter_id>GET /api/equipment/accessoriesPOST /api/equipment/accessoriesGET /api/equipment/accessories/<accessory_id>PUT /api/equipment/accessories/<accessory_id>DELETE /api/equipment/accessories/<accessory_id>GET /api/equipment/combinationsPOST /api/equipment/combinationsGET /api/equipment/combinations/<combination_id>PUT /api/equipment/combinations/<combination_id>DELETE /api/equipment/combinations/<combination_id>POST /api/equipment/fov-calculatorGET /api/equipment/summary
Last updated 2026-11-13