components:
    schemas:
        github_com_trakrf_platform_backend_internal_models_apikey.APIKeyCreateResponse:
            properties:
                created_at:
                    format: date-time
                    type: string
                expires_at:
                    format: date-time
                    type: string
                id:
                    type: integer
                jti:
                    type: string
                key:
                    type: string
                name:
                    type: string
                scopes:
                    items:
                        type: string
                    type: array
            type: object
        github_com_trakrf_platform_backend_internal_models_apikey.APIKeyListItem:
            properties:
                created_at:
                    format: date-time
                    type: string
                created_by:
                    type: integer
                created_by_key_id:
                    type: integer
                expires_at:
                    format: date-time
                    type: string
                id:
                    type: integer
                jti:
                    type: string
                last_used_at:
                    format: date-time
                    type: string
                name:
                    type: string
                scopes:
                    items:
                        type: string
                    type: array
            type: object
        github_com_trakrf_platform_backend_internal_models_apikey.CreateAPIKeyRequest:
            properties:
                expires_at:
                    format: date-time
                    type: string
                name:
                    maxLength: 255
                    minLength: 1
                    type: string
                scopes:
                    items:
                        type: string
                    minItems: 1
                    type: array
            required:
                - name
                - scopes
            type: object
        github_com_trakrf_platform_backend_internal_models_asset.CreateAssetWithIdentifiersRequest:
            properties:
                current_location:
                    example: WHS-01
                    maxLength: 255
                    minLength: 1
                    type: string
                description:
                    maxLength: 1024
                    type: string
                identifier:
                    maxLength: 255
                    type: string
                identifiers:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_shared.TagIdentifierRequest'
                    type: array
                is_active:
                    example: true
                    type: boolean
                metadata:
                    additionalProperties: true
                    type: object
                name:
                    maxLength: 255
                    minLength: 1
                    type: string
                type:
                    enum:
                        - asset
                        - person
                        - inventory
                    example: asset
                    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
                    type: string
            required:
                - name
            type: object
        github_com_trakrf_platform_backend_internal_models_asset.PublicAssetView:
            properties:
                created_at:
                    format: date-time
                    type: string
                current_location:
                    type: string
                description:
                    type: string
                identifier:
                    type: string
                identifiers:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_shared.TagIdentifier'
                    type: array
                is_active:
                    type: boolean
                metadata:
                    additionalProperties: true
                    type: object
                name:
                    type: string
                surrogate_id:
                    type: integer
                type:
                    type: string
                updated_at:
                    format: date-time
                    type: string
                valid_from:
                    format: date-time
                    type: string
                valid_to:
                    format: date-time
                    type: string
            type: object
        github_com_trakrf_platform_backend_internal_models_asset.UpdateAssetRequest:
            properties:
                current_location:
                    example: WHS-01
                    maxLength: 255
                    minLength: 1
                    type: string
                description:
                    maxLength: 1024
                    type: string
                identifier:
                    maxLength: 255
                    minLength: 1
                    type: string
                is_active:
                    type: boolean
                metadata:
                    additionalProperties: true
                    type: object
                name:
                    maxLength: 255
                    minLength: 1
                    type: string
                type:
                    enum:
                        - asset
                        - person
                        - inventory
                    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
                    type: string
            type: object
        github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse:
            properties:
                error:
                    properties:
                        detail:
                            type: string
                        fields:
                            items:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.FieldError'
                            type: array
                        instance:
                            type: string
                        request_id:
                            type: string
                        status:
                            type: integer
                        title:
                            type: string
                        type:
                            enum:
                                - validation_error
                                - bad_request
                                - unauthorized
                                - forbidden
                                - not_found
                                - conflict
                                - rate_limited
                                - internal_error
                            example: validation_error
                            type: string
                            x-extensible-enum: true
                    type: object
            type: object
        github_com_trakrf_platform_backend_internal_models_errors.FieldError:
            properties:
                code:
                    type: string
                field:
                    type: string
                message:
                    type: string
                params:
                    additionalProperties: {}
                    type: object
            type: object
        github_com_trakrf_platform_backend_internal_models_location.CreateLocationWithIdentifiersRequest:
            properties:
                description:
                    example: Main warehouse location
                    maxLength: 1024
                    type: string
                identifier:
                    example: wh1
                    maxLength: 255
                    minLength: 1
                    type: string
                identifiers:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_shared.TagIdentifierRequest'
                    type: array
                is_active:
                    example: true
                    type: boolean
                name:
                    example: Warehouse 1
                    maxLength: 255
                    minLength: 1
                    type: string
                parent_identifier:
                    example: wh1
                    maxLength: 255
                    minLength: 1
                    type: string
                valid_from:
                    example: "2025-12-14T00:00:00Z"
                    format: date-time
                    type: string
                valid_to:
                    example: "2026-12-14T00:00:00Z"
                    format: date-time
                    type: string
            required:
                - identifier
                - name
            type: object
        github_com_trakrf_platform_backend_internal_models_location.PublicLocationView:
            properties:
                created_at:
                    format: date-time
                    type: string
                depth:
                    type: integer
                description:
                    type: string
                identifier:
                    type: string
                identifiers:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_shared.TagIdentifier'
                    type: array
                is_active:
                    type: boolean
                name:
                    type: string
                parent:
                    type: string
                path:
                    type: string
                surrogate_id:
                    type: integer
                updated_at:
                    format: date-time
                    type: string
                valid_from:
                    format: date-time
                    type: string
                valid_to:
                    format: date-time
                    type: string
            type: object
        github_com_trakrf_platform_backend_internal_models_location.UpdateLocationRequest:
            properties:
                description:
                    example: Updated description
                    maxLength: 1024
                    type: string
                identifier:
                    example: wh1
                    maxLength: 255
                    minLength: 1
                    type: string
                is_active:
                    example: true
                    type: boolean
                name:
                    example: Warehouse 1
                    maxLength: 255
                    minLength: 1
                    type: string
                parent_identifier:
                    example: wh1
                    maxLength: 255
                    minLength: 1
                    type: string
                valid_from:
                    example: "2025-12-14T00:00:00Z"
                    format: date-time
                    type: string
                valid_to:
                    example: "2026-12-14T00:00:00Z"
                    format: date-time
                    type: string
            type: object
        github_com_trakrf_platform_backend_internal_models_report.PublicAssetHistoryItem:
            properties:
                duration_seconds:
                    type: integer
                location:
                    type: string
                timestamp:
                    format: date-time
                    type: string
            type: object
        github_com_trakrf_platform_backend_internal_models_report.PublicCurrentLocationItem:
            properties:
                asset:
                    type: string
                last_seen:
                    format: date-time
                    type: string
                location:
                    type: string
            type: object
        github_com_trakrf_platform_backend_internal_models_shared.TagIdentifier:
            properties:
                id:
                    type: integer
                is_active:
                    type: boolean
                type:
                    enum:
                        - rfid
                        - ble
                        - barcode
                    example: rfid
                    type: string
                    x-extensible-enum: true
                value:
                    maxLength: 255
                    minLength: 1
                    type: string
            required:
                - type
                - value
            type: object
        github_com_trakrf_platform_backend_internal_models_shared.TagIdentifierRequest:
            properties:
                type:
                    enum:
                        - rfid
                        - ble
                        - barcode
                    example: rfid
                    type: string
                    x-extensible-enum: true
                value:
                    maxLength: 255
                    minLength: 1
                    type: string
            required:
                - value
            type: object
        github_com_trakrf_platform_backend_internal_storage.SaveInventoryResult:
            properties:
                count:
                    type: integer
                location_id:
                    type: integer
                location_name:
                    type: string
                timestamp:
                    format: date-time
                    type: string
            type: object
        internal_handlers_assets.CreateAssetResponse:
            properties:
                data:
                    $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_asset.PublicAssetView'
            type: object
        internal_handlers_assets.GetAssetResponse:
            properties:
                data:
                    $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_asset.PublicAssetView'
            type: object
        internal_handlers_assets.ListAssetsResponse:
            properties:
                data:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_asset.PublicAssetView'
                    type: array
                limit:
                    example: 50
                    type: integer
                offset:
                    example: 0
                    type: integer
                total_count:
                    example: 100
                    type: integer
            type: object
        internal_handlers_assets.UpdateAssetResponse:
            properties:
                data:
                    $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_asset.PublicAssetView'
            type: object
        internal_handlers_inventory.SaveRequest:
            properties:
                asset_identifiers:
                    example:
                        - ASSET-0001
                    items:
                        type: string
                    minItems: 1
                    type: array
                location_identifier:
                    example: WH-01
                    maxLength: 255
                    minLength: 1
                    type: string
            type: object
        internal_handlers_inventory.SaveResponse:
            properties:
                data:
                    $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_storage.SaveInventoryResult'
            type: object
        internal_handlers_locations.CreateLocationResponse:
            properties:
                data:
                    $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_location.PublicLocationView'
            type: object
        internal_handlers_locations.GetLocationResponse:
            properties:
                data:
                    $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_location.PublicLocationView'
            type: object
        internal_handlers_locations.ListAncestorsResponse:
            properties:
                data:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_location.PublicLocationView'
                    type: array
                limit:
                    example: 50
                    type: integer
                offset:
                    example: 0
                    type: integer
                total_count:
                    example: 100
                    type: integer
            type: object
        internal_handlers_locations.ListChildrenResponse:
            properties:
                data:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_location.PublicLocationView'
                    type: array
                limit:
                    example: 50
                    type: integer
                offset:
                    example: 0
                    type: integer
                total_count:
                    example: 100
                    type: integer
            type: object
        internal_handlers_locations.ListDescendantsResponse:
            properties:
                data:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_location.PublicLocationView'
                    type: array
                limit:
                    example: 50
                    type: integer
                offset:
                    example: 0
                    type: integer
                total_count:
                    example: 100
                    type: integer
            type: object
        internal_handlers_locations.ListLocationsResponse:
            properties:
                data:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_location.PublicLocationView'
                    type: array
                limit:
                    example: 50
                    type: integer
                offset:
                    example: 0
                    type: integer
                total_count:
                    example: 100
                    type: integer
            type: object
        internal_handlers_locations.UpdateLocationResponse:
            properties:
                data:
                    $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_location.PublicLocationView'
            type: object
        internal_handlers_orgs.CreateAPIKeyResponse:
            properties:
                data:
                    $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_apikey.APIKeyCreateResponse'
            type: object
        internal_handlers_orgs.GetOrgMeResponse:
            properties:
                data:
                    $ref: '#/components/schemas/internal_handlers_orgs.OrgMeView'
            type: object
        internal_handlers_orgs.ListAPIKeysResponse:
            properties:
                data:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_apikey.APIKeyListItem'
                    type: array
                limit:
                    example: 50
                    type: integer
                offset:
                    example: 0
                    type: integer
                total_count:
                    example: 100
                    type: integer
            type: object
        internal_handlers_orgs.OrgMeView:
            properties:
                id:
                    example: 42
                    type: integer
                name:
                    example: Acme Logistics
                    type: string
            type: object
        internal_handlers_reports.AssetHistoryResponse:
            properties:
                data:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_report.PublicAssetHistoryItem'
                    type: array
                limit:
                    example: 50
                    type: integer
                offset:
                    example: 0
                    type: integer
                total_count:
                    example: 100
                    type: integer
            type: object
        internal_handlers_reports.ListCurrentLocationsResponse:
            properties:
                data:
                    items:
                        $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_report.PublicCurrentLocationItem'
                    type: array
                limit:
                    example: 50
                    type: integer
                offset:
                    example: 0
                    type: integer
                total_count:
                    example: 100
                    type: integer
            type: object
    securitySchemes:
        APIKey:
            description: 'TrakRF API key (JWT). Format: "Bearer <jwt>". Mint keys from the API Keys section of your TrakRF account.'
            in: header
            name: Authorization
            type: apiKey
        BearerAuth:
            bearerFormat: JWT
            description: Session JWT for internal endpoints (platform frontend uses this).
            scheme: bearer
            type: http
