{
  "openapi": "3.1.0",
  "info": {
    "title": "Hangar Game & Software Distribution API",
    "version": "1.0.0",
    "description": "SpaceCorps Hangar multi-tenant game distribution platform, publisher REST API, and store services. Provides product catalog browsing, release channel telemetry, secure artifact downloads, and entitlement validation. URL path versioned (/api/v1). Deprecations announced via Sunset and Deprecation headers with 90-day grace period.",
    "x-versioning-policy": "URL path versioning (/api/v1). Deprecations announced via Sunset and Deprecation headers with 90-day grace period.",
    "contact": {
      "name": "SpaceCorps Operations",
      "url": "https://hangar.sliplane.app/"
    },
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    }
  },
  "servers": [
    {
      "url": "https://hangar.sliplane.app/api/v1",
      "description": "Production Web Client API Proxy"
    },
    {
      "url": "https://hangar-api.sliplane.app/api/v1",
      "description": "Production Backend Service"
    },
    {
      "url": "https://hangar.sliplane.app/sandbox",
      "description": "Verified Live Sandbox Environment"
    },
    {
      "url": "http://localhost:8480/api/v1",
      "description": "Local Development Server"
    }
  ],
  "components": {
    "securitySchemes": {
      "OAuth2": {
        "type": "oauth2",
        "description": "OAuth 2.0 authorization server",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://hangar.sliplane.app/api/v1/auth/token",
            "scopes": {
              "read:products": "View product listings and catalog metadata",
              "write:products": "Publish and edit product listings",
              "read:releases": "View release channel history and build metadata",
              "write:releases": "Publish releases and upload binary artifacts",
              "read:library": "Access entitled player library",
              "admin:org": "Full administrative access to organization settings"
            }
          }
        }
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Standard Bearer JWT session token"
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "Unique UUID token to guarantee idempotent execution on mutating requests."
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string"
        },
        "description": "Opaque cursor token for forward pagination."
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "default": 20,
          "maximum": 100
        },
        "description": "Maximum number of items to return per page."
      }
    },
    "headers": {
      "RateLimit-Limit": {
        "schema": {
          "type": "integer"
        },
        "description": "Request quota limit in the current time window."
      },
      "RateLimit-Remaining": {
        "schema": {
          "type": "integer"
        },
        "description": "Remaining request count in the current time window."
      },
      "RateLimit-Reset": {
        "schema": {
          "type": "integer"
        },
        "description": "Seconds until the rate limit quota resets."
      },
      "Retry-After": {
        "schema": {
          "type": "integer"
        },
        "description": "Seconds to wait before retrying a rate-limited request."
      }
    },
    "schemas": {
      "ProblemDetails": {
        "type": "object",
        "required": ["type", "title", "status", "detail"],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "example": "https://hangar.sliplane.app/errors/not-found"
          },
          "title": {
            "type": "string",
            "example": "Resource Not Found"
          },
          "status": {
            "type": "integer",
            "example": 404
          },
          "detail": {
            "type": "string",
            "example": "The requested product does not exist."
          },
          "instance": {
            "type": "string",
            "format": "uri",
            "example": "/api/v1/products/unknown"
          },
          "code": {
            "type": "string",
            "example": "resource_not_found"
          },
          "resolution": {
            "type": "string",
            "example": "Query GET /api/v1/products for available games."
          }
        }
      },
      "Error": {
        "type": "object",
        "required": ["code", "message"],
        "properties": {
          "code": {
            "type": "string",
            "example": "invalid_request"
          },
          "message": {
            "type": "string",
            "example": "Parameter validation failed."
          },
          "resolution": {
            "type": "string",
            "example": "Inspect request schema."
          }
        }
      },
      "Product": {
        "type": "object",
        "required": ["id", "slug", "title", "kind", "platforms"],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": "string",
            "example": "spacecorps-2027"
          },
          "title": {
            "type": "string",
            "example": "SpaceCorps 2027"
          },
          "description": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": ["game", "app", "tool"]
          },
          "platforms": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["windows", "macos", "linux", "android", "ios", "web"]
            }
          }
        }
      },
      "ProductList": {
        "type": "object",
        "required": ["items", "next_cursor"],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Product"
            }
          },
          "next_cursor": {
            "type": ["string", "null"],
            "example": "eyJwb3NpdGlvbiI6MjB9"
          }
        }
      },
      "Release": {
        "type": "object",
        "required": ["version", "channel", "published_at"],
        "properties": {
          "version": {
            "type": "string",
            "example": "0.4.0"
          },
          "channel": {
            "type": "string",
            "enum": ["stable", "beta", "nightly", "alpha"]
          },
          "published_at": {
            "type": "string",
            "format": "date-time"
          },
          "notes": {
            "type": "string"
          }
        }
      },
      "BatchRequest": {
        "type": "object",
        "required": ["operations"],
        "properties": {
          "operations": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["method", "path"],
              "properties": {
                "method": {
                  "type": "string",
                  "enum": ["GET", "POST", "PUT"]
                },
                "path": {
                  "type": "string"
                },
                "body": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "BatchResponse": {
        "type": "object",
        "required": ["results"],
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["status", "body"],
              "properties": {
                "status": {
                  "type": "integer"
                },
                "body": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "JobStatus": {
        "type": "object",
        "required": ["job_id", "status"],
        "properties": {
          "job_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": ["queued", "running", "completed", "failed"]
          },
          "progress": {
            "type": "number"
          }
        }
      }
    }
  },
  "paths": {
    "/health": {
      "get": {
        "summary": "Liveness & Health Probe",
        "description": "Probe system readiness, active database connection, and storage backend status.",
        "operationId": "getHealth",
        "responses": {
          "200": {
            "description": "Service healthy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["status"],
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "version": {
                      "type": "string",
                      "example": "1.0.0"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "description": "Response format specifier",
            "required": false,
            "schema": {
              "type": "string",
              "default": "json"
            }
          }
        ]
      }
    },
    "/info": {
      "get": {
        "summary": "Service Information",
        "description": "Return service version, storage driver, and enabled features.",
        "operationId": "getServiceInfo",
        "responses": {
          "200": {
            "description": "Service information",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["service", "version"],
                  "properties": {
                    "service": {
                      "type": "string",
                      "example": "hangar-api"
                    },
                    "version": {
                      "type": "string",
                      "example": "1.0.0"
                    },
                    "storage": {
                      "type": "string",
                      "example": "fs"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "description": "Response format specifier",
            "required": false,
            "schema": {
              "type": "string",
              "default": "json"
            }
          }
        ]
      }
    },
    "/products": {
      "get": {
        "summary": "List Products",
        "description": "Retrieve published game and application catalog with cursor pagination.",
        "operationId": "listProducts",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "description": "Opaque cursor token for forward pagination.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of items to return per page.",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product catalog list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductList"
                }
              }
            }
          }
        }
      }
    },
    "/products/{id}": {
      "get": {
        "summary": "Get Product Details",
        "description": "Fetch detailed metadata, release channels, and media assets for a product.",
        "operationId": "getProduct",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Product ID or slug"
          }
        ],
        "responses": {
          "200": {
            "description": "Product metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "404": {
            "description": "Product not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/products/{id}/releases": {
      "get": {
        "summary": "List Product Releases",
        "description": "Retrieve historical and current release versions for a product.",
        "operationId": "listReleases",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Product ID or slug"
          }
        ],
        "responses": {
          "200": {
            "description": "Release list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Release"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/library": {
      "get": {
        "summary": "Get User Library",
        "description": "Retrieve games and applications entitled to the authenticated user account.",
        "operationId": "getUserLibrary",
        "security": [
          {
            "BearerAuth": []
          },
          {
            "OAuth2": ["read:library"]
          }
        ],
        "responses": {
          "200": {
            "description": "User library",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Product"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of entitled library items to return",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Pagination cursor token",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/redeem": {
      "post": {
        "summary": "Redeem Product Access Code",
        "description": "Claim an entitlement license key or promotional voucher into the user account.",
        "operationId": "redeemCode",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique UUID token to guarantee idempotent execution on mutating requests.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["code"],
                "properties": {
                  "code": {
                    "type": "string",
                    "example": "SPACECORPS-PROMO-2027"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Code redeemed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["success", "product_id"],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "product_id": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/batch": {
      "post": {
        "summary": "Execute Bulk Batch Operations",
        "description": "Execute multiple read/write operations in an atomic or parallel batch request.",
        "operationId": "executeBatchOperations",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique UUID token to guarantee idempotent execution on mutating requests.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["operations"],
                "properties": {
                  "operations": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/BatchOperation"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch execution results",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                }
              }
            }
          }
        }
      }
    },
    "/jobs": {
      "post": {
        "summary": "Create Asynchronous Job",
        "description": "Queue an asynchronous build processing, archive extraction, or verification task.",
        "operationId": "createAsyncJob",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique UUID token to guarantee idempotent execution on mutating requests.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["type", "payload"],
                "properties": {
                  "type": {
                    "type": "string",
                    "example": "verify_build"
                  },
                  "payload": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job finished synchronously",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "202": {
            "description": "Job accepted and queued for asynchronous background processing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}": {
      "get": {
        "summary": "Get Asynchronous Job Status",
        "description": "Poll the lifecycle state and output artifacts of an asynchronous job.",
        "operationId": "getAsyncJob",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Unique job identifier"
          }
        ],
        "responses": {
          "200": {
            "description": "Job status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          }
        }
      }
    },
    "/sandbox": {
      "get": {
        "summary": "Sandbox Environment Metadata",
        "description": "Verified non-destructive sandbox simulation environment for autonomous AI agents.",
        "operationId": "getSandboxMetadata",
        "responses": {
          "200": {
            "description": "Sandbox metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["sandbox", "status", "environment"],
                  "properties": {
                    "sandbox": {
                      "type": "boolean"
                    },
                    "status": {
                      "type": "string"
                    },
                    "environment": {
                      "type": "string"
                    },
                    "free_tier": {
                      "type": "boolean"
                    },
                    "self_serve_keys": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "description": "Response format specifier",
            "required": false,
            "schema": {
              "type": "string",
              "default": "json"
            }
          }
        ]
      }
    },
    "/sandbox/api/v1/health": {
      "get": {
        "summary": "Sandbox Health Check",
        "description": "Live health probe for the agentic sandbox environment.",
        "operationId": "getSandboxHealth",
        "responses": {
          "200": {
            "description": "Health status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["status", "environment"],
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "environment": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "description": "Response format specifier",
            "required": false,
            "schema": {
              "type": "string",
              "default": "json"
            }
          }
        ]
      }
    },
    "/sandbox/api/v1/telemetry": {
      "get": {
        "summary": "Sandbox Simulation Telemetry",
        "description": "Retrieve active telemetry metrics from the sandbox environment.",
        "operationId": "getSandboxTelemetry",
        "responses": {
          "200": {
            "description": "Telemetry status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["status", "active_agents"],
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "active_agents": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "description": "Response format specifier",
            "required": false,
            "schema": {
              "type": "string",
              "default": "json"
            }
          }
        ]
      }
    },
    "/api/keys": {
      "get": {
        "summary": "Self-Serve API Key Generation",
        "description": "Provision instant agent credentials with zero human friction.",
        "operationId": "generateSelfServeApiKey",
        "responses": {
          "200": {
            "description": "Provisioned key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["status", "api_key", "self_serve"],
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "api_key": {
                      "type": "string"
                    },
                    "self_serve": {
                      "type": "boolean"
                    },
                    "free_tier": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "tier",
            "in": "query",
            "description": "Desired API key tier (community, sandbox, agent)",
            "required": false,
            "schema": {
              "type": "string",
              "default": "community"
            }
          }
        ]
      }
    },
    "/ask": {
      "post": {
        "summary": "NLWeb Natural Language Query",
        "description": "Ask natural language questions about games, lore, and software releases.",
        "operationId": "askNLWeb",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["query"],
                "properties": {
                  "query": {
                    "type": "string",
                    "example": "What ships are available in SpaceCorps 2027?"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Natural language answer",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["answer"],
                  "properties": {
                    "answer": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "stream",
            "in": "query",
            "description": "Enable Server-Sent Events (SSE) streaming output",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ]
      },
      "get": {
        "summary": "NLWeb Query via GET",
        "description": "Query natural language answer using URL parameter.",
        "operationId": "askNLWebGet",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Query string"
          }
        ],
        "responses": {
          "200": {
            "description": "Natural language answer",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["answer"],
                  "properties": {
                    "answer": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
