{
  "openapi": "3.1.0",
  "info": {
    "title": "LabNote ELN Lite — Public API",
    "version": "1.1.0",
    "description": "Stable public HTTP surface of the LabNote backend. Designed for machine-to-machine\nintegration (LIMS, ERP, instrument automation) and AI-agent use.\n\n## Authentication\n\nTwo stable token kinds are accepted as `Authorization: Bearer <token>`:\n\n- **API key** (org-scoped, recommended for server-to-server). The org id is\n  embedded in the key; no extra header needed.\n- **Personal Access Token (PAT)** (user-scoped, multi-org). Must include\n  either `?org_id=<uuid>` query parameter or `X-Org-Id: <uuid>` header.\n\nToken scopes: `read`, `write`, `audit:read`, `admin`, `*`.\n`write` implies `read`; `admin` and `*` imply everything.\n\n## Rate limiting\n\nPer token: 120 requests/minute and 5000 requests/hour by default\n(configurable per org). 429 responses include `Retry-After` (seconds)\nand `X-RateLimit-*` headers.\n\n## Idempotency\n\nAll write endpoints accept `Idempotency-Key: <string>`. Identical\nkey + payload within 24h replays the original response (with\n`Idempotent-Replay: true`). Same key with a different payload returns\n`409 idempotency_key_conflict`.\n\n## Pagination\n\n- Main resources: `?limit=<n>&offset=<n>`; response includes\n  `pagination.total`.\n- Audit log and jobs list: cursor pagination via `?cursor=<value>`;\n  response includes `next_cursor`.\n\n## Versioning\n\nPath-segment versioning (`/v1/...`). Breaking changes ship under `/v2/...`.\nField additions are non-breaking. Removals get a 6-month deprecation\nwindow with `Sunset` and `Deprecation` response headers.\n\n## Error envelope\n\nAll `api-v1` endpoints return errors as:\n```json\n{ \"error\": { \"code\": \"string_machine_code\", \"message\": \"human readable\" } }\n```\n",
    "contact": {
      "name": "LabNote Security",
      "url": "https://labnote-light.com/.well-known/security.txt"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://vilasdqkwlszlulteqrb.supabase.co/functions/v1/api-v1",
      "description": "Production — public REST API (api-v1)"
    },
    {
      "url": "https://vilasdqkwlszlulteqrb.supabase.co/functions/v1",
      "description": "Production — other Edge Functions (exports, email, OAuth)"
    },
    {
      "url": "https://vilasdqkwlszlulteqrb.supabase.co/rest/v1",
      "description": "Production — PostgREST RPCs"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "opaque",
        "description": "API key (`lk_*`) or Personal Access Token (`pat_*`)."
      }
    },
    "parameters": {
      "OrgIdQuery": {
        "in": "query",
        "name": "org_id",
        "required": false,
        "description": "Required for PAT tokens unless `X-Org-Id` is sent.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "Limit": {
        "in": "query",
        "name": "limit",
        "schema": {
          "type": "integer",
          "default": 100,
          "minimum": 1,
          "maximum": 500
        }
      },
      "Offset": {
        "in": "query",
        "name": "offset",
        "schema": {
          "type": "integer",
          "default": 0,
          "minimum": 0
        }
      },
      "IdempotencyKey": {
        "in": "header",
        "name": "Idempotency-Key",
        "required": false,
        "schema": {
          "type": "string",
          "minLength": 8,
          "maxLength": 200
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "total": {
            "type": "integer",
            "nullable": true
          }
        }
      },
      "ListEnvelope": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "ItemEnvelope": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "Job": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "job_type": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "succeeded",
              "failed",
              "dead"
            ]
          },
          "progress": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "status_text": {
            "type": "string",
            "nullable": true
          },
          "result_path": {
            "type": "string",
            "nullable": true,
            "description": "Storage path of produced artifact, if any"
          },
          "result_meta": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          },
          "error_message": {
            "type": "string",
            "nullable": true
          },
          "attempts": {
            "type": "integer"
          },
          "max_attempts": {
            "type": "integer"
          },
          "enqueued_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "finished_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "JobCreate": {
        "type": "object",
        "required": [
          "job_type"
        ],
        "properties": {
          "job_type": {
            "type": "string",
            "enum": [
              "audit_export",
              "biosafety_export",
              "gdpr_export",
              "org_data_export",
              "equipment_lifecycle_pdf",
              "maintenance_report_pdf",
              "equipment_book_pdf",
              "experiment_entry_pdf",
              "risk_assessment_pdf",
              "box_layout_pdf"
            ]
          },
          "input": {
            "type": "object",
            "additionalProperties": true,
            "description": "Job-type-specific input. See per-type docs."
          }
        }
      },
      "Notification": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "notification_type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "link_url": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "read_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "NotificationCreate": {
        "type": "object",
        "required": [
          "title"
        ],
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "body": {
            "type": "string",
            "maxLength": 2000
          },
          "notification_type": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "default": "external"
          },
          "link_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2000
          },
          "entry_id": {
            "type": "string",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "user_ids": {
            "type": "array",
            "minItems": 1,
            "maxItems": 500,
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "role": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          }
        },
        "description": "Exactly one of user_id, user_ids, or role must be provided."
      },
      "NotificationCreated": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "created",
              "notification_ids"
            ],
            "properties": {
              "created": {
                "type": "integer"
              },
              "notification_ids": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            }
          }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid Bearer token.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Token lacks required scope, or job_type not allowed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found in this org.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Conflict": {
        "description": "Idempotency-Key reused with different payload.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  },
  "paths": {
    "/v1/health": {
      "get": {
        "summary": "Liveness probe (unauthenticated)",
        "tags": [
          "Meta"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/ping": {
      "get": {
        "summary": "Authenticated ping — returns identity and resource list",
        "tags": [
          "Meta"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "authenticated_as": {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "api_key",
                            "pat"
                          ]
                        },
                        "user_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "org_id": {
                          "type": "string",
                          "format": "uuid"
                        }
                      }
                    },
                    "resources": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/experiments": {
      "get": {
        "summary": "List experiments",
        "tags": [
          "Experiments"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgIdQuery"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "summary": "Create an experiment",
        "tags": [
          "Experiments"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "content": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "status": {
                    "type": "string"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "project_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "template_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/experiments/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Experiments"
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "patch": {
        "tags": [
          "Experiments"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "delete": {
        "tags": [
          "Experiments"
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          }
        }
      }
    },
    "/v1/projects": {
      "get": {
        "summary": "List projects",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgIdQuery"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a project",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "department_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "lead_researcher_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "parent_project_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "start_date": {
                    "type": "string",
                    "format": "date"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/projects/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Projects"
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "patch": {
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Projects"
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          }
        }
      }
    },
    "/v1/samples": {
      "get": {
        "summary": "List samples",
        "tags": [
          "Samples"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgIdQuery"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a sample",
        "tags": [
          "Samples"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "storage_location": {
                    "type": "string"
                  },
                  "department_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "owner_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/samples/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Samples"
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "patch": {
        "tags": [
          "Samples"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Samples"
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          }
        }
      }
    },
    "/v1/equipment": {
      "get": {
        "summary": "List equipment",
        "tags": [
          "Equipment"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgIdQuery"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Register equipment",
        "tags": [
          "Equipment"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "manufacturer": {
                    "type": "string"
                  },
                  "model": {
                    "type": "string"
                  },
                  "serial_number": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  },
                  "location": {
                    "type": "string"
                  },
                  "notes": {
                    "type": "string"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "department_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "room_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "storage_location_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "last_maintenance_date": {
                    "type": "string",
                    "format": "date"
                  },
                  "next_maintenance_date": {
                    "type": "string",
                    "format": "date"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/equipment/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Equipment"
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "patch": {
        "tags": [
          "Equipment"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Equipment"
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          }
        }
      }
    },
    "/v1/reagents": {
      "get": {
        "summary": "List reagent catalog entries",
        "tags": [
          "Reagents"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgIdQuery"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a reagent catalog entry",
        "tags": [
          "Reagents"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "alias": {
                    "type": "string"
                  },
                  "cas_number": {
                    "type": "string"
                  },
                  "formula": {
                    "type": "string"
                  },
                  "molecular_weight": {
                    "type": "number"
                  },
                  "purity": {
                    "type": "string"
                  },
                  "density": {
                    "type": "number"
                  },
                  "aggregate_state": {
                    "type": "string"
                  },
                  "signal_word": {
                    "type": "string",
                    "enum": [
                      "danger",
                      "warning",
                      "none"
                    ]
                  },
                  "h_phrases": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "p_phrases": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "hazard_pictograms": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "storage_temperature": {
                    "type": "string"
                  },
                  "storage_class": {
                    "type": "string"
                  },
                  "flash_point": {
                    "type": "number"
                  },
                  "un_number": {
                    "type": "string"
                  },
                  "external_link": {
                    "type": "string",
                    "format": "uri"
                  },
                  "description": {
                    "type": "string"
                  },
                  "notes": {
                    "type": "string"
                  },
                  "department_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/reagents/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Reagents"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "patch": {
        "tags": [
          "Reagents"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Reagents"
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          }
        }
      }
    },
    "/v1/stock-items": {
      "get": {
        "summary": "List reagent stock items",
        "tags": [
          "Stock"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgIdQuery"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a stock item",
        "tags": [
          "Stock"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "catalog_id",
                  "quantity",
                  "unit"
                ],
                "properties": {
                  "catalog_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "name_suffix": {
                    "type": "string"
                  },
                  "manufacturer": {
                    "type": "string"
                  },
                  "supplier": {
                    "type": "string"
                  },
                  "article_number": {
                    "type": "string"
                  },
                  "order_number": {
                    "type": "string"
                  },
                  "lot_number": {
                    "type": "string"
                  },
                  "lot_status": {
                    "type": "string"
                  },
                  "quantity": {
                    "type": "number"
                  },
                  "unit": {
                    "type": "string"
                  },
                  "package_size_full": {
                    "type": "number"
                  },
                  "package_size_current": {
                    "type": "number"
                  },
                  "container_material": {
                    "type": "string"
                  },
                  "storage_location_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "department_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "purchase_price": {
                    "type": "number"
                  },
                  "cost_center": {
                    "type": "string"
                  },
                  "project_number": {
                    "type": "string"
                  },
                  "intended_use": {
                    "type": "string"
                  },
                  "min_stock": {
                    "type": "number"
                  },
                  "acquired_on": {
                    "type": "string",
                    "format": "date"
                  },
                  "opened_on": {
                    "type": "string",
                    "format": "date"
                  },
                  "expires_on": {
                    "type": "string",
                    "format": "date"
                  },
                  "inspected_on": {
                    "type": "string",
                    "format": "date"
                  },
                  "notes": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stock-items/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Stock"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "patch": {
        "tags": [
          "Stock"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Stock"
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          }
        }
      }
    },
    "/v1/stock-movements": {
      "get": {
        "summary": "List stock movements",
        "tags": [
          "Stock"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgIdQuery"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Record a stock movement (consume / restock / adjust)",
        "tags": [
          "Stock"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "stock_item_id",
                  "movement_type",
                  "quantity_delta"
                ],
                "properties": {
                  "stock_item_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "movement_type": {
                    "type": "string",
                    "enum": [
                      "consume",
                      "restock",
                      "adjustment",
                      "transfer",
                      "dispose"
                    ]
                  },
                  "quantity_delta": {
                    "type": "number",
                    "description": "Negative for consumption, positive for restock."
                  },
                  "reason": {
                    "type": "string"
                  },
                  "intended_use": {
                    "type": "string"
                  },
                  "entry_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Link to experiment entry that triggered the consumption."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inventories": {
      "get": {
        "summary": "List physical inventory runs",
        "tags": [
          "Inventories"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgIdQuery"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Start a new inventory run",
        "tags": [
          "Inventories"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "notes": {
                    "type": "string"
                  },
                  "scope_room_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "scope_location_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "open",
                      "closed",
                      "archived"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inventories/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Inventories"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "patch": {
        "tags": [
          "Inventories"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "notes": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "open",
                      "closed",
                      "archived"
                    ]
                  },
                  "closed_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "closed_by": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Inventories"
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          }
        }
      }
    },
    "/v1/equipment/{id}/usage": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "summary": "List usage sessions for a piece of equipment",
        "tags": [
          "Equipment"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "summary": "Start / record a usage session",
        "tags": [
          "Equipment"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "started_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "ended_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "purpose": {
                    "type": "string"
                  },
                  "project_id": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  },
                  "entry_id": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  },
                  "settings": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "notes": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        }
      }
    },
    "/v1/equipment/{id}/maintenance": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Equipment"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Equipment"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "maintenance_type": {
                    "type": "string",
                    "enum": [
                      "scheduled",
                      "unscheduled",
                      "repair",
                      "inspection"
                    ]
                  },
                  "scheduled_date": {
                    "type": "string",
                    "nullable": true
                  },
                  "completed_date": {
                    "type": "string",
                    "nullable": true
                  },
                  "description": {
                    "type": "string"
                  },
                  "result": {
                    "type": "string"
                  },
                  "performed_by": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  },
                  "next_maintenance_date": {
                    "type": "string",
                    "nullable": true
                  },
                  "severity": {
                    "type": "string",
                    "enum": [
                      "low",
                      "normal",
                      "high",
                      "critical"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          }
        }
      }
    },
    "/v1/equipment/{id}/calibrations": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Equipment"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Equipment"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          }
        }
      }
    },
    "/v1/equipment/{id}/qualifications": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Equipment"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Equipment"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          }
        }
      }
    },
    "/v1/audit": {
      "get": {
        "summary": "Read the org audit log (requires `audit:read` scope)",
        "tags": [
          "Audit"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 1000
            }
          },
          {
            "in": "query",
            "name": "since_created_at",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Pair with since_id for keyset pagination."
          },
          {
            "in": "query",
            "name": "since_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "from",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "to",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "next_cursor": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "since_created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "since_id": {
                          "type": "string",
                          "format": "uuid"
                        }
                      }
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/v1/jobs": {
      "get": {
        "summary": "List background jobs in this org",
        "tags": [
          "Jobs"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string",
              "enum": [
                "queued",
                "running",
                "succeeded",
                "failed",
                "dead"
              ]
            }
          },
          {
            "in": "query",
            "name": "job_type",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "enqueued_at of last item from previous page"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Job"
                      }
                    },
                    "next_cursor": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Enqueue an asynchronous job (allowlisted job_type)",
        "description": "Triggers a long-running background job. The response is `202 Accepted`\nwith a job id; poll `GET /v1/jobs/{id}` or subscribe to the\n`background_jobs` realtime channel for status updates.\n",
        "tags": [
          "Jobs"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobCreate"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Job enqueued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Job"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "summary": "Poll a background job",
        "tags": [
          "Jobs"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Job"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/devices": {
      "get": {
        "tags": [
          "Instruments"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Instruments"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          }
        }
      }
    },
    "/v1/results": {
      "get": {
        "tags": [
          "Instruments"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Instruments"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          }
        }
      }
    },
    "/v1/notifications": {
      "get": {
        "summary": "List the caller's own notifications",
        "tags": [
          "Notifications"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Notification"
                      }
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "summary": "Push notifications to users or roles",
        "tags": [
          "Notifications"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NotificationCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationCreated"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Conflict"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/org-data-export": {
      "post": {
        "summary": "Start EU Data Act org-wide data export (admin only)",
        "tags": [
          "GDPR",
          "EU Data Act"
        ],
        "servers": [
          {
            "url": "https://vilasdqkwlszlulteqrb.supabase.co/functions/v1"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "org_id"
                ],
                "properties": {
                  "org_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/gdpr-delete-account": {
      "post": {
        "summary": "GDPR Art. 17 — self-service account deletion",
        "tags": [
          "GDPR"
        ],
        "servers": [
          {
            "url": "https://vilasdqkwlszlulteqrb.supabase.co/functions/v1"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "confirmation"
                ],
                "properties": {
                  "confirmation": {
                    "type": "string",
                    "description": "Must equal the user's primary email"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deletion scheduled"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/send-transactional-email": {
      "post": {
        "summary": "Send a templated transactional email (admin / service)",
        "tags": [
          "Email"
        ],
        "servers": [
          {
            "url": "https://vilasdqkwlszlulteqrb.supabase.co/functions/v1"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "templateName",
                  "recipientEmail",
                  "idempotencyKey"
                ],
                "properties": {
                  "templateName": {
                    "type": "string"
                  },
                  "recipientEmail": {
                    "type": "string",
                    "format": "email"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "minLength": 8
                  },
                  "templateData": {
                    "type": "object",
                    "additionalProperties": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Email queued"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/oauth-authorize": {
      "post": {
        "summary": "OAuth 2.0 authorization endpoint (third-party app consent)",
        "tags": [
          "OAuth"
        ],
        "servers": [
          {
            "url": "https://vilasdqkwlszlulteqrb.supabase.co/functions/v1"
          }
        ],
        "responses": {
          "200": {
            "description": "Authorization code issued"
          }
        }
      }
    },
    "/oauth-token": {
      "post": {
        "summary": "OAuth 2.0 token endpoint (authorization_code / refresh_token grants)",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "servers": [
          {
            "url": "https://vilasdqkwlszlulteqrb.supabase.co/functions/v1"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "grant_type",
                  "client_id",
                  "client_secret"
                ],
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "authorization_code",
                      "refresh_token"
                    ]
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "code": {
                    "type": "string"
                  },
                  "redirect_uri": {
                    "type": "string",
                    "format": "uri"
                  },
                  "refresh_token": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token issued"
          },
          "400": {
            "description": "Invalid request (RFC 6749 error envelope)"
          }
        }
      }
    },
    "/handle-email-unsubscribe": {
      "get": {
        "summary": "One-click unsubscribe (RFC 8058)",
        "tags": [
          "Email"
        ],
        "security": [],
        "servers": [
          {
            "url": "https://vilasdqkwlszlulteqrb.supabase.co/functions/v1"
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "token",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Unsubscribed"
          }
        }
      }
    },
    "/rpc/search_experiments": {
      "post": {
        "summary": "Full-text search across experiments in caller's org",
        "tags": [
          "Experiments"
        ],
        "servers": [
          {
            "url": "https://vilasdqkwlszlulteqrb.supabase.co/rest/v1"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "_org_id",
                  "_query"
                ],
                "properties": {
                  "_org_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "_query": {
                    "type": "string"
                  },
                  "_status": {
                    "type": "string",
                    "nullable": true
                  },
                  "_project_id": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  },
                  "_limit": {
                    "type": "integer",
                    "default": 50,
                    "maximum": 200
                  },
                  "_offset": {
                    "type": "integer",
                    "default": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "List of matching entries",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "title": {
                        "type": "string"
                      },
                      "rank": {
                        "type": "number"
                      },
                      "status": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/rpc/create_signature": {
      "post": {
        "summary": "Create a 21 CFR Part 11 electronic signature",
        "tags": [
          "Signatures",
          "GxP"
        ],
        "servers": [
          {
            "url": "https://vilasdqkwlszlulteqrb.supabase.co/rest/v1"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "_target_table",
                  "_target_id",
                  "_meaning_code",
                  "_stepup_token_id"
                ],
                "properties": {
                  "_target_table": {
                    "type": "string"
                  },
                  "_target_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "_meaning_code": {
                    "type": "string",
                    "enum": [
                      "author",
                      "witness",
                      "approval",
                      "review"
                    ]
                  },
                  "_reason_text": {
                    "type": "string",
                    "nullable": true
                  },
                  "_stepup_token_id": {
                    "type": "string"
                  },
                  "_client_session_id": {
                    "type": "string",
                    "nullable": true
                  },
                  "_is_continuous_session": {
                    "type": "boolean",
                    "default": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signature id",
            "content": {
              "application/json": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            }
          },
          "401": {
            "description": "Step-up token invalid or expired"
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Meta",
      "description": "Identity / health"
    },
    {
      "name": "Experiments"
    },
    {
      "name": "Equipment"
    },
    {
      "name": "Jobs",
      "description": "Asynchronous background jobs (exports",
      "PDFs)": null
    },
    {
      "name": "Notifications",
      "description": "In-app notifications pushed by external systems"
    },
    {
      "name": "Audit"
    },
    {
      "name": "Instruments",
      "description": "Instrument devices + measurement results"
    },
    {
      "name": "OAuth",
      "description": "OAuth 2.0 for third-party apps"
    },
    {
      "name": "GDPR"
    },
    {
      "name": "EU Data Act"
    },
    {
      "name": "Email"
    },
    {
      "name": "Signatures"
    },
    {
      "name": "GxP"
    }
  ]
}