info:
    contact:
        email: support@trakrf.id
        name: TrakRF Support
    description: TrakRF public REST API. See docs.trakrf.id/api for the customer-facing reference.
    license:
        name: Business Source License 1.1
        url: https://github.com/trakrf/platform/blob/main/LICENSE
    title: TrakRF API
    version: v1
openapi: 3.0.3
paths:
    /api/v1/assets:
        get:
            description: Paginated assets list with natural-key filters, sort, and substring search
            operationId: assets.list
            parameters:
                - description: max 200
                  in: query
                  name: limit
                  schema:
                    default: 50
                    type: integer
                - description: min 0
                  in: query
                  name: offset
                  schema:
                    default: 0
                    type: integer
                - description: filter by location natural key (may repeat)
                  in: query
                  name: location
                  schema:
                    type: string
                - description: filter by active flag
                  in: query
                  name: is_active
                  schema:
                    type: boolean
                - description: filter by type
                  in: query
                  name: type
                  schema:
                    type: string
                - description: substring search (case-insensitive) on name, identifier, description, and active identifier values
                  in: query
                  name: q
                  schema:
                    type: string
                - description: comma-separated; prefix '-' for DESC
                  in: query
                  name: sort
                  schema:
                    type: string
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_assets.ListAssetsResponse'
                    description: OK
                    headers:
                        X-RateLimit-Limit:
                            description: Steady-state requests/min for this API key
                            schema:
                                type: integer
                        X-RateLimit-Remaining:
                            description: Requests remaining before throttling; bounded by X-RateLimit-Limit
                            schema:
                                type: integer
                        X-RateLimit-Reset:
                            description: Unix timestamp (seconds) when X-RateLimit-Remaining will next equal X-RateLimit-Limit
                            schema:
                                type: integer
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Bad Request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Forbidden
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                    headers:
                        Retry-After:
                            description: Seconds to wait before retrying
                            schema:
                                type: integer
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Internal Server Error
            security:
                - APIKey:
                    - assets:read
            summary: List assets
            tags:
                - assets
        post:
            description: |-
                Create a new asset record, optionally with one or more tag identifiers (RFID, BLE, barcode).
                Returns the created asset with its assigned identifiers. The Location response header contains the canonical URL.
            operationId: assets.create
            requestBody:
                content:
                    application/json:
                        schema:
                            $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_asset.CreateAssetWithIdentifiersRequest'
                description: Asset to create with optional identifiers
                required: true
                x-originalParamName: request
            responses:
                "201":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_assets.CreateAssetResponse'
                    description: Created
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "409":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: conflict
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - assets:write
            summary: Create an asset
            tags:
                - assets
    /api/v1/assets/{identifier}:
        delete:
            description: Delete an asset by its natural identifier. The asset is removed from all subsequent queries and its identifier becomes immediately available for reuse. Returns 204 on success, 404 if the asset does not exist or has already been deleted.
            operationId: assets.delete
            parameters:
                - description: Asset identifier
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
            responses:
                "204":
                    description: deleted
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: not_found
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - assets:write
            summary: Delete an asset
            tags:
                - assets
        get:
            description: Retrieve an asset by its natural identifier. Returns 404 if the asset does not exist.
            operationId: assets.get
            parameters:
                - description: Asset identifier (natural key)
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_assets.GetAssetResponse'
                    description: OK
                    headers:
                        X-RateLimit-Limit:
                            description: Steady-state requests/min for this API key
                            schema:
                                type: integer
                        X-RateLimit-Remaining:
                            description: Requests remaining before throttling; bounded by X-RateLimit-Limit
                            schema:
                                type: integer
                        X-RateLimit-Reset:
                            description: Unix timestamp (seconds) when X-RateLimit-Remaining will next equal X-RateLimit-Limit
                            schema:
                                type: integer
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Bad Request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Not Found
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                    headers:
                        Retry-After:
                            description: Seconds to wait before retrying
                            schema:
                                type: integer
            security:
                - APIKey:
                    - assets:read
            summary: Get asset by natural identifier
            tags:
                - assets
        put:
            description: Update mutable fields on an existing asset. Only fields included in the request body are changed.
            operationId: assets.update
            parameters:
                - description: Asset identifier
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
            requestBody:
                content:
                    application/json:
                        schema:
                            $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_asset.UpdateAssetRequest'
                description: Fields to update
                required: true
                x-originalParamName: request
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_assets.UpdateAssetResponse'
                    description: OK
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: not_found
                "409":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: conflict
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - assets:write
            summary: Update an asset
            tags:
                - assets
    /api/v1/assets/{identifier}/history:
        get:
            description: Location history for an asset identified by its natural key.
            operationId: assets.history
            parameters:
                - description: Asset identifier (natural key)
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
                - description: max 200
                  in: query
                  name: limit
                  schema:
                    default: 50
                    type: integer
                - description: min 0
                  in: query
                  name: offset
                  schema:
                    default: 0
                    type: integer
                - description: RFC 3339 start timestamp
                  in: query
                  name: from
                  schema:
                    type: string
                - description: RFC 3339 end timestamp
                  in: query
                  name: to
                  schema:
                    type: string
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_reports.AssetHistoryResponse'
                    description: OK
                    headers:
                        X-RateLimit-Limit:
                            description: Steady-state requests/min for this API key
                            schema:
                                type: integer
                        X-RateLimit-Remaining:
                            description: Requests remaining before throttling; bounded by X-RateLimit-Limit
                            schema:
                                type: integer
                        X-RateLimit-Reset:
                            description: Unix timestamp (seconds) when X-RateLimit-Remaining will next equal X-RateLimit-Limit
                            schema:
                                type: integer
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Bad Request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Not Found
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                    headers:
                        Retry-After:
                            description: Seconds to wait before retrying
                            schema:
                                type: integer
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Internal Server Error
            security:
                - APIKey:
                    - scans:read
            summary: Asset movement history
            tags:
                - reports
    /api/v1/assets/{identifier}/identifiers:
        post:
            description: |-
                Attach a tag identifier (RFID EPC, BLE beacon ID, barcode, etc.) to an existing asset.
                The identifier must be unique within the organization.
            operationId: assets.identifiers.add
            parameters:
                - description: Asset identifier
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
            requestBody:
                content:
                    application/json:
                        schema:
                            $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_shared.TagIdentifierRequest'
                description: Tag identifier to attach
                required: true
                x-originalParamName: request
            responses:
                "201":
                    content:
                        application/json:
                            schema:
                                additionalProperties: true
                                type: object
                    description: 'data: shared.TagIdentifier'
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: not_found
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - assets:write
            summary: Add an identifier to an asset
            tags:
                - assets
    /api/v1/assets/{identifier}/identifiers/{identifierId}:
        delete:
            description: Detach a tag identifier from an asset by its identifier record ID.
            operationId: assets.identifiers.remove
            parameters:
                - description: Asset identifier
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
                - description: Identifier ID
                  in: path
                  name: identifierId
                  required: true
                  schema:
                    type: integer
            responses:
                "204":
                    description: deleted
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: not_found
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - assets:write
            summary: Remove an identifier from an asset
            tags:
                - assets
    /api/v1/inventory/save:
        post:
            description: Persist scanned RFID assets to the asset_scans hypertable
            operationId: inventory.save
            requestBody:
                content:
                    application/json:
                        schema:
                            $ref: '#/components/schemas/internal_handlers_inventory.SaveRequest'
                description: Save request with location and asset IDs
                required: true
                x-originalParamName: request
            responses:
                "201":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_inventory.SaveResponse'
                    description: Created
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Invalid request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Location or assets not owned by org
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                    headers:
                        Retry-After:
                            description: Seconds to wait before retrying
                            schema:
                                type: integer
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Internal server error
            security:
                - APIKey:
                    - scans:write
            summary: Save inventory scans
            tags:
                - inventory
    /api/v1/locations:
        get:
            operationId: locations.list
            parameters:
                - description: max 200
                  in: query
                  name: limit
                  schema:
                    default: 50
                    type: integer
                - description: min 0
                  in: query
                  name: offset
                  schema:
                    default: 0
                    type: integer
                - description: filter by parent identifier (may repeat)
                  in: query
                  name: parent
                  schema:
                    type: string
                - description: filter by active flag
                  in: query
                  name: is_active
                  schema:
                    type: boolean
                - description: substring search (case-insensitive) on name, identifier, description, and active identifier values
                  in: query
                  name: q
                  schema:
                    type: string
                - description: comma-separated, prefix '-' for DESC
                  in: query
                  name: sort
                  schema:
                    type: string
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_locations.ListLocationsResponse'
                    description: OK
                    headers:
                        X-RateLimit-Limit:
                            description: Steady-state requests/min for this API key
                            schema:
                                type: integer
                        X-RateLimit-Remaining:
                            description: Requests remaining before throttling; bounded by X-RateLimit-Limit
                            schema:
                                type: integer
                        X-RateLimit-Reset:
                            description: Unix timestamp (seconds) when X-RateLimit-Remaining will next equal X-RateLimit-Limit
                            schema:
                                type: integer
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                    headers:
                        Retry-After:
                            description: Seconds to wait before retrying
                            schema:
                                type: integer
            security:
                - APIKey:
                    - locations:read
            summary: List locations
            tags:
                - locations
        post:
            description: |-
                Create a new location in the hierarchy, optionally with one or more tag identifiers.
                Set ParentLocationID to nest the location under an existing parent. The Location response header contains the canonical URL.
            operationId: locations.create
            requestBody:
                content:
                    application/json:
                        schema:
                            $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_location.CreateLocationWithIdentifiersRequest'
                description: Location to create with optional identifiers
                required: true
                x-originalParamName: request
            responses:
                "201":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_locations.CreateLocationResponse'
                    description: Created
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "409":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: conflict
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - locations:write
            summary: Create a location
            tags:
                - locations
    /api/v1/locations/{identifier}:
        delete:
            description: Delete a location by its natural identifier. The location is removed from all subsequent queries and its identifier becomes immediately available for reuse. Returns 204 on success, 404 if the location does not exist or has already been deleted.
            operationId: locations.delete
            parameters:
                - description: Location identifier
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
            responses:
                "204":
                    description: deleted
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: not_found
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - locations:write
            summary: Delete location
            tags:
                - locations
        get:
            description: Retrieve a location by its natural identifier. Returns 404 if the location does not exist.
            operationId: locations.get
            parameters:
                - description: Location identifier (natural key)
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_locations.GetLocationResponse'
                    description: OK
                    headers:
                        X-RateLimit-Limit:
                            description: Steady-state requests/min for this API key
                            schema:
                                type: integer
                        X-RateLimit-Remaining:
                            description: Requests remaining before throttling; bounded by X-RateLimit-Limit
                            schema:
                                type: integer
                        X-RateLimit-Reset:
                            description: Unix timestamp (seconds) when X-RateLimit-Remaining will next equal X-RateLimit-Limit
                            schema:
                                type: integer
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Bad Request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Not Found
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                    headers:
                        Retry-After:
                            description: Seconds to wait before retrying
                            schema:
                                type: integer
            security:
                - APIKey:
                    - locations:read
            summary: Get location by natural identifier
            tags:
                - locations
        put:
            description: Update mutable fields on an existing location. Only fields included in the request body are changed.
            operationId: locations.update
            parameters:
                - description: Location identifier
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
            requestBody:
                content:
                    application/json:
                        schema:
                            $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_location.UpdateLocationRequest'
                description: Fields to update
                required: true
                x-originalParamName: request
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_locations.UpdateLocationResponse'
                    description: OK
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: not_found
                "409":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: conflict
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - locations:write
            summary: Update a location
            tags:
                - locations
    /api/v1/locations/{identifier}/ancestors:
        get:
            description: Return all ancestor locations from the root of the hierarchy down to the immediate parent of the specified location.
            operationId: locations.ancestors
            parameters:
                - description: Location identifier
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
                - description: max 200
                  in: query
                  name: limit
                  schema:
                    default: 50
                    type: integer
                - description: min 0
                  in: query
                  name: offset
                  schema:
                    default: 0
                    type: integer
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_locations.ListAncestorsResponse'
                    description: OK
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - locations:read
            summary: List location ancestors
            tags:
                - locations
    /api/v1/locations/{identifier}/children:
        get:
            description: Return the immediate child locations of the specified location (one level deep only).
            operationId: locations.children
            parameters:
                - description: Location identifier
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
                - description: max 200
                  in: query
                  name: limit
                  schema:
                    default: 50
                    type: integer
                - description: min 0
                  in: query
                  name: offset
                  schema:
                    default: 0
                    type: integer
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_locations.ListChildrenResponse'
                    description: OK
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - locations:read
            summary: List location children
            tags:
                - locations
    /api/v1/locations/{identifier}/descendants:
        get:
            description: Return all descendant locations (children, grandchildren, etc.) beneath the specified location in the hierarchy.
            operationId: locations.descendants
            parameters:
                - description: Location identifier
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
                - description: max 200
                  in: query
                  name: limit
                  schema:
                    default: 50
                    type: integer
                - description: min 0
                  in: query
                  name: offset
                  schema:
                    default: 0
                    type: integer
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_locations.ListDescendantsResponse'
                    description: OK
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - locations:read
            summary: List location descendants
            tags:
                - locations
    /api/v1/locations/{identifier}/identifiers:
        post:
            description: |-
                Attach a tag identifier (RFID EPC, BLE beacon ID, barcode, etc.) to an existing location.
                The identifier must be unique within the organization.
            operationId: locations.identifiers.add
            parameters:
                - description: Location identifier
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
            requestBody:
                content:
                    application/json:
                        schema:
                            $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_shared.TagIdentifierRequest'
                description: Tag identifier to attach
                required: true
                x-originalParamName: request
            responses:
                "201":
                    content:
                        application/json:
                            schema:
                                additionalProperties: true
                                type: object
                    description: 'data: shared.TagIdentifier'
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: not_found
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - locations:write
            summary: Add an identifier to a location
            tags:
                - locations
    /api/v1/locations/{identifier}/identifiers/{identifierId}:
        delete:
            description: Detach a tag identifier from a location by its identifier record ID.
            operationId: locations.identifiers.remove
            parameters:
                - description: Location identifier
                  in: path
                  name: identifier
                  required: true
                  schema:
                    type: string
                - description: Identifier ID
                  in: path
                  name: identifierId
                  required: true
                  schema:
                    type: integer
            responses:
                "204":
                    description: deleted
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: bad_request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: not_found
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: internal_error
            security:
                - APIKey:
                    - locations:write
            summary: Remove an identifier from a location
            tags:
                - locations
    /api/v1/locations/current:
        get:
            description: Snapshot of each asset's most recent location, filterable by natural key.
            operationId: locations.current
            parameters:
                - description: max 200
                  in: query
                  name: limit
                  schema:
                    default: 50
                    type: integer
                - description: min 0
                  in: query
                  name: offset
                  schema:
                    default: 0
                    type: integer
                - description: filter by location identifier (may repeat)
                  in: query
                  name: location
                  schema:
                    type: string
                - description: substring search (case-insensitive) on asset name, identifier, and active identifier values
                  in: query
                  name: q
                  schema:
                    type: string
                - description: comma-separated sort fields; prefix '-' for DESC
                  in: query
                  name: sort
                  schema:
                    type: string
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_reports.ListCurrentLocationsResponse'
                    description: OK
                    headers:
                        X-RateLimit-Limit:
                            description: Steady-state requests/min for this API key
                            schema:
                                type: integer
                        X-RateLimit-Remaining:
                            description: Requests remaining before throttling; bounded by X-RateLimit-Limit
                            schema:
                                type: integer
                        X-RateLimit-Reset:
                            description: Unix timestamp (seconds) when X-RateLimit-Remaining will next equal X-RateLimit-Limit
                            schema:
                                type: integer
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Bad Request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Forbidden
                "429":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: rate_limited
                    headers:
                        Retry-After:
                            description: Seconds to wait before retrying
                            schema:
                                type: integer
            security:
                - APIKey:
                    - scans:read
            summary: List current asset locations
            tags:
                - reports
    /api/v1/orgs/{id}/api-keys:
        get:
            operationId: api_keys.list
            parameters:
                - description: Organization id
                  in: path
                  name: id
                  required: true
                  schema:
                    type: integer
                - description: max 200
                  in: query
                  name: limit
                  schema:
                    default: 50
                    type: integer
                - description: min 0
                  in: query
                  name: offset
                  schema:
                    default: 0
                    type: integer
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_orgs.ListAPIKeysResponse'
                    description: OK
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Bad Request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Forbidden
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Internal Server Error
            security:
                - BearerAuth: []
                - APIKey:
                    - keys:admin
            summary: List active API keys for an organization
            tags:
                - api-keys
        post:
            description: Mints an API-key JWT scoped to the target org. Accepts either session-admin or an API key with the keys:admin scope.
            operationId: api_keys.create
            parameters:
                - description: Organization id
                  in: path
                  name: id
                  required: true
                  schema:
                    type: integer
            requestBody:
                content:
                    application/json:
                        schema:
                            $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_apikey.CreateAPIKeyRequest'
                description: Key creation payload
                required: true
                x-originalParamName: request
            responses:
                "201":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_orgs.CreateAPIKeyResponse'
                    description: Created
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Bad Request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Forbidden
                "409":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Active-key cap reached
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Internal Server Error
            security:
                - BearerAuth: []
                - APIKey:
                    - keys:admin
            summary: Create a new API key for an organization
            tags:
                - api-keys
    /api/v1/orgs/{id}/api-keys/{key_id}:
        delete:
            operationId: api_keys.revoke
            parameters:
                - description: Organization id
                  in: path
                  name: id
                  required: true
                  schema:
                    type: integer
                - description: Either the integer surrogate id or the UUID jti
                  in: path
                  name: key_id
                  required: true
                  schema:
                    type: string
            responses:
                "204":
                    description: No Content
                "400":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Bad Request
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Unauthorized
                "403":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Forbidden
                "404":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Not Found
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Internal Server Error
            security:
                - BearerAuth: []
                - APIKey:
                    - keys:admin
            summary: Revoke an API key
            tags:
                - api-keys
    /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: orgs.me
            responses:
                "200":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/internal_handlers_orgs.GetOrgMeResponse'
                    description: OK
                "401":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Unauthorized
                "500":
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/github_com_trakrf_platform_backend_internal_models_errors.ErrorResponse'
                    description: Internal server error
            security:
                - APIKey: []
            summary: Get the org associated with the authenticated API key
            tags:
                - orgs
servers:
    - description: Production
      url: https://app.trakrf.id
    - description: Preview (per-PR deploys)
      url: https://app.preview.trakrf.id
