{
  "openapi": "3.1.0",
  "info": {
    "title": "Batterypass API",
    "version": "1.1.0",
    "description": "REST API for battery models, passports, components, measurements, evidence and suppliers. Test keys (bp_test_) validate requests without saving."
  },
  "servers": [
    {
      "url": "https://app.batterypass2027.eu/api/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "request_id"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "field": {
                "type": "string"
              },
              "request_id": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Connection test",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/fields": {
      "get": {
        "operationId": "listFields",
        "summary": "Field catalogue",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List models",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "models:read"
      },
      "post": {
        "operationId": "createModel",
        "summary": "Create model",
        "responses": {
          "201": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "models:write",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/models/validate": {
      "post": {
        "operationId": "validateModel",
        "summary": "Check a draft without saving",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "models:read",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/models/{id}": {
      "get": {
        "operationId": "getModel",
        "summary": "Get model",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "models:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "patch": {
        "operationId": "updateModel",
        "summary": "Update model",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "models:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/passports": {
      "get": {
        "operationId": "listPassports",
        "summary": "List passports",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "passports:read"
      },
      "post": {
        "operationId": "createPassport",
        "summary": "Create one passport",
        "responses": {
          "201": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "passports:write",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/passports/batch": {
      "post": {
        "operationId": "createPassports",
        "summary": "Create up to 1000 passports",
        "responses": {
          "201": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "passports:write",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/passports/{id}": {
      "get": {
        "operationId": "getPassport",
        "summary": "Get passport",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "passports:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "patch": {
        "operationId": "updatePassport",
        "summary": "Update passport",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "passports:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/passports/{id}/events": {
      "get": {
        "operationId": "listEvents",
        "summary": "List events",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "passports:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "operationId": "createEvent",
        "summary": "Report event",
        "responses": {
          "201": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "passports:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/passports/{id}/components": {
      "get": {
        "operationId": "listComponents",
        "summary": "List components",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "passports:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "operationId": "createComponent",
        "summary": "Install component",
        "responses": {
          "201": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "passports:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/passports/{id}/components/{cid}": {
      "patch": {
        "operationId": "updateComponent",
        "summary": "Update or remove component",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "passports:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/passports/{id}/components/{cid}/replace": {
      "post": {
        "operationId": "replaceComponent",
        "summary": "Replace component",
        "responses": {
          "201": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "passports:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/passports/{id}/telemetry": {
      "get": {
        "operationId": "listTelemetry",
        "summary": "Read measurements",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "telemetry:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "operationId": "createTelemetry",
        "summary": "Report measurements",
        "responses": {
          "201": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "telemetry:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/certificates": {
      "get": {
        "operationId": "listCertificates",
        "summary": "List evidence",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "certificates:read"
      }
    },
    "/certificates/{id}": {
      "get": {
        "operationId": "getCertificate",
        "summary": "Get evidence with download link",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "certificates:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/suppliers": {
      "get": {
        "operationId": "listSuppliers",
        "summary": "List suppliers",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "suppliers:read"
      }
    },
    "/supplier-requests": {
      "get": {
        "operationId": "listSupplierRequests",
        "summary": "List supplier requests",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "suppliers:read"
      },
      "post": {
        "operationId": "createSupplierRequest",
        "summary": "Send supplier request",
        "responses": {
          "201": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "suppliers:write",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/supplier-requests/{id}": {
      "get": {
        "operationId": "getSupplierRequest",
        "summary": "Get supplier request",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "suppliers:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/supplier-requests/{id}/accept": {
      "post": {
        "operationId": "acceptSupplierRequest",
        "summary": "Accept supplied values",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "suppliers:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/audit": {
      "get": {
        "operationId": "listAudit",
        "summary": "Read audit trail",
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-required-scope": "audit:read"
      }
    },
    "/health": {
      "get": {
        "operationId": "health",
        "summary": "Public health check",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  }
}
