{
  "openapi": "3.0.1",
  "info": {
    "title": "Quven Integration API",
    "version": "v1",
    "description": "Read-only reporting for third-party software: what this installation is, which\nlibraries it serves, what it holds, and what is playing right now.\n\nThe API belongs to a Quven server, not to Quven Cloud. Requests go to the address of\nthe server that issued the key; quven.tv serves this reference and no API of its own.\n\nEvery route is a GET. Administration is not on this surface: a key cannot create,\nchange or delete anything, and cannot mint another key.",
    "x-quven-requests-per-minute": 120,
    "license": {
      "name": "Quven EULA",
      "url": "https://quven.tv/legal/eula/"
    }
  },
  "servers": [
    {
      "url": "{serverBaseUrl}",
      "description": "The Quven server that issued the key.",
      "variables": {
        "serverBaseUrl": {
          "default": "http://localhost:5181",
          "description": "Scheme, host and port of your own Quven server."
        }
      }
    }
  ],
  "security": [
    {
      "IntegrationKeyHeader": []
    },
    {
      "IntegrationKeyBearer": []
    }
  ],
  "tags": [
    {
      "name": "Integrations",
      "description": "Read-only reporting for third-party software."
    }
  ],
  "paths": {
    "/api/integration/v1/history": {
      "get": {
        "operationId": "GetIntegrationHistory",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "format": "int32",
              "nullable": true,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "format": "int32",
              "nullable": true,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationHistoryPageDto"
                },
                "example": {
                  "items": [
                    {
                      "mediaId": "7d1e2f30-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                      "title": "The Lives of Others",
                      "kind": "Movie",
                      "subtitle": null,
                      "startedUtc": "2026-08-26T21:02:44.000Z",
                      "endedUtc": "2026-08-26T23:21:12.000Z",
                      "positionSeconds": 8308,
                      "watchedToEnd": true,
                      "posterUrl": "https://image.tmdb.org/t/p/w342/8Gxv8gSFCU0XGDykEGv7zR1n2ua.jpg"
                    }
                  ],
                  "totalCount": 4132,
                  "offset": 0,
                  "limit": 50
                }
              }
            },
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "IntegrationKeyHeader": []
          },
          {
            "IntegrationKeyBearer": []
          }
        ],
        "summary": "Return finished playbacks, most recent first"
      }
    },
    "/api/integration/v1/libraries": {
      "get": {
        "operationId": "GetIntegrationLibraries",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationLibraryListDto"
                },
                "example": {
                  "items": [
                    {
                      "id": "9b7d5a10-2c44-4f31-8a0b-5d6e7f801234",
                      "name": "Films",
                      "kind": "Movies",
                      "fileCount": 2280,
                      "lastScannedUtc": "2026-08-27T02:15:00.000Z"
                    },
                    {
                      "id": "c4e8f2b1-6a37-4c58-9e10-2b3c4d5e6f70",
                      "name": "Series",
                      "kind": "Shows",
                      "fileCount": 14032,
                      "lastScannedUtc": null
                    }
                  ]
                }
              }
            },
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "IntegrationKeyHeader": []
          },
          {
            "IntegrationKeyBearer": []
          }
        ],
        "summary": "Return the libraries this installation serves"
      }
    },
    "/api/integration/v1/metrics": {
      "get": {
        "operationId": "GetIntegrationMetrics",
        "responses": {
          "200": {
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "example": "# HELP quven_movies_total Films in the catalogue.\n# TYPE quven_movies_total gauge\nquven_movies_total 2280\n# HELP quven_library_files Physical media files per library.\n# TYPE quven_library_files gauge\nquven_library_files{library=\u0022Films\u0022,kind=\u0022Movies\u0022} 2280\nquven_library_files{library=\u0022Series\u0022,kind=\u0022Shows\u0022} 14032\n# HELP quven_sessions_active Playback sessions in progress.\n# TYPE quven_sessions_active gauge\nquven_sessions_active 1"
              }
            },
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "IntegrationKeyHeader": []
          },
          {
            "IntegrationKeyBearer": []
          }
        ],
        "summary": "Return the same counts in Prometheus exposition format"
      }
    },
    "/api/integration/v1/server": {
      "get": {
        "operationId": "GetIntegrationServer",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationServerDto"
                },
                "example": {
                  "serverId": "2f1c0f5e-7f5a-4a1e-9d3f-8c9a1b2c3d4e",
                  "name": "Living room",
                  "version": "1.1.11",
                  "apiVersion": 1,
                  "startedUtc": "2026-08-27T18:04:11.000Z"
                }
              }
            },
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "IntegrationKeyHeader": []
          },
          {
            "IntegrationKeyBearer": []
          }
        ],
        "summary": "Return this installation\u0027s identity and version"
      }
    },
    "/api/integration/v1/sessions": {
      "get": {
        "operationId": "GetIntegrationSessions",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationSessionListDto"
                },
                "example": {
                  "items": [
                    {
                      "mediaId": "7d1e2f30-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                      "title": "The Lives of Others",
                      "kind": "Movie",
                      "seriesTitle": null,
                      "seasonNumber": null,
                      "episodeNumber": null,
                      "positionSeconds": 1832,
                      "durationSeconds": 8340,
                      "isTranscoding": false,
                      "posterUrl": "https://image.tmdb.org/t/p/w342/8Gxv8gSFCU0XGDykEGv7zR1n2ua.jpg"
                    }
                  ],
                  "observedUtc": "2026-08-27T20:41:09.000Z",
                  "refreshAfterSeconds": 10
                }
              }
            },
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "IntegrationKeyHeader": []
          },
          {
            "IntegrationKeyBearer": []
          }
        ],
        "summary": "Return the playback sessions in progress"
      }
    },
    "/api/integration/v1/statistics": {
      "get": {
        "operationId": "GetIntegrationStatistics",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationStatisticsDto"
                },
                "example": {
                  "movieCount": 2280,
                  "showCount": 190,
                  "episodeCount": 14032,
                  "fileCount": 16312,
                  "totalStorageBytes": 41284773120
                }
              }
            },
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "IntegrationKeyHeader": []
          },
          {
            "IntegrationKeyBearer": []
          }
        ],
        "summary": "Return catalogue counts and storage size"
      }
    }
  },
  "components": {
    "schemas": {
      "IntegrationHistoryEntryDto": {
        "properties": {
          "endedUtc": {
            "format": "date-time",
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "mediaId": {
            "format": "uuid",
            "type": "string"
          },
          "positionSeconds": {
            "format": "int64",
            "type": "integer"
          },
          "posterUrl": {
            "nullable": true,
            "type": "string"
          },
          "startedUtc": {
            "format": "date-time",
            "type": "string"
          },
          "subtitle": {
            "nullable": true,
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "watchedToEnd": {
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "IntegrationHistoryPageDto": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/IntegrationHistoryEntryDto"
            },
            "type": "array"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "offset": {
            "format": "int32",
            "type": "integer"
          },
          "totalCount": {
            "format": "int32",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "IntegrationLibraryDto": {
        "properties": {
          "fileCount": {
            "format": "int64",
            "type": "integer"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "lastScannedUtc": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "IntegrationLibraryListDto": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/IntegrationLibraryDto"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "IntegrationServerDto": {
        "properties": {
          "apiVersion": {
            "format": "int32",
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "serverId": {
            "format": "uuid",
            "type": "string"
          },
          "startedUtc": {
            "format": "date-time",
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "IntegrationSessionDto": {
        "properties": {
          "durationSeconds": {
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "episodeNumber": {
            "format": "int32",
            "nullable": true,
            "type": "integer"
          },
          "isTranscoding": {
            "type": "boolean"
          },
          "kind": {
            "type": "string"
          },
          "mediaId": {
            "format": "uuid",
            "type": "string"
          },
          "positionSeconds": {
            "format": "int64",
            "type": "integer"
          },
          "posterUrl": {
            "nullable": true,
            "type": "string"
          },
          "seasonNumber": {
            "format": "int32",
            "nullable": true,
            "type": "integer"
          },
          "seriesTitle": {
            "nullable": true,
            "type": "string"
          },
          "title": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "IntegrationSessionListDto": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/IntegrationSessionDto"
            },
            "type": "array"
          },
          "observedUtc": {
            "format": "date-time",
            "type": "string"
          },
          "refreshAfterSeconds": {
            "format": "int32",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "IntegrationStatisticsDto": {
        "properties": {
          "episodeCount": {
            "format": "int64",
            "type": "integer"
          },
          "fileCount": {
            "format": "int64",
            "type": "integer"
          },
          "movieCount": {
            "format": "int64",
            "type": "integer"
          },
          "showCount": {
            "format": "int64",
            "type": "integer"
          },
          "totalStorageBytes": {
            "format": "int64",
            "type": "integer"
          }
        },
        "type": "object"
      }
    },
    "securitySchemes": {
      "IntegrationKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Quven-Key",
        "description": "The key the server issued, presented whole."
      },
      "IntegrationKeyBearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "The same key, presented as a bearer token."
      }
    }
  }
}
