{"openapi":"3.1.0","info":{"title":"Hey Support API","version":"1.1.0","description":"Programmatic access to your Hey Support workspace. Authenticate with `Authorization: Bearer hs_live_…`. Rate limit: 1,000 requests per hour per key."},"servers":[{"url":"https://www.hey.support/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"hs_live_*"}},"schemas":{"Pagination":{"type":"object","required":["limit","offset","total","has_more"],"properties":{"limit":{"type":"integer","minimum":1,"maximum":100},"offset":{"type":"integer","minimum":0},"total":{"type":"integer","minimum":0},"has_more":{"type":"boolean"}}},"Error":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable message. Do not match on this string.","example":"Invalid API key."},"code":{"type":"string","description":"Stable machine-readable error code.","enum":["bad_request","unauthorized","forbidden","not_found","method_not_allowed","not_acceptable","rate_limited","internal_error"],"example":"unauthorized"},"docs_url":{"type":"string","format":"uri","description":"Where to read about resolving this error.","example":"https://www.hey.support/docs/api"}}},"Conversation":{"type":"object","required":["id","chatbot_id","is_lead","is_resolved","message_count","created_at"],"properties":{"id":{"type":"string","description":"Sqid-encoded conversation id","example":"k7m2x"},"chatbot_id":{"type":"string","example":"ncimu"},"visitor_id":{"type":"string","nullable":true},"is_lead":{"type":"boolean"},"is_resolved":{"type":"boolean"},"status":{"type":"string","nullable":true,"example":"pending_handoff","description":"Lifecycle status. Common values: open, pending_handoff, human_active, resolved."},"tags":{"type":"array","nullable":true,"items":{"type":"string"},"example":["vip","enterprise"]},"message_count":{"type":"integer","minimum":0},"language_code":{"type":"string","nullable":true,"example":"en"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time","nullable":true}}},"Message":{"type":"object","required":["id","role","content","created_at"],"properties":{"id":{"type":"string"},"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}},"ConversationDetail":{"allOf":[{"$ref":"#/components/schemas/Conversation"},{"type":"object","required":["messages"],"properties":{"messages":{"type":"array","items":{"$ref":"#/components/schemas/Message"}}}}]},"Lead":{"type":"object","required":["id","chatbot_id","status","created_at"],"properties":{"id":{"type":"string"},"chatbot_id":{"type":"string"},"name":{"type":"string","nullable":true},"email":{"type":"string","format":"email","nullable":true},"phone":{"type":"string","nullable":true},"status":{"type":"string","example":"new"},"notes":{"type":"string","nullable":true},"conversation_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"LeadCreate":{"type":"object","required":["chatbot_id"],"properties":{"chatbot_id":{"type":"string","description":"Sqid-encoded chatbot id"},"conversation_id":{"type":"string","nullable":true},"name":{"type":"string","nullable":true,"maxLength":200},"email":{"type":"string","format":"email","nullable":true,"maxLength":320},"phone":{"type":"string","nullable":true,"maxLength":50},"company":{"type":"string","nullable":true,"maxLength":200},"source":{"type":"string","nullable":true,"maxLength":100,"example":"zapier"},"source_url":{"type":"string","format":"uri","nullable":true,"maxLength":2048},"status":{"type":"string","maxLength":40,"example":"new"},"notes":{"type":"string","nullable":true,"maxLength":5000}}},"Booking":{"type":"object","required":["id","chatbot_id","status","created_at"],"properties":{"id":{"type":"string","format":"uuid","description":"Booking UUID (not sqid-encoded)"},"chatbot_id":{"type":"string","example":"ncimu"},"conversation_id":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"email":{"type":"string","format":"email","nullable":true},"event_label":{"type":"string","nullable":true,"example":"Intro call"},"provider":{"type":"string","nullable":true,"example":"calcom"},"external_uid":{"type":"string","nullable":true,"description":"Provider booking uid (Cal.com) — null on legacy rows."},"start_at":{"type":"string","format":"date-time","nullable":true},"end_at":{"type":"string","format":"date-time","nullable":true},"attendee_timezone":{"type":"string","nullable":true,"example":"Asia/Kolkata"},"status":{"type":"string","example":"confirmed"},"created_at":{"type":"string","format":"date-time"}}},"ConversationPatch":{"type":"object","description":"At least one of `tags` or `is_resolved` must be provided. `tags` REPLACES the existing array.","properties":{"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":40},"maxItems":20},"is_resolved":{"type":"boolean"}}},"MessageCreate":{"type":"object","required":["content"],"properties":{"content":{"type":"string","minLength":1,"maxLength":10000}}},"Me":{"type":"object","required":["team_id","key_name","key_prefix"],"properties":{"team_id":{"type":"string","example":"ncimu"},"team_name":{"type":"string","nullable":true,"example":"Acme Inc."},"key_name":{"type":"string","example":"Zapier integration"},"key_prefix":{"type":"string","example":"hs_live_abcd"}}},"Chatbot":{"type":"object","required":["id","name","is_active","created_at"],"properties":{"id":{"type":"string","description":"Sqid-encoded chatbot id","example":"ncimu"},"name":{"type":"string","example":"Acme support agent"},"is_active":{"type":"boolean","description":"False when the agent is paused and no longer answering visitors."},"created_at":{"type":"string","format":"date-time"}}},"KnowledgeSource":{"type":"object","required":["source_url","chunk_count"],"properties":{"source_url":{"type":"string","example":"https://example.com/docs/getting-started"},"chunk_count":{"type":"integer"},"last_indexed_at":{"type":"string","format":"date-time","nullable":true}}},"AnalyticsSummary":{"type":"object","required":["window","totals","by_day"],"properties":{"window":{"type":"string","enum":["30d"]},"totals":{"type":"object","required":["conversations","leads","messages","tokens"],"properties":{"conversations":{"type":"integer"},"leads":{"type":"integer"},"messages":{"type":"integer"},"tokens":{"type":"integer"}}},"by_day":{"type":"array","items":{"type":"object","required":["date","conversations","messages","tokens"],"properties":{"date":{"type":"string","format":"date"},"conversations":{"type":"integer"},"messages":{"type":"integer"},"tokens":{"type":"integer"}}}}}}}},"paths":{"/chatbots":{"get":{"operationId":"listChatbots","summary":"List chatbots","description":"Returns the workspace’s chatbots, newest first, with their sqid-encoded ids. Call this first to discover the `chatbot_id` that every other scoped endpoint expects.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Chatbot"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/conversations":{"get":{"operationId":"listConversations","summary":"List conversations","description":"Returns a paginated list of chat conversations for the workspace, newest first. Filter by chatbot, lead status, resolved state, lifecycle status, language, or start date. Messages are not included — fetch a single conversation to read its transcript.","parameters":[{"name":"chatbot_id","in":"query","schema":{"type":"string"},"description":"Sqid-encoded chatbot id. Scopes results to one chatbot."},{"name":"is_lead","in":"query","schema":{"type":"boolean"}},{"name":"is_resolved","in":"query","schema":{"type":"boolean"}},{"name":"status","in":"query","schema":{"type":"string","example":"pending_handoff"},"description":"Lifecycle status filter (e.g. `pending_handoff`)."},{"name":"language","in":"query","schema":{"type":"string","example":"en"}},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Conversation"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/conversations/{id}":{"get":{"operationId":"getConversation","summary":"Get a conversation with its messages","description":"Returns one conversation and its full message transcript, including visitor messages, AI replies, human agent replies, and internal notes. Responds 404 if the conversation belongs to another workspace, so ids cannot be enumerated.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/ConversationDetail"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateConversation","summary":"Update a conversation (tags, resolved state)","description":"Updates the operator-owned fields of a conversation. Tags REPLACE the existing array rather than merging, so send the full list you want. Does not emit a webhook — automation-driven edits deliberately do not echo back out.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationPatch"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Conversation"}}}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/conversations/{id}/messages":{"post":{"operationId":"createConversationNote","summary":"Add an internal note to a conversation","description":"Inserts a `note` message visible only in the operator dashboard. Notes are never shown to the visitor and are not sent to the AI. The role is always `note` — this endpoint cannot post a reply on the agent’s behalf.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageCreate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Message"}}}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/bookings":{"get":{"operationId":"listBookings","summary":"List bookings","description":"Returns meetings booked through the agent, paginated — both natively scheduled meetings on your connected Google Calendar and Cal.com bookings, each carrying its provider, start and end time, attendee timezone, and status. Read-only: bookings are created by visitors in the widget.","parameters":[{"name":"chatbot_id","in":"query","schema":{"type":"string"},"description":"Sqid-encoded chatbot id. Scopes results to one chatbot."},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Booking"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/leads":{"get":{"operationId":"listLeads","summary":"List leads","description":"Returns contact details captured by the agent — from the lead form, a human handoff, or a booking — newest first. Filter by chatbot, status, or capture date.","parameters":[{"name":"chatbot_id","in":"query","schema":{"type":"string"},"description":"Sqid-encoded chatbot id. Scopes results to one chatbot."},{"name":"status","in":"query","schema":{"type":"string","example":"new"}},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createLead","summary":"Create a lead","description":"Records a lead against a chatbot, optionally linked to a conversation, and emits the `lead.created` webhook. Deduplicated per conversation: when `conversation_id` is provided and a lead already exists for it, the existing lead is returned with `existing: true` rather than a duplicate being created.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadCreate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Lead"},"existing":{"type":"boolean"}}}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Chatbot or conversation not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/me":{"get":{"operationId":"getCurrentKey","summary":"Identify the calling API key","description":"Returns metadata about the workspace and key behind the request. Use it to verify credentials and to discover your workspace id before calling other endpoints — it is the cheapest way to test that a key works, and integrations such as Zapier call it to label connections.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Me"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/leads/{id}":{"get":{"operationId":"getLead","summary":"Get a lead","description":"Returns one captured lead by its sqid-encoded id. Responds 404 rather than 403 when the lead belongs to another workspace, so ids cannot be enumerated.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Lead"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/knowledge/sources":{"get":{"operationId":"listKnowledgeSources","summary":"List knowledge sources for a chatbot","description":"Returns what one chatbot has been trained on — crawled pages, uploaded files, text snippets, and Q&A pairs — with the number of indexed chunks each contributed. Requires the `chatbot_id` query parameter.","parameters":[{"name":"chatbot_id","in":"query","schema":{"type":"string"},"description":"Sqid-encoded chatbot id. Scopes results to one chatbot.","required":true}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/KnowledgeSource"}}}}}}},"400":{"description":"chatbot_id is required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Chatbot not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/analytics/summary":{"get":{"operationId":"getAnalyticsSummary","summary":"Last-30-days rollup","description":"Returns aggregate counts for the trailing 30 days — conversations, messages, leads captured, and resolution rate — for the workspace, or for one chatbot when `chatbot_id` is supplied.","parameters":[{"name":"chatbot_id","in":"query","schema":{"type":"string"},"description":"Sqid-encoded chatbot id. Scopes results to one chatbot."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/AnalyticsSummary"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}