{
  "components": {
    "headers": {
      "Deprecation": {
        "description": "RFC 8594 deprecation indicator. Either the literal value `true` or an HTTP-date marking when the endpoint became deprecated. Present on every response from a deprecated endpoint until the sunset date.",
        "schema": {
          "type": "string"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying.",
        "schema": {
          "type": "integer"
        }
      },
      "Sunset": {
        "description": "RFC 8594 sunset date. HTTP-date marking when the endpoint will stop responding (200 series replaced by 410 Gone). Pairs with Deprecation; appears on every response from a deprecated endpoint.",
        "schema": {
          "format": "http-date",
          "type": "string"
        }
      },
      "WWWAuthenticate": {
        "description": "RFC 7235 authentication challenge. Always `Bearer realm=\"trakrf-api\"` on 401 responses.",
        "schema": {
          "type": "string"
        }
      },
      "XRateLimitLimit": {
        "description": "Steady-state requests/min for this API key.",
        "schema": {
          "type": "integer"
        }
      },
      "XRateLimitRemaining": {
        "description": "Requests remaining before throttling; bounded by X-RateLimit-Limit.",
        "schema": {
          "type": "integer"
        }
      },
      "XRateLimitReset": {
        "description": "Unix timestamp (seconds) when X-RateLimit-Remaining will next equal X-RateLimit-Limit.",
        "schema": {
          "type": "integer"
        }
      },
      "XRequestId": {
        "description": "Server-assigned request correlation identifier; mirrored as error.request_id in error envelopes and echoed in server logs. Quote this when filing support tickets.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Gone": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Endpoint sunset. The endpoint was deprecated and has now passed its Sunset date; clients should migrate to the documented replacement (RFC 8594)."
      },
      "MethodNotAllowed": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Method not allowed",
        "headers": {
          "Allow": {
            "description": "Comma-separated list of HTTP methods supported on this resource (RFC 7231 §6.5.5).",
            "schema": {
              "type": "string"
            }
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/XRateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/XRateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/XRateLimitReset"
          },
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        }
      }
    },
    "schemas": {
      "AddAssetTagResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Tag"
          }
        },
        "required": [
          "data"
        ],
        "type": "object"
      },
      "AddLocationTagResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Tag"
          }
        },
        "required": [
          "data"
        ],
        "type": "object"
      },
      "AssetHistoryItem": {
        "properties": {
          "duration_seconds": {
            "format": "int32",
            "nullable": true,
            "type": "integer"
          },
          "event_observed_at": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "type": "string"
          },
          "location_external_key": {
            "nullable": true,
            "type": "string"
          },
          "location_id": {
            "format": "int64",
            "nullable": true,
            "type": "integer"
          }
        },
        "required": [
          "event_observed_at",
          "location_id",
          "location_external_key",
          "duration_seconds"
        ],
        "type": "object"
      },
      "AssetHistoryResponse": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/AssetHistoryItem"
            },
            "type": "array"
          },
          "limit": {
            "example": 50,
            "format": "int32",
            "type": "integer"
          },
          "offset": {
            "example": 0,
            "format": "int32",
            "type": "integer"
          },
          "total_count": {
            "example": 100,
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "data",
          "limit",
          "offset",
          "total_count"
        ],
        "type": "object"
      },
      "AssetLocationItem": {
        "properties": {
          "asset_deleted_at": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "type": "string"
          },
          "asset_external_key": {
            "type": "string"
          },
          "asset_id": {
            "format": "int64",
            "type": "integer"
          },
          "asset_last_seen": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "type": "string"
          },
          "location_external_key": {
            "nullable": true,
            "type": "string"
          },
          "location_id": {
            "format": "int64",
            "nullable": true,
            "type": "integer"
          }
        },
        "required": [
          "asset_id",
          "asset_external_key",
          "location_id",
          "location_external_key",
          "asset_last_seen",
          "asset_deleted_at"
        ],
        "type": "object"
      },
      "AssetLocationsResponse": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/AssetLocationItem"
            },
            "type": "array"
          },
          "limit": {
            "example": 50,
            "format": "int32",
            "type": "integer"
          },
          "offset": {
            "example": 0,
            "format": "int32",
            "type": "integer"
          },
          "total_count": {
            "example": 100,
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "data",
          "limit",
          "offset",
          "total_count"
        ],
        "type": "object"
      },
      "AssetView": {
        "properties": {
          "created_at": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "readOnly": true,
            "type": "string"
          },
          "deleted_at": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "type": "string"
          },
          "description": {
            "nullable": true,
            "type": "string"
          },
          "external_key": {
            "type": "string"
          },
          "id": {
            "format": "int64",
            "readOnly": true,
            "type": "integer"
          },
          "is_active": {
            "type": "boolean"
          },
          "location_external_key": {
            "nullable": true,
            "type": "string"
          },
          "location_id": {
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "metadata": {
            "additionalProperties": true,
            "type": "object"
          },
          "name": {
            "type": "string"
          },
          "tags": {
            "description": "Tags currently attached to this resource. Read-only on PATCH; mutate via POST /{resource}/{id}/tags and DELETE /{resource}/{id}/tags/{tag_id}.",
            "items": {
              "$ref": "#/components/schemas/Tag"
            },
            "type": "array"
          },
          "updated_at": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "readOnly": true,
            "type": "string"
          },
          "valid_from": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "type": "string"
          },
          "valid_to": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "id",
          "external_key",
          "name",
          "description",
          "location_id",
          "location_external_key",
          "metadata",
          "is_active",
          "valid_from",
          "valid_to",
          "created_at",
          "updated_at",
          "deleted_at",
          "tags"
        ],
        "type": "object"
      },
      "BarcodeTag": {
        "description": "Polymorphic identifier attached to an asset or location, discriminated by `tag_type` into one of three variants: `RfidTag` (RFID transponder, `tag_type: rfid`), `BleTag` (Bluetooth Low Energy beacon, `tag_type: ble`), or `BarcodeTag` (1D/2D barcode, `tag_type: barcode`). The `/assets/{asset_id}/tags` and `/locations/{location_id}/tags` subresources accept and return all three variants; `tag_type` together with `value` form the natural key (a tag value is unique within its kind, not across kinds). \n\n`tag_type` is an **open** enumeration per the versioning policy — new variants may be added in additive minor revisions without a `/api/v2` cut. Integrators should treat unknown `tag_type` values as forward-compatible: pass the row through untouched rather than rejecting it. \n\n**Codegen note:** some strict-typed generators (e.g. datamodel-codegen for Pydantic) materialize the single-value `tag_type` constants on each variant as separate enum classes — `TagType`, `TagType2`, `TagType4` or similar. That is a generator artifact and not part of the contract; the wire shape is a single discriminated union with three variants today. Treat the generated classes as implementation detail.",
        "properties": {
          "id": {
            "format": "int64",
            "readOnly": true,
            "type": "integer"
          },
          "tag_type": {
            "description": "Discriminator for the polymorphic Tag resource. `rfid` denotes an RFID transponder, `ble` denotes a Bluetooth Low Energy beacon, and `barcode` denotes a 1D/2D barcode. Together with `value`, this forms the natural key — the same `value` may exist under different `tag_type`s without conflict.",
            "enum": [
              "barcode"
            ],
            "type": "string"
          },
          "value": {
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          }
        },
        "required": [
          "id",
          "tag_type",
          "value"
        ],
        "type": "object"
      },
      "BarcodeTagRequest": {
        "additionalProperties": false,
        "description": "Polymorphic identifier attached to an asset or location, discriminated by `tag_type` into one of three variants: `RfidTag` (RFID transponder, `tag_type: rfid`), `BleTag` (Bluetooth Low Energy beacon, `tag_type: ble`), or `BarcodeTag` (1D/2D barcode, `tag_type: barcode`). The `/assets/{asset_id}/tags` and `/locations/{location_id}/tags` subresources accept and return all three variants; `tag_type` together with `value` form the natural key (a tag value is unique within its kind, not across kinds). \n\n`tag_type` is an **open** enumeration per the versioning policy — new variants may be added in additive minor revisions without a `/api/v2` cut. Integrators should treat unknown `tag_type` values as forward-compatible: pass the row through untouched rather than rejecting it. \n\n**Codegen note:** some strict-typed generators (e.g. datamodel-codegen for Pydantic) materialize the single-value `tag_type` constants on each variant as separate enum classes — `TagType`, `TagType2`, `TagType4` or similar. That is a generator artifact and not part of the contract; the wire shape is a single discriminated union with three variants today. Treat the generated classes as implementation detail.",
        "properties": {
          "tag_type": {
            "description": "Discriminator for the polymorphic Tag resource. `rfid` denotes an RFID transponder, `ble` denotes a Bluetooth Low Energy beacon, and `barcode` denotes a 1D/2D barcode. Together with `value`, this forms the natural key — the same `value` may exist under different `tag_type`s without conflict.",
            "enum": [
              "barcode"
            ],
            "type": "string"
          },
          "value": {
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          }
        },
        "required": [
          "tag_type",
          "value"
        ],
        "type": "object"
      },
      "BleTag": {
        "description": "Polymorphic identifier attached to an asset or location, discriminated by `tag_type` into one of three variants: `RfidTag` (RFID transponder, `tag_type: rfid`), `BleTag` (Bluetooth Low Energy beacon, `tag_type: ble`), or `BarcodeTag` (1D/2D barcode, `tag_type: barcode`). The `/assets/{asset_id}/tags` and `/locations/{location_id}/tags` subresources accept and return all three variants; `tag_type` together with `value` form the natural key (a tag value is unique within its kind, not across kinds). \n\n`tag_type` is an **open** enumeration per the versioning policy — new variants may be added in additive minor revisions without a `/api/v2` cut. Integrators should treat unknown `tag_type` values as forward-compatible: pass the row through untouched rather than rejecting it. \n\n**Codegen note:** some strict-typed generators (e.g. datamodel-codegen for Pydantic) materialize the single-value `tag_type` constants on each variant as separate enum classes — `TagType`, `TagType2`, `TagType4` or similar. That is a generator artifact and not part of the contract; the wire shape is a single discriminated union with three variants today. Treat the generated classes as implementation detail.",
        "properties": {
          "id": {
            "format": "int64",
            "readOnly": true,
            "type": "integer"
          },
          "tag_type": {
            "description": "Discriminator for the polymorphic Tag resource. `rfid` denotes an RFID transponder, `ble` denotes a Bluetooth Low Energy beacon, and `barcode` denotes a 1D/2D barcode. Together with `value`, this forms the natural key — the same `value` may exist under different `tag_type`s without conflict.",
            "enum": [
              "ble"
            ],
            "type": "string"
          },
          "value": {
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          }
        },
        "required": [
          "id",
          "tag_type",
          "value"
        ],
        "type": "object"
      },
      "BleTagRequest": {
        "additionalProperties": false,
        "description": "Polymorphic identifier attached to an asset or location, discriminated by `tag_type` into one of three variants: `RfidTag` (RFID transponder, `tag_type: rfid`), `BleTag` (Bluetooth Low Energy beacon, `tag_type: ble`), or `BarcodeTag` (1D/2D barcode, `tag_type: barcode`). The `/assets/{asset_id}/tags` and `/locations/{location_id}/tags` subresources accept and return all three variants; `tag_type` together with `value` form the natural key (a tag value is unique within its kind, not across kinds). \n\n`tag_type` is an **open** enumeration per the versioning policy — new variants may be added in additive minor revisions without a `/api/v2` cut. Integrators should treat unknown `tag_type` values as forward-compatible: pass the row through untouched rather than rejecting it. \n\n**Codegen note:** some strict-typed generators (e.g. datamodel-codegen for Pydantic) materialize the single-value `tag_type` constants on each variant as separate enum classes — `TagType`, `TagType2`, `TagType4` or similar. That is a generator artifact and not part of the contract; the wire shape is a single discriminated union with three variants today. Treat the generated classes as implementation detail.",
        "properties": {
          "tag_type": {
            "description": "Discriminator for the polymorphic Tag resource. `rfid` denotes an RFID transponder, `ble` denotes a Bluetooth Low Energy beacon, and `barcode` denotes a 1D/2D barcode. Together with `value`, this forms the natural key — the same `value` may exist under different `tag_type`s without conflict.",
            "enum": [
              "ble"
            ],
            "type": "string"
          },
          "value": {
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          }
        },
        "required": [
          "tag_type",
          "value"
        ],
        "type": "object"
      },
      "CreateAssetResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/AssetView"
          }
        },
        "required": [
          "data"
        ],
        "type": "object"
      },
      "CreateAssetWithTagsRequest": {
        "additionalProperties": false,
        "properties": {
          "description": {
            "example": "Main warehouse forklift",
            "maxLength": 1024,
            "minLength": 1,
            "nullable": true,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          },
          "external_key": {
            "description": "external_key is optional. Omit to receive a server-assigned key in the\nformat ASSET-NNNN (per-organization sequence). When supplied, must\nsatisfy the external_key_pattern.",
            "example": "forklift-3",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[A-Za-z0-9-]+$",
            "type": "string"
          },
          "is_active": {
            "example": true,
            "type": "boolean"
          },
          "metadata": {
            "additionalProperties": {},
            "type": "object"
          },
          "name": {
            "example": "Forklift 3",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          },
          "tags": {
            "items": {
              "$ref": "#/components/schemas/TagRequest"
            },
            "nullable": true,
            "type": "array"
          },
          "valid_from": {
            "example": "2025-01-01T00:00:00Z",
            "format": "date-time",
            "type": "string"
          },
          "valid_to": {
            "example": "2026-01-01T00:00:00Z",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "CreateLocationResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/LocationView"
          }
        },
        "required": [
          "data"
        ],
        "type": "object"
      },
      "CreateLocationWithTagsRequest": {
        "additionalProperties": false,
        "not": {
          "required": [
            "parent_id",
            "parent_external_key"
          ]
        },
        "properties": {
          "description": {
            "example": "Main warehouse location",
            "maxLength": 1024,
            "minLength": 1,
            "nullable": true,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          },
          "external_key": {
            "description": "external_key is optional. Omit to receive a server-assigned key in the\nformat LOC-NNNN (per-organization sequence), parallel to assets'\nASSET-NNNN behavior. When supplied, must satisfy the external_key_pattern.",
            "example": "wh1",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[A-Za-z0-9-]+$",
            "type": "string"
          },
          "is_active": {
            "example": true,
            "type": "boolean"
          },
          "name": {
            "example": "Warehouse 1",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          },
          "parent_external_key": {
            "example": "wh1",
            "maxLength": 255,
            "minLength": 1,
            "nullable": true,
            "pattern": "^[A-Za-z0-9-]+$",
            "type": "string"
          },
          "parent_id": {
            "example": 42,
            "format": "int64",
            "minimum": 1,
            "nullable": true,
            "type": "integer"
          },
          "tags": {
            "items": {
              "$ref": "#/components/schemas/TagRequest"
            },
            "nullable": true,
            "type": "array"
          },
          "valid_from": {
            "example": "2025-12-14T00:00:00Z",
            "format": "date-time",
            "type": "string"
          },
          "valid_to": {
            "example": "2026-12-14T00:00:00Z",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "ErrorResponse": {
        "description": "TrakRF error envelope, modeled on RFC 7807 but not 7807-compliant. Fields are nested under `error.*` and content-type is `application/json` (not `application/problem+json`). Generated clients should branch on `error.type` and `error.title`, not `error.detail`. `error.title` is a stable, machine-readable summary that does not vary between calls for the same condition. `error.detail` is the specific, human-readable cause of this particular failure and may be empty when title alone fully describes the condition.",
        "properties": {
          "error": {
            "properties": {
              "detail": {
                "description": "Specific, human-readable cause of this particular failure. May be empty when title alone fully describes the condition. Do not branch on this value.",
                "type": "string"
              },
              "fields": {
                "items": {
                  "$ref": "#/components/schemas/FieldError"
                },
                "type": "array"
              },
              "instance": {
                "type": "string"
              },
              "request_id": {
                "type": "string"
              },
              "status": {
                "format": "int32",
                "type": "integer"
              },
              "title": {
                "description": "Stable, machine-readable summary suitable for client-side branching. Does not vary between calls for the same condition.",
                "type": "string"
              },
              "type": {
                "$ref": "#/components/schemas/ErrorType"
              }
            },
            "required": [
              "type",
              "title",
              "status",
              "detail",
              "instance",
              "request_id"
            ],
            "type": "object"
          }
        },
        "required": [
          "error"
        ],
        "type": "object"
      },
      "ErrorType": {
        "description": "Machine-readable error envelope discriminator. Pairs with `title` and `detail` to drive client-side branching on a stable token (per RFC 9457).",
        "enum": [
          "validation_error",
          "bad_request",
          "unauthorized",
          "forbidden",
          "not_found",
          "conflict",
          "rate_limited",
          "internal_error",
          "method_not_allowed",
          "unsupported_media_type",
          "missing_org_context"
        ],
        "example": "validation_error",
        "type": "string",
        "x-extensible-enum": true
      },
      "FieldError": {
        "properties": {
          "code": {
            "$ref": "#/components/schemas/FieldErrorCode"
          },
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "params": {
            "additionalProperties": {},
            "type": "object"
          }
        },
        "required": [
          "field",
          "code",
          "message"
        ],
        "type": "object"
      },
      "FieldErrorCode": {
        "description": "Machine-readable field-level validation error code. Identifies which constraint a request payload violated; pairs with the field path and human-readable message in a FieldError entry.",
        "enum": [
          "required",
          "invalid_value",
          "unknown_field",
          "too_short",
          "too_long",
          "too_small",
          "too_large",
          "fk_not_found",
          "ambiguous_fields",
          "read_only"
        ],
        "example": "required",
        "type": "string",
        "x-extensible-enum": true
      },
      "GetAssetResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/AssetView"
          }
        },
        "required": [
          "data"
        ],
        "type": "object"
      },
      "GetCurrentOrgResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/OrgView"
          }
        },
        "required": [
          "data"
        ],
        "type": "object"
      },
      "GetLocationResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/LocationView"
          }
        },
        "required": [
          "data"
        ],
        "type": "object"
      },
      "ListAssetsResponse": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/AssetView"
            },
            "type": "array"
          },
          "limit": {
            "example": 50,
            "format": "int32",
            "type": "integer"
          },
          "offset": {
            "example": 0,
            "format": "int32",
            "type": "integer"
          },
          "total_count": {
            "example": 100,
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "data",
          "limit",
          "offset",
          "total_count"
        ],
        "type": "object"
      },
      "ListLocationAncestorsResponse": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/LocationView"
            },
            "type": "array"
          },
          "limit": {
            "example": 50,
            "format": "int32",
            "type": "integer"
          },
          "offset": {
            "example": 0,
            "format": "int32",
            "type": "integer"
          },
          "total_count": {
            "example": 100,
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "data",
          "limit",
          "offset",
          "total_count"
        ],
        "type": "object"
      },
      "ListLocationChildrenResponse": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/LocationView"
            },
            "type": "array"
          },
          "limit": {
            "example": 50,
            "format": "int32",
            "type": "integer"
          },
          "offset": {
            "example": 0,
            "format": "int32",
            "type": "integer"
          },
          "total_count": {
            "example": 100,
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "data",
          "limit",
          "offset",
          "total_count"
        ],
        "type": "object"
      },
      "ListLocationDescendantsResponse": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/LocationView"
            },
            "type": "array"
          },
          "limit": {
            "example": 50,
            "format": "int32",
            "type": "integer"
          },
          "offset": {
            "example": 0,
            "format": "int32",
            "type": "integer"
          },
          "total_count": {
            "example": 100,
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "data",
          "limit",
          "offset",
          "total_count"
        ],
        "type": "object"
      },
      "ListLocationsResponse": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/LocationView"
            },
            "type": "array"
          },
          "limit": {
            "example": 50,
            "format": "int32",
            "type": "integer"
          },
          "offset": {
            "example": 0,
            "format": "int32",
            "type": "integer"
          },
          "total_count": {
            "example": 100,
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "data",
          "limit",
          "offset",
          "total_count"
        ],
        "type": "object"
      },
      "LocationView": {
        "properties": {
          "created_at": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "readOnly": true,
            "type": "string"
          },
          "deleted_at": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "type": "string"
          },
          "description": {
            "nullable": true,
            "type": "string"
          },
          "external_key": {
            "type": "string"
          },
          "id": {
            "format": "int64",
            "readOnly": true,
            "type": "integer"
          },
          "is_active": {
            "type": "boolean"
          },
          "name": {
            "type": "string"
          },
          "parent_external_key": {
            "nullable": true,
            "type": "string"
          },
          "parent_id": {
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "tags": {
            "description": "Tags currently attached to this resource. Read-only on PATCH; mutate via POST /{resource}/{id}/tags and DELETE /{resource}/{id}/tags/{tag_id}.",
            "items": {
              "$ref": "#/components/schemas/Tag"
            },
            "type": "array"
          },
          "updated_at": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "readOnly": true,
            "type": "string"
          },
          "valid_from": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "type": "string"
          },
          "valid_to": {
            "example": "2025-04-29T12:34:56.000Z",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "id",
          "external_key",
          "name",
          "description",
          "parent_id",
          "parent_external_key",
          "is_active",
          "valid_from",
          "valid_to",
          "created_at",
          "updated_at",
          "deleted_at",
          "tags"
        ],
        "type": "object"
      },
      "OrgView": {
        "properties": {
          "api_key_id": {
            "example": "550e8400-e29b-41d4-a716-446655440000",
            "type": "string"
          },
          "id": {
            "example": 42,
            "format": "int64",
            "readOnly": true,
            "type": "integer"
          },
          "name": {
            "example": "Acme Logistics",
            "type": "string"
          },
          "scopes": {
            "example": [
              "assets:read",
              "assets:write"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "id",
          "name",
          "scopes",
          "api_key_id"
        ],
        "type": "object"
      },
      "RenameAssetRequest": {
        "additionalProperties": false,
        "properties": {
          "external_key": {
            "example": "ASSET-0042",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[A-Za-z0-9-]+$",
            "type": "string"
          }
        },
        "required": [
          "external_key"
        ],
        "type": "object"
      },
      "RenameAssetResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/AssetView"
          },
          "descendant_count_affected": {
            "example": 0,
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "data",
          "descendant_count_affected"
        ],
        "type": "object"
      },
      "RenameLocationRequest": {
        "additionalProperties": false,
        "properties": {
          "external_key": {
            "example": "wh1",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[A-Za-z0-9-]+$",
            "type": "string"
          }
        },
        "required": [
          "external_key"
        ],
        "type": "object"
      },
      "RenameLocationResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/LocationView"
          },
          "descendant_count_affected": {
            "example": 7,
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "data",
          "descendant_count_affected"
        ],
        "type": "object"
      },
      "RfidTag": {
        "description": "Polymorphic identifier attached to an asset or location, discriminated by `tag_type` into one of three variants: `RfidTag` (RFID transponder, `tag_type: rfid`), `BleTag` (Bluetooth Low Energy beacon, `tag_type: ble`), or `BarcodeTag` (1D/2D barcode, `tag_type: barcode`). The `/assets/{asset_id}/tags` and `/locations/{location_id}/tags` subresources accept and return all three variants; `tag_type` together with `value` form the natural key (a tag value is unique within its kind, not across kinds). \n\n`tag_type` is an **open** enumeration per the versioning policy — new variants may be added in additive minor revisions without a `/api/v2` cut. Integrators should treat unknown `tag_type` values as forward-compatible: pass the row through untouched rather than rejecting it. \n\n**Codegen note:** some strict-typed generators (e.g. datamodel-codegen for Pydantic) materialize the single-value `tag_type` constants on each variant as separate enum classes — `TagType`, `TagType2`, `TagType4` or similar. That is a generator artifact and not part of the contract; the wire shape is a single discriminated union with three variants today. Treat the generated classes as implementation detail.",
        "properties": {
          "id": {
            "format": "int64",
            "readOnly": true,
            "type": "integer"
          },
          "tag_type": {
            "description": "Discriminator for the polymorphic Tag resource. `rfid` denotes an RFID transponder, `ble` denotes a Bluetooth Low Energy beacon, and `barcode` denotes a 1D/2D barcode. Together with `value`, this forms the natural key — the same `value` may exist under different `tag_type`s without conflict.",
            "enum": [
              "rfid"
            ],
            "type": "string"
          },
          "value": {
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          }
        },
        "required": [
          "id",
          "tag_type",
          "value"
        ],
        "type": "object"
      },
      "RfidTagRequest": {
        "additionalProperties": false,
        "description": "Polymorphic identifier attached to an asset or location, discriminated by `tag_type` into one of three variants: `RfidTag` (RFID transponder, `tag_type: rfid`), `BleTag` (Bluetooth Low Energy beacon, `tag_type: ble`), or `BarcodeTag` (1D/2D barcode, `tag_type: barcode`). The `/assets/{asset_id}/tags` and `/locations/{location_id}/tags` subresources accept and return all three variants; `tag_type` together with `value` form the natural key (a tag value is unique within its kind, not across kinds). \n\n`tag_type` is an **open** enumeration per the versioning policy — new variants may be added in additive minor revisions without a `/api/v2` cut. Integrators should treat unknown `tag_type` values as forward-compatible: pass the row through untouched rather than rejecting it. \n\n**Codegen note:** some strict-typed generators (e.g. datamodel-codegen for Pydantic) materialize the single-value `tag_type` constants on each variant as separate enum classes — `TagType`, `TagType2`, `TagType4` or similar. That is a generator artifact and not part of the contract; the wire shape is a single discriminated union with three variants today. Treat the generated classes as implementation detail.",
        "properties": {
          "tag_type": {
            "description": "Discriminator for the polymorphic Tag resource. `rfid` denotes an RFID transponder, `ble` denotes a Bluetooth Low Energy beacon, and `barcode` denotes a 1D/2D barcode. Together with `value`, this forms the natural key — the same `value` may exist under different `tag_type`s without conflict.",
            "enum": [
              "rfid"
            ],
            "type": "string"
          },
          "value": {
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          }
        },
        "required": [
          "tag_type",
          "value"
        ],
        "type": "object"
      },
      "Tag": {
        "description": "Polymorphic identifier attached to an asset or location, discriminated by `tag_type` into one of three variants: `RfidTag` (RFID transponder, `tag_type: rfid`), `BleTag` (Bluetooth Low Energy beacon, `tag_type: ble`), or `BarcodeTag` (1D/2D barcode, `tag_type: barcode`). The `/assets/{asset_id}/tags` and `/locations/{location_id}/tags` subresources accept and return all three variants; `tag_type` together with `value` form the natural key (a tag value is unique within its kind, not across kinds). \n\n`tag_type` is an **open** enumeration per the versioning policy — new variants may be added in additive minor revisions without a `/api/v2` cut. Integrators should treat unknown `tag_type` values as forward-compatible: pass the row through untouched rather than rejecting it. \n\n**Codegen note:** some strict-typed generators (e.g. datamodel-codegen for Pydantic) materialize the single-value `tag_type` constants on each variant as separate enum classes — `TagType`, `TagType2`, `TagType4` or similar. That is a generator artifact and not part of the contract; the wire shape is a single discriminated union with three variants today. Treat the generated classes as implementation detail.",
        "discriminator": {
          "mapping": {
            "barcode": "#/components/schemas/BarcodeTag",
            "ble": "#/components/schemas/BleTag",
            "rfid": "#/components/schemas/RfidTag"
          },
          "propertyName": "tag_type"
        },
        "oneOf": [
          {
            "$ref": "#/components/schemas/RfidTag"
          },
          {
            "$ref": "#/components/schemas/BleTag"
          },
          {
            "$ref": "#/components/schemas/BarcodeTag"
          }
        ]
      },
      "TagRequest": {
        "description": "Polymorphic identifier attached to an asset or location, discriminated by `tag_type` into one of three variants: `RfidTag` (RFID transponder, `tag_type: rfid`), `BleTag` (Bluetooth Low Energy beacon, `tag_type: ble`), or `BarcodeTag` (1D/2D barcode, `tag_type: barcode`). The `/assets/{asset_id}/tags` and `/locations/{location_id}/tags` subresources accept and return all three variants; `tag_type` together with `value` form the natural key (a tag value is unique within its kind, not across kinds). \n\n`tag_type` is an **open** enumeration per the versioning policy — new variants may be added in additive minor revisions without a `/api/v2` cut. Integrators should treat unknown `tag_type` values as forward-compatible: pass the row through untouched rather than rejecting it. \n\n**Codegen note:** some strict-typed generators (e.g. datamodel-codegen for Pydantic) materialize the single-value `tag_type` constants on each variant as separate enum classes — `TagType`, `TagType2`, `TagType4` or similar. That is a generator artifact and not part of the contract; the wire shape is a single discriminated union with three variants today. Treat the generated classes as implementation detail.",
        "discriminator": {
          "mapping": {
            "barcode": "#/components/schemas/BarcodeTagRequest",
            "ble": "#/components/schemas/BleTagRequest",
            "rfid": "#/components/schemas/RfidTagRequest"
          },
          "propertyName": "tag_type"
        },
        "oneOf": [
          {
            "$ref": "#/components/schemas/RfidTagRequest"
          },
          {
            "$ref": "#/components/schemas/BleTagRequest"
          },
          {
            "$ref": "#/components/schemas/BarcodeTagRequest"
          }
        ]
      },
      "UpdateAssetRequest": {
        "properties": {
          "description": {
            "example": "Updated description",
            "maxLength": 1024,
            "minLength": 1,
            "nullable": true,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          },
          "is_active": {
            "example": true,
            "type": "boolean"
          },
          "metadata": {
            "additionalProperties": {},
            "type": "object"
          },
          "name": {
            "example": "Forklift 3",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          },
          "valid_from": {
            "example": "2025-01-01T00:00:00Z",
            "format": "date-time",
            "type": "string"
          },
          "valid_to": {
            "example": "2026-01-01T00:00:00Z",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateAssetResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/AssetView"
          }
        },
        "required": [
          "data"
        ],
        "type": "object"
      },
      "UpdateLocationRequest": {
        "properties": {
          "description": {
            "example": "Updated description",
            "maxLength": 1024,
            "minLength": 1,
            "nullable": true,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          },
          "is_active": {
            "example": true,
            "type": "boolean"
          },
          "name": {
            "example": "Warehouse 1",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
            "type": "string"
          },
          "parent_external_key": {
            "example": "wh1",
            "maxLength": 255,
            "minLength": 1,
            "nullable": true,
            "pattern": "^[A-Za-z0-9-]+$",
            "type": "string"
          },
          "parent_id": {
            "example": 42,
            "format": "int64",
            "minimum": 1,
            "nullable": true,
            "type": "integer"
          },
          "valid_from": {
            "example": "2025-12-14T00:00:00Z",
            "format": "date-time",
            "type": "string"
          },
          "valid_to": {
            "example": "2026-12-14T00:00:00Z",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateLocationResponse": {
        "properties": {
          "data": {
            "$ref": "#/components/schemas/LocationView"
          }
        },
        "required": [
          "data"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "BearerAuth": {
        "bearerFormat": "JWT",
        "description": "TrakRF API key (JWT). Format: \"Bearer \u003cjwt\u003e\". Mint keys from the API Keys section of your TrakRF account. Some OpenAPI generators (e.g. openapi-fetch) do not auto-attach the Authorization header from this scheme — set it manually if your generated client does not.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "contact": {
      "email": "support@trakrf.id",
      "name": "TrakRF Support",
      "url": "https://docs.trakrf.id/"
    },
    "description": "TrakRF public REST API. See /api for the customer-facing reference.\n\nSpec available as YAML (/api/openapi.yaml) and JSON (/api/openapi.json).\n\nHTTP method coverage (HEAD, OPTIONS, 405 / Allow): /api/http-method-coverage\n\nSurrogate ID width: declared `format: int64` on the wire so SDK regeneration does not break when the ID namespace eventually outgrows int32. Service-side ID generation stays within int32 (2^31-1) during v1; values above that bound are rejected with 400 validation_error / `too_large`. The wider wire type is a long-horizon contract, not a claim that current values exceed int32.\n\nNullable field interpretation: OpenAPI 3.0's `nullable: true` keyword is interpreted differently across codegen targets. Verified-working: `openapi-typescript@7.x` emits `string | null` correctly, and the `openapi-generator-cli` python target emits `Optional[StrictStr]` correctly — both round-trip CRUD against null-bearing responses unmodified. Known-broken: `datamodel-codegen@0.57.0` emits `nullable: true` read-shape fields as non-Optional required fields, so Pydantic validation fails on every nullable field that is actually null. Integrators using `datamodel-codegen` should either switch to the `openapi-generator-cli` python target or apply `--use-annotated --use-union-operator` with a custom post-processing pass.",
    "license": {
      "name": "Business Source License 1.1",
      "url": "https://github.com/trakrf/platform/blob/main/LICENSE"
    },
    "title": "TrakRF API",
    "version": "1.0.0"
  },
  "openapi": "3.0.3",
  "paths": {
    "/api/v1/assets": {
      "get": {
        "description": "**Required scope:** `assets:read`\n\nPaginated assets list with natural-key filters, sort, and substring search.\n\nDefault scope returns currently-effective assets only — rows whose `valid_from` is in the past AND whose `valid_to` is null or in the future. The `is_active` filter is independent of temporal validity; omit it to include both active and inactive rows within the effective window, or pass `?is_active=true`/`false` to filter further.",
        "operationId": "listAssets",
        "parameters": [
          {
            "description": "max 200",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "min 0",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "filter by current location id (canonical, may repeat); mutually exclusive with location_external_key (400 ambiguous_fields if both supplied)",
            "explode": true,
            "in": "query",
            "name": "location_id",
            "schema": {
              "default": [],
              "items": {
                "format": "int64",
                "maximum": 2147483647,
                "minimum": 1,
                "type": "integer"
              },
              "type": "array"
            },
            "style": "form"
          },
          {
            "description": "filter by current location external_key (may repeat); mutually exclusive with location_id (400 ambiguous_fields if both supplied)",
            "explode": true,
            "in": "query",
            "name": "location_external_key",
            "schema": {
              "default": [],
              "items": {
                "pattern": "^[A-Za-z0-9-]+$",
                "type": "string"
              },
              "type": "array"
            },
            "style": "form"
          },
          {
            "description": "filter by asset external_key, equality match (may repeat for any-of)",
            "explode": true,
            "in": "query",
            "name": "external_key",
            "schema": {
              "default": [],
              "items": {
                "pattern": "^[A-Za-z0-9-]+$",
                "type": "string"
              },
              "type": "array"
            },
            "style": "form"
          },
          {
            "description": "filter by active flag",
            "in": "query",
            "name": "is_active",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "when true, include soft-deleted rows in the response. deleted_at is populated for those rows. Orthogonal to is_active.",
            "in": "query",
            "name": "include_deleted",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          },
          {
            "description": "substring search (case-insensitive) on name, external_key, description, and active tag values",
            "in": "query",
            "name": "q",
            "schema": {
              "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
              "type": "string"
            }
          },
          {
            "description": "comma-separated; prefix '-' for DESC",
            "explode": false,
            "in": "query",
            "name": "sort",
            "schema": {
              "default": "",
              "pattern": "^(|(?:external_key|-external_key|name|-name|created_at|-created_at|updated_at|-updated_at)(?:,(?:external_key|-external_key|name|-name|created_at|-created_at|updated_at|-updated_at))*)$",
              "type": "string"
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListAssetsResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "List assets",
        "tags": [
          "assets"
        ],
        "x-required-scopes": [
          "assets:read"
        ]
      },
      "post": {
        "description": "**Required scope:** `assets:write`\n\nCreate a new asset record, optionally with one or more tags (RFID, BLE, barcode).\n\nThe `external_key` field is optional. Provide a value from your system of record\n(ERP, WMS, asset management) for natural-key joins, or omit it to receive a\nserver-assigned external_key in the format `ASSET-NNNN` (per-organization sequence).\nA caller-supplied external_key that collides with an existing asset returns 409.\n\nReturns the created asset with its assigned tags. The Location response header contains the canonical URL.",
        "operationId": "createAsset",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAssetWithTagsRequest"
              }
            }
          },
          "description": "Asset to create with optional tags",
          "required": true,
          "x-originalParamName": "request"
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateAssetResponse"
                }
              }
            },
            "description": "Created",
            "headers": {
              "Location": {
                "description": "Canonical URL of the created resource",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "conflict",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unsupported_media_type",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Create an asset",
        "tags": [
          "assets"
        ],
        "x-required-scopes": [
          "assets:write"
        ]
      }
    },
    "/api/v1/assets/{asset_id}": {
      "delete": {
        "description": "**Required scope:** `assets:write`\n\nDelete an asset by its canonical id. The asset is removed from all subsequent queries and its external_key becomes immediately available for reuse. Returns 204 on success, 404 if the asset does not exist or has already been deleted.",
        "operationId": "deleteAsset",
        "parameters": [
          {
            "description": "Asset id (canonical)",
            "in": "path",
            "name": "asset_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "deleted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Delete an asset",
        "tags": [
          "assets"
        ],
        "x-required-scopes": [
          "assets:write"
        ]
      },
      "get": {
        "description": "**Required scope:** `assets:read`\n\nRetrieve an asset by its canonical id. Returns 404 if the asset does not exist.\n\nPath-addressed retrieval bypasses the temporal-validity filter applied on list endpoints — any non-deleted asset is returned regardless of its `valid_from` / `valid_to` values. Use this endpoint when you have an id and need the row even if its effective window has elapsed.",
        "operationId": "getAsset",
        "parameters": [
          {
            "description": "Asset id (canonical)",
            "in": "path",
            "name": "asset_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetAssetResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Get asset by canonical id",
        "tags": [
          "assets"
        ],
        "x-required-scopes": [
          "assets:read"
        ]
      },
      "patch": {
        "description": "**Required scope:** `assets:write`\n\nApply a JSON Merge Patch (RFC 7396) to an asset. Only fields included in the request body are changed; fields set to `null` clear the corresponding nullable column. Omitted fields are left unchanged. An empty body (`{}`) is a no-op and returns the current resource unchanged. Read-only fields are uniformly governed by the accept-if-matches, reject-if-differs rule: a value matching the current resource state is silently normalized out (so a verbatim GET → PATCH round-trip succeeds without manual scrubbing), and a differing value returns 400 with `code: read_only`. This applies to the server-managed surrogate id + timestamps (`id`, `created_at`, `updated_at`, `deleted_at`), the `tags` collection, and the natural-key reference fields (`external_key`, `location_id`, `location_external_key`). Mutate `external_key` via POST /assets/{asset_id}/rename; asset location is collected through scan event ingestion (fixed-reader MQTT pipeline or handheld UI submission) and is not directly settable through the public API; mutate `tags` via POST /assets/{asset_id}/tags and DELETE /assets/{asset_id}/tags/{tag_id}.",
        "operationId": "updateAsset",
        "parameters": [
          {
            "description": "Asset id (canonical)",
            "in": "path",
            "name": "asset_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/merge-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAssetRequest"
              }
            }
          },
          "description": "Fields to merge-patch",
          "required": true,
          "x-originalParamName": "request"
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateAssetResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "conflict",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unsupported_media_type",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Update an asset",
        "tags": [
          "assets"
        ],
        "x-required-scopes": [
          "assets:write"
        ]
      }
    },
    "/api/v1/assets/{asset_id}/history": {
      "get": {
        "description": "**Required scope:** `tracking:read`\n\nLocation history for an asset identified by its canonical id.\n\nThe asset existence check follows path-addressed semantics — the asset is returned even if its `valid_to` has elapsed. Each history row's location reference applies the temporal-validity predicate, so an event referencing a location whose effective window is past surfaces with null `location_external_key`.",
        "operationId": "getAssetHistory",
        "parameters": [
          {
            "description": "Asset id (canonical)",
            "in": "path",
            "name": "asset_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "max 200",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "min 0",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "RFC 3339 start timestamp",
            "in": "query",
            "name": "from",
            "schema": {
              "example": "2025-04-29T12:34:56.000Z",
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "RFC 3339 end timestamp",
            "in": "query",
            "name": "to",
            "schema": {
              "example": "2025-04-29T12:34:56.000Z",
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "comma-separated; prefix '-' for DESC",
            "explode": false,
            "in": "query",
            "name": "sort",
            "schema": {
              "default": "",
              "pattern": "^(|(?:event_observed_at|-event_observed_at)(?:,(?:event_observed_at|-event_observed_at))*)$",
              "type": "string"
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetHistoryResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Asset movement history",
        "tags": [
          "assets"
        ],
        "x-required-scopes": [
          "tracking:read"
        ]
      }
    },
    "/api/v1/assets/{asset_id}/rename": {
      "post": {
        "description": "**Required scope:** `assets:write`\n\nMutate the asset's `external_key` (natural / join key). This operation is **destructive to downstream joins**: any external system that has cached or indexed records on the old `external_key` will silently disconnect. Prefer a coordinated cutover with downstream consumers.\n\n`external_key` is immutable via PATCH; this operation is the only way to change it. Distinct from a regular PATCH in audit logs (different URL surface).\n\nThe response includes `descendant_count_affected` for shape uniformity with the location rename verb. Assets have no hierarchy, so this value is always 0; it is emitted to save typed-client consumers from branching on rename verb.",
        "operationId": "renameAsset",
        "parameters": [
          {
            "description": "Asset id (canonical)",
            "in": "path",
            "name": "asset_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenameAssetRequest"
              }
            }
          },
          "description": "New external_key",
          "required": true,
          "x-originalParamName": "request"
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenameAssetResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "conflict",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unsupported_media_type",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Rename an asset (mutate external_key)",
        "tags": [
          "assets"
        ],
        "x-required-scopes": [
          "assets:write"
        ]
      }
    },
    "/api/v1/assets/{asset_id}/tags": {
      "post": {
        "description": "**Required scope:** `assets:write`\n\nAttach a tag (RFID EPC, BLE beacon ID, barcode, etc.) to an existing asset.\nThe tag must be unique within the organization.",
        "operationId": "addAssetTag",
        "parameters": [
          {
            "description": "Asset id (canonical)",
            "in": "path",
            "name": "asset_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TagRequest"
              }
            }
          },
          "description": "Tag to attach",
          "required": true,
          "x-originalParamName": "request"
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddAssetTagResponse"
                }
              }
            },
            "description": "tag attached",
            "headers": {
              "Location": {
                "description": "Canonical URL of the created tag",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "conflict",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unsupported_media_type",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Add a tag to an asset",
        "tags": [
          "assets"
        ],
        "x-required-scopes": [
          "assets:write"
        ]
      }
    },
    "/api/v1/assets/{asset_id}/tags/{tag_id}": {
      "delete": {
        "description": "**Required scope:** `assets:write`\n\nDetach a tag from an asset by its tag record id.\nFirst successful removal returns 204; repeated calls return 404 — consistent with top-level resource DELETE semantics. The cross-asset / cross-org case (a tag that exists but is not attached to this asset, or belongs to a different org) also surfaces as 404.",
        "operationId": "removeAssetTag",
        "parameters": [
          {
            "description": "Asset id (canonical)",
            "in": "path",
            "name": "asset_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Tag id",
            "in": "path",
            "name": "tag_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "deleted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Remove a tag from an asset",
        "tags": [
          "assets"
        ],
        "x-required-scopes": [
          "assets:write"
        ]
      }
    },
    "/api/v1/locations": {
      "get": {
        "description": "**Required scope:** `locations:read`\n\nPaginated locations list with natural-key filters, sort, and substring search.\n\nDefault scope returns currently-effective locations only — rows whose `valid_from` is in the past AND whose `valid_to` is null or in the future. The `is_active` filter is independent of temporal validity; omit it to include both active and inactive rows within the effective window, or pass `?is_active=true`/`false` to filter further.",
        "operationId": "listLocations",
        "parameters": [
          {
            "description": "max 200",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "min 0",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "filter by parent id (canonical, may repeat); mutually exclusive with parent_external_key (400 ambiguous_fields if both supplied)",
            "explode": true,
            "in": "query",
            "name": "parent_id",
            "schema": {
              "default": [],
              "items": {
                "format": "int64",
                "maximum": 2147483647,
                "minimum": 1,
                "type": "integer"
              },
              "type": "array"
            },
            "style": "form"
          },
          {
            "description": "filter by parent's external_key (may repeat); mutually exclusive with parent_id (400 ambiguous_fields if both supplied)",
            "explode": true,
            "in": "query",
            "name": "parent_external_key",
            "schema": {
              "default": [],
              "items": {
                "pattern": "^[A-Za-z0-9-]+$",
                "type": "string"
              },
              "type": "array"
            },
            "style": "form"
          },
          {
            "description": "filter by location external_key, equality match (may repeat for any-of)",
            "explode": true,
            "in": "query",
            "name": "external_key",
            "schema": {
              "default": [],
              "items": {
                "pattern": "^[A-Za-z0-9-]+$",
                "type": "string"
              },
              "type": "array"
            },
            "style": "form"
          },
          {
            "description": "filter by active flag",
            "in": "query",
            "name": "is_active",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "when true, include soft-deleted rows in the response. deleted_at is populated for those rows. Orthogonal to is_active.",
            "in": "query",
            "name": "include_deleted",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          },
          {
            "description": "substring search (case-insensitive) on name, external_key, description, and active tag values",
            "in": "query",
            "name": "q",
            "schema": {
              "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
              "type": "string"
            }
          },
          {
            "description": "comma-separated, prefix '-' for DESC",
            "explode": false,
            "in": "query",
            "name": "sort",
            "schema": {
              "default": "",
              "pattern": "^(|(?:external_key|-external_key|name|-name|created_at|-created_at)(?:,(?:external_key|-external_key|name|-name|created_at|-created_at))*)$",
              "type": "string"
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListLocationsResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "List locations",
        "tags": [
          "locations"
        ],
        "x-required-scopes": [
          "locations:read"
        ]
      },
      "post": {
        "description": "**Required scope:** `locations:write`\n\nCreate a new location in the hierarchy, optionally with one or more tags.\nSet parent_id (canonical) or parent_external_key (alternate) to nest under an existing parent.\n\nThe `external_key` field is optional. Provide a value from your system of record\n(ERP, WMS, layout/plan) for natural-key joins, or omit it to receive a\nserver-assigned external_key in the format `LOC-NNNN` (per-organization sequence).\nA caller-supplied external_key that collides with an existing location returns 409.",
        "operationId": "createLocation",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLocationWithTagsRequest"
              }
            }
          },
          "description": "Location to create with optional tags",
          "required": true,
          "x-originalParamName": "request"
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateLocationResponse"
                }
              }
            },
            "description": "Created",
            "headers": {
              "Location": {
                "description": "Canonical URL of the created resource",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "conflict",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unsupported_media_type",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Create a location",
        "tags": [
          "locations"
        ],
        "x-required-scopes": [
          "locations:write"
        ]
      }
    },
    "/api/v1/locations/{location_id}": {
      "delete": {
        "description": "**Required scope:** `locations:write`\n\nDelete a location by its ID. Returns 204 on success, 404 if the location does not exist or has already been deleted, and 409 if the location has descendant locations or assets placed directly at it. Descendants must be reassigned or removed and placed assets must be moved or removed before their parent location can be deleted; bulk cascade is not supported.",
        "operationId": "deleteLocation",
        "parameters": [
          {
            "description": "Location ID",
            "in": "path",
            "name": "location_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "deleted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "conflict — has descendants or placed assets",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Delete location",
        "tags": [
          "locations"
        ],
        "x-required-scopes": [
          "locations:write"
        ]
      },
      "get": {
        "description": "**Required scope:** `locations:read`\n\nRetrieve a location by its canonical ID. Returns 404 if not found.\n\nPath-addressed retrieval bypasses the temporal-validity filter applied on list endpoints — any non-deleted location is returned regardless of its `valid_from` / `valid_to` values. Use this endpoint when you have an id and need the row even if its effective window has elapsed.",
        "operationId": "getLocation",
        "parameters": [
          {
            "description": "Location ID",
            "in": "path",
            "name": "location_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetLocationResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Too Many Requests",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Get location by ID",
        "tags": [
          "locations"
        ],
        "x-required-scopes": [
          "locations:read"
        ]
      },
      "patch": {
        "description": "**Required scope:** `locations:write`\n\nApply a JSON Merge Patch (RFC 7396) to a location. Only fields included in the request body are changed; fields set to `null` clear the corresponding nullable column. Omitted fields are left unchanged. An empty body (`{}`) is a no-op and returns the current resource unchanged. Read-only fields are uniformly governed by the accept-if-matches, reject-if-differs rule: a value matching the current resource state is silently normalized out (so a verbatim GET → PATCH round-trip succeeds without manual scrubbing), and a differing value returns 400 with `code: read_only`. This applies to the server-managed surrogate id + timestamps (`id`, `created_at`, `updated_at`, `deleted_at`), the `tags` collection, and the `external_key` natural key. To re-parent, send EITHER `parent_id` (surrogate) OR `parent_external_key` (natural key); both forms accept `null` to clear the FK, and supplying both in the same body returns 400 `ambiguous_fields` (symmetric with CreateLocationRequest). Mutate `external_key` via POST /locations/{location_id}/rename; mutate `tags` via POST /locations/{location_id}/tags and DELETE /locations/{location_id}/tags/{tag_id}.",
        "operationId": "updateLocation",
        "parameters": [
          {
            "description": "Location ID",
            "in": "path",
            "name": "location_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/merge-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLocationRequest"
              }
            }
          },
          "description": "Fields to merge-patch",
          "required": true,
          "x-originalParamName": "request"
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateLocationResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "conflict",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unsupported_media_type",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Update a location",
        "tags": [
          "locations"
        ],
        "x-required-scopes": [
          "locations:write"
        ]
      }
    },
    "/api/v1/locations/{location_id}/ancestors": {
      "get": {
        "description": "**Required scope:** `locations:read`\n\nSort order is fixed: ancestors are returned root first (walking up the `parent_id` chain), with `id` ascending as a deterministic tiebreaker. No `sort` query parameter is exposed because the natural order toward the root is the only meaningful order for this list.",
        "operationId": "listLocationAncestors",
        "parameters": [
          {
            "description": "Location ID",
            "in": "path",
            "name": "location_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "max 200",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "min 0",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListLocationAncestorsResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "List location ancestors",
        "tags": [
          "locations"
        ],
        "x-required-scopes": [
          "locations:read"
        ]
      }
    },
    "/api/v1/locations/{location_id}/children": {
      "get": {
        "description": "**Required scope:** `locations:read`\n\nSort order is fixed: immediate children are returned ordered alphabetically by `name` ascending, with `id` ascending as a deterministic tiebreaker when sibling names collide. No `sort` query parameter is exposed because alphabetical-by-name is the only meaningful order for a single level of siblings.",
        "operationId": "listLocationChildren",
        "parameters": [
          {
            "description": "Location ID",
            "in": "path",
            "name": "location_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "max 200",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "min 0",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListLocationChildrenResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "List location children",
        "tags": [
          "locations"
        ],
        "x-required-scopes": [
          "locations:read"
        ]
      }
    },
    "/api/v1/locations/{location_id}/descendants": {
      "get": {
        "description": "**Required scope:** `locations:read`\n\nSort order is fixed: descendants are returned in depth-first tree order (each level sorted by lowercased `external_key`), with `id` ascending as a deterministic tiebreaker. No `sort` query parameter is exposed because the depth-first tree walk is the only meaningful order for this list.",
        "operationId": "listLocationDescendants",
        "parameters": [
          {
            "description": "Location ID",
            "in": "path",
            "name": "location_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "max 200",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "min 0",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListLocationDescendantsResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "List location descendants",
        "tags": [
          "locations"
        ],
        "x-required-scopes": [
          "locations:read"
        ]
      }
    },
    "/api/v1/locations/{location_id}/rename": {
      "post": {
        "description": "**Required scope:** `locations:write`\n\nMutate the location's `external_key`. This operation is **destructive to downstream joins** because consumers of the natural key must re-resolve it. Only this row's `external_key` changes on the server; descendants are not modified.\n\nThe response includes `descendant_count_affected` (the live descendant count reachable through `parent_id`) so an integrator can decide whether to refresh derived natural-key joins for the subtree. `external_key` is immutable via PATCH; this operation is the only way to change it. Distinct from a regular PATCH in audit logs (different URL surface).",
        "operationId": "renameLocation",
        "parameters": [
          {
            "description": "Location ID",
            "in": "path",
            "name": "location_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenameLocationRequest"
              }
            }
          },
          "description": "New external_key",
          "required": true,
          "x-originalParamName": "request"
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenameLocationResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "conflict",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unsupported_media_type",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Rename a location (mutate external_key)",
        "tags": [
          "locations"
        ],
        "x-required-scopes": [
          "locations:write"
        ]
      }
    },
    "/api/v1/locations/{location_id}/tags": {
      "post": {
        "description": "**Required scope:** `locations:write`",
        "operationId": "addLocationTag",
        "parameters": [
          {
            "description": "Location ID",
            "in": "path",
            "name": "location_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TagRequest"
              }
            }
          },
          "description": "Tag to attach",
          "required": true,
          "x-originalParamName": "request"
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddLocationTagResponse"
                }
              }
            },
            "description": "tag attached",
            "headers": {
              "Location": {
                "description": "Canonical URL of the created tag",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "conflict",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unsupported_media_type",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Add a tag to a location",
        "tags": [
          "locations"
        ],
        "x-required-scopes": [
          "locations:write"
        ]
      }
    },
    "/api/v1/locations/{location_id}/tags/{tag_id}": {
      "delete": {
        "description": "**Required scope:** `locations:write`\n\nDetach a tag from a location by its tag record id.\nFirst successful removal returns 204; repeated calls return 404 — consistent with top-level resource DELETE semantics. The cross-location / cross-org case (a tag that exists but is not attached to this location, or belongs to a different org) also surfaces as 404.",
        "operationId": "removeLocationTag",
        "parameters": [
          {
            "description": "Location ID",
            "in": "path",
            "name": "location_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Tag ID",
            "in": "path",
            "name": "tag_id",
            "required": true,
            "schema": {
              "format": "int64",
              "maximum": 2147483647,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "deleted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "internal_error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Remove a tag from a location",
        "tags": [
          "locations"
        ],
        "x-required-scopes": [
          "locations:write"
        ]
      }
    },
    "/api/v1/orgs/me": {
      "get": {
        "description": "Returns the organization scoped by the API key presented in Authorization. Intended as a lightweight health-check primitive for integrators verifying a key works end-to-end.",
        "operationId": "getCurrentOrg",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetCurrentOrgResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "bad_request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "not_found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "missing_org_context — the API key authenticated but its org no longer exists",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal server error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Get the org associated with the authenticated API key",
        "tags": [
          "orgs"
        ],
        "x-required-scopes": []
      }
    },
    "/api/v1/reports/asset-locations": {
      "get": {
        "description": "**Required scope:** `tracking:read`\n\nSnapshot of each asset's most recent location, filterable by either side of the join. Filter by location (`location_id` / `location_external_key`) to retrieve everything currently at a place; filter by asset (`asset_id` / `asset_external_key`, repeatable) to resolve a batch of assets from a master system to their current locations in one round-trip. Within each pair the surrogate and natural-key forms are mutually exclusive (400 `ambiguous_fields` if both are supplied); the asset and location filter pairs are independent and intersect when combined. Because this view is derived from immutable scan history, it can resolve references for assets that have since been deleted. By default those rows are excluded; pass `include_deleted=true` to include them, and check `asset_deleted_at` to distinguish deleted from live.\n\nTemporal validity is applied to both joined entities. Assets whose effective window is past or future are excluded entirely. Locations whose effective window is past or future surface with null `location_id` / `location_external_key` while the parent asset row remains visible. Soft-deleted locations are projected the same way here — null on the report row — even though the identifier still lives on the location row; reports endpoints intentionally hide tombstoned anchor points from scan-derived summaries. Use the locations endpoint with `include_deleted=true` to retrieve the underlying identifier.",
        "operationId": "getAssetLocations",
        "parameters": [
          {
            "description": "max 200",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "min 0",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "filter by location id (canonical, may repeat); mutually exclusive with location_external_key (400 ambiguous_fields if both supplied)",
            "explode": true,
            "in": "query",
            "name": "location_id",
            "schema": {
              "default": [],
              "items": {
                "format": "int64",
                "maximum": 2147483647,
                "minimum": 1,
                "type": "integer"
              },
              "type": "array"
            },
            "style": "form"
          },
          {
            "description": "filter by location external_key (may repeat); mutually exclusive with location_id (400 ambiguous_fields if both supplied)",
            "explode": true,
            "in": "query",
            "name": "location_external_key",
            "schema": {
              "default": [],
              "items": {
                "pattern": "^[A-Za-z0-9-]+$",
                "type": "string"
              },
              "type": "array"
            },
            "style": "form"
          },
          {
            "description": "filter by asset id (canonical, may repeat); mutually exclusive with asset_external_key (400 ambiguous_fields if both supplied)",
            "explode": true,
            "in": "query",
            "name": "asset_id",
            "schema": {
              "default": [],
              "items": {
                "format": "int64",
                "maximum": 2147483647,
                "minimum": 1,
                "type": "integer"
              },
              "type": "array"
            },
            "style": "form"
          },
          {
            "description": "filter by asset external_key (may repeat); mutually exclusive with asset_id (400 ambiguous_fields if both supplied)",
            "explode": true,
            "in": "query",
            "name": "asset_external_key",
            "schema": {
              "default": [],
              "items": {
                "pattern": "^[A-Za-z0-9-]+$",
                "type": "string"
              },
              "type": "array"
            },
            "style": "form"
          },
          {
            "description": "substring search (case-insensitive) on asset name, external_key, and active tag values",
            "in": "query",
            "name": "q",
            "schema": {
              "pattern": "^[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]*$",
              "type": "string"
            }
          },
          {
            "description": "include rows for soft-deleted assets",
            "in": "query",
            "name": "include_deleted",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          },
          {
            "description": "comma-separated sort fields; prefix '-' for DESC",
            "explode": false,
            "in": "query",
            "name": "sort",
            "schema": {
              "default": "",
              "pattern": "^(|(?:asset_last_seen|-asset_last_seen|asset_external_key|-asset_external_key|location_external_key|-location_external_key)(?:,(?:asset_last_seen|-asset_last_seen|asset_external_key|-asset_external_key|location_external_key|-location_external_key))*)$",
              "type": "string"
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetLocationsResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized",
            "headers": {
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticate"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "rate_limited",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unmodeled error. Generated clients should treat any response not otherwise enumerated as a structured ErrorResponse.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "List current asset locations",
        "tags": [
          "reports"
        ],
        "x-required-scopes": [
          "tracking:read"
        ]
      }
    }
  },
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "servers": [
    {
      "description": "Preview (per-PR deploys). Preview-scoped API keys authenticate here only — they will fail with 401 against Production, and Production keys will fail here.",
      "url": "https://app.preview.trakrf.id"
    },
    {
      "description": "Production. Production-scoped API keys authenticate here only — they will fail with 401 against Preview, and Preview keys will fail here.",
      "url": "https://app.trakrf.id"
    }
  ],
  "tags": [
    {
      "description": "Asset CRUD, history, and tag membership.",
      "name": "assets"
    },
    {
      "description": "Location CRUD, hierarchy traversal, and tag membership.",
      "name": "locations"
    },
    {
      "description": "Caller's organization context.",
      "name": "orgs"
    },
    {
      "description": "Cross-cutting reporting endpoints (asset locations, etc.).",
      "name": "reports"
    }
  ]
}