{
  "openapi": "3.0.3",
  "info": {
    "title": "Law Hired API",
    "version": "1.0.0",
    "description": "Integrate legal automation into your applications. Manage matters, clients, time entries, invoices, leads, and webhooks — all scoped to your Law Hired account.\n\n## Authentication\nAll requests (except `GET /openapi.json`) require an API key sent as a Bearer token:\n```\nAuthorization: Bearer lh_live_xxxxxxxxxxxxxxxx\n```\nCreate and manage keys at https://www.lawhired.com/lawyer/api-keys\n\n## Base URL\n```\nhttps://www.lawhired.com/api/v1\n```\n\n## Rate Limits\n| Tier | Limit |\n|------|-------|\n| Free | 100 req/min |\n| Pro | 1,000 req/min |\n| Enterprise | Unlimited |\n\n## Webhooks\nSubscribe to real-time events. Each delivery is signed with HMAC-SHA256:\n```\nX-LawHired-Signature: sha256=<hex>\n```\nEvents: `lead.created`, `matter.created`, `client.created`, `invoice.paid`, `document.signed`\n\n## ERP / CRM Sync\nAll writable resources support idempotent upsert via `PUT` + `external_id`. Pass your system's ID and we create-or-update without duplicates.",
    "contact": {
      "name": "Law Hired Developer Support",
      "email": "support@lawhired.com",
      "url": "https://www.lawhired.com/developers"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://www.lawhired.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://www.lawhired.com/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    { "BearerAuth": [] }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "lh_live_…",
        "description": "API key — create at https://www.lawhired.com/lawyer/api-keys"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": { "type": "string", "example": "Invalid or revoked API key." }
        }
      },
      "Matter": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "readOnly": true },
          "title": { "type": "string", "example": "Smith v. Jones" },
          "description": { "type": "string" },
          "case_category": { "type": "string", "example": "Litigation" },
          "service_type": { "type": "string", "example": "Full representation" },
          "status": { "type": "string", "example": "In Progress", "enum": ["In Progress", "Case Won", "Case Closed", "Settled", "Dismissed", "On Hold"] },
          "official_case_number": { "type": "string", "example": "2024-CV-00123" },
          "case_type": { "type": "string" },
          "client_id": { "type": "integer" },
          "estimated_hours": { "type": "number", "format": "float" },
          "estimated_budget_min": { "type": "number", "format": "float" },
          "estimated_budget_max": { "type": "number", "format": "float" },
          "start_date": { "type": "string", "format": "date" },
          "end_date": { "type": "string", "format": "date" },
          "external_id": { "type": "string", "description": "Your ERP/CRM record ID — used for idempotent PUT upsert", "example": "ERP-MATTER-001" },
          "created_at": { "type": "string", "format": "date-time", "readOnly": true },
          "updated_at": { "type": "string", "format": "date-time", "readOnly": true }
        }
      },
      "Client": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "readOnly": true },
          "company_name": { "type": "string", "example": "Acme Corp" },
          "contact_person": { "type": "string", "example": "Jane Doe" },
          "email": { "type": "string", "format": "email", "example": "jane@acme.com" },
          "phone": { "type": "string", "example": "+1-555-0123" },
          "address": { "type": "string" },
          "client_type": { "type": "string", "enum": ["individual", "business"] },
          "status": { "type": "string", "enum": ["active", "inactive", "prospect"] },
          "notes": { "type": "string" },
          "bio": { "type": "string" },
          "website": { "type": "string", "format": "uri" },
          "location": { "type": "string" },
          "external_id": { "type": "string", "description": "Your CRM contact ID", "example": "CRM-CONTACT-456" },
          "created_at": { "type": "string", "format": "date-time", "readOnly": true },
          "updated_at": { "type": "string", "format": "date-time", "readOnly": true }
        }
      },
      "TimeEntry": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "readOnly": true },
          "case_id": { "type": "integer" },
          "client_id": { "type": "integer" },
          "description": { "type": "string", "example": "Draft motion for summary judgment" },
          "duration": { "type": "number", "format": "float", "description": "Duration in hours", "example": 2.5 },
          "start_time": { "type": "string", "format": "date-time" },
          "end_time": { "type": "string", "format": "date-time" },
          "is_billable": { "type": "boolean", "default": true },
          "rate": { "type": "number", "format": "float", "example": 350.00 },
          "hourly_rate": { "type": "number", "format": "float" },
          "activity_type": { "type": "string", "example": "Research" },
          "status": { "type": "string", "enum": ["pending", "billed", "paid"] },
          "external_id": { "type": "string", "example": "ERP-TIME-789" },
          "created_at": { "type": "string", "format": "date-time", "readOnly": true }
        }
      },
      "Invoice": {
        "type": "object",
        "description": "Read-only. Invoices are created and managed from within the Law Hired dashboard.",
        "properties": {
          "invoice_id": { "type": "integer", "readOnly": true },
          "invoice_number": { "type": "string", "example": "INV-2024-001" },
          "case_id": { "type": "integer" },
          "client_user_id": { "type": "integer" },
          "total_amount": { "type": "number", "format": "float", "example": 5000.00 },
          "status": { "type": "string", "enum": ["draft", "sent", "paid", "overdue", "cancelled"] },
          "issue_date": { "type": "string", "format": "date" },
          "due_date": { "type": "string", "format": "date" },
          "paid_date": { "type": "string", "format": "date" },
          "amount_paid": { "type": "number", "format": "float" },
          "created_at": { "type": "string", "format": "date-time", "readOnly": true }
        }
      },
      "Lead": {
        "type": "object",
        "properties": {
          "lead_id": { "type": "string", "format": "uuid", "readOnly": true },
          "first_name": { "type": "string", "example": "John" },
          "last_name": { "type": "string", "example": "Doe" },
          "email": { "type": "string", "format": "email", "example": "john.doe@email.com" },
          "phone": { "type": "string", "example": "+1-555-0123" },
          "company": { "type": "string" },
          "practice_area": { "type": "string", "example": "Family Law" },
          "description": { "type": "string", "example": "Need help with custody dispute" },
          "urgency": { "type": "string", "enum": ["low", "medium", "high"], "default": "medium" },
          "status": { "type": "string", "readOnly": true },
          "created_at": { "type": "string", "format": "date-time", "readOnly": true }
        }
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "readOnly": true },
          "url": { "type": "string", "format": "uri", "example": "https://your-crm.com/hooks/lawhired" },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["lead.created", "matter.created", "client.created", "invoice.paid", "document.signed"]
            },
            "example": ["lead.created", "invoice.paid"]
          },
          "description": { "type": "string" },
          "is_active": { "type": "boolean", "default": true },
          "failure_count": { "type": "integer", "readOnly": true },
          "last_delivery_at": { "type": "string", "format": "date-time", "readOnly": true },
          "created_at": { "type": "string", "format": "date-time", "readOnly": true }
        }
      },
      "WebhookPayload": {
        "type": "object",
        "description": "The JSON body POSTed to your endpoint for every event. Verify the signature with HMAC-SHA256(secret, raw_body) and compare to X-LawHired-Signature (strip the 'sha256=' prefix).",
        "properties": {
          "event": { "type": "string", "example": "lead.created", "description": "The event type that triggered this delivery" },
          "delivery_id": { "type": "string", "format": "uuid", "description": "Unique ID for this delivery attempt — matches X-LawHired-Delivery header" },
          "timestamp": { "type": "string", "format": "date-time", "example": "2026-03-15T10:00:00Z" },
          "data": { "type": "object", "description": "The affected resource record — schema matches the relevant resource endpoint response" }
        }
      },
      "ListResponse": {
        "type": "object",
        "properties": {
          "count": { "type": "integer", "description": "Number of records in this page" },
          "limit": { "type": "integer" },
          "offset": { "type": "integer" },
          "data": { "type": "array", "items": {} }
        }
      }
    },
    "parameters": {
      "limit": {
        "name": "limit", "in": "query",
        "schema": { "type": "integer", "default": 50, "maximum": 200 },
        "description": "Maximum records to return"
      },
      "offset": {
        "name": "offset", "in": "query",
        "schema": { "type": "integer", "default": 0 },
        "description": "Pagination offset"
      },
      "updated_since": {
        "name": "updated_since", "in": "query",
        "schema": { "type": "string", "format": "date-time" },
        "description": "Return only records updated after this timestamp — use for incremental/delta sync",
        "example": "2026-01-01T00:00:00Z"
      },
      "resource_id": {
        "name": "id", "in": "path", "required": true,
        "schema": { "type": "integer" },
        "description": "Numeric record ID"
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "Forbidden": {
        "description": "API key lacks the required scope",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "NotFound": {
        "description": "Record not found or belongs to another account",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "headers": { "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until the limit resets" } },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    }
  },
  "tags": [
    { "name": "Identity", "description": "API key introspection" },
    { "name": "Matters", "description": "Legal cases / matters — full CRUD + idempotent ERP upsert" },
    { "name": "Clients", "description": "Client records — full CRUD + idempotent CRM upsert" },
    { "name": "Time Entries", "description": "Billable and non-billable time — full CRUD + idempotent upsert" },
    { "name": "Invoices", "description": "Invoice list and lookup (read-only)" },
    { "name": "Leads", "description": "Inbound lead capture and retrieval" },
    { "name": "Webhooks", "description": "Real-time event subscriptions with HMAC-signed delivery" }
  ],
  "paths": {
    "/me": {
      "get": {
        "tags": ["Identity"],
        "summary": "Get API key identity",
        "description": "Returns the authenticated key's metadata — name, environment, scopes, rate tier, and owner UUID.",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "object",
                      "properties": {
                        "id": { "type": "integer" },
                        "name": { "type": "string" },
                        "environment": { "type": "string", "enum": ["live", "test"] },
                        "scopes": { "type": "array", "items": { "type": "string" } },
                        "rate_tier": { "type": "string", "enum": ["free", "pro", "enterprise"] }
                      }
                    },
                    "owner_uuid": { "type": "string", "format": "uuid" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/matters": {
      "get": {
        "tags": ["Matters"],
        "summary": "List matters",
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/updated_since" }
        ],
        "responses": {
          "200": { "description": "Paginated list of matters", "content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/ListResponse" }, { "properties": { "data": { "items": { "$ref": "#/components/schemas/Matter" } } } }] } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "tags": ["Matters"],
        "summary": "Create a matter",
        "security": [{ "BearerAuth": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Matter" } } } },
        "responses": {
          "201": { "description": "Matter created", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Matter" } } } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      },
      "put": {
        "tags": ["Matters"],
        "summary": "Upsert a matter by external_id",
        "description": "Idempotent create-or-update keyed on `external_id`. If a matter with that `external_id` already exists for your account it is updated; otherwise a new one is created. Use this for ERP/CRM bi-directional sync.",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "allOf": [{ "$ref": "#/components/schemas/Matter" }, { "required": ["external_id"] }] },
              "example": { "external_id": "ERP-MATTER-001", "title": "Smith v. Jones", "status": "In Progress", "client_id": 42 }
            }
          }
        },
        "responses": {
          "200": { "description": "Existing matter updated", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Matter" }, "created": { "type": "boolean", "example": false } } } } } },
          "201": { "description": "New matter created", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Matter" }, "created": { "type": "boolean", "example": true } } } } } }
        }
      }
    },
    "/matters/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/resource_id" }],
      "get": {
        "tags": ["Matters"], "summary": "Get a matter",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Matter" } } } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "patch": {
        "tags": ["Matters"], "summary": "Update a matter",
        "security": [{ "BearerAuth": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Matter" } } } },
        "responses": { "200": { "description": "Updated", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Matter" } } } } } }, "404": { "$ref": "#/components/responses/NotFound" } }
      },
      "delete": {
        "tags": ["Matters"], "summary": "Delete a matter",
        "security": [{ "BearerAuth": [] }],
        "responses": { "200": { "description": "Deleted", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" } } } } } }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/clients": {
      "get": {
        "tags": ["Clients"], "summary": "List clients",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "$ref": "#/components/parameters/limit" }, { "$ref": "#/components/parameters/offset" }, { "$ref": "#/components/parameters/updated_since" }],
        "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/ListResponse" }, { "properties": { "data": { "items": { "$ref": "#/components/schemas/Client" } } } }] } } } } }
      },
      "post": {
        "tags": ["Clients"], "summary": "Create a client",
        "security": [{ "BearerAuth": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Client" } } } },
        "responses": { "201": { "description": "Created" } }
      },
      "put": {
        "tags": ["Clients"], "summary": "Upsert a client by external_id",
        "description": "Pass your CRM contact ID as `external_id` for conflict-free sync.",
        "security": [{ "BearerAuth": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/Client" }, { "required": ["external_id"] }] }, "example": { "external_id": "HUBSPOT-CONTACT-123", "company_name": "Acme Corp", "email": "ap@acme.com", "client_type": "business" } } } },
        "responses": { "200": { "description": "Updated" }, "201": { "description": "Created" } }
      }
    },
    "/clients/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/resource_id" }],
      "get": { "tags": ["Clients"], "summary": "Get a client", "security": [{ "BearerAuth": [] }], "responses": { "200": { "description": "OK" }, "404": { "$ref": "#/components/responses/NotFound" } } },
      "patch": { "tags": ["Clients"], "summary": "Update a client", "security": [{ "BearerAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Client" } } } }, "responses": { "200": { "description": "Updated" } } },
      "delete": { "tags": ["Clients"], "summary": "Delete a client", "security": [{ "BearerAuth": [] }], "responses": { "200": { "description": "Deleted" } } }
    },
    "/time-entries": {
      "get": {
        "tags": ["Time Entries"], "summary": "List time entries",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "$ref": "#/components/parameters/limit" }, { "$ref": "#/components/parameters/offset" }, { "$ref": "#/components/parameters/updated_since" }],
        "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/ListResponse" }, { "properties": { "data": { "items": { "$ref": "#/components/schemas/TimeEntry" } } } }] } } } } }
      },
      "post": {
        "tags": ["Time Entries"], "summary": "Create a time entry",
        "security": [{ "BearerAuth": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TimeEntry" } } } },
        "responses": { "201": { "description": "Created" } }
      },
      "put": {
        "tags": ["Time Entries"], "summary": "Upsert a time entry by external_id",
        "security": [{ "BearerAuth": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/TimeEntry" }, { "required": ["external_id"] }] } } } },
        "responses": { "200": { "description": "Updated" }, "201": { "description": "Created" } }
      }
    },
    "/time-entries/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/resource_id" }],
      "get": { "tags": ["Time Entries"], "summary": "Get a time entry", "security": [{ "BearerAuth": [] }], "responses": { "200": { "description": "OK" } } },
      "patch": { "tags": ["Time Entries"], "summary": "Update a time entry", "security": [{ "BearerAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TimeEntry" } } } }, "responses": { "200": { "description": "Updated" } } },
      "delete": { "tags": ["Time Entries"], "summary": "Delete a time entry", "security": [{ "BearerAuth": [] }], "responses": { "200": { "description": "Deleted" } } }
    },
    "/invoices": {
      "get": {
        "tags": ["Invoices"], "summary": "List invoices (read-only)",
        "description": "Returns invoices for the authenticated lawyer. Write operations are not supported — use QuickBooks or Xero sync for write-back.",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "$ref": "#/components/parameters/limit" }, { "$ref": "#/components/parameters/offset" }, { "$ref": "#/components/parameters/updated_since" }],
        "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/ListResponse" }, { "properties": { "data": { "items": { "$ref": "#/components/schemas/Invoice" } } } }] } } } } }
      }
    },
    "/invoices/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/resource_id" }],
      "get": { "tags": ["Invoices"], "summary": "Get an invoice", "security": [{ "BearerAuth": [] }], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Invoice" } } } } } }, "404": { "$ref": "#/components/responses/NotFound" } } }
    },
    "/leads": {
      "get": {
        "tags": ["Leads"], "summary": "List leads captured via this API key",
        "description": "Returns leads that were submitted via this specific API key. Does not return leads from other sources (web intake, manual entry, etc.).",
        "security": [{ "BearerAuth": [] }],
        "parameters": [{ "$ref": "#/components/parameters/limit" }],
        "responses": {
          "200": {
            "description": "OK",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "count": { "type": "integer" }, "leads": { "type": "array", "items": { "$ref": "#/components/schemas/Lead" } } } } } }
          }
        }
      },
      "post": {
        "tags": ["Leads"],
        "summary": "Capture a lead",
        "description": "Submit a new lead from any source. Supports automatic deduplication by email and auto-scoring based on practice area and urgency.",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "leadData": {
                    "type": "object",
                    "properties": {
                      "first_name": { "type": "string", "example": "John" },
                      "last_name": { "type": "string", "example": "Doe" },
                      "email": { "type": "string", "format": "email", "example": "john.doe@email.com" },
                      "phone": { "type": "string", "example": "+1-555-0123" },
                      "company": { "type": "string" },
                      "practice_area": { "type": "string", "example": "Family Law" },
                      "description": { "type": "string", "example": "Need help with custody dispute" },
                      "urgency": { "type": "string", "enum": ["low", "medium", "high"], "default": "medium" }
                    }
                  }
                }
              },
              "example": {
                "leadData": {
                  "first_name": "John",
                  "last_name": "Doe",
                  "email": "john.doe@email.com",
                  "phone": "+1-555-0123",
                  "practice_area": "Family Law",
                  "description": "Need help with custody dispute",
                  "urgency": "high"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Lead captured",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "lead": { "$ref": "#/components/schemas/Lead" } } } } }
          },
          "400": { "description": "email or first_name required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/webhooks": {
      "get": {
        "tags": ["Webhooks"], "summary": "List webhook endpoints",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": {
            "description": "OK",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "webhooks": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEndpoint" } } } } } }
          }
        }
      },
      "post": {
        "tags": ["Webhooks"],
        "summary": "Create a webhook endpoint",
        "description": "Subscribe a URL to one or more events. The `secret` (whsec_…) is returned **once** — store it immediately. Each delivery is signed:\n```\nX-LawHired-Signature: sha256=<hmac-hex>\n```\nVerify with: `HMAC-SHA256(secret, raw_body) == signature`",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["url", "events"],
                "properties": {
                  "url": { "type": "string", "format": "uri", "example": "https://your-crm.com/hooks/lawhired" },
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "items": { "type": "string", "enum": ["lead.created", "matter.created", "client.created", "invoice.paid", "document.signed", "ping.test"] },
                    "example": ["lead.created", "invoice.paid"]
                  },
                  "description": { "type": "string", "example": "HubSpot CRM sync" }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Endpoint created — secret shown once",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/WebhookEndpoint" },
                    { "type": "object", "properties": { "secret": { "type": "string", "description": "whsec_… signing secret — store immediately, never shown again", "example": "whsec_a1b2c3d4e5f6..." } } }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/resource_id" }],
      "delete": {
        "tags": ["Webhooks"], "summary": "Delete a webhook endpoint",
        "security": [{ "BearerAuth": [] }],
        "responses": { "200": { "description": "Deleted", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" } } } } } } }
      }
    },
    "/webhooks/{id}/test": {
      "parameters": [{ "$ref": "#/components/parameters/resource_id" }],
      "post": {
        "tags": ["Webhooks"], "summary": "Send a test event to a webhook",
        "description": "Sends a `ping.test` event to verify your endpoint is reachable and that your signature verification logic works. The posted body follows the WebhookPayload schema.",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": { "description": "Test event queued", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" } } } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    }
  }
}
