{
  "openapi": "3.1.0",
  "info": {
    "title": "Virtual Inspection Pro Public API",
    "version": "2.2",
    "description": "REST API for inspections, responses, media, templates, reports and Custom Sets. Authenticate with an organization API key: `Authorization: Bearer vip_live_...`."
  },
  "servers": [
    {
      "url": "https://virtualinspection.ai/api/public/v2"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Sessions & integrations",
      "description": "The adapter layer CRM and contact-centre platforms use: test a key, start a live session with a one-tap SMS join link, and subscribe to completed-report events. Works with Zapier, HubSpot, Zoho, Dynamics 365, Salesforce, Zendesk, Genesys, NICE, and Procore."
    },
    {
      "name": "Inspections",
      "description": "Create, retrieve, and update inspections. Use this to sync jobs from an ERP or CRM and to pull results back out."
    },
    {
      "name": "Responses",
      "description": "Checklist answers for an inspection. v2.2 adds reference_id and isFlagged, plus targeting by question ID."
    },
    {
      "name": "Files & images",
      "description": "Pull captured photos, clips, and their verification metadata into your own systems."
    },
    {
      "name": "Templates",
      "description": "List, retrieve, and clone report template structures."
    },
    {
      "name": "Reports",
      "description": "List completed reports, trigger generation, and download finished PDFs."
    },
    {
      "name": "Users",
      "description": "Read organization members so your systems can map inspectors to internal identities."
    },
    {
      "name": "Custom Sets",
      "description": "Global lists — statuses, causes, locations, part codes — referenced from fields in templates. Manage them programmatically to keep VIP consistent with your source systems."
    },
    {
      "name": "Evidence Integrity",
      "description": "Photo compliance, retake turnaround, and outstanding evidence requests across the workspace. Use it to feed QA dashboards or block ERP job closure while retakes are open."
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  },
  "paths": {
    "/me": {
      "get": {
        "summary": "Test a key — returns the organization and scopes",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/sessions": {
      "post": {
        "summary": "Start a live session and text the join link (send an Idempotency-Key header to make retries safe)",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/hooks": {
      "get": {
        "summary": "List webhook subscriptions",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "post": {
        "summary": "Subscribe to an event — returns the signing secret once",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/hooks/{id}": {
      "delete": {
        "summary": "Unsubscribe",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/hooks/{id}/test": {
      "post": {
        "summary": "Send a signed sample event to verify your receiver",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/sessions/{id}": {
      "get": {
        "summary": "Retrieve a session and its join link",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "patch": {
        "summary": "Reschedule or update a session's contact and job details",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "delete": {
        "summary": "Cancel a session",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/hooks/{id}/deliveries": {
      "get": {
        "summary": "Delivery history for a subscription",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "post": {
        "summary": "Replay a past delivery (body: `{ delivery_id }`)",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/hooks/{id}/rotate-secret": {
      "post": {
        "summary": "Rotate the signing secret — the previous one stays valid for 24 hours",
        "tags": [
          "Sessions & integrations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/inspections": {
      "get": {
        "summary": "List inspections",
        "tags": [
          "Inspections"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, 1–200. Defaults to 50.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from the previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "draft, scheduled, in_progress, completed, cancelled.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "updated_after",
            "in": "query",
            "required": false,
            "description": "ISO 8601 — only records changed since.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "inspector_id",
            "in": "query",
            "required": false,
            "description": "Filter by assigned inspector.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "post": {
        "summary": "Create an inspection",
        "tags": [
          "Inspections"
        ],
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/inspections/{id}": {
      "get": {
        "summary": "Retrieve an inspection",
        "tags": [
          "Inspections"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "patch": {
        "summary": "Update an inspection",
        "tags": [
          "Inspections"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/inspections/{id}/responses": {
      "get": {
        "summary": "List responses (checklist items)",
        "tags": [
          "Responses"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, 1–200. Defaults to 50.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from the previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "question_ids",
            "in": "query",
            "required": false,
            "description": "Comma-separated question IDs to retrieve.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "flagged",
            "in": "query",
            "required": false,
            "description": "true returns only flagged responses.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "rating",
            "in": "query",
            "required": false,
            "description": "Filter by rating.",
            "schema": {
              "type": "string",
              "enum": [
                "pass",
                "fail",
                "na"
              ]
            }
          },
          {
            "name": "updated_after",
            "in": "query",
            "required": false,
            "description": "Only responses changed since.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/inspections/{id}/media": {
      "get": {
        "summary": "List inspection media with capture metadata",
        "tags": [
          "Files & images"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, 1–200. Defaults to 50.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/media/{id}/download": {
      "get": {
        "summary": "Download a file — 302 to a signed URL, or add ?format=json for the URL itself",
        "tags": [
          "Files & images"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "Return the signed URL as JSON instead of redirecting.",
            "schema": {
              "type": "string",
              "enum": [
                "json"
              ]
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to a short-lived signed URL"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/templates": {
      "get": {
        "summary": "List report templates",
        "tags": [
          "Templates"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, 1–200. Defaults to 50.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/templates/{id}": {
      "get": {
        "summary": "Retrieve a template",
        "tags": [
          "Templates"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/templates/{id}/clone": {
      "post": {
        "summary": "Clone a template",
        "tags": [
          "Templates"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/reports": {
      "get": {
        "summary": "List completed reports (`limit`, `since`, `job_reference`)",
        "tags": [
          "Reports"
        ],
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "post": {
        "summary": "Generate a report PDF for an inspection",
        "tags": [
          "Reports"
        ],
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/reports/{id}": {
      "get": {
        "summary": "Report status",
        "tags": [
          "Reports"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/reports/{id}/download": {
      "get": {
        "summary": "Download a report PDF",
        "tags": [
          "Reports"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to a short-lived signed URL"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/users": {
      "get": {
        "summary": "List organization members",
        "tags": [
          "Users"
        ],
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/custom-sets": {
      "get": {
        "summary": "List Custom Sets",
        "tags": [
          "Custom Sets"
        ],
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "post": {
        "summary": "Create a Custom Set",
        "tags": [
          "Custom Sets"
        ],
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/custom-sets/{id}": {
      "get": {
        "summary": "Retrieve a Custom Set with items",
        "tags": [
          "Custom Sets"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "patch": {
        "summary": "Update a Custom Set",
        "tags": [
          "Custom Sets"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "delete": {
        "summary": "Delete a Custom Set",
        "tags": [
          "Custom Sets"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `admin` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/custom-sets/{id}/items": {
      "get": {
        "summary": "List items",
        "tags": [
          "Custom Sets"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "post": {
        "summary": "Append items",
        "tags": [
          "Custom Sets"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "put": {
        "summary": "Replace all items",
        "tags": [
          "Custom Sets"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Resource ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `write` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/evidence": {
      "get": {
        "summary": "Evidence integrity metrics",
        "tags": [
          "Evidence Integrity"
        ],
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Window size, 1-365. Defaults to 30.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "inspection_id",
            "in": "query",
            "required": false,
            "description": "Scope the metrics to a single inspection.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Requires the `read` scope"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    }
  }
}