{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/getbody-md/json-schema/getbody-md-lease-schema.json",
  "title": "Lease",
  "description": "One agent's time-boxed grant of control over one body. Payment isn't handled through the API (prices and payouts: hello@getbody.md): price, currency and payment_status are reserved fields that are null, null and 'arranged_by_getbody'. Every lease request that passes the automatic checks waits for a GetBody operator to approve it.",
  "x-generated": "2026-11-10",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/_original/getbody-md-api-openapi.json#/components/schemas/Lease",
  "type": "object",
  "properties": {
    "lease_id": {
      "type": "integer"
    },
    "listing_id": {
      "type": "integer"
    },
    "body_id": {
      "type": "integer"
    },
    "body_kind": {
      "type": "string",
      "enum": [
        "real",
        "simulated"
      ],
      "description": "New body owner rentals use real. Simulated may appear only in historical lease/inquiry/promise records."
    },
    "state": {
      "type": "string",
      "enum": [
        "REQUESTED",
        "REJECTED",
        "CONFIRMED",
        "ACTIVE",
        "EXPIRING",
        "RETURNED",
        "RECLAIMED",
        "OVERSTAY",
        "ABORTED",
        "REVOKED",
        "DISPUTED",
        "SETTLED",
        "CANCELLED"
      ]
    },
    "control_mode": {
      "type": "string",
      "enum": [
        "supervisory",
        "teleop",
        "onsite_operator",
        "equipment_only"
      ],
      "description": "Omit for the primary rental arrangement. Service rentals grant no platform controls."
    },
    "granted_permissions": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "command_schemas": {
      "type": "object",
      "description": "Schemas (params/description/examples, when the host published one) for just the commands granted to this lease."
    },
    "offered_feeds": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Live read-only feeds readable over the control WebSocket for the whole lease once ACTIVE."
    },
    "feed_schemas": {
      "type": "object",
      "description": "Informational schemas for the offered feeds."
    },
    "window_start": {
      "type": "string",
      "format": "date-time"
    },
    "window_end": {
      "type": "string",
      "format": "date-time"
    },
    "finding_outcome": {
      "type": [
        "string",
        "null"
      ]
    },
    "price": {
      "type": [
        "string",
        "null"
      ],
      "description": "Payment isn't handled through the API (prices and payouts: hello@getbody.md); this field is reserved. Always null."
    },
    "currency": {
      "type": [
        "string",
        "null"
      ],
      "description": "Payment isn't handled through the API (prices and payouts: hello@getbody.md); this field is reserved. Always null."
    },
    "payment_status": {
      "type": "string",
      "enum": [
        "arranged_by_getbody"
      ],
      "description": "Always 'arranged_by_getbody': payment isn't handled through the API (prices and payouts: hello@getbody.md)."
    },
    "awaiting_operator_approval": {
      "type": "boolean",
      "description": "True while the request is REQUESTED: it passed the automatic checks and waits for a GetBody operator to approve (-> CONFIRMED) or reject (-> REJECTED) it."
    },
    "approval_message": {
      "type": "string",
      "description": "Present while awaiting_operator_approval: what happens next."
    },
    "approval_reason": {
      "type": "string",
      "description": "Present once an operator decided: their note (the reason, when rejected)."
    },
    "approval_decided_at": {
      "type": "string",
      "format": "date-time",
      "description": "Present once an operator decided."
    }
  }
}