驗證: 每個功能端點都需要標頭 X-API-Key: <your key>(值來自 .env)。
/health、/docs、/redoc 與 /openapi.json 為開放端點(不需金鑰)。
互動式文件由 FastAPI 自動產生:
| URL | 用途 |
|---|---|
/docs |
Swagger UI(線上試用) |
/redoc |
ReDoc 參考文件 |
/openapi.json |
機器可讀的 OpenAPI 3.1 規格 |
1. get_schedule — 列出研討會議程
GET /get_schedule?day=&track=&speaker=
查詢參數(皆為選填):
| 名稱 | 型別 | 說明 |
|---|---|---|
day |
string | 日期標籤 "Day 1" / "Day 2",或 ISO 日期 "2026-06-24" / "2026-06-25"。 |
track |
string | 主題軌的子字串,例如 "Leadership"、"Performance"、"Workshop"。 |
speaker |
string | 講者姓名的子字串,例如 "Ohtani" 或 "Kumamon"。 |
JSON Schema — 查詢參數(貼入 Perxona CallFunc › query params):
{
"type": "object",
"properties": {
"day": { "type": "string", "description": "Day label ('Day 1') or ISO date ('2026-06-24')." },
"track": { "type": "string", "description": "Track substring, e.g. 'Performance' or 'Workshop'." },
"speaker": { "type": "string", "description": "Speaker name substring, e.g. 'Ohtani'." }
}
}
範例
curl -s "$BASE/get_schedule?day=Day%201&track=Performance" -H "X-API-Key: $KEY"
{
"count": 1,
"sessions": [
{ "id": "s2", "title": "Full-Stack Athlete: How to Pitch AND Hit in the Same Sprint", "speaker": "Shohei Ohtani",
"track": "Performance", "room": "Room A", "day": "Day 1", "date": "2026-06-24",
"start": "2026-06-24T11:00", "end": "2026-06-24T11:45" }
]
}
輸出結構(貼入 Perxona CallFunc › Output data):
| 欄位 | 型別 | 說明 |
|---|---|---|
count |
integer | 回傳的議程數量。 |
sessions |
array of objects | 符合條件的議程;每個項目包含下列欄位。 |
sessions[].id |
string | 議程 id。 |
sessions[].title |
string | 議程標題。 |
sessions[].speaker |
string | 講者姓名。 |
sessions[].track |
string | 主題軌,例如 "Performance"。 |
sessions[].room |
string | 會議室名稱。 |
sessions[].day |
string | 日期標籤,例如 "Day 1"。 |
sessions[].date |
string | ISO 日期 YYYY-MM-DD。 |
sessions[].start |
string | 當地開始日期時間,ISO 8601(無時區偏移)。 |
sessions[].end |
string | 當地結束日期時間,ISO 8601(無時區偏移)。 |
{
"type": "object",
"properties": {
"count": { "type": "integer", "description": "Number of sessions returned." },
"sessions": {
"type": "array",
"description": "Matching sessions.",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "description": "Session id." },
"title": { "type": "string", "description": "Session title." },
"speaker": { "type": "string", "description": "Speaker name." },
"track": { "type": "string", "description": "Track, e.g. 'Performance'." },
"room": { "type": "string", "description": "Room name." },
"day": { "type": "string", "description": "Day label, e.g. 'Day 1'." },
"date": { "type": "string", "description": "ISO date YYYY-MM-DD." },
"start": { "type": "string", "description": "Local start datetime, ISO 8601 (no offset)." },
"end": { "type": "string", "description": "Local end datetime, ISO 8601 (no offset)." }
}
}
}
}
}
2. get_speaker — 查詢講者
GET /get_speaker?name=&id=
查詢參數(兩者皆為選填;兩者皆省略則列出所有人):
| 名稱 | 型別 | 說明 |
|---|---|---|
name |
string | 講者姓名的子字串(不分大小寫)。 |
id |
string | 確切的講者 id,例如 "spk_ohtani"。 |
JSON Schema — 查詢參數:
{
"type": "object",
"properties": {
"name": { "type": "string", "description": "Speaker name to search for (substring)." },
"id": { "type": "string", "description": "Exact speaker id, e.g. 'spk_ohtani'." }
}
}
範例
curl -s "$BASE/get_speaker?name=ohtani" -H "X-API-Key: $KEY"
{
"count": 1,
"speakers": [
{ "id": "spk_ohtani", "name": "Shohei Ohtani", "title": "Two-Way Player — Pitcher & Designated Hitter",
"company": "Los Angeles Dodgers", "bio": "The only engineer who is both the frontend AND the backend. Throws it at 100 mph, then hits it back even harder. Swears his real secret weapon is sleeping 10 hours a night — he calls it his cache layer.",
"topics": ["peak performance", "two-way ops", "discipline"],
"sessions": ["Full-Stack Athlete: How to Pitch AND Hit in the Same Sprint", "Batting Practice for Builders: Swinging at Every Pitch Life Throws"] }
]
}
輸出結構(貼入 Perxona CallFunc › Output data):
| 欄位 | 型別 | 說明 |
|---|---|---|
count |
integer | 回傳的講者數量。 |
speakers |
array of objects | 符合條件的講者;每個項目包含下列欄位。 |
speakers[].id |
string | 講者 id,例如 "spk_ohtani"。 |
speakers[].name |
string | 全名。 |
speakers[].title |
string | 職稱。 |
speakers[].company |
string | 公司/組織。 |
speakers[].bio |
string | 簡短自傳。 |
speakers[].topics |
array of strings | 講者涵蓋的主題。 |
speakers[].sessions |
array of strings | 此講者主講的議程標題。 |
{
"type": "object",
"properties": {
"count": { "type": "integer", "description": "Number of speakers returned." },
"speakers": {
"type": "array",
"description": "Matching speakers.",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "description": "Speaker id, e.g. 'spk_ohtani'." },
"name": { "type": "string", "description": "Full name." },
"title": { "type": "string", "description": "Job title." },
"company": { "type": "string", "description": "Company / organization." },
"bio": { "type": "string", "description": "Short biography." },
"topics": { "type": "array", "items": { "type": "string" }, "description": "Topics the speaker covers." },
"sessions": { "type": "array", "items": { "type": "string" }, "description": "Titles of sessions this speaker presents." }
}
}
}
}
}
3. book_meeting — 預約與講者的一對一會議(→ Google Calendar)
POST /book_meeting
Content-Type: application/json
請求內容
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
attendee_name |
string | ✓ | 提出會議申請的人。 |
speaker |
string | ✓ | 欲會面的講者(參見 get_speaker),例如 "Shohei Ohtani" 或 "Tanjiro Kamado"。 |
date |
string | ✓ | YYYY-MM-DD,示範研討會通常為 2026-06-24 或 2026-06-25。 |
start_time |
string | ✓ | HH:MM(24 小時制),以伺服器時區解讀。 |
duration_minutes |
integer | – | 5–240,預設 30。 |
attendee_email |
string | – | 加入活動說明中。 |
topic |
string | – | 會議主題。 |
JSON Schema — payload(貼入 Perxona CallFunc › payload):
{
"type": "object",
"required": ["attendee_name", "speaker", "date", "start_time"],
"properties": {
"attendee_name": { "type": "string", "description": "Name of the person requesting the meeting." },
"speaker": { "type": "string", "description": "Name of the speaker to meet, e.g. 'Shohei Ohtani'." },
"date": { "type": "string", "description": "Meeting date, YYYY-MM-DD (for the demo, usually 2026-06-24 or 2026-06-25)." },
"start_time": { "type": "string", "description": "Local start time, 24h HH:MM." },
"duration_minutes": { "type": "integer", "minimum": 5, "maximum": 240, "default": 30 },
"attendee_email": { "type": "string", "description": "Optional attendee email." },
"topic": { "type": "string", "description": "Optional meeting topic." }
}
}
範例
curl -s -X POST "$BASE/book_meeting" \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"attendee_name":"Sam Patel","speaker":"Shohei Ohtani","date":"2026-06-24","start_time":"16:00","duration_minutes":30,"topic":"Peak performance Q&A"}'
{
"booking_id": "bk-1a2b3c4d5e",
"status": "confirmed",
"mode": "google_calendar",
"summary": "1:1: Sam Patel ↔ Shohei Ohtani — Peak performance Q&A",
"speaker": "Shohei Ohtani",
"start": "2026-06-24T16:00:00+08:00",
"end": "2026-06-24T16:30:00+08:00",
"timezone": "Asia/Taipei",
"event_link": "https://www.google.com/calendar/event?eid=…",
"message": "Meeting confirmed and added to the calendar for 2026-06-24 16:00."
}
輸出結構(貼入 Perxona CallFunc › Output data):
| 欄位 | 型別 | 說明 |
|---|---|---|
booking_id |
string | 唯一的預約 id,例如 "bk-1a2b3c4d5e"。 |
status |
string | 成功時恆為 "confirmed"。 |
mode |
string | 若寫入真實行事曆則為 "google_calendar",否則為 "mock"。 |
summary |
string | 活動標題。 |
speaker |
string | 解析後的講者姓名。 |
start |
string | 活動開始時間,ISO 8601 含時區偏移。 |
end |
string | 活動結束時間,ISO 8601 含時區偏移。 |
timezone |
string | IANA 時區,例如 "Asia/Taipei"。 |
event_link |
string | null | Google Calendar 活動網址(mock 模式下為 null)。 |
message |
string | 人類可讀的確認訊息。 |
{
"type": "object",
"properties": {
"booking_id": { "type": "string", "description": "Unique booking id, e.g. 'bk-1a2b3c4d5e'." },
"status": { "type": "string", "description": "Always 'confirmed' on success." },
"mode": { "type": "string", "description": "'google_calendar' if written to a real calendar, else 'mock'." },
"summary": { "type": "string", "description": "Event title." },
"speaker": { "type": "string", "description": "Resolved speaker name." },
"start": { "type": "string", "description": "Event start, ISO 8601 with timezone offset." },
"end": { "type": "string", "description": "Event end, ISO 8601 with timezone offset." },
"timezone": { "type": "string", "description": "IANA timezone, e.g. 'Asia/Taipei'." },
"event_link": { "type": ["string", "null"], "description": "Google Calendar event URL (null in mock mode)." },
"message": { "type": "string", "description": "Human-readable confirmation message." }
}
}
錯誤
| 狀態碼 | 發生時機 |
|---|---|
401 |
缺少/無效的 X-API-Key。 |
422 |
date/start_time 格式錯誤,或缺少必填的請求內容欄位。 |
502 |
已設定 Google 但行事曆寫入失敗(含詳細資訊)。 |