{
  "openapi": "3.1.0",
  "info": {
    "title": "ComputerUse management API",
    "version": "0.2.0",
    "description": "Deployed management API; physical computer availability, live payments and host transfers disabled. Planned desktop-control APIs are intentionally not represented as deployed operations."
  },
  "servers": [
    {
      "url": "https://api.computeruse.space",
      "description": "Deployed HTTPS management service; compute launch pending."
    }
  ],
  "paths": {
    "/api/v1/stock": {
      "get": {
        "operationId": "get_stock",
        "summary": "Read verified capacity and plan pricing",
        "tags": [
          "Rentals"
        ],
        "description": "Public inventory. purchases_enabled must be true and available positive before checkout; a read is not a reservation.",
        "security": [],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/account": {
      "get": {
        "operationId": "get_account",
        "summary": "Read account-owned rentals and credit metadata",
        "tags": [
          "Accounts"
        ],
        "description": "Read account-owned rentals and credit metadata",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "account:read"
      }
    },
    "/api/v1/register": {
      "post": {
        "operationId": "post_register",
        "summary": "Register a customer account",
        "tags": [
          "Accounts"
        ],
        "description": "Register a customer account",
        "security": [],
        "responses": {
          "201": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 254
                  },
                  "password": {
                    "type": "string",
                    "minLength": 15,
                    "maxLength": 128
                  }
                },
                "required": [
                  "email",
                  "password"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/login": {
      "post": {
        "operationId": "post_login",
        "summary": "Sign in and issue an expiring session",
        "tags": [
          "Accounts"
        ],
        "description": "Administrators need an MFA code. Response fields: token, id, expires (Unix seconds). Session lifetime: one hour.",
        "security": [],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  },
                  "code": {
                    "type": "string"
                  }
                },
                "required": [
                  "email",
                  "password"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/logout": {
      "post": {
        "operationId": "post_logout",
        "summary": "Revoke the current credential",
        "tags": [
          "Accounts"
        ],
        "description": "Revoke the current credential",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "authenticated",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "required": [],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/recover": {
      "post": {
        "operationId": "post_recover",
        "summary": "Reset password using an issued recovery token",
        "tags": [
          "Accounts"
        ],
        "description": "Reset password using an issued recovery token",
        "security": [],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "recovery_token": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  },
                  "code": {
                    "type": "string"
                  }
                },
                "required": [
                  "recovery_token",
                  "password"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/keys": {
      "post": {
        "operationId": "post_keys",
        "summary": "Create an expiring customer API key",
        "tags": [
          "Keys"
        ],
        "description": "Session only. Customer keys expire after 30 days. Response: token, id, expires. Store token securely; it is not retrievable from key metadata.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "keys:write",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "scopes": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string",
                      "enum": [
                        "account:read",
                        "rentals:write",
                        "agents:write"
                      ]
                    }
                  }
                },
                "required": [
                  "scopes"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/keys/revoke": {
      "post": {
        "operationId": "post_keys_revoke",
        "summary": "Revoke an owned credential",
        "tags": [
          "Keys"
        ],
        "description": "Revoke an owned credential",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "keys:write",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "id"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/purchases": {
      "post": {
        "operationId": "post_purchases",
        "summary": "Spend prepaid credit and reserve one computer",
        "tags": [
          "Rentals"
        ],
        "description": "Prelaunch checkout is closed (503). Atomic stock/balance checks. Returns id, plan, state, amount, billing_period, agent_id; no internal host credentials.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "rentals:write",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "Stable identifier for this intended operation; reuse across retries."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "plan": {
                    "type": "string",
                    "enum": [
                      "standard",
                      "creator"
                    ]
                  },
                  "term": {
                    "type": "string",
                    "enum": [
                      "30_days",
                      "1_year"
                    ],
                    "default": "30_days"
                  }
                },
                "required": [
                  "plan"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/orders": {
      "post": {
        "operationId": "post_orders",
        "summary": "Reserve a mixed fleet of computers atomically",
        "tags": [
          "Rentals"
        ],
        "description": "1\u2013100 computers total. Mixed 8 GB/16 GB plans supported. Full stock and credit checked in one transaction; no partial reservation on failure. Returns order id, quantity, amount_minor, currency, term and individual rentals. Reuse the same key across uncertain retries. Provisioning/refunds/renewal operate per computer. Prelaunch checkout returns 503.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "rentals:write",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "Stable identifier for this intended operation; reuse across retries."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 100,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "plan",
                        "quantity"
                      ],
                      "properties": {
                        "plan": {
                          "type": "string",
                          "enum": [
                            "standard",
                            "creator"
                          ]
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 100
                        }
                      }
                    }
                  },
                  "term": {
                    "type": "string",
                    "enum": [
                      "30_days",
                      "1_year"
                    ],
                    "default": "30_days"
                  }
                },
                "required": [
                  "items"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/rentals/renewal": {
      "post": {
        "operationId": "post_rentals_renewal",
        "summary": "Set the renewal preference on an owned rental",
        "tags": [
          "Rentals"
        ],
        "description": "Stops or re-enables prepaid renewal. Does not erase files or revoke the already paid term.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "rentals:write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "rental_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "auto_renew": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "rental_id",
                  "auto_renew"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/assignments": {
      "post": {
        "operationId": "post_assignments",
        "summary": "Assign an agent identifier to an owned active rental",
        "tags": [
          "Rentals"
        ],
        "description": "Records an agent association only. Does not provide desktop control.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "agents:write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "rental_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "agent_id": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "rental_id",
                  "agent_id"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/topups": {
      "post": {
        "operationId": "post_topups",
        "summary": "Create a Stripe credit top-up Checkout",
        "tags": [
          "Billing"
        ],
        "description": "USD minor units. Requires configured sandbox provider; no credit until verified payment settlement. Live billing remains disabled.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "billing:write",
        "x-session-required": true,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "Stable identifier for this intended operation; reuse across retries."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount_minor": {
                    "type": "integer"
                  }
                },
                "required": [
                  "amount_minor"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/stripe/webhook": {
      "post": {
        "operationId": "post_stripe_webhook",
        "summary": "Receive a signed Stripe event",
        "tags": [
          "Billing"
        ],
        "description": "Provider webhook, not a customer API. Requires configured Stripe-Signature verification and exact raw JSON body, up to 256 KiB. Credit is idempotent against matching paid settlement.",
        "security": [],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "required": [],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Stripe-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/v1/proxies/catalog": {
      "get": {
        "operationId": "get_proxies_catalog",
        "summary": "Read configured proxy catalog",
        "tags": [
          "Proxies"
        ],
        "description": "Read configured proxy catalog",
        "security": [],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/proxies/quote": {
      "post": {
        "operationId": "post_proxies_quote",
        "summary": "Quote an optional proxy without purchasing",
        "tags": [
          "Proxies"
        ],
        "description": "Quote an optional proxy without purchasing",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "account:read",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sku": {
                    "type": "string",
                    "minLength": 1
                  },
                  "quantity": {
                    "type": "integer"
                  }
                },
                "required": [
                  "sku",
                  "quantity"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/admin": {
      "get": {
        "operationId": "get_admin",
        "summary": "Read administrative account and machine state",
        "tags": [
          "Administration"
        ],
        "description": "Administrator MFA session only.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "admin:read",
        "x-session-required": true
      }
    },
    "/api/v1/admin/operations": {
      "get": {
        "operationId": "get_admin_operations",
        "summary": "Read provider and lifecycle operations",
        "tags": [
          "Administration"
        ],
        "description": "Read provider and lifecycle operations",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "admin:read",
        "x-session-required": true
      }
    },
    "/api/v1/admin/suspend": {
      "post": {
        "operationId": "post_admin_suspend",
        "summary": "Suspend an account and queue desktop revocation",
        "tags": [
          "Administration"
        ],
        "description": "Revokes account credentials. Desktop access is pending until a physical controller confirms revocation.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "admin:write",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "account_id": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "account_id"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/admin/reconcile": {
      "post": {
        "operationId": "post_admin_reconcile",
        "summary": "Reconcile a provider operation",
        "tags": [
          "Administration"
        ],
        "description": "Reconcile a provider operation",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "admin:write",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "kind": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "provider_id": {
                    "type": "string"
                  }
                },
                "required": [
                  "kind",
                  "id"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/admin/refunds": {
      "post": {
        "operationId": "post_admin_refunds",
        "summary": "Start a validated top-up refund",
        "tags": [
          "Administration"
        ],
        "description": "Start a validated top-up refund",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "admin:write",
        "x-session-required": true,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "Stable identifier for this intended operation; reuse across retries."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "topup_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "amount_minor": {
                    "type": "integer"
                  }
                },
                "required": [
                  "topup_id",
                  "amount_minor"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/hosts/account": {
      "get": {
        "operationId": "get_hosts_account",
        "summary": "Read own host ID, nodes and assessment",
        "tags": [
          "Hosts"
        ],
        "description": "Read own host ID, nodes and assessment",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "account:read",
        "x-session-required": true
      }
    },
    "/api/v1/hosts/connect": {
      "get": {
        "operationId": "get_hosts_connect",
        "summary": "Read own Stripe Connect status",
        "tags": [
          "Hosts"
        ],
        "description": "Read own Stripe Connect status",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "account:read",
        "x-session-required": true
      },
      "post": {
        "operationId": "post_hosts_connect",
        "summary": "Open Stripe-hosted onboarding in test mode",
        "tags": [
          "Hosts"
        ],
        "description": "Open Stripe-hosted onboarding in test mode",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "account:read",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "required": [],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/hosts/apply": {
      "post": {
        "operationId": "post_hosts_apply",
        "summary": "Apply as a host and receive a numeric ID",
        "tags": [
          "Hosts"
        ],
        "description": "Apply as a host and receive a numeric ID",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "account:read",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string"
                  },
                  "assessment_consent": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "name",
                  "country",
                  "assessment_consent"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/hosts/lookup": {
      "post": {
        "operationId": "post_hosts_lookup",
        "summary": "Check a public host ID without exposing contact information",
        "tags": [
          "Hosts"
        ],
        "description": "Check a public host ID without exposing contact information",
        "security": [],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "host_id": {
                    "type": "integer"
                  }
                },
                "required": [
                  "host_id"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/hosts/pairing": {
      "post": {
        "operationId": "post_hosts_pairing",
        "summary": "Generate a one-use 24-hour node pairing code",
        "tags": [
          "Hosts"
        ],
        "description": "Generate a one-use 24-hour node pairing code",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "account:read",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "required": [],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/hosts/connect/refresh": {
      "post": {
        "operationId": "post_hosts_connect_refresh",
        "summary": "Retrieve verified current Connect account status",
        "tags": [
          "Hosts"
        ],
        "description": "Retrieve verified current Connect account status",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "account:read",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "required": [],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/workers/join": {
      "post": {
        "operationId": "post_workers_join",
        "summary": "Enroll a company or paired host node",
        "tags": [
          "Workers"
        ],
        "description": "Rate-limited. Company mode needs company_password; host mode needs host_id and private pairing_code. Installs no saleable capacity; response distinguishes approval from pending rental readiness.",
        "security": [],
        "responses": {
          "201": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mode": {
                    "enum": [
                      "company",
                      "host"
                    ]
                  },
                  "company_password": {
                    "type": "string"
                  },
                  "host_id": {
                    "type": "integer"
                  },
                  "pairing_code": {
                    "type": "string"
                  },
                  "installation_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "worker_token": {
                    "type": "string"
                  },
                  "report": {
                    "type": "object"
                  }
                },
                "required": [
                  "mode",
                  "installation_id",
                  "worker_token",
                  "report"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/workers/enroll": {
      "post": {
        "operationId": "post_workers_enroll",
        "summary": "Enroll through a scoped operator grant",
        "tags": [
          "Workers"
        ],
        "description": "Enroll through a scoped operator grant",
        "security": [],
        "responses": {
          "201": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enrollment_token": {
                    "type": "string"
                  },
                  "installation_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "worker_token": {
                    "type": "string"
                  },
                  "report": {
                    "type": "object"
                  }
                },
                "required": [
                  "enrollment_token",
                  "installation_id",
                  "worker_token",
                  "report"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/workers/heartbeat": {
      "post": {
        "operationId": "post_workers_heartbeat",
        "summary": "Report worker metrics",
        "tags": [
          "Workers"
        ],
        "description": "Report worker metrics",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "worker credential",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "worker_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "report": {
                    "type": "object"
                  }
                },
                "required": [
                  "worker_id",
                  "report"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/workers/bandwidth": {
      "post": {
        "operationId": "post_workers_bandwidth",
        "summary": "Report approximate timed transfer samples",
        "tags": [
          "Workers"
        ],
        "description": "Report approximate timed transfer samples",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "worker credential",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "download_mbps": {
                    "type": "integer"
                  },
                  "upload_mbps": {
                    "type": "integer"
                  },
                  "latency_ms": {
                    "type": "integer"
                  }
                },
                "required": [
                  "download_mbps",
                  "upload_mbps",
                  "latency_ms"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet": {
      "get": {
        "operationId": "get_fleet",
        "summary": "Read fleet health and qualification evidence",
        "tags": [
          "Fleet"
        ],
        "description": "Staff MFA session or owner-issued read-only observer key. Financial and applicant contact data is owner-only.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "fleet:read"
      }
    },
    "/api/v1/fleet/revoke": {
      "post": {
        "operationId": "post_fleet_revoke",
        "summary": "Fleet Revoke",
        "tags": [
          "Fleet"
        ],
        "description": "Staff permissions and MFA enforced by operation. Staff grants, observer keys, host review, inventory binding and Connect reconciliation require the owner. No operation enables live transfers.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "fleet:write",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "kind": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "kind",
                  "id"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet/staff": {
      "post": {
        "operationId": "post_fleet_staff",
        "summary": "Fleet Staff",
        "tags": [
          "Fleet"
        ],
        "description": "Staff permissions and MFA enforced by operation. Staff grants, observer keys, host review, inventory binding and Connect reconciliation require the owner. No operation enables live transfers.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "fleet:write",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "account_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "role": {
                    "type": "string"
                  }
                },
                "required": [
                  "account_id",
                  "role"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet/observer-keys": {
      "post": {
        "operationId": "post_fleet_observer-keys",
        "summary": "Fleet Observer-Keys",
        "tags": [
          "Fleet"
        ],
        "description": "Staff permissions and MFA enforced by operation. Staff grants, observer keys, host review, inventory binding and Connect reconciliation require the owner. No operation enables live transfers.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "fleet:write",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string"
                  }
                },
                "required": [
                  "label"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet/enrollment": {
      "post": {
        "operationId": "post_fleet_enrollment",
        "summary": "Fleet Enrollment",
        "tags": [
          "Fleet"
        ],
        "description": "Staff permissions and MFA enforced by operation. Staff grants, observer keys, host review, inventory binding and Connect reconciliation require the owner. No operation enables live transfers.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "fleet:write",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string"
                  },
                  "uses": {
                    "type": "integer"
                  },
                  "hours": {
                    "type": "integer"
                  }
                },
                "required": [
                  "label",
                  "uses",
                  "hours"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet/host-review": {
      "post": {
        "operationId": "post_fleet_host-review",
        "summary": "Fleet Host-Review",
        "tags": [
          "Fleet"
        ],
        "description": "Staff permissions and MFA enforced by operation. Staff grants, observer keys, host review, inventory binding and Connect reconciliation require the owner. No operation enables live transfers.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "fleet:write",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "application_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "decision": {
                    "type": "string"
                  }
                },
                "required": [
                  "application_id",
                  "decision"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet/bind": {
      "post": {
        "operationId": "post_fleet_bind",
        "summary": "Fleet Bind",
        "tags": [
          "Fleet"
        ],
        "description": "Staff permissions and MFA enforced by operation. Staff grants, observer keys, host review, inventory binding and Connect reconciliation require the owner. No operation enables live transfers.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "fleet:write",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "worker_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "machine_id": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "worker_id",
                  "machine_id"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet/connect/reconcile": {
      "post": {
        "operationId": "post_fleet_connect_reconcile",
        "summary": "Fleet Connect Reconcile",
        "tags": [
          "Fleet"
        ],
        "description": "Staff permissions and MFA enforced by operation. Staff grants, observer keys, host review, inventory binding and Connect reconciliation require the owner. No operation enables live transfers.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "fleet:write",
        "x-session-required": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "host_id": {
                    "type": "integer"
                  },
                  "stripe_id": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "host_id",
                  "stripe_id"
                ],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    },
    "/api/v1/connect/webhook": {
      "post": {
        "operationId": "post_connect_webhook",
        "summary": "Receive signed Stripe Connect account updates",
        "tags": [
          "Hosts"
        ],
        "description": "Verified exact raw body and Connect-specific webhook secret required. Test mode only. Retrieves current account state to avoid stale webhook regression.",
        "security": [],
        "responses": {
          "200": {
            "description": "Successful request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Request denied, invalid, unavailable or uncertain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "required": [],
                "description": "Normal request body limit: 16 KiB."
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Expiring account session or scoped API key. Admin routes require an MFA-authenticated admin session."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      }
    }
  }
}
