{
  "components": {
    "schemas": {
      "errors.ErrorResponse": {
        "properties": {
          "error": {
            "properties": {
              "detail": {
                "type": "string"
              },
              "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"
      }
    },
    "securitySchemes": {
      "APIKey": {
        "bearerFormat": "JWT",
        "description": "TrakRF API key (JWT). Format: \"Bearer \u003cjwt\u003e\". Mint keys from the API Keys section of your TrakRF account (key-management UI is tracked by TRA-393).",
        "scheme": "bearer",
        "type": "http"
      },
      "BearerAuth": {
        "description": "Session JWT for internal endpoints (platform frontend uses this).",
        "in": "header",
        "name": "Authorization",
        "type": "apiKey"
      }
    }
  },
  "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 fuzzy search",
        "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": "fuzzy search on name / identifier / description",
            "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": {
                  "additionalProperties": true,
                  "type": "object"
                }
              }
            },
            "description": "envelope with data / limit / offset / total_count"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "List assets",
        "tags": [
          "assets"
        ]
      }
    },
    "/api/v1/assets/{identifier}": {
      "get": {
        "parameters": [
          {
            "description": "Asset identifier (natural key)",
            "in": "path",
            "name": "identifier",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object"
                }
              }
            },
            "description": "OK"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Get asset by natural identifier",
        "tags": [
          "assets"
        ]
      }
    },
    "/api/v1/assets/{identifier}/history": {
      "get": {
        "description": "Location history for an asset identified by its natural key.",
        "parameters": [
          {
            "description": "Asset identifier (natural key)",
            "in": "path",
            "name": "identifier",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "max 200",
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "pagination offset",
            "in": "query",
            "name": "offset",
            "schema": {
              "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": {
                  "additionalProperties": true,
                  "type": "object"
                }
              }
            },
            "description": "OK"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Asset movement history",
        "tags": [
          "reports"
        ]
      }
    },
    "/api/v1/locations": {
      "get": {
        "parameters": [
          {
            "description": "max 200",
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "pagination offset",
            "in": "query",
            "name": "offset",
            "schema": {
              "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": "fuzzy search on name, identifier, description",
            "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": {
                  "additionalProperties": true,
                  "type": "object"
                }
              }
            },
            "description": "OK"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "List locations",
        "tags": [
          "locations"
        ]
      }
    },
    "/api/v1/locations/current": {
      "get": {
        "description": "Snapshot of each asset's most recent location, filterable by natural key.",
        "parameters": [
          {
            "description": "max 200",
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "pagination offset",
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "filter by location identifier (may repeat)",
            "in": "query",
            "name": "location",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "fuzzy search on asset name / identifier",
            "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": {
                  "additionalProperties": true,
                  "type": "object"
                }
              }
            },
            "description": "OK"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "List current asset locations",
        "tags": [
          "reports"
        ]
      }
    },
    "/api/v1/locations/{identifier}": {
      "get": {
        "parameters": [
          {
            "description": "Location identifier (natural key)",
            "in": "path",
            "name": "identifier",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object"
                }
              }
            },
            "description": "OK"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errors.ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Get location by natural identifier",
        "tags": [
          "locations"
        ]
      }
    }
  },
  "servers": [
    {
      "description": "Production",
      "url": "https://app.trakrf.id"
    },
    {
      "description": "Preview (per-PR deploys)",
      "url": "https://app.preview.trakrf.id"
    }
  ]
}