{
  "openapi": "3.1.0",
  "info": {
    "title": "Fieldwork CRM API",
    "version": "0.2.0",
    "description": "The complete API used by the Fieldwork web interface and agentic clients such as Hermes. Protected operations generally accept a named user token in the Authorization: Bearer header. Human-release actions such as approving and sending email require a browser session. Mutations create an audit event identifying both the user and credential."
  },
  "servers": [{ "url": "/", "description": "Current Fieldwork installation" }],
  "security": [{ "bearerAuth": [] }],
  "tags": [
    { "name": "Authentication" },
    { "name": "Users" },
    { "name": "Tokens" },
    { "name": "Companies" },
    { "name": "Contacts" },
    { "name": "Email" },
    { "name": "Timeline" },
    { "name": "Reminders" },
    { "name": "Audit" }
  ],
  "paths": {
    "/api/auth/bootstrap": {
      "get": {
        "tags": ["Authentication"],
        "summary": "Check whether first-run setup is required",
        "security": [],
        "responses": { "200": { "description": "Bootstrap state", "content": { "application/json": { "schema": { "type": "object", "properties": { "required": { "type": "boolean" } }, "required": ["required"] } } } } }
      },
      "post": {
        "tags": ["Authentication"],
        "summary": "Create the first administrator",
        "description": "Available only while no users exist. Creates an administrator and a 30-day browser session.",
        "security": [],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserCreate" } } } },
        "responses": { "201": { "description": "Administrator created" }, "409": { "$ref": "#/components/responses/Conflict" } }
      }
    },
    "/api/auth/login": {
      "post": {
        "tags": ["Authentication"],
        "summary": "Start a browser session",
        "security": [],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["email", "password"], "properties": { "email": { "type": "string", "format": "email" }, "password": { "type": "string" } } } } } },
        "responses": { "200": { "description": "Login successful" }, "401": { "$ref": "#/components/responses/Unauthorized" } }
      }
    },
    "/api/auth/logout": {
      "post": { "tags": ["Authentication"], "summary": "Revoke the current browser session", "responses": { "200": { "$ref": "#/components/responses/Success" } } }
    },
    "/api/auth/me": {
      "get": { "tags": ["Authentication"], "summary": "Get the current user and credential", "responses": { "200": { "description": "Authenticated identity" }, "401": { "$ref": "#/components/responses/Unauthorized" } } }
    },
    "/api/users": {
      "get": { "tags": ["Users"], "summary": "List users", "description": "Administrator only.", "responses": { "200": { "description": "Users" }, "403": { "$ref": "#/components/responses/Forbidden" } } },
      "post": {
        "tags": ["Users"], "summary": "Create a user", "description": "Administrator only.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserCreate" } } } },
        "responses": { "201": { "description": "User created" }, "403": { "$ref": "#/components/responses/Forbidden" } }
      }
    },
    "/api/tokens": {
      "get": { "tags": ["Tokens"], "summary": "List the current user's API tokens", "responses": { "200": { "description": "Tokens; raw token values are never returned" } } },
      "post": {
        "tags": ["Tokens"], "summary": "Create a named API token", "description": "The raw token is returned once. Store it securely.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string", "example": "Hermes" }, "expiresAt": { "type": ["string", "null"], "format": "date-time" } } } } } },
        "responses": { "201": { "description": "Token created and returned once" } }
      }
    },
    "/api/tokens/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "delete": { "tags": ["Tokens"], "summary": "Revoke one of the current user's API tokens", "responses": { "200": { "$ref": "#/components/responses/Success" }, "404": { "$ref": "#/components/responses/NotFound" } } }
    },
    "/api/companies": {
      "get": {
        "tags": ["Companies"], "summary": "List active companies", "description": "Archived companies are excluded. Filter by an individual stage, the active/conversations pipeline segments, or priority, and sort by name, priority or stage.",
        "parameters": [
          { "name": "stage", "in": "query", "description": "An individual company stage or a dashboard segment.", "schema": { "type": "string", "enum": ["active", "conversations", "researching", "ready_to_contact", "contacted", "engaged", "opportunity", "customer", "parked", "disqualified"] } },
          { "name": "status", "in": "query", "deprecated": true, "description": "Legacy alias for an individual stage.", "schema": { "$ref": "#/components/schemas/CompanyStatus" } },
          { "name": "priority", "in": "query", "schema": { "type": "string", "enum": ["low", "medium", "high"] } },
          { "name": "sort", "in": "query", "schema": { "type": "string", "enum": ["name_asc", "name_desc", "priority_desc", "priority_asc", "stage_asc", "stage_desc"], "default": "name_asc" } },
          { "name": "search", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Companies", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Company" } } } } } } } }
      },
      "post": {
        "tags": ["Companies"], "summary": "Create a company",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CompanyWrite" } } } },
        "responses": { "201": { "description": "Company created" }, "400": { "$ref": "#/components/responses/BadRequest" }, "409": { "$ref": "#/components/responses/Conflict" } }
      }
    },
    "/api/companies/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "get": { "tags": ["Companies"], "summary": "Get a company workspace", "description": "Returns the company with contacts, matched emails, activities, notes, news and reminders.", "responses": { "200": { "description": "Complete company workspace" }, "404": { "$ref": "#/components/responses/NotFound" } } },
      "patch": { "tags": ["Companies"], "summary": "Update a company", "description": "Send only fields to change.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CompanyWrite" } } } }, "responses": { "200": { "description": "Updated company" } } },
      "delete": { "tags": ["Companies"], "summary": "Archive a company", "description": "Soft-deletes the company while preserving its history.", "responses": { "200": { "$ref": "#/components/responses/Success" } } }
    },
    "/api/companies/{id}/contacts": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "get": { "tags": ["Contacts"], "summary": "List company contacts", "responses": { "200": { "description": "Contacts" } } },
      "post": { "tags": ["Contacts"], "summary": "Add a company contact", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContactWrite" } } } }, "responses": { "201": { "description": "Contact created" } } }
    },
    "/api/companies/{id}/contacts/{contactId}": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }, { "name": "contactId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
      "patch": { "tags": ["Contacts"], "summary": "Update a contact", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContactWrite" } } } }, "responses": { "200": { "description": "Updated contact" } } },
      "delete": { "tags": ["Contacts"], "summary": "Delete a contact", "responses": { "200": { "$ref": "#/components/responses/Success" } } }
    },
    "/api/companies/{id}/emails": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "get": {
        "tags": ["Email"],
        "summary": "List matched company emails",
        "description": "Returns imported messages newest first. The exact raw MIME source is available from the individual raw endpoint and is not included here.",
        "responses": {
          "200": { "description": "Matched messages", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/EmailMessage" } } }, "required": ["data"] } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/api/emails/{id}/raw": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "get": {
        "tags": ["Email"],
        "summary": "Download an email's original MIME source",
        "description": "Returns the exact imported .eml message, including original headers and MIME parts.",
        "responses": {
          "200": { "description": "Original message", "content": { "message/rfc822": { "schema": { "type": "string", "format": "binary" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/api/email/sync": {
      "get": {
        "tags": ["Email"],
        "summary": "Get Migadu IMAP sync status",
        "responses": { "200": { "description": "Current configuration, run and cooldown state", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/EmailSyncStatus" } }, "required": ["data"] } } } } }
      },
      "post": {
        "tags": ["Email"],
        "summary": "Import new matched emails",
        "description": "Performs a read-only incremental IMAP sync of Inbox and Sent. Only messages involving an email address on an active CRM contact are stored. At most one run is accepted per hour. Fieldwork also runs this operation internally every hour when EMAIL_SYNC_TOKEN is configured.",
        "responses": {
          "200": { "description": "Sync completed", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "importedCount": { "type": "integer" }, "completedAt": { "type": "string", "format": "date-time" } }, "required": ["importedCount", "completedAt"] } }, "required": ["data"] } } } },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "description": "The one-hour sync cooldown has not elapsed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "503": { "description": "IMAP credentials are not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/email/drafts": {
      "get": {
        "tags": ["Email"],
        "summary": "List staged outgoing emails",
        "description": "Defaults to emails awaiting review or delivery. Pass a comma-separated status list to include sent mail.",
        "parameters": [{ "name": "status", "in": "query", "schema": { "type": "string", "example": "staged,approved" } }],
        "responses": { "200": { "description": "Outgoing email drafts with company, contact and author summaries" } }
      },
      "post": {
        "tags": ["Email"],
        "summary": "Stage an outgoing email for human review",
        "description": "Intended for Hermes and other API clients. This endpoint never sends mail. Give a contactId to snapshot that contact's name and email, or supply toEmail directly.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailDraftWrite" } } } },
        "responses": { "201": { "description": "Email staged for review" }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/api/email/drafts/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "patch": {
        "tags": ["Email"],
        "summary": "Edit an outgoing email draft",
        "description": "Browser session only. Editing always resets the draft to staged and clears approval.",
        "security": [{ "cookieAuth": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailDraftEdit" } } } },
        "responses": { "200": { "description": "Updated draft" }, "403": { "$ref": "#/components/responses/Forbidden" }, "409": { "$ref": "#/components/responses/Conflict" } }
      },
      "delete": {
        "tags": ["Email"],
        "summary": "Discard an unsent email draft",
        "description": "Browser session only.",
        "security": [{ "cookieAuth": [] }],
        "responses": { "200": { "$ref": "#/components/responses/Success" }, "403": { "$ref": "#/components/responses/Forbidden" }, "409": { "$ref": "#/components/responses/Conflict" } }
      }
    },
    "/api/email/drafts/{id}/approve": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "post": {
        "tags": ["Email"],
        "summary": "Approve an outgoing email",
        "description": "Browser session only; API tokens cannot approve mail.",
        "security": [{ "cookieAuth": [] }],
        "responses": { "200": { "description": "Approved draft" }, "403": { "$ref": "#/components/responses/Forbidden" }, "409": { "$ref": "#/components/responses/Conflict" } }
      }
    },
    "/api/email/drafts/{id}/send": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "post": {
        "tags": ["Email"],
        "summary": "Send an approved email",
        "description": "Browser session only. Submits through SMTP, verifies that Migadu accepted the primary recipient, stores the exact MIME message on the company timeline, and appends it to the Migadu IMAP Sent folder for Thunderbird. SMTP acceptance is a successful handoff to Migadu, not proof of final delivery by the recipient's mail system.",
        "security": [{ "cookieAuth": [] }],
        "responses": { "200": { "description": "Sent email" }, "403": { "$ref": "#/components/responses/Forbidden" }, "409": { "$ref": "#/components/responses/Conflict" }, "502": { "description": "SMTP delivery failed" }, "503": { "description": "SMTP is not configured" } }
      }
    },
    "/api/companies/{id}/activities": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "get": { "tags": ["Timeline"], "summary": "List company activities", "responses": { "200": { "description": "Activities newest first" } } },
      "post": { "tags": ["Timeline"], "summary": "Log an activity", "description": "Use this for emails, replies, calls, meetings and other completed events.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ActivityWrite" } } } }, "responses": { "201": { "description": "Activity logged" } } }
    },
    "/api/companies/{id}/notes": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "get": { "tags": ["Timeline"], "summary": "List company learnings", "responses": { "200": { "description": "Notes newest first" } } },
      "post": { "tags": ["Timeline"], "summary": "Add a learning or research note", "description": "Use sourceUrl when the note is derived from a public source. Phrase unverified ideas as hypotheses.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NoteWrite" } } } }, "responses": { "201": { "description": "Note created" } } }
    },
    "/api/companies/{id}/news": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "get": { "tags": ["Timeline"], "summary": "List company news", "responses": { "200": { "description": "News items" } } },
      "post": { "tags": ["Timeline"], "summary": "Add sourced company news", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewsWrite" } } } }, "responses": { "201": { "description": "News item created" } } }
    },
    "/api/reminders": {
      "get": {
        "tags": ["Reminders"], "summary": "List the current user's reminders", "description": "Defaults to open reminders ordered by due date.",
        "parameters": [
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["open", "completed", "cancelled"], "default": "open" } },
          { "name": "dueBefore", "in": "query", "schema": { "type": "string", "format": "date-time" } }
        ],
        "responses": { "200": { "description": "Reminders with company, contact and assignee summaries" } }
      },
      "post": { "tags": ["Reminders"], "summary": "Schedule a next action", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReminderWrite" } } } }, "responses": { "201": { "description": "Reminder created" } } }
    },
    "/api/reminders/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/Id" }],
      "patch": { "tags": ["Reminders"], "summary": "Reschedule, complete or cancel a reminder", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "description": { "type": "string" }, "dueAt": { "type": "string", "format": "date-time" }, "status": { "type": "string", "enum": ["open", "completed", "cancelled"] } } } } } }, "responses": { "200": { "description": "Updated reminder" } } },
      "delete": { "tags": ["Reminders"], "summary": "Delete a reminder", "responses": { "200": { "$ref": "#/components/responses/Success" } } }
    },
    "/api/audit": {
      "get": { "tags": ["Audit"], "summary": "List the latest 200 mutations", "description": "Each event identifies the user and named credential responsible.", "responses": { "200": { "description": "Audit events newest first" } } }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "Opaque API token", "description": "Create a named token in Settings. Send it as Authorization: Bearer crm_…" },
      "cookieAuth": { "type": "apiKey", "in": "cookie", "name": "crm_session", "description": "Browser session established by POST /api/auth/login. Required for human email approval and sending." }
    },
    "parameters": {
      "Id": { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
    },
    "schemas": {
      "CompanyStatus": { "type": "string", "enum": ["researching", "ready_to_contact", "contacted", "engaged", "opportunity", "customer", "parked", "disqualified"] },
      "Company": {
        "type": "object", "required": ["id", "name", "bio", "fitHypothesis", "status", "priority", "createdAt", "updatedAt"],
        "properties": {
          "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "website": { "type": ["string", "null"], "format": "uri" },
          "bio": { "type": "string" }, "location": { "type": ["string", "null"] }, "industry": { "type": ["string", "null"] },
          "fitHypothesis": { "type": "string" }, "status": { "$ref": "#/components/schemas/CompanyStatus" }, "priority": { "type": "string", "enum": ["low", "medium", "high"] },
          "droppedReason": { "type": ["string", "null"], "description": "Reason or revisit trigger when the company is parked or disqualified. Retained under its original API name for compatibility." }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" }
        }
      },
      "CompanyWrite": {
        "type": "object", "properties": {
          "name": { "type": "string" }, "website": { "type": ["string", "null"], "format": "uri" }, "bio": { "type": "string" },
          "location": { "type": ["string", "null"] }, "industry": { "type": ["string", "null"] }, "fitHypothesis": { "type": "string" },
          "status": { "$ref": "#/components/schemas/CompanyStatus" }, "priority": { "type": "string", "enum": ["low", "medium", "high"] }, "droppedReason": { "type": ["string", "null"] }
        }
      },
      "ContactWrite": {
		"type": "object", "properties": { "name": { "type": "string" }, "email": { "type": ["string", "null"], "format": "email" }, "phone": { "type": ["string", "null"] }, "position": { "type": ["string", "null"] }, "linkedinUrl": { "type": ["string", "null"], "format": "uri" }, "isPrimary": { "type": "boolean", "default": false }, "isGeneric": { "type": "boolean", "default": false, "description": "True for shared inboxes such as enquiries@ or sales@ rather than a named stakeholder." } }
      },
      "EmailAddress": {
        "type": "object", "required": ["address"], "properties": { "name": { "type": "string" }, "address": { "type": "string", "format": "email" } }
      },
      "EmailMessage": {
        "type": "object",
        "required": ["id", "companyId", "direction", "subject", "from", "to", "cc", "bcc", "textBody", "mailbox", "uid", "uidValidity", "occurredAt", "createdAt"],
        "properties": {
          "id": { "type": "string", "format": "uuid" }, "companyId": { "type": "string", "format": "uuid" }, "contactId": { "type": ["string", "null"], "format": "uuid" },
          "direction": { "type": "string", "enum": ["inbound", "outbound"] }, "messageId": { "type": ["string", "null"] }, "inReplyTo": { "type": ["string", "null"] },
          "references": { "type": "array", "items": { "type": "string" } }, "subject": { "type": "string" },
          "from": { "type": "array", "items": { "$ref": "#/components/schemas/EmailAddress" } }, "to": { "type": "array", "items": { "$ref": "#/components/schemas/EmailAddress" } }, "cc": { "type": "array", "items": { "$ref": "#/components/schemas/EmailAddress" } }, "bcc": { "type": "array", "items": { "$ref": "#/components/schemas/EmailAddress" }, "description": "Retained by Fieldwork for outbound messages but omitted from recipient-visible MIME headers." },
          "textBody": { "type": "string" }, "htmlBody": { "type": ["string", "null"], "description": "Sanitised HTML; use textBody or the raw endpoint when exact representation matters." },
          "mailbox": { "type": "string" }, "uid": { "type": "integer" }, "uidValidity": { "type": "string" }, "occurredAt": { "type": "string", "format": "date-time" }, "createdAt": { "type": "string", "format": "date-time" }
        }
      },
      "EmailSyncStatus": {
        "type": "object", "required": ["configured", "automaticSyncEnabled", "inProgress", "lastImportedCount"],
        "properties": {
          "configured": { "type": "boolean" }, "automaticSyncEnabled": { "type": "boolean", "description": "True when the built-in hourly job has an EMAIL_SYNC_TOKEN." }, "inProgress": { "type": "boolean" }, "lastStartedAt": { "type": ["string", "null"], "format": "date-time" },
          "lastCompletedAt": { "type": ["string", "null"], "format": "date-time" }, "lastImportedCount": { "type": "integer" }, "lastError": { "type": ["string", "null"] }, "nextAllowedAt": { "type": ["string", "null"], "format": "date-time" }
        }
      },
      "EmailDraftWrite": {
        "type": "object",
        "required": ["companyId", "subject", "textBody"],
        "properties": {
          "companyId": { "type": "string", "format": "uuid" },
          "contactId": { "type": ["string", "null"], "format": "uuid", "description": "When supplied, must belong to companyId. Its current name and email are copied into the draft." },
          "toName": { "type": ["string", "null"] },
          "toEmail": { "type": ["string", "null"], "format": "email", "description": "Required when contactId has no email or is omitted." },
		  "cc": { "type": "array", "items": { "oneOf": [{ "type": "string", "format": "email" }, { "$ref": "#/components/schemas/EmailAddress" }] }, "default": [] },
		  "bcc": { "type": "array", "items": { "oneOf": [{ "type": "string", "format": "email" }, { "$ref": "#/components/schemas/EmailAddress" }] }, "default": [], "description": "Blind-copy recipients; not exposed in the delivered message headers." },
          "subject": { "type": "string" },
          "textBody": { "type": "string", "description": "Plain-text email body." }
        }
      },
      "EmailDraftEdit": {
        "type": "object",
        "properties": {
          "toName": { "type": ["string", "null"] },
          "toEmail": { "type": "string", "format": "email" },
		  "cc": { "type": "array", "items": { "type": "string", "format": "email" } },
		  "bcc": { "type": "array", "items": { "type": "string", "format": "email" } },
          "subject": { "type": "string" },
          "textBody": { "type": "string" }
        }
      },
      "ActivityWrite": {
        "type": "object", "required": ["type", "summary"], "properties": { "type": { "type": "string", "enum": ["email_sent", "email_received", "call", "meeting", "status_changed", "other"] }, "summary": { "type": "string" }, "contactId": { "type": ["string", "null"], "format": "uuid" }, "occurredAt": { "type": "string", "format": "date-time" } }
      },
      "NoteWrite": { "type": "object", "required": ["body"], "properties": { "body": { "type": "string" }, "sourceUrl": { "type": ["string", "null"], "format": "uri" } } },
      "NewsWrite": { "type": "object", "required": ["headline", "sourceUrl"], "properties": { "headline": { "type": "string" }, "summary": { "type": "string" }, "sourceUrl": { "type": "string", "format": "uri" }, "publishedAt": { "type": ["string", "null"], "format": "date-time" } } },
      "ReminderWrite": { "type": "object", "required": ["companyId", "description", "dueAt"], "properties": { "companyId": { "type": "string", "format": "uuid" }, "contactId": { "type": ["string", "null"], "format": "uuid" }, "assigneeId": { "type": "string", "format": "uuid", "description": "Defaults to the authenticated user" }, "description": { "type": "string" }, "dueAt": { "type": "string", "format": "date-time" } } },
      "UserCreate": { "type": "object", "required": ["name", "email", "password"], "properties": { "name": { "type": "string" }, "email": { "type": "string", "format": "email" }, "password": { "type": "string", "minLength": 10 }, "role": { "type": "string", "enum": ["admin", "member"], "default": "member" } } },
      "Error": { "type": "object", "properties": { "message": { "type": "string" } }, "required": ["message"] }
    },
    "responses": {
      "Success": { "description": "Operation successful", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "const": true } } } } } },
      "BadRequest": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Unauthorized": { "description": "Missing, expired or revoked credential", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Forbidden": { "description": "The user lacks permission", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "NotFound": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Conflict": { "description": "Resource state conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  }
}
