{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/getbody-md/json-schema/getbody-md-listing-schema.json",
  "title": "Listing",
  "description": "A current body owner listing offers one physical robot (never neither).",
  "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/Listing",
  "type": "object",
  "properties": {
    "listing_id": {
      "type": "integer"
    },
    "real_body_id": {
      "type": [
        "integer",
        "null"
      ]
    },
    "simulated_body_id": {
      "type": [
        "integer",
        "null"
      ],
      "deprecated": true,
      "description": "Legacy compatibility field. Current rental offers are physical robots; simulated references and planned real availability are absent."
    },
    "real_available_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "Legacy compatibility field. Current rental offers are physical robots; simulated references and planned real availability are absent.",
      "deprecated": true
    },
    "real_available_note": {
      "type": "string",
      "deprecated": true,
      "description": "Legacy compatibility field. Current rental offers are physical robots; simulated references and planned real availability are absent."
    },
    "simulator_only": {
      "type": "boolean",
      "description": "Legacy compatibility field. Current rental offers are physical robots; simulated references and planned real availability are absent.",
      "deprecated": true
    },
    "location": {
      "$ref": "#/$defs/Location"
    },
    "real_delivery": {
      "type": [
        "string",
        "null"
      ],
      "enum": [
        "deliverable",
        "remote_only"
      ],
      "description": "Whether the real body can be delivered to the renter's premises (deliverable) or is remote control only (remote_only). Applies to the real body only; null on a simulated-only listing that did not say."
    },
    "delivery": {
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "dispatch_hours": {
          "type": "integer"
        },
        "delivery_speed_kmh": {
          "type": "integer"
        }
      },
      "description": "Only for a deliverable listing; null otherwise."
    },
    "terms_of_use": {
      "type": "string"
    },
    "notes": {
      "type": "string"
    },
    "pricing": {
      "$ref": "#/$defs/Pricing"
    },
    "bodies": {
      "type": "object",
      "properties": {
        "real": {
          "$ref": "#/$defs/ListingBody"
        },
        "simulated": {
          "$ref": "#/$defs/ListingBody"
        }
      }
    },
    "offered_control_modes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "permissions_offered": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "command_schemas": {
      "type": "object"
    },
    "offered_feeds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "feed_schemas": {
      "type": "object"
    },
    "available": {
      "type": "boolean"
    },
    "unavailable_reason": {
      "type": [
        "string",
        "null"
      ]
    },
    "requestable_control_modes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "drop_off": {
      "type": [
        "object",
        "null"
      ],
      "description": "Only with renter_lat/renter_lng, and null unless real_delivery is deliverable: when the real body could reach you, counted from now or, without a real body yet, from real_available_at. An estimate; it never blocks a lease.",
      "properties": {
        "distance_km": {
          "type": "number"
        },
        "estimated_hours": {
          "type": "number"
        },
        "estimated_drop_off_at": {
          "type": "string",
          "format": "date-time"
        },
        "counted_from": {
          "type": "string",
          "enum": [
            "now",
            "real_available_at"
          ]
        }
      }
    },
    "payment_status": {
      "type": "string",
      "enum": [
        "arranged_by_getbody"
      ]
    },
    "access_type": {
      "$ref": "#/$defs/AccessType"
    },
    "access_options": {
      "$ref": "#/$defs/AccessOptions"
    },
    "rental_policy": {
      "type": "object",
      "description": "Structured body owner services, deposit terms, service area, expense categories and travel zones. Public responses omit the home base, coverage notes and center."
    }
  },
  "$defs": {
    "AccessOption": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "terms": {
          "type": "string"
        },
        "terms_customized": {
          "type": "boolean"
        },
        "allowed_commands": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "read_only_feeds": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "command_schemas": {
          "type": "object"
        },
        "feed_schemas": {
          "type": "object"
        }
      },
      "description": "A rental arrangement. Declarations alone do not enable platform controls."
    },
    "AccessOptions": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "onsite_operator": {
          "$ref": "#/$defs/AccessOption"
        },
        "equipment_only": {
          "$ref": "#/$defs/AccessOption"
        },
        "remote_teleoperation": {
          "$ref": "#/$defs/AccessOption"
        }
      }
    },
    "AccessType": {
      "type": "string",
      "enum": [
        "onsite_operator",
        "equipment_only",
        "remote_teleoperation"
      ]
    },
    "ListingBody": {
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "body_id": {
          "type": "integer"
        },
        "interface_mode": {
          "type": "string",
          "enum": [
            "real",
            "simulated"
          ]
        },
        "requestable_control_modes": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "online": {
          "type": "boolean"
        },
        "currently_leased": {
          "type": "boolean"
        },
        "busy_until": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        },
        "inquiry_possible": {
          "type": "boolean"
        },
        "model": {
          "type": "string"
        },
        "robot_type": {
          "type": "string"
        },
        "capabilities": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "Location": {
      "type": "object",
      "description": "Where the body is right now. Each coordinate may instead be 'available on request'; if either is withheld, both are stored that way and no public area or drop-off estimate is available.",
      "required": [
        "lat",
        "lng"
      ],
      "properties": {
        "lat": {
          "oneOf": [
            {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            },
            {
              "type": "string",
              "enum": [
                "available on request"
              ]
            }
          ]
        },
        "lng": {
          "oneOf": [
            {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            },
            {
              "type": "string",
              "enum": [
                "available on request"
              ]
            }
          ]
        },
        "description": {
          "type": "string",
          "maxLength": 300,
          "description": "Human-readable place, e.g. a city or address."
        }
      }
    },
    "Pricing": {
      "oneOf": [
        {
          "type": "object",
          "description": "The host's asking rates in US dollars, display only: nothing is charged through the API. At least one rate. Instead of numeric rates, use {on_request: true}, the string 'available on request', or that string in an individual rate. Responses always use an object; the whole-string input becomes {currency: 'USD', on_request: true}.",
          "required": [],
          "properties": {
            "currency": {
              "type": "string",
              "enum": [
                "USD"
              ],
              "default": "USD",
              "description": "Always USD (may be omitted); anything else is 400 invalid_pricing."
            },
            "per_hour": {
              "type": "string",
              "description": "Decimal amount, e.g. \"12.50\". Or 'available on request'."
            },
            "per_day": {
              "type": "string",
              "description": "Decimal amount, e.g. \"12.50\". Or 'available on request'."
            },
            "per_week": {
              "type": "string",
              "description": "Decimal amount, e.g. \"12.50\". Or 'available on request'."
            },
            "per_month": {
              "type": "string",
              "description": "Decimal amount, e.g. \"12.50\". Or 'available on request'."
            },
            "on_request": {
              "type": "boolean",
              "description": "True when pricing is available on request; no rate is then required."
            }
          }
        },
        {
          "type": "string",
          "enum": [
            "available on request"
          ]
        }
      ],
      "description": "The host's asking rates in US dollars, display only: nothing is charged through the API. At least one rate. Instead of numeric rates, use {on_request: true}, the string 'available on request', or that string in an individual rate. Responses always use an object; the whole-string input becomes {currency: 'USD', on_request: true}."
    }
  }
}