{
  "openapi": "3.0.3",
  "info": {
    "title": "Convo API",
    "version": "1.0.0",
    "description": "Programmatic access to your AI meeting assistant data. Build integrations with Zapier, Make.com, or custom applications.\n\n## Authentication\nAll requests require a Bearer token via the `Authorization` header. Generate API keys in your Convo dashboard settings.\n\n## Tier Access\n| Capability | Starter | Professional | Enterprise |\n|---|---|---|---|\n| API keys | 1 | 3 | 10 |\n| Read endpoints | Yes | Yes | Yes |\n| Write endpoints | Yes | Yes | Yes |\n| AI generations | 10/month | 100/month | Unlimited |\n| Webhooks | No | 3 | Unlimited |\n| Rate limit | 100/hr | 500/hr | 2,000/hr |\n\n## Rate Limits\nEvery response includes `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers. Exceeding limits returns a `429` with a `Retry-After` header.",
    "contact": { "email": "ivan@itsconvo.com" },
    "termsOfService": "https://www.itsconvo.com/terms/api"
  },
  "servers": [
    { "url": "https://www.itsconvo.com", "description": "Production" }
  ],
  "security": [{ "bearerAuth": [] }],
  "tags": [
    { "name": "Conversations", "description": "List, read, update, and delete conversations" },
    { "name": "AI Generation", "description": "AI-powered endpoints (count against monthly limit)" },
    { "name": "Calendar", "description": "Google Calendar events" },
    { "name": "User", "description": "Profile and usage stats" },
    { "name": "Webhooks", "description": "Webhook registration and management (Professional+)" }
  ],
  "paths": {
    "/api/v1/conversations": {
      "get": {
        "tags": ["Conversations"],
        "summary": "List conversations",
        "operationId": "listConversations",
        "parameters": [
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 }, "description": "Max results to return" },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 }, "description": "Number of results to skip" },
          { "name": "search", "in": "query", "schema": { "type": "string" }, "description": "Search conversations by title" },
          { "name": "since", "in": "query", "schema": { "type": "string", "format": "date-time" }, "description": "Return conversations after this date (ISO 8601)" }
        ],
        "responses": {
          "200": {
            "description": "List of conversations",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Conversation" }
                    },
                    "pagination": { "$ref": "#/components/schemas/Pagination" }
                  }
                },
                "example": {
                  "data": [
                    { "id": "sess_a1b2c3", "title": "Q1 Planning Review", "startTime": "2026-03-18T14:00:00Z", "endTime": "2026-03-18T14:45:00Z", "duration": 45, "segmentCount": 128, "linkedCalendarEventId": null }
                  ],
                  "pagination": { "total": 42, "limit": 20, "offset": 0 }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/conversations/{id}/transcript": {
      "get": {
        "tags": ["Conversations"],
        "summary": "Get transcript",
        "operationId": "getTranscript",
        "parameters": [{ "$ref": "#/components/parameters/conversationId" }],
        "responses": {
          "200": {
            "description": "Conversation transcript",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": { "type": "string" },
                        "segments": { "type": "array", "items": { "$ref": "#/components/schemas/Segment" } }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/conversations/{id}/keypoints": {
      "get": {
        "tags": ["Conversations"],
        "summary": "Get cached keypoints",
        "operationId": "getKeypoints",
        "parameters": [{ "$ref": "#/components/parameters/conversationId" }],
        "responses": {
          "200": {
            "description": "Cached keypoints",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/KeypointsResponse" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "tags": ["AI Generation"],
        "summary": "Generate keypoints",
        "description": "Generates AI-powered keypoints for a conversation. Returns cached result if available (no AI credit consumed). Use `forceRefresh: true` to regenerate.",
        "operationId": "generateKeypoints",
        "parameters": [{ "$ref": "#/components/parameters/conversationId" }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "forceRefresh": { "type": "boolean", "default": false, "description": "Force regeneration even if cached result exists" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated keypoints",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "allOf": [
                        { "$ref": "#/components/schemas/KeypointsResponse" },
                        { "type": "object", "properties": { "cached": { "type": "boolean" } } }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/AILimitExceeded" }
        }
      }
    },
    "/api/v1/conversations/{id}/feedback": {
      "get": {
        "tags": ["Conversations"],
        "summary": "Get cached feedback",
        "operationId": "getFeedback",
        "parameters": [{ "$ref": "#/components/parameters/conversationId" }],
        "responses": {
          "200": {
            "description": "Cached feedback",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/FeedbackResponse" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "tags": ["AI Generation"],
        "summary": "Generate feedback",
        "description": "Generates AI-powered communication feedback. Returns cached result if available. Requires at least 10 transcript segments.",
        "operationId": "generateFeedback",
        "parameters": [{ "$ref": "#/components/parameters/conversationId" }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "forceRefresh": { "type": "boolean", "default": false }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated feedback",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "allOf": [
                        { "$ref": "#/components/schemas/FeedbackResponse" },
                        { "type": "object", "properties": { "cached": { "type": "boolean" } } }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/AILimitExceeded" }
        }
      }
    },
    "/api/v1/conversations/{id}/query": {
      "post": {
        "tags": ["AI Generation"],
        "summary": "Query conversation",
        "description": "Ask a natural-language question about a conversation. AI-powered, counts against monthly limit.",
        "operationId": "queryConversation",
        "parameters": [{ "$ref": "#/components/parameters/conversationId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["query"],
                "properties": {
                  "query": { "type": "string", "maxLength": 500, "description": "The question to ask", "example": "What were the main action items?" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "AI-generated answer",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/QueryResponse" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/AILimitExceeded" }
        }
      }
    },
    "/api/v1/conversations/{id}/email": {
      "post": {
        "tags": ["AI Generation"],
        "summary": "Generate follow-up email",
        "description": "Generates a follow-up email based on the conversation. AI-powered, counts against monthly limit.",
        "operationId": "generateEmail",
        "parameters": [{ "$ref": "#/components/parameters/conversationId" }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "recipientName": { "type": "string", "description": "Name of the email recipient", "example": "Sarah" },
                  "tone": { "type": "string", "enum": ["professional", "casual", "concise"], "default": "professional" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated email",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/EmailResponse" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/AILimitExceeded" }
        }
      }
    },
    "/api/v1/conversations/{id}/share": {
      "post": {
        "tags": ["Conversations"],
        "summary": "Share conversation",
        "description": "Generates a public share URL for the conversation.",
        "operationId": "shareConversation",
        "parameters": [{ "$ref": "#/components/parameters/conversationId" }],
        "responses": {
          "200": {
            "description": "Share URL generated",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "example": { "data": { "id": "sess_a1b2c3", "shareUrl": "https://www.itsconvo.com/shared/abc123" } }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/conversations/{id}": {
      "patch": {
        "tags": ["Conversations"],
        "summary": "Update conversation",
        "description": "Update the conversation title.",
        "operationId": "updateConversation",
        "parameters": [{ "$ref": "#/components/parameters/conversationId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["title"],
                "properties": {
                  "title": { "type": "string", "description": "New conversation title", "example": "Updated Meeting Title" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Conversation updated",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "example": { "data": { "id": "sess_a1b2c3", "title": "Updated Meeting Title" } }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "tags": ["Conversations"],
        "summary": "Delete conversation",
        "description": "Soft-deletes a conversation. Data can be recovered.",
        "operationId": "deleteConversation",
        "parameters": [{ "$ref": "#/components/parameters/conversationId" }],
        "responses": {
          "200": {
            "description": "Conversation deleted",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "example": { "data": { "id": "sess_a1b2c3", "deleted": true } }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/calendar/events": {
      "get": {
        "tags": ["Calendar"],
        "summary": "List calendar events",
        "description": "Returns upcoming Google Calendar events. Requires Google Calendar connected in the Convo dashboard.",
        "operationId": "listCalendarEvents",
        "parameters": [
          { "name": "maxResults", "in": "query", "schema": { "type": "integer", "default": 10, "minimum": 1, "maximum": 50 } },
          { "name": "timeMin", "in": "query", "schema": { "type": "string", "format": "date-time" }, "description": "Filter events starting after this time (ISO 8601)" }
        ],
        "responses": {
          "200": {
            "description": "Calendar events",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/CalendarEvent" } }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "description": "Google Calendar not connected" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/user/profile": {
      "get": {
        "tags": ["User"],
        "summary": "Get profile and usage",
        "description": "Returns user profile, subscription tier, and API usage statistics.",
        "operationId": "getUserProfile",
        "responses": {
          "200": {
            "description": "User profile and usage stats",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/UserProfile" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/webhooks": {
      "get": {
        "tags": ["Webhooks"],
        "summary": "List webhooks",
        "description": "List all active webhooks. Professional and Enterprise tiers only.",
        "operationId": "listWebhooks",
        "responses": {
          "200": {
            "description": "Active webhooks",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/Webhook" } }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "tags": ["Webhooks"],
        "summary": "Register webhook",
        "description": "Register a new webhook endpoint. HTTPS URLs only. The `secret` for HMAC verification is returned once on creation.",
        "operationId": "createWebhook",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/WebhookCreateRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook created",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/WebhookCreated" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "tags": ["Webhooks"],
        "summary": "Delete webhook",
        "description": "Revoke and delete a webhook by ID.",
        "operationId": "deleteWebhook",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["id"],
                "properties": {
                  "id": { "type": "string", "description": "Webhook ID to delete" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook deleted",
            "content": {
              "application/json": {
                "example": { "data": { "id": "wh_abc123", "deleted": true } }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/webhooks/test": {
      "post": {
        "tags": ["Webhooks"],
        "summary": "Test a webhook",
        "description": "Sends a test event to a registered webhook URL and returns the delivery status. Professional plan and above.",
        "security": [{ "bearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["webhookId"],
                "properties": {
                  "webhookId": { "type": "string", "description": "ID of the webhook to test", "example": "wh_abc123" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Test result",
            "content": {
              "application/json": {
                "example": { "data": { "webhookId": "wh_abc123", "delivered": true, "statusCode": 200 } }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key as Bearer token. Generate keys in your Convo dashboard settings."
      }
    },
    "parameters": {
      "conversationId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": { "type": "string" },
        "description": "Conversation session ID",
        "example": "sess_a1b2c3"
      }
    },
    "headers": {
      "X-RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Requests allowed per hour for your tier" },
      "X-RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Requests remaining in the current window" },
      "X-RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Unix timestamp when the rate limit window resets" }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": { "type": "string", "enum": ["unauthorized", "forbidden", "not_found", "rate_limited", "ai_limit_exceeded", "validation_error", "internal_error"] },
              "message": { "type": "string" }
            }
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "total": { "type": "integer", "example": 42 },
          "limit": { "type": "integer", "example": 20 },
          "offset": { "type": "integer", "example": 0 }
        }
      },
      "Conversation": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "example": "sess_a1b2c3" },
          "title": { "type": "string", "example": "Q1 Planning Review" },
          "startTime": { "type": "string", "format": "date-time" },
          "endTime": { "type": "string", "format": "date-time" },
          "duration": { "type": "number", "description": "Duration in minutes" },
          "segmentCount": { "type": "integer" },
          "linkedCalendarEventId": { "type": "string", "nullable": true }
        }
      },
      "Segment": {
        "type": "object",
        "properties": {
          "text": { "type": "string", "example": "Let's review the Q1 targets." },
          "speaker": { "type": "string", "example": "Alice" },
          "timestamp": { "type": "string", "format": "date-time" }
        }
      },
      "KeypointsResponse": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "title": { "type": "string", "example": "Q1 Planning Review" },
          "keypoints": {
            "type": "object",
            "properties": {
              "title": { "type": "string" },
              "sections": { "type": "array", "items": { "type": "object", "properties": { "heading": { "type": "string" }, "points": { "type": "array", "items": { "type": "string" } } } } },
              "decisions": { "type": "array", "items": { "type": "string" } },
              "actionItems": { "type": "array", "items": { "type": "object", "properties": { "item": { "type": "string" }, "owner": { "type": "string" }, "confidence": { "type": "number" }, "priority": { "type": "string", "enum": ["high", "medium", "low"] } } } },
              "participants": { "type": "array", "items": { "type": "string" } },
              "importantDates": { "type": "array", "items": { "type": "object", "properties": { "date": { "type": "string" }, "context": { "type": "string" } } } }
            }
          },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      },
      "FeedbackResponse": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "feedback": {
            "type": "object",
            "properties": {
              "overallScore": { "type": "number", "example": 8.5 },
              "strengths": { "type": "array", "items": { "type": "object", "properties": { "category": { "type": "string" }, "description": { "type": "string" }, "timestamp": { "type": "string" }, "quote": { "type": "string" } } } },
              "growthAreas": { "type": "array", "items": { "type": "object", "properties": { "category": { "type": "string" }, "description": { "type": "string" }, "suggestion": { "type": "string" }, "timestamp": { "type": "string" } } } },
              "categoryScores": { "type": "object", "properties": { "clarity": { "type": "number" }, "listening": { "type": "number" }, "timeManagement": { "type": "number" }, "collaboration": { "type": "number" }, "decisionMaking": { "type": "number" } } },
              "talkListenRatio": { "type": "number" },
              "actionPlan": { "type": "array", "items": { "type": "string" } }
            }
          },
          "overallScore": { "type": "number" },
          "userSpeakerName": { "type": "string" },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      },
      "QueryResponse": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "query": { "type": "string" },
          "response": { "type": "string" },
          "metadata": { "type": "object", "properties": { "segmentsAnalyzed": { "type": "integer" }, "conversationDuration": { "type": "number", "description": "Duration in minutes" } } },
          "suggestedQueries": { "type": "array", "items": { "type": "string" } }
        }
      },
      "EmailResponse": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "subject": { "type": "string", "example": "Follow-up: Q1 Planning Review" },
          "body": { "type": "string" },
          "keyPoints": { "type": "array", "items": { "type": "string" } },
          "actionItems": { "type": "array", "items": { "type": "string" } },
          "generatedAt": { "type": "string", "format": "date-time" }
        }
      },
      "CalendarEvent": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "summary": { "type": "string", "example": "Weekly Standup" },
          "start": { "type": "object", "properties": { "dateTime": { "type": "string", "format": "date-time" }, "timeZone": { "type": "string" } } },
          "end": { "type": "object", "properties": { "dateTime": { "type": "string", "format": "date-time" }, "timeZone": { "type": "string" } } },
          "attendees": { "type": "array", "items": { "type": "object", "properties": { "email": { "type": "string" }, "displayName": { "type": "string" }, "responseStatus": { "type": "string" } } } }
        }
      },
      "UserProfile": {
        "type": "object",
        "properties": {
          "profile": { "type": "object", "properties": { "name": { "type": "string" }, "email": { "type": "string" }, "timezone": { "type": "string" }, "language": { "type": "string" }, "profilePictureUrl": { "type": "string", "nullable": true }, "createdAt": { "type": "string", "format": "date-time" } } },
          "subscription": { "type": "object", "properties": { "tier": { "type": "string", "enum": ["starter", "professional", "enterprise"] }, "status": { "type": "string", "nullable": true }, "currentPeriodEnd": { "type": "string", "nullable": true, "format": "date-time" } } },
          "apiUsage": { "type": "object", "properties": { "aiGenerations": { "type": "object", "properties": { "used": { "type": "integer" }, "limit": { "type": "integer", "nullable": true }, "remaining": { "type": "integer", "nullable": true }, "resetsAt": { "type": "string", "format": "date-time" } } } } }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "example": "wh_abc123" },
          "url": { "type": "string", "format": "uri", "example": "https://hooks.example.com/convo" },
          "events": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEvent" } },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "WebhookCreated": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "url": { "type": "string", "format": "uri" },
          "events": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEvent" } },
          "secret": { "type": "string", "description": "HMAC-SHA256 secret. Shown once on creation.", "example": "whsec_a1b2c3d4e5f6..." },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      },
      "WebhookCreateRequest": {
        "type": "object",
        "required": ["url", "events"],
        "properties": {
          "url": { "type": "string", "format": "uri", "description": "HTTPS endpoint URL", "example": "https://hooks.example.com/convo" },
          "events": { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/WebhookEvent" } }
        }
      },
      "WebhookEvent": {
        "type": "string",
        "enum": ["conversation.created", "conversation.updated", "conversation.keypoints.ready", "conversation.summary.ready", "conversation.action_items.ready", "conversation.feedback.ready", "conversation.shared", "conversation.deleted", "transcript.ready", "transcript.failed", "webhook.test"]
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": { "code": "unauthorized", "message": "Missing or invalid Authorization header. Use: Bearer <api_key>" } } } }
      },
      "Forbidden": {
        "description": "Insufficient plan tier",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": { "code": "forbidden", "message": "Webhooks require a Professional plan or above." } } } }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": { "code": "not_found", "message": "Conversation not found" } } } }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "headers": {
          "X-RateLimit-Limit": { "$ref": "#/components/headers/X-RateLimit-Limit" },
          "X-RateLimit-Remaining": { "$ref": "#/components/headers/X-RateLimit-Remaining" },
          "X-RateLimit-Reset": { "$ref": "#/components/headers/X-RateLimit-Reset" },
          "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until the rate limit resets" }
        },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": { "code": "rate_limited", "message": "Rate limit exceeded (100 requests per hour for starter plan)" } } } }
      },
      "AILimitExceeded": {
        "description": "Monthly AI generation limit reached",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": { "code": "ai_limit_exceeded", "message": "Monthly AI generation limit reached. Upgrade your plan for more." } } } }
      }
    }
  }
}
