Hedy
Access a user's Hedy meeting data through the Hedy REST API. Read sessions with transcripts, highlights, and todos. Manage topics, session contexts, and webhooks.
Hedy is an AI-powered meeting coach that provides real-time speech transcription and AI-powered conversation analysis. This skill lets you query the user's meeting history, search for specific sessions, retrieve structured meeting outputs, and manage organizational features like topics and webhooks.
Setup
1. Get your API key
Generate an API key inside the Hedy app under Settings > API. Keys start with hedy_live_.
2. Configure OpenClaw
Add the following to ~/.openclaw/openclaw.json:
CODEBLOCK0
Set "region" to "eu" if your Hedy account uses EU data residency. Default is "us".
3. Sandbox users
If you run OpenClaw in a Docker sandbox, apiKey and env values from openclaw.json are injected into the host process only. Add the key to your sandbox environment separately:
CODEBLOCK1
4. Restart OpenClaw
Start a new session so the skill is picked up.
Region and Base URL
Determine the base URL from the configured region:
| Region | Base URL |
|---|
| INLINECODE8 (default) | INLINECODE9 |
| INLINECODE10 |
https://eu-api.hedy.bot |
If no region is configured, default to us.
All endpoints below use {BASE_URL} as a placeholder. Replace it with the resolved URL.
Authentication
Every request requires:
CODEBLOCK2
The API key is injected via the HEDY_API_KEY environment variable. Never display, log, or include the API key in output shown to the user.
Endpoints
All endpoints return JSON. Response shapes vary by endpoint (documented individually below). Error responses always use:
CODEBLOCK3
GET /me
Returns the authenticated user's profile. Response is a bare JSON object (no wrapper).
CODEBLOCK4
Response:
CODEBLOCK5
GET /sessions
List recent meeting sessions. Only cloud-synced sessions are returned. Response is wrapped in { success, data, pagination }.
CODEBLOCK6
Query parameters:
- -
limit (int, 1-100, default 50): Number of sessions to return
Note: This endpoint returns the most recent limit sessions only. There is no cursor-based pagination. To retrieve more sessions, increase the limit value (max 100).
Response:
CODEBLOCK7
GET /sessions/{sessionId}
Full session detail including transcript, AI outputs, highlights, and todos. Response is a bare JSON object (no wrapper).
CODEBLOCK8
Response:
CODEBLOCK9
GET /sessions/{sessionId}/highlights
Highlights (key quotes) from a specific session.
CODEBLOCK10
GET /sessions/{sessionId}/todos
Todos from a specific session.
CODEBLOCK11
GET /sessions/{sessionId}/todos/{todoId}
A specific todo item.
CODEBLOCK12
GET /highlights
List all highlights across all sessions, sorted by timestamp (newest first). Response is wrapped in { success, data, pagination }.
CODEBLOCK13
Query parameters:
- -
limit (int, 1-100, default 50)
Note: This endpoint returns the most recent limit highlights only. There is no cursor-based pagination. To retrieve more highlights, increase the limit value (max 100).
Response:
CODEBLOCK14
GET /highlights/{highlightId}
Full highlight detail. Response is a bare JSON object (no wrapper).
CODEBLOCK15
Response:
CODEBLOCK16
GET /todos
All todos across all sessions. Returns a flat array (no pagination wrapper).
CODEBLOCK17
Response (array of):
CODEBLOCK18
GET /topics
List all topics (conversation groupings), sorted by last update. Response is wrapped in { success, data }. No pagination.
CODEBLOCK19
Response data (array of):
CODEBLOCK20
Fields like overview, overviewUpdatedAt, topicContext, and dominantSessionType may be null or absent if not yet generated.
GET /topics/{topicId}
Full topic detail including overview and insights. Response is wrapped in { success, data }.
CODEBLOCK21
GET /topics/{topicId}/sessions
Sessions grouped under a topic. This is the only endpoint with cursor-based pagination.
CODEBLOCK22
Query parameters:
- -
limit (int, 1-100, default 50) - INLINECODE31 (string): Session ID cursor for next page (from
data.pagination.nextCursor)
Response:
CODEBLOCK23
To paginate: pass ?startAfter={data.pagination.nextCursor} until hasMore is false.
GET /contexts
List session contexts (pre-meeting preparation notes), sorted by most recently updated. Response is wrapped in { success, data }. No pagination.
CODEBLOCK24
Response data (array of):
CODEBLOCK25
GET /contexts/{contextId}
A specific session context. Response is wrapped in { success, data }.
CODEBLOCK26
POST /topics
Create a new topic. Response is wrapped in { success, data }.
CODEBLOCK27
Request body:
- -
name (string, required): 1-100 chars - INLINECODE41 (string, optional): 0-500 chars
- INLINECODE42 (string, optional): Hex format INLINECODE43
- INLINECODE44 (string, optional): Material icon name
- INLINECODE45 (string, optional): Custom instructions, 0-20,000 chars
Returns HTTP 201 with the created topic object.
PATCH /topics/{topicId}
Update an existing topic. Response is wrapped in { success, data }.
CODEBLOCK28
Request body (all fields optional):
- -
name (string): 1-100 chars - INLINECODE48 (string): 0-500 chars
- INLINECODE49 (string): Hex format INLINECODE50
- INLINECODE51 (string)
- INLINECODE52 (string or null): Set to
null to clear
Returns HTTP 200 with the updated topic object.
DELETE /topics/{topicId}
Delete a topic. Sessions under this topic are unlinked (topicId set to null) but not deleted.
CODEBLOCK29
Returns HTTP 200:
CODEBLOCK30
Warning: Deletion is not fully atomic for large topics. The backend unlinks up to 4,000 sessions in batches. If a topic has more than 4,000 sessions, the request returns 400 deletion_limit_exceeded after partially unlinking sessions, and the topic is left in a deletion_failed state. If this happens, inform the user that manual cleanup may be needed in the Hedy app. A 409 deletion_in_progress error means another delete is already running for this topic.
POST /contexts
Create a new session context. Response is wrapped in { success, data }.
CODEBLOCK31
Request body:
- -
title (string, required): 1-200 chars - INLINECODE59 (string, optional): 0-20,000 chars
- INLINECODE60 (boolean, optional): If true, clears default from all other contexts
Returns HTTP 201 with the created context object.
Note: Free tier users are limited to 1 session context. Additional contexts require a Pro subscription.
PATCH /contexts/{contextId}
Update an existing session context. Response is wrapped in { success, data }.
CODEBLOCK32
Request body (all fields optional):
- -
title (string): 1-200 chars - INLINECODE63 (string): 0-20,000 chars
- INLINECODE64 (boolean): If true, clears default from all other contexts
Returns HTTP 200 with the updated context object.
DELETE /contexts/{contextId}
Delete a session context. If the deleted context was the default, the most recently updated remaining context is promoted to default.
CODEBLOCK33
Returns HTTP 200:
CODEBLOCK34
GET /webhooks
List all configured webhooks. Response is wrapped in { success, data }.
CODEBLOCK35
Response data (array of):
CODEBLOCK36
POST /webhooks
Create a webhook. Rate limited to 5 per minute. Maximum 50 webhooks per user. Requires HTTPS URL in production.
CODEBLOCK37
Request body:
- -
url (string, required): Valid HTTPS URL - INLINECODE68 (string) or
events (string array): At least one required. Valid event types:
-
session.created - New session started
-
session.ended - Session finished processing
-
session.exported - User manually exported session
-
highlight.created - New highlight generated
-
todo.exported - Todo marked for export
Returns HTTP 200 with the created webhook object (signing secret is stored but not returned).
DELETE /webhooks/{webhookId}
Delete a webhook.
CODEBLOCK38
Returns HTTP 200:
CODEBLOCK39
Pagination
Most endpoints do NOT support cursor-based pagination. They return up to limit items (max 100) sorted by recency. The /todos, /topics, and /contexts endpoints return all items with no pagination at all.
The only endpoint with true cursor pagination is GET /topics/{topicId}/sessions, which uses startAfter (documented above).
For /sessions and /highlights, if the user needs more than 100 items, inform them that only the most recent 100 are available via the API.
Error Handling
| HTTP Status | Error Code | Meaning | Action |
|---|
| 400 | INLINECODE82 | Request body failed validation | Show the error message; check field constraints |
| 400 |
invalid_webhook_url | Webhook URL is invalid | Ask user to provide a valid HTTPS URL |
| 400 |
missing_event | Neither
event nor
events provided | Ask user which events to subscribe to |
| 400 |
invalid_event | Single event type is invalid | Show the list of valid events |
| 400 |
invalid_events | One or more event types invalid | Show the list of valid events |
| 400 |
webhook_limit_exceeded | User has 50 webhooks already | Suggest deleting unused webhooks first |
| 400 |
deletion_limit_exceeded | Topic has too many sessions (>4,000) for full cleanup | Inform user; partial unlink occurred, manual cleanup needed |
| 401 |
missing_api_key | Authorization header missing | Check that
HEDY_API_KEY is set |
| 401 |
invalid_api_key | Key not found or wrong format | Ask user to verify their API key in Hedy app settings |
| 403 |
tier_limit_exceeded | Feature requires Hedy Pro subscription | Inform user this feature requires a Pro plan |
| 404 |
session_not_found | Session ID does not exist | Inform user; suggest listing sessions first |
| 404 |
highlight_not_found | Highlight ID does not exist | Inform user |
| 404 |
not_found | Topic or context does not exist | Inform user; suggest listing topics or contexts first |
| 404 |
todo_not_found | Todo ID does not exist | Inform user |
| 404 |
webhook_not_found | Webhook ID does not exist | Inform user; suggest listing webhooks first |
| 409 |
deletion_in_progress | Topic deletion already running | Wait and retry later |
| 429 |
rate_limit_exceeded | Too many requests (200/min global, 5/min for webhooks) | Wait 30 seconds before retrying. Do NOT retry immediately. |
| 500 |
internal_error | Server error | Inform user and suggest trying again later |
For user-actionable errors (401, 403, 404), show the error.message from the response. For 429 and 500 errors, show a friendly summary instead (e.g., "The server is busy, please try again in a moment") since raw server messages may contain technical details. Never retry more than once on 429 or 500 errors.
Safety Rules
- 1. Confirm before writing. Before any POST, PATCH, or DELETE request, show the user exactly what will be created, changed, or deleted and wait for explicit confirmation.
- Confirm deletions twice. For DELETE requests, state the target (topic name, context title, webhook URL) and ask "Are you sure?" before proceeding.
- Extra caution for webhooks. Creating a webhook causes Hedy to send future meeting event data (session metadata, highlight titles, todo text) to an external URL. Before creating a webhook, explicitly confirm: (a) the exact destination host, (b) which events will be sent, and (c) warn the user that meeting-derived data will be sent outside Hedy to that URL.
- Never display, log, or include the API key in any output, message, file, or code block shown to the user.
- Never prompt the user to paste their API key in chat. Direct them to configure it in
~/.openclaw/openclaw.json. - Respect rate limits. On 429 responses, wait before retrying. Do not loop.
- Present data clearly. Format session transcripts, highlights, and todos in a readable way. Use markdown tables or lists as appropriate.
- Handle missing data gracefully. Some fields (transcript, cleaned_transcript, recap, topic) may be null or empty. Do not treat this as an error.
- Protect user privacy. Meeting transcripts and notes contain sensitive content. Do not send this data to any external service, tool, or URL beyond the Hedy API itself.
Usage Examples
"Show me my recent meetings"
-> GET /sessions with limit=10, display as a table with title, date, duration, and topic.
"What were the key takeaways from my last meeting?"
-> GET /sessions with limit=1 to find the most recent session, then GET /sessions/{id} for full detail. Present the recap and highlights.
"Do I have any open todos?"
-> GET /todos, filter where completed is false, present as a checklist.
"Show me everything about Project Alpha"
-> GET /topics to find the topic by name, then GET /topics/{id}/sessions to list all sessions under it.
"What did we discuss last Tuesday?"
-> GET /sessions, scan startTime fields for the matching date, then GET /sessions/{id} for that session's detail.
"Show my session contexts"
-> GET /contexts, present as a list with title and whether it's the default.
"Create a topic called Client Calls with a blue color"
-> Confirm with user, then POST /topics with name "Client Calls" and color "#4A90D9".
"Delete the Project Alpha topic"
-> GET /topics to find the ID, confirm with user showing the topic name and session count, then DELETE /topics/{id}.
"Set up a webhook for new highlights"
-> Confirm the URL with user, then POST /webhooks with events ["highlight.created"].
"Create a context for investor meetings"
-> Confirm with user, then POST /contexts with title "Investor Meetings" and relevant content.
Hedy
通过 Hedy REST API 访问用户的 Hedy 会议数据。读取包含转录文本、重点内容和待办事项的会议记录。管理主题、会话上下文和 Webhook。
Hedy 是一款由 AI 驱动的会议教练,提供实时语音转录和 AI 驱动的对话分析。此技能允许您查询用户的会议历史、搜索特定会议、检索结构化会议输出,并管理主题和 Webhook 等组织功能。
设置
1. 获取您的 API 密钥
在 Hedy 应用的设置 > API 中生成 API 密钥。密钥以 hedylive 开头。
2. 配置 OpenClaw
将以下内容添加到 ~/.openclaw/openclaw.json:
json
{
skills: {
entries: {
hedy: {
enabled: true,
apiKey: hedyliveYOURKEYHERE,
config: {
region: us
}
}
}
}
}
如果您的 Hedy 账户使用欧盟数据驻留,请将 region 设置为 eu。默认为 us。
3. 沙箱用户
如果您在 Docker 沙箱中运行 OpenClaw,openclaw.json 中的 apiKey 和 env 值仅注入到主机进程中。请将密钥单独添加到您的沙箱环境中:
json
{
agents: {
defaults: {
sandbox: {
docker: {
env: {
HEDYAPIKEY: hedyliveYOURKEYHERE
}
}
}
}
}
}
4. 重启 OpenClaw
启动一个新会话,以便技能被识别。
区域和基础 URL
根据配置的区域确定基础 URL:
| 区域 | 基础 URL |
|---|
| us(默认) | https://api.hedy.bot |
| eu |
https://eu-api.hedy.bot |
如果未配置区域,默认为 us。
以下所有端点均使用 {BASE_URL} 作为占位符。请将其替换为解析后的 URL。
身份验证
每个请求都需要:
Authorization: Bearer {HEDYAPIKEY}
API 密钥通过 HEDYAPIKEY 环境变量注入。切勿在向用户显示的输出中展示、记录或包含 API 密钥。
端点
所有端点均返回 JSON。响应形状因端点而异(下文单独说明)。错误响应始终使用:
json
{
success: false,
error: { code: error_code, message: 人类可读的消息 }
}
GET /me
返回已验证用户的个人资料。响应为裸 JSON 对象(无包装)。
bash
curl -s -H Authorization: Bearer $HEDYAPIKEY {BASE_URL}/me | jq
响应:
json
{
id: uid_123,
email: user@example.com,
name: John Doe
}
GET /sessions
列出最近的会议记录。仅返回云同步的会议记录。响应包装在 { success, data, pagination } 中。
bash
curl -s -H Authorization: Bearer $HEDYAPIKEY {BASE_URL}/sessions?limit=20 | jq
查询参数:
- - limit(整数,1-100,默认 50):返回的会议记录数量
注意:此端点仅返回最近的 limit 条会议记录。没有基于游标的分页。要检索更多会议记录,请增加 limit 值(最大 100)。
响应:
json
{
success: true,
data: [
{
sessionId: sess_123,
title: 每周同步,
startTime: 2026-03-15T14:30:00Z,
duration: 45,
topic: { id: topic_1, name: 团队会议 }
}
],
pagination: { hasMore: false, next: null, total: 42 }
}
GET /sessions/{sessionId}
完整的会议详情,包括转录文本、AI 输出、重点内容和待办事项。响应为裸 JSON 对象(无包装)。
bash
curl -s -H Authorization: Bearer $HEDYAPIKEY {BASE_URL}/sessions/{sessionId} | jq
响应:
json
{
sessionId: sess_123,
title: 每周同步,
startTime: 2026-03-15T14:30:00Z,
endTime: 2026-03-15T15:15:00Z,
duration: 45,
transcript: 完整会议转录文本,
cleaned_transcript: AI 清理版本或 null,
cleaned_at: 2026-03-15T16:00:00Z,
conversations: 问答结构化格式,
meeting_minutes: 格式化会议纪要,
recap: 简要总结,
highlights: [],
user_todos: [],
topic: { id: topic_1, name: 团队会议 }
}
GET /sessions/{sessionId}/highlights
特定会议的重点内容(关键引用)。
bash
curl -s -H Authorization: Bearer $HEDYAPIKEY {BASE_URL}/sessions/{sessionId}/highlights | jq
GET /sessions/{sessionId}/todos
特定会议的待办事项。
bash
curl -s -H Authorization: Bearer $HEDYAPIKEY {BASE_URL}/sessions/{sessionId}/todos | jq
GET /sessions/{sessionId}/todos/{todoId}
特定的待办事项。
bash
curl -s -H Authorization: Bearer $HEDYAPIKEY {BASE_URL}/sessions/{sessionId}/todos/{todoId} | jq
GET /highlights
列出所有会议中的所有重点内容,按时间戳排序(最新的在前)。响应包装在 { success, data, pagination } 中。
bash
curl -s -H Authorization: Bearer $HEDYAPIKEY {BASE_URL}/highlights?limit=20 | jq
查询参数:
注意:此端点仅返回最近的 limit 条重点内容。没有基于游标的分页。要检索更多重点内容,请增加 limit 值(最大 100)。
响应:
json
{
success: true,
data: [
{
highlightId: high_123,
sessionId: sess_456,
timestamp: 2026-03-15T14:35:00Z,
title: 关键决策
}
],
pagination: { hasMore: false, next: null, total: 15 }
}
GET /highlights/{highlightId}
完整的重点内容详情。响应为裸 JSON 对象(无包装)。
bash
curl -s -H Authorization: Bearer $HEDYAPIKEY {BASE_URL}/highlights/{highlightId} | jq
响应:
json
{
highlightId: high_123,
sessionId: sess_456,
timestamp: 2026-03-15T14:35:00Z,
timeIndex: 300000,
title: 关于移动应用的关键决策,
rawQuote: 是的,我认为我们应该优先考虑移动应用,
cleanedQuote: 我们应该优先考虑移动应用,
mainIdea: 团队同意优先考虑移动应用开发,
aiInsight: 移动平台的战略优先级
}
GET /todos
所有会议中的所有待办事项。返回扁平数组(无分页包装)。
bash
curl -s -H Authorization: Bearer $HEDYAPIKEY {BASE_URL}/todos | jq
响应(数组元素):
json
{
id: uuid-1234,
text: 跟进 John,
dueDate: 明天,
sessionId: sess_123,
completed: false,
topic: { id: topic_1, name: 团队会议 }
}
GET /topics
列出所有主题(对话分组),按最后更新时间排序。响应包装在 { success, data } 中。无分页。
bash
curl -s -H Authorization: Bearer $HEDYAPIKEY {BASE_URL}/topics | jq
响应 data(数组元素):
json
{
id: