{ "openapi": "3.1.0", "info": { "title": "Astra Companion API", "version": "2.0.0", "description": "A bounded companion and automation API for a running Astra desktop app. All application endpoints require bearer authentication; pairing endpoints for LAN clients remain part of Astra's transport protocol." }, "servers": [ { "url": "http://127.0.0.1:38401", "description": "Default loopback API" } ], "components": { "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer" } }, "schemas": { "Error": { "type": "object", "required": ["error"], "properties": { "error": { "type": "object", "required": ["code", "message"], "properties": { "code": { "type": "string" }, "message": { "type": "string" } } } } }, "AstraRef": { "type": "string", "description": "Opaque signed reference. Clients must not parse or construct it." }, "TrackSummary": { "type": "object", "required": ["ref", "title", "artist", "artists", "album", "albumArtists", "durationSeconds", "year", "genres", "format", "sampleRateHz", "bitDepth", "channels", "favorite", "artworkUrl"], "properties": { "ref": { "oneOf": [{ "$ref": "#/components/schemas/AstraRef" }, { "type": "null" }] }, "title": { "type": "string" }, "artist": { "type": "string" }, "artists": { "type": "array", "items": { "type": "string" } }, "album": { "type": "string" }, "albumArtists": { "type": "array", "items": { "type": "string" } }, "durationSeconds": { "type": ["number", "null"] }, "year": { "type": ["integer", "null"] }, "genres": { "type": "array", "items": { "type": "string" } }, "format": { "type": ["string", "null"] }, "sampleRateHz": { "type": ["integer", "null"] }, "bitDepth": { "type": ["integer", "null"] }, "channels": { "type": ["integer", "null"] }, "favorite": { "type": "boolean" }, "artworkUrl": { "type": ["string", "null"] } } }, "Playback": { "type": "object", "required": ["state", "positionSeconds", "durationSeconds", "volume", "muted", "shuffle", "repeat", "outputDeviceLabel", "queueCount", "currentTrack", "updatedAt"], "properties": { "state": { "enum": ["stopped", "playing", "paused", "loading"] }, "positionSeconds": { "type": "number", "minimum": 0 }, "durationSeconds": { "type": "number", "minimum": 0 }, "volume": { "type": "number", "minimum": 0, "maximum": 1 }, "muted": { "type": "boolean" }, "shuffle": { "type": "boolean" }, "repeat": { "enum": ["none", "one", "all"] }, "outputDeviceLabel": { "type": ["string", "null"] }, "queueCount": { "type": "integer", "minimum": 0 }, "currentTrack": { "oneOf": [{ "$ref": "#/components/schemas/TrackSummary" }, { "type": "null" }] }, "updatedAt": { "type": "integer" } } }, "PlaybackAction": { "type": "object", "required": ["action"], "properties": { "action": { "enum": ["play", "pause", "stop", "next", "previous", "seek", "set-volume", "set-muted", "set-shuffle", "set-repeat"] }, "positionSeconds": { "type": "number", "minimum": 0 }, "volume": { "type": "number", "minimum": 0, "maximum": 1 }, "muted": { "type": "boolean" }, "enabled": { "type": "boolean" }, "mode": { "enum": ["none", "one", "all"] } } }, "Intent": { "type": "object", "required": ["action", "targetRef"], "properties": { "action": { "enum": ["open", "play", "enqueue"] }, "targetRef": { "$ref": "#/components/schemas/AstraRef" }, "position": { "enum": ["next", "end"] } } }, "PositionMutation": { "type": "object", "required": ["position"], "properties": { "position": { "type": "integer", "minimum": 0 } } }, "FavoriteMutation": { "type": "object", "required": ["favorite"], "properties": { "favorite": { "type": "boolean" } } }, "PlaylistMutation": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200 } } }, "PlaylistItemsMutation": { "type": "object", "required": ["trackRefs"], "properties": { "trackRefs": { "type": "array", "minItems": 1, "maxItems": 100, "items": { "$ref": "#/components/schemas/AstraRef" } } } } } }, "security": [{ "bearerAuth": [] }], "paths": { "/v2/openapi.json": { "get": { "operationId": "getOpenApiDocument", "security": [], "responses": { "200": { "description": "OpenAPI document" } } } }, "/v2/capabilities": { "get": { "operationId": "getCapabilities", "x-astra-scope": "authenticated", "responses": { "200": { "description": "Granted scopes, features, and limits" } } } }, "/v2/playback": { "get": { "operationId": "getPlayback", "x-astra-scope": "observe", "responses": { "200": { "description": "Playback snapshot", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Playback" } } } } } } }, "/v2/playback/actions": { "post": { "operationId": "performPlaybackAction", "x-astra-scope": "playback-control", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlaybackAction" } } } }, "responses": { "202": { "description": "Action accepted" } } } }, "/v2/events": { "get": { "operationId": "streamEvents", "x-astra-scope": "observe", "parameters": [ { "name": "topics", "in": "query", "schema": { "type": "string" }, "description": "Comma-separated playback,queue,favorite,playlist topics" }, { "name": "positionIntervalMs", "in": "query", "schema": { "type": "integer", "minimum": 250, "maximum": 5000, "default": 1000 } } ], "responses": { "200": { "description": "Server-sent event stream", "content": { "text/event-stream": {} } } } } }, "/v2/search": { "get": { "operationId": "searchLibrary", "x-astra-scope": "library-search", "parameters": [ { "name": "q", "in": "query", "required": true, "schema": { "type": "string", "minLength": 1, "maxLength": 200 } }, { "name": "types", "in": "query", "schema": { "type": "string" }, "description": "Comma-separated track,album,artist,playlist target types" }, { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 20 } } ], "responses": { "200": { "description": "Bounded search results" } } } }, "/v2/intents": { "post": { "operationId": "performIntent", "x-astra-scopes": { "open": "library-search", "play": "playback-control", "enqueue": "playback-control" }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Intent" } } } }, "responses": { "202": { "description": "Intent accepted" } } } }, "/v2/queue": { "get": { "operationId": "getQueue", "x-astra-scope": "observe", "responses": { "200": { "description": "Current and upcoming queue" } } }, "delete": { "operationId": "clearUpcomingQueue", "x-astra-scope": "playback-control", "responses": { "202": { "description": "Clear accepted without stopping the current track" } } } }, "/v2/queue/items/{id}": { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }], "patch": { "operationId": "moveQueueItem", "x-astra-scope": "playback-control", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PositionMutation" } } } }, "responses": { "202": { "description": "Move accepted" } } }, "delete": { "operationId": "removeQueueItem", "x-astra-scope": "playback-control", "responses": { "202": { "description": "Removal accepted" } } } }, "/v2/artwork/{ref}": { "get": { "operationId": "getArtwork", "x-astra-scope": "observe", "parameters": [{ "name": "ref", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/AstraRef" } }], "responses": { "200": { "description": "Bounded artwork thumbnail", "content": { "image/jpeg": {}, "image/png": {}, "image/webp": {} } } } } }, "/v2/tracks/{ref}/favorite": { "put": { "operationId": "setFavorite", "x-astra-scope": "library-write", "parameters": [{ "name": "ref", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/AstraRef" } }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FavoriteMutation" } } } }, "responses": { "200": { "description": "Favorite state set" } } } }, "/v2/playlists": { "post": { "operationId": "createPlaylist", "x-astra-scope": "library-write", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlaylistMutation" } } } }, "responses": { "201": { "description": "Normal playlist created" } } } }, "/v2/playlists/{ref}": { "patch": { "operationId": "renamePlaylist", "x-astra-scope": "library-write", "parameters": [{ "name": "ref", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/AstraRef" } }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlaylistMutation" } } } }, "responses": { "200": { "description": "Playlist renamed" } } } }, "/v2/playlists/{ref}/items": { "post": { "operationId": "addPlaylistItems", "x-astra-scope": "library-write", "parameters": [{ "name": "ref", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/AstraRef" } }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlaylistItemsMutation" } } } }, "responses": { "200": { "description": "Tracks added" } } } }, "/v2/playlists/{ref}/items/{trackRef}": { "parameters": [ { "name": "ref", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/AstraRef" } }, { "name": "trackRef", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/AstraRef" } } ], "patch": { "operationId": "movePlaylistItem", "x-astra-scope": "library-write", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PositionMutation" } } } }, "responses": { "200": { "description": "Track moved" } } }, "delete": { "operationId": "removePlaylistItem", "x-astra-scope": "library-write", "responses": { "200": { "description": "Track removed" } } } } } }