{
  "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"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "sess_a1b2c3",
                    "segments": [
                      {
                        "text": "Let's review the Q1 targets.",
                        "speaker": "Alice",
                        "timestamp": "2026-03-18T14:01:12.000Z"
                      },
                      {
                        "text": "Revenue is up 15% from last quarter.",
                        "speaker": "Bob",
                        "timestamp": "2026-03-18T14:01:18.000Z"
                      },
                      {
                        "text": "That's great progress. What about retention?",
                        "speaker": "Alice",
                        "timestamp": "2026-03-18T14:01:25.000Z"
                      }
                    ]
                  }
                }
              }
            }
          },
          "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"
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "sess_a1b2c3",
                    "title": "Q1 Planning Review",
                    "keypoints": {
                      "title": "Q1 Planning Review",
                      "sections": [
                        {
                          "heading": "Revenue Performance",
                          "points": [
                            "Revenue increased 15% quarter-over-quarter",
                            "Enterprise segment grew fastest at 22%"
                          ]
                        },
                        {
                          "heading": "Customer Retention",
                          "points": [
                            "Retention rate held steady at 94%",
                            "Churn concentrated in SMB segment"
                          ]
                        }
                      ],
                      "decisions": [
                        "Increase enterprise sales team by 2 headcount",
                        "Launch SMB retention campaign by end of April"
                      ],
                      "actionItems": [
                        {
                          "item": "Draft enterprise hiring plan",
                          "owner": "Alice",
                          "confidence": 0.95,
                          "priority": "high"
                        },
                        {
                          "item": "Prepare SMB retention proposal",
                          "owner": "Bob",
                          "confidence": 0.87,
                          "priority": "medium"
                        }
                      ],
                      "participants": [
                        "Alice",
                        "Bob"
                      ],
                      "importantDates": [
                        {
                          "date": "2026-04-30",
                          "context": "Deadline for SMB retention campaign launch"
                        }
                      ]
                    },
                    "createdAt": "2026-03-18T15:00:00.000Z"
                  }
                }
              }
            }
          },
          "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"
                            }
                          }
                        }
                      ]
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "sess_a1b2c3",
                    "title": "Q1 Planning Review",
                    "keypoints": {
                      "title": "Q1 Planning Review",
                      "sections": [
                        {
                          "heading": "Revenue Performance",
                          "points": [
                            "Revenue increased 15% quarter-over-quarter",
                            "Enterprise segment grew fastest at 22%"
                          ]
                        },
                        {
                          "heading": "Customer Retention",
                          "points": [
                            "Retention rate held steady at 94%",
                            "Churn concentrated in SMB segment"
                          ]
                        }
                      ],
                      "decisions": [
                        "Increase enterprise sales team by 2 headcount",
                        "Launch SMB retention campaign by end of April"
                      ],
                      "actionItems": [
                        {
                          "item": "Draft enterprise hiring plan",
                          "owner": "Alice",
                          "confidence": 0.95,
                          "priority": "high"
                        },
                        {
                          "item": "Prepare SMB retention proposal",
                          "owner": "Bob",
                          "confidence": 0.87,
                          "priority": "medium"
                        }
                      ],
                      "participants": [
                        "Alice",
                        "Bob"
                      ],
                      "importantDates": [
                        {
                          "date": "2026-04-30",
                          "context": "Deadline for SMB retention campaign launch"
                        }
                      ]
                    },
                    "createdAt": "2026-03-18T15:00:00.000Z",
                    "cached": false
                  }
                }
              }
            }
          },
          "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"
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "sess_a1b2c3",
                    "feedback": {
                      "overallScore": 8.5,
                      "topPriority": {
                        "focus": "Pause before answering Bob's pushback",
                        "quote": "Yeah no, we already considered that.",
                        "reason": "The two interruptions both came when Bob raised retention risk, and both shut the topic down before he finished the thought. Holding the pause is the single change that unblocks the retention conversation next call.",
                        "alternative": "That's a fair concern, Bob. Walk me through what you're seeing."
                      },
                      "strengths": [
                        {
                          "category": "clarity",
                          "description": "Clear and structured presentation of quarterly results",
                          "timestamp": "14:01",
                          "quote": "Let's review the Q1 targets one by one."
                        }
                      ],
                      "growthAreas": [
                        {
                          "category": "listening",
                          "description": "Interrupted Bob twice during the retention discussion",
                          "suggestion": "Pause for 2-3 seconds after others finish speaking before responding.",
                          "timestamp": "14:12"
                        }
                      ],
                      "categoryScores": {
                        "clarity": 9,
                        "listening": 7.5,
                        "timeManagement": 8.5,
                        "collaboration": 8,
                        "decisionMaking": 9
                      },
                      "talkListenRatio": 0.62,
                      "actionPlan": [
                        "Practice active listening by pausing before responding",
                        "Summarize others' points before adding your own"
                      ]
                    },
                    "overallScore": 8.5,
                    "userSpeakerName": "Alice",
                    "createdAt": "2026-03-18T15:00:00.000Z"
                  }
                }
              }
            }
          },
          "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"
                            }
                          }
                        }
                      ]
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "sess_a1b2c3",
                    "feedback": {
                      "overallScore": 8.5,
                      "topPriority": {
                        "focus": "Pause before answering Bob's pushback",
                        "quote": "Yeah no, we already considered that.",
                        "reason": "The two interruptions both came when Bob raised retention risk, and both shut the topic down before he finished the thought. Holding the pause is the single change that unblocks the retention conversation next call.",
                        "alternative": "That's a fair concern, Bob. Walk me through what you're seeing."
                      },
                      "strengths": [
                        {
                          "category": "clarity",
                          "description": "Clear and structured presentation of quarterly results",
                          "timestamp": "14:01",
                          "quote": "Let's review the Q1 targets one by one."
                        }
                      ],
                      "growthAreas": [
                        {
                          "category": "listening",
                          "description": "Interrupted Bob twice during the retention discussion",
                          "suggestion": "Pause for 2-3 seconds after others finish speaking before responding.",
                          "timestamp": "14:12"
                        }
                      ],
                      "categoryScores": {
                        "clarity": 9,
                        "listening": 7.5,
                        "timeManagement": 8.5,
                        "collaboration": 8,
                        "decisionMaking": 9
                      },
                      "talkListenRatio": 0.62,
                      "actionPlan": [
                        "Practice active listening by pausing before responding",
                        "Summarize others' points before adding your own"
                      ]
                    },
                    "overallScore": 8.5,
                    "userSpeakerName": "Alice",
                    "createdAt": "2026-03-18T15:00:00.000Z",
                    "cached": false
                  }
                }
              }
            }
          },
          "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"
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "sess_a1b2c3",
                    "query": "What were the main action items?",
                    "response": "Two action items were identified: (1) Alice will draft an enterprise hiring plan by next week, and (2) Bob will prepare an SMB retention proposal by end of April.",
                    "metadata": {
                      "segmentsAnalyzed": 187,
                      "conversationDuration": 45
                    },
                    "suggestedQueries": [
                      "Who is responsible for the retention campaign?",
                      "What was the revenue growth percentage?"
                    ]
                  }
                }
              }
            }
          },
          "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"
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "sess_a1b2c3",
                    "subject": "Follow-up: Q1 Planning Review",
                    "body": "Hi Sarah,\n\nThanks for joining the Q1 Planning Review today. Here are the key takeaways:\n\n- Revenue increased 15% quarter-over-quarter, with enterprise leading at 22% growth\n- Customer retention held at 94%, though SMB churn needs attention\n\nAction items:\n- Alice: Draft enterprise hiring plan by next week\n- Bob: Prepare SMB retention proposal by end of April\n\nLet me know if I missed anything.\n\nBest,\nAlice",
                    "keyPoints": [
                      "Revenue increased 15% quarter-over-quarter",
                      "Enterprise segment grew fastest at 22%",
                      "Retention rate held steady at 94%"
                    ],
                    "actionItems": [
                      "Draft enterprise hiring plan (Alice, next week)",
                      "Prepare SMB retention proposal (Bob, end of April)"
                    ],
                    "generatedAt": "2026-03-18T15:05:00.000Z"
                  }
                }
              }
            }
          },
          "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"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "evt_abc123",
                      "summary": "Weekly Standup",
                      "start": {
                        "dateTime": "2026-03-19T09:00:00-04:00",
                        "timeZone": "America/New_York"
                      },
                      "end": {
                        "dateTime": "2026-03-19T09:30:00-04:00",
                        "timeZone": "America/New_York"
                      },
                      "attendees": [
                        {
                          "email": "alice@example.com",
                          "displayName": "Alice Chen",
                          "responseStatus": "accepted"
                        },
                        {
                          "email": "bob@example.com",
                          "displayName": "Bob Smith",
                          "responseStatus": "accepted"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "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"
                    }
                  }
                },
                "example": {
                  "data": {
                    "profile": {
                      "name": "Alice Chen",
                      "email": "alice@example.com",
                      "timezone": "America/New_York",
                      "language": "en",
                      "profilePictureUrl": null,
                      "createdAt": "2025-09-15T10:00:00.000Z"
                    },
                    "subscription": {
                      "tier": "professional",
                      "status": "active",
                      "currentPeriodEnd": "2026-04-15T00:00:00.000Z"
                    },
                    "apiUsage": {
                      "aiGenerations": {
                        "used": 12,
                        "limit": 100,
                        "remaining": 88,
                        "resetsAt": "2026-04-01T00:00:00.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "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"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "wh_abc123",
                      "url": "https://hooks.example.com/convo",
                      "events": [
                        "conversation.keypoints.ready",
                        "transcript.ready"
                      ],
                      "created_at": "2026-03-10T12:00:00.000Z"
                    }
                  ]
                }
              }
            }
          },
          "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"
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "wh_def456",
                    "url": "https://hooks.example.com/convo",
                    "events": [
                      "conversation.keypoints.ready"
                    ],
                    "secret": "whsec_a1b2c3d4e5f6...",
                    "createdAt": "2026-03-18T16:00:00.000Z"
                  }
                }
              }
            }
          },
          "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
              },
              "topPriority": {
                "type": "object",
                "description": "Optional. The single highest-leverage focus area to act on before the next call — synthesized from across the growth areas, not necessarily a copy of growthAreas[0]. Absent when the call was too brief/routine for a clear priority, or in feedback generated before this field existed.",
                "properties": {
                  "focus": {
                    "type": "string",
                    "description": "Short imperative theme, 4-8 words ('Slow down before committing to scope')."
                  },
                  "quote": {
                    "type": "string",
                    "description": "Verbatim anchoring moment from the user's transcript."
                  },
                  "reason": {
                    "type": "string",
                    "description": "Why this is the #1 priority for next call (1-2 sentences)."
                  },
                  "alternative": {
                    "type": "string",
                    "description": "Verbatim line the user could have said instead. Rendered as a 'Try saying' callout."
                  }
                }
              },
              "strengths": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "category": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "quote": {
                      "type": "string",
                      "description": "Verbatim line the user said (primary content for chat-bubble rendering)."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Why this specific moment landed well (1-2 sentences)."
                    }
                  }
                }
              },
              "growthAreas": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "category": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "suggestion": {
                      "type": "string"
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "quote": {
                      "type": "string",
                      "description": "Verbatim line the user said that could be improved."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Why this moment fell short (1-2 sentences)."
                    },
                    "alternative": {
                      "type": "string",
                      "description": "Verbatim better phrasing the user could have used instead. Rendered as a 'Try saying' callout."
                    }
                  }
                }
              },
              "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."
              }
            }
          }
        }
      }
    }
  }
}