Every API here is available over the APIs.io API and to AI agents over MCP.
{
"swagger": "2.0",
"info": {
"description": "The Anbox Stream Gateway provides federated access to Anbox Cloud regions.\nIt's primary purpose is it to connect clients to individual Android containers and enable WebRTC based streaming.\nTt does so via `sessions` which are 'chatrooms' for clients and stream providers to communicate.\nWhen the communication is established, the stream is sent directly from one peer to another.\n\nThe Anbox Stream Gateway keeps things simple and only manages what is required to make streaming happen.\nOther components can invoke its REST API to add other capabilities on top such as user management, limiting, etc.\n\n## Authentication\n\nAll calls to the Stream Gateway must be authenticated. Authentication takes the form of a single\ntoken per client you must embed in your requests\n\n### 1. Creating the token\n\nAn internal HTTP API is exposed for managing client tokens. This API is only accessible via a Unix domain socket\nwhich resides at `/var/snap/anbox-stream-gateway/common/service/unix.socket` by default. \nFor convenience, the Stream Gateway has a built-in client designed to communicate to that API.\n\n**Creating a token**\n\n $ anbox-stream-gateway account create my-client\n AgEUYW5ib3gtc3RyZWFtLWdhdGV3YXkCBGFzZGYAAhkyMDIwLTA2LTIzVDA5OjMyOjE5KzAyOjAwAAAGIDcZMdTrdNdJB6kzjoXyx1_T6s8-0C1AQSyzaA_GHLYQ\n\n**Deleting a token**\n\n $ anbox-stream-gateway account delete my-client\n Account my-client deleted successfully\n\nYou can type `anbox-stream-gateway --help` to list all commands\n\n### 2. Using the token in your requests\n\nWhen making requests to the Stream Gateway API you can either place the token in the request HTTP headers or\nin the query parameters.\n\n**Request headers**\n\n $ curl -X GET https://20.234.75.29:4000/1.0/sessions \\\n -H 'authorization=macaroon root=AgEUYW5ib3...QSyzaA_GHLYQ'\n\n**Query parameters**\n\n $ curl -X GET https://20.234.75.29:4000/1.0/sessions?api_token=AgEUYW5ib3...QSyzaA_GHLYQ\n",
"title": "Anbox Stream Gateway",
"contact": {
"name": "Canonical",
"url": "https://ubuntu.com/support",
"email": "indore@lists.canonical.com"
},
"license": {
"name": "Proprietary"
},
"version": "1.0"
},
"basePath": "/1.0/",
"paths": {
"/1.0/applications": {
"get": {
"security": [
{
"AuthToken": []
}
],
"description": "Return all applications that were registered via AMS and that support streaming.",
"tags": [
"application"
],
"summary": "Get applications",
"operationId": "handle-get-applications",
"responses": {
"200": {
"description": "List of applications",
"schema": {
"$ref": "#/definitions/api.ApplicationsGetResponse"
}
}
}
}
},
"/1.0/regions": {
"get": {
"security": [
{
"AuthToken": []
}
],
"description": "Regions are cloud regions, allowing clients to be as close as possible\nto the agent running the Android container.\n\nThe list is dynamic and regions might change as agents are added or removed.",
"tags": [
"region"
],
"summary": "Get regions",
"operationId": "handle-get-regions",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.RegionsGetResponse"
}
}
}
}
},
"/1.0/session/{id}/sockets/adb": {
"get": {
"description": "A websocket connection endpoint which initiates the signaling process with the adb role.\nThis URL is returned then joining a session along with its credentials.",
"tags": [
"session"
],
"summary": "Join session as ADB client",
"operationId": "handle-adb-connect-session",
"responses": {}
}
},
"/1.0/session/{id}/sockets/master": {
"get": {
"description": "A websocket connection endpoint which initiates the signaling process with the master role.\nYou MUST call /sessions/{id}/join beforehand to prepare the android container.",
"tags": [
"session"
],
"summary": "Join session as master",
"operationId": "handle-master-connect-session",
"responses": {}
}
},
"/1.0/session/{id}/sockets/slave": {
"get": {
"description": "A websocket connection endpoint which initiates the signaling process with the slave role.\nThis URL is returned then joining a session along with its credentials.",
"tags": [
"session"
],
"summary": "Join session as slave",
"operationId": "handle-slave-connect-session",
"responses": {}
}
},
"/1.0/sessions": {
"get": {
"security": [
{
"AuthToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"session"
],
"summary": "Get all sessions",
"operationId": "handle-get-sessions",
"parameters": [
{
"type": "string",
"description": "Filter returned sessions by given status",
"name": "status",
"in": "query"
},
{
"type": "boolean",
"description": "Return full session objects rather than just their ID",
"name": "recursive",
"in": "query"
},
{
"type": "integer",
"description": "Limit number of results returned",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Offset to list results from",
"name": "offset",
"in": "query"
},
{
"type": "string",
"description": "Field of the session to sort results by",
"name": "sort_by",
"in": "query"
},
{
"type": "string",
"description": "Sort order of the returned results. Possible values are: asc, desc",
"name": "sort_order",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.SessionsGetResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
}
}
},
"post": {
"security": [
{
"AuthToken": []
}
],
"description": "Create a new session based on an application, application version, region\nand screen details. The newly created session is started immediately after\nbeing created. The returned session details can be used to immediately start\nthe signaling process. If an application version is not specified, the latest\napplication version will always be in use for a session creation.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"session"
],
"summary": "Create session",
"operationId": "handle-new-session",
"parameters": [
{
"description": "Session details",
"name": "session",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.SessionPost"
}
}
],
"responses": {
"201": {
"description": "Newly created session along with the information needed to connect to it",
"schema": {
"$ref": "#/definitions/api.SessionPostResponse"
}
},
"400": {
"description": "Invalid body or missing application",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"404": {
"description": "No agent can host the container",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
}
}
},
"delete": {
"security": [
{
"AuthToken": []
}
],
"tags": [
"session"
],
"summary": "Batch delete sessions",
"operationId": "handle-delete-sessions",
"parameters": [
{
"description": "List of session IDs to delete",
"name": "ids",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.SessionsDelete"
}
},
{
"type": "boolean",
"description": "Force deletion even if agent is not available. This may leave a container around on the agent.",
"name": "force",
"in": "query"
},
{
"type": "boolean",
"description": "Set to true to wait for the response (can take a long time for lots of sessions) or to false to return without waiting for all sessions to be deleted. Defaults to false",
"name": "sync",
"in": "query"
}
],
"responses": {
"200": {
"description": "Contains an array of deleted sessions as well as potential errors",
"schema": {
"$ref": "#/definitions/api.SessionsDeleteResponse"
}
},
"202": {
"description": "Returned when sync=true. Watch the session list for progress on the operation",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"207": {
"description": "Some sessions could not be deleted",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"400": {
"description": "Invalid request body",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"404": {
"description": "Non-existent sessions",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"500": {
"description": "Internal issue",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
}
}
}
},
"/1.0/sessions/{id}": {
"get": {
"security": [
{
"AuthToken": []
}
],
"description": "Returns a session from its ID.",
"produces": [
"application/json"
],
"tags": [
"session"
],
"summary": "Get session",
"operationId": "handle-get-session",
"parameters": [
{
"type": "string",
"description": "Session ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "The requested session",
"schema": {
"$ref": "#/definitions/api.SessionGetResponse"
}
},
"400": {
"description": "Invalid session ID",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"404": {
"description": "Non-existent session",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
}
}
},
"delete": {
"security": [
{
"AuthToken": []
}
],
"tags": [
"session"
],
"summary": "Delete a session",
"operationId": "handle-delete-session",
"parameters": [
{
"type": "string",
"description": "Session ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "boolean",
"description": "Force deletion even if agent is not available. This may leave a container around on the agent.",
"name": "force",
"in": "query"
},
{
"type": "boolean",
"description": "Set to true to wait for the response or to false to return early without waiting for the session to be deleted",
"name": "sync",
"in": "query"
}
],
"responses": {
"200": {
"description": "Empty response to indicate success",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"400": {
"description": "Invalid session ID",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"404": {
"description": "Non-existent session",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
}
}
}
},
"/1.0/sessions/{id}/connect": {
"get": {
"description": "Connect an existing running session from a client. The returned\nobject contains a URL with the required credentials for a client\nto connect to the remote Anbox instance.",
"tags": [
"session"
],
"summary": "Connect a session",
"operationId": "handle-connect-session",
"responses": {
"200": {
"description": "Object containing a URL with the required credentials to connect to the remote Anbox instance",
"schema": {
"$ref": "#/definitions/api.SessionConnectGetResponse"
}
},
"400": {
"description": "Missing session ID, inactive session, invalid connection type",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"401": {
"description": "Authorization failed",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"500": {
"description": "Error when failing to generate auth token/STUN servers, or setup connection",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
}
}
}
},
"/1.0/sessions/{id}/join": {
"post": {
"security": [
{
"AuthToken": []
}
],
"description": "Join an existing running session. The session must already be running. The\nreturned object contains a URL with the required credentials for a client\nto join the signaling process.",
"tags": [
"session"
],
"summary": "Join session",
"operationId": "handle-join-session",
"parameters": [
{
"description": "Additional information about the join request",
"name": "session",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.SessionJoinPost"
}
}
],
"responses": {
"200": {
"description": "Object containing the slave URL as well as optional additional STUN/TURN servers",
"schema": {
"$ref": "#/definitions/api.SessionJoinResponse"
}
},
"400": {
"description": "Missing session ID or invalid session state",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"404": {
"description": "The session does not exist",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"500": {
"description": "Error when trying to generate session details",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
}
}
}
},
"/1.0/sessions/{id}/share": {
"post": {
"security": [
{
"AuthToken": []
}
],
"description": "Share an existing running session with a client. The returned\nobject contains a URL for a client to interact with a session",
"tags": [
"session"
],
"summary": "Share session",
"operationId": "handle-share-session",
"parameters": [
{
"description": "Required parameters to the share request",
"name": "session",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.SessionSharePost"
}
}
],
"responses": {
"200": {
"description": "Object containing a URL for a client to interact with a session",
"schema": {
"$ref": "#/definitions/api.SessionSharePostResponse"
}
},
"400": {
"description": "Missing session ID, invalid request content, share type or expiration time",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"404": {
"description": "The session does not exist",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"500": {
"description": "Error when failing to generate auth token",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
}
}
}
},
"/1.0/status": {
"get": {
"description": "Returns the current status of the Gateway service along with some indicators that\ncan be helpful to determine larger issues. The Gateway can be either healthy or unhealthy.\nPlease note that a healthy status does not necessarily mean that a deployment is fully working.\nOther issues can affect the Streaming Stack but a healthy status only guarantees that the Gateway itself\nis not experiencing issues that would prevent it from working normally.\nChecking for status can take up to 7 seconds. Note that this is the upper bound, in normal\ncircumstances, the timing will be much lower and timings higher than a couple seconds are usually\nindicators or something wrong (network issue, node restarted, etc).\n",
"produces": [
"application/json"
],
"tags": [
"status"
],
"summary": "Returns the Gateway service status.",
"operationId": "handle-get-status",
"responses": {
"200": {
"description": "Only status is present if the request is not authenticated",
"schema": {
"$ref": "#/definitions/api.StatusGetResponseAuthenticated"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
},
"503": {
"description": "The Gateway is not fully started",
"schema": {
"$ref": "#/definitions/api_gateway.Response"
}
}
}
}
}
},
"definitions": {
"api.ApplicationsGetResponse": {
"type": "object",
"properties": {
"error": {
"description": "Error is an optional error message",
"type": "string",
"example": "invalid body format"
},
"metadata": {
"type": "array",
"items": {
"$ref": "#/definitions/api_gateway.Application"
}
},
"status": {
"description": "Status of the response",
"enum": [
"success",
"failed",
"unknown"
],
"allOf": [
{
"$ref": "#/definitions/api_gateway.ResponseStatus"
}
]
},
"status_code": {
"description": "StatusCode is the HTTP code of the response",
"type": "integer"
},
"type": {
"description": "Type of the operation",
"enum": [
"sync",
"async",
"error"
],
"allOf": [
{
"$ref": "#/definitions/api_gateway.ResponseType"
}
],
"example": "sync"
}
}
},
"api.Region": {
"type": "object",
"properties": {
"name": {
"type": "string",
"example": "eu-west-1"
}
}
},
"api.RegionsGetResponse": {
"type": "object",
"properties": {
"error": {
"description": "Error is an optional error message",
"type": "string",
"example": "invalid body format"
},
"metadata": {
"type": "array",
"items": {
"$ref": "#/definitions/api.Region"
}
},
"status": {
"description": "Status of the response",
"enum": [
"success",
"failed",
"unknown"
],
"allOf": [
{
"$ref": "#/definitions/api_gateway.ResponseStatus"
}
]
},
"status_code": {
"description": "StatusCode is the HTTP code of the response",
"type": "integer"
},
"type": {
"description": "Type of the operation",
"enum": [
"sync",
"async",
"error"
],
"allOf": [
{
"$ref": "#/definitions/api_gateway.ResponseType"
}
],
"example": "sync"
}
}
},
"api.Screen": {
"type": "object",
"properties": {
"density": {
"description": "Display density Android will be configured with. See https://developer.android.com/training/multiscreen/screendensities\nfor more details",
"type": "integer",
"default": 240,
"minimum": 72,
"example": 240
},
"fps": {
"description": "FPS the video stream will use",
"type": "integer",
"minimum": 1,
"example": 25
},
"height": {
"description": "Height of the screen",
"type": "integer",
"minimum": 1,
"example": 720
},
"width": {
"description": "Width of the screen",
"type": "integer",
"minimum": 1,
"example": 1280
}
}
},
"api.Session": {
"type": "object",
"properties": {
"app": {
"description": "App that will be run in the session.\nApplications are listed from AMS if they have been configured for streaming.",
"type": "string"
},
"cluster_id": {
"description": "ID of the cluster which the instance is deployed to",
"type": "string",
"example": "cluster0"
},
"container_id": {
"description": "ID of the container powering the session. If no container was created yet\nor the container is destroyed, the ID will be empty.",
"type": "string",
"example": "c05h1jj3pn6a8q46taug"
},
"id": {
"description": "ID of the session.",
"type": "string",
"example": "e25f3e3bcead096461d89d8ab7043f14bdb1ecd39"
},
"joinable": {
"description": "Marks wether the session is joinable or not",
"type": "boolean"
},
"region": {
"description": "Region on which the instance is located.",
"type": "string",
"example": "eu-west-1"
},
"status": {
"description": "Status of the session.\n created: sent creation request to an available agent.\n active: container is up and running.\n error: an error occurred and the container is stopped.\n terminated: the container has stopped gracefully, either by manual command or timeout.",
"enum": [
"created",
"active",
"error",
"terminating",
"terminated"
],
"allOf": [
{
"$ref": "#/definitions/api.SessionStatus"
}
]
},
"status_message": {
"description": "Message giving more information about the current status",
# --- truncated at 32 KB (59 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/canonical/refs/heads/main/openapi/canonical-anbox-stream-gateway-api-openapi.json