{"openapi":"3.1.0","info":{"title":"Glyph API","version":"1.0.0","description":"Embed the Glyph voice tutor in your own software, keep conversations across calls, and receive transcripts when calls end. Authenticate with an API key: Authorization: Bearer glk_... Guides: /docs."},"servers":[{"url":"https://glyph.myapps.ai"}],"security":[{"apiKey":[]}],"tags":[{"name":"Embed player","description":"One call returns a URL that opens the full Glyph player."},{"name":"Conversations","description":"Threads that keep context across calls for one student."},{"name":"Sessions and transcripts","description":"Each call is a session. Transcripts land when it ends."},{"name":"Webhooks","description":"Get the transcript pushed to your server when a call ends."},{"name":"Accounts and credits","description":"Look up students, balances, and usage."}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"glk_...","description":"A personal key (one account) or an organization key (any account)."}}},"paths":{"/api/v1/embed-links":{"post":{"operationId":"create-embed-link","summary":"Open the player","description":"One call returns a player URL for a student. Show it two ways: mode \"embed\" (default) puts the full Glyph player in an iframe or a new tab; mode \"custom\" lets your page draw its own Glyph with the SDK at sdk_url while Glyph handles voice, tools, billing and transcripts. Give account_id and the student's latest conversation with your key continues, so Glyph remembers earlier calls. Pass conversation: \"new\" to start fresh, or conversation_id to pick one. Links are revocable and expire.\n\nMCP tool: `open_player`.","tags":["Embed player"],"responses":{"201":{"description":"Success","content":{"application/json":{"example":{"id":"emb_cCRsU8h1NK211Qe97JdHrQ","url":"https://glyph.example.com/portal?embed=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","conversation_id":"conv_fOl2E6E1-3caIeRZt8ZMuQ","account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","engine":"live","expires_at":"2026-10-05T08:11:41.000Z","revoked_at":null,"created_at":"2026-10-05T07:11:41.000Z","status":"active","mode":"custom","settings":{"input_mode":"vad","voice":"marin","language":"en","vad":{"type":"server_vad","threshold":0.6,"silence_ms":700}},"sdk_url":"https://glyph.example.com/sdk/glyph.js","how_to_use":"Load sdk_url in your page, call GlyphVoice.connect(url), then start() from a click and draw from the levels event."}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"account_id":{"description":"The student: account id (uuid) or access code like GLYP-G5D6-7XRW. Optional with a personal key.","example":"GLYP-G5D6-7XRW","type":"string"},"mode":{"description":"embed (default): the Glyph player in an iframe or tab. custom: your own UI, using the SDK at sdk_url.","type":"string","enum":["embed","custom"]},"settings":{"description":"Player settings: input_mode \"vad\" (hands-free) or \"ptt\" (push-to-talk); voice; language (\"\" auto, or \"en\", \"es\", ...); vad { type \"server_vad\" | \"semantic_vad\", threshold 0..1, silence_ms, prefix_padding_ms, eagerness, interrupt }; tools (which tools Glyph may use, [] for none); theme (orb color of the Glyph player). All optional; the SDK can change them live.","type":"object","additionalProperties":true},"conversation_id":{"description":"Play this conversation instead of the latest one.","type":"string"},"conversation":{"description":"With account_id: continue the latest conversation (default) or start a new one.","type":"string","enum":["latest","new"]},"title":{"description":"Title for a newly created conversation.","type":"string"},"engine":{"description":"Force an engine. Omit to let the student's plan decide.","type":"string","enum":["classic","live"]},"ttl_minutes":{"description":"Link lifetime, 1 to 1440. Default 60.","type":"integer"},"resume":{"description":"Seed the call with the conversation's last transcript. Default true.","type":"boolean"}},"required":[]},"example":{"account_id":"GLYP-G5D6-7XRW","mode":"custom","settings":{"input_mode":"vad","voice":"marin","language":"en","vad":{"type":"server_vad","threshold":0.6,"silence_ms":700}},"ttl_minutes":60}}}}},"get":{"operationId":"list-embed-links","summary":"List player links","description":"Links created with this key, newest first, with their status (active, expired, revoked).","tags":["Embed player"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"description":"1 to 100. Default 30.","type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"data":[{"id":"emb_cCRsU8h1NK211Qe97JdHrQ","url":"https://glyph.example.com/portal?embed=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","conversation_id":"conv_fOl2E6E1-3caIeRZt8ZMuQ","account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","engine":"live","expires_at":"2026-10-05T08:11:41.000Z","revoked_at":null,"created_at":"2026-10-05T07:11:41.000Z","status":"active"}]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/embed-links/{id}":{"delete":{"operationId":"revoke-embed-link","summary":"Revoke a player link","description":"The player loses access within about 30 seconds. A call in progress is stopped at its next check.\n\nMCP tool: `revoke_player_link`.","tags":["Embed player"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"description":"The link id (emb_...).","example":"emb_cCRsU8h1NK211Qe97JdHrQ","type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"id":"emb_cCRsU8h1NK211Qe97JdHrQ","revoked":true}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/conversations":{"post":{"operationId":"create-conversation","summary":"Create a conversation","description":"A thread for one student. Every call in it is seeded with the previous call's transcript, so the tutor picks up where it left off.\n\nMCP tool: `create_conversation`.","tags":["Conversations"],"responses":{"201":{"description":"Success","content":{"application/json":{"example":{"id":"conv_fOl2E6E1-3caIeRZt8ZMuQ","account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","title":"French Revolution review","metadata":{"course":"HIST-201"},"last_session_id":null,"created_at":"2026-10-05T07:11:41.000Z","updated_at":"2026-10-05T07:14:22.000Z"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"account_id":{"description":"The student: account id (uuid) or access code like GLYP-G5D6-7XRW. Optional with a personal key.","example":"GLYP-G5D6-7XRW","type":"string"},"title":{"description":"Shown in lists. Filled from the student's first sentence when empty.","type":"string"},"metadata":{"description":"Your own data, up to 8 KB, returned with the conversation and in webhooks.","type":"object","additionalProperties":true}},"required":["account_id"]},"example":{"account_id":"GLYP-G5D6-7XRW","title":"French Revolution review","metadata":{"course":"HIST-201"}}}}}},"get":{"operationId":"list-conversations","summary":"List conversations","description":"Conversations created with this key, most recently active first.\n\nMCP tool: `list_conversations`.","tags":["Conversations"],"parameters":[{"name":"account_id","in":"query","required":false,"schema":{"description":"Only this student's conversations.","example":"GLYP-G5D6-7XRW","type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"description":"1 to 100. Default 30.","type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"data":[{"id":"conv_fOl2E6E1-3caIeRZt8ZMuQ","account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","title":"French Revolution review","metadata":{"course":"HIST-201"},"last_session_id":"live_8f2c1a7b3d9e","created_at":"2026-10-05T07:11:41.000Z","updated_at":"2026-10-05T07:14:22.000Z"}]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/conversations/{id}":{"get":{"operationId":"get-conversation","summary":"Get a conversation","description":"One conversation.","tags":["Conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"description":"conv_...","example":"conv_fOl2E6E1-3caIeRZt8ZMuQ","type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"id":"conv_fOl2E6E1-3caIeRZt8ZMuQ","account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","title":"French Revolution review","metadata":{"course":"HIST-201"},"last_session_id":"live_8f2c1a7b3d9e","created_at":"2026-10-05T07:11:41.000Z","updated_at":"2026-10-05T07:14:22.000Z"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/conversations/{id}/transcript":{"get":{"operationId":"conversation-transcript","summary":"Conversation transcript","description":"Every call in the conversation with its turns, oldest first.\n\nMCP tool: `get_conversation_transcript`.","tags":["Conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"description":"conv_...","example":"conv_fOl2E6E1-3caIeRZt8ZMuQ","type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"conversation_id":"conv_fOl2E6E1-3caIeRZt8ZMuQ","title":"French Revolution review","sessions":[{"session_id":"live_8f2c1a7b3d9e","conversation_id":"conv_fOl2E6E1-3caIeRZt8ZMuQ","engine":"live","status":"ended","complete":true,"transcript_note":null,"usage_seconds":91,"started_at":"2026-10-05T07:12:51.000Z","ended_at":"2026-10-05T07:14:22.000Z","close_reason":"user_stop","summary":null,"turns":[{"role":"user","text":"Can you quiz me on the French Revolution?","sequence":0},{"role":"assistant","text":"Of course. First question: what year was the storming of the Bastille?","sequence":1},{"role":"user","text":"1789.","sequence":2},{"role":"assistant","text":"Correct, July 14th, 1789. Next: who was king at the time?","sequence":3},{"role":"tool","text":"generate_image({\"prompt\":\"The storming of the Bastille, painted\"})","sequence":4,"tool":{"name":"generate_image","status":"called","arguments":{"prompt":"The storming of the Bastille, painted"}}},{"role":"tool","text":"generate_image result:\n{\"kind\":\"generated_image\",\"prompt\":\"The storming of the Bastille, painted\",\"imageUrl\":\"https://cdn.example.com/glyph/bastille.png\"}","sequence":5,"tool":{"name":"generate_image","status":"done","result":{"kind":"generated_image","prompt":"The storming of the Bastille, painted","imageUrl":"https://cdn.example.com/glyph/bastille.png"}},"images":[{"url":"https://cdn.example.com/glyph/bastille.png","source":"generated","prompt":"The storming of the Bastille, painted"}]}]}]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/conversations/{id}/sessions":{"get":{"operationId":"conversation-sessions","summary":"List calls in a conversation","description":"Sessions without their turns, oldest first.","tags":["Conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"description":"conv_...","example":"conv_fOl2E6E1-3caIeRZt8ZMuQ","type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"data":[{"id":"live_8f2c1a7b3d9e","conversation_id":"conv_fOl2E6E1-3caIeRZt8ZMuQ","account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","engine":"live","status":"ended","started_at":"2026-10-05T07:12:51.000Z","ended_at":"2026-10-05T07:14:22.000Z","close_reason":"user_stop","usage_seconds":91,"summary":null}]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}},"post":{"operationId":"mint-session","summary":"Start a raw Live session","description":"Advanced: for apps that run their own WebRTC client instead of the player. Send your SDP offer and get the answer. Live only, and only when the Glyph server meters Live usage itself (LIVE_DIRECTOR_ENABLED). Save turns with POST /sessions/{id}/turns so the transcript is not empty.","tags":["Sessions and transcripts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"description":"conv_...","example":"conv_fOl2E6E1-3caIeRZt8ZMuQ","type":"string"}}],"responses":{"201":{"description":"Success","content":{"application/json":{"example":{"session":{"id":"live_8f2c1a7b3d9e","conversation_id":"conv_fOl2E6E1-3caIeRZt8ZMuQ","account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","engine":"live","status":"active","started_at":"2026-10-05T07:12:51.000Z","ended_at":null,"close_reason":"user_stop","usage_seconds":null,"summary":null},"sdp":"v=0\r\n...","model":"gpt-live-1","voice":"marin","resumed_turns":4,"credits_remaining":4213}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sdp":{"description":"Your WebRTC SDP offer.","type":"string"},"engine":{"description":"Only live is supported here.","type":"string","enum":["live"]},"voice":{"description":"Voice name.","type":"string"},"instructions":{"description":"Replaces the default tutor instructions.","type":"string"},"tools":{"description":"Function tools your client will execute.","type":"array","items":{"type":"object","additionalProperties":true}},"resume":{"description":"Seed with the conversation's last transcript. Default true.","type":"boolean"}},"required":["sdp"]},"example":{"engine":"live","sdp":"v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\n..."}}}}}},"/api/v1/sessions/{id}/transcript":{"get":{"operationId":"session-transcript","summary":"Session transcript","description":"One call's turns. While the call runs you get the turns saved so far. About 20 seconds after it ends, complete becomes true and the transcript is final. transcript_note explains an empty transcript.\n\nMCP tool: `get_transcript`.","tags":["Sessions and transcripts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"description":"The session id from a conversation or webhook.","example":"live_8f2c1a7b3d9e","type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"session_id":"live_8f2c1a7b3d9e","conversation_id":"conv_fOl2E6E1-3caIeRZt8ZMuQ","engine":"live","status":"ended","complete":true,"transcript_note":null,"usage_seconds":91,"started_at":"2026-10-05T07:12:51.000Z","ended_at":"2026-10-05T07:14:22.000Z","close_reason":"user_stop","summary":null,"turns":[{"role":"user","text":"Can you quiz me on the French Revolution?","sequence":0},{"role":"assistant","text":"Of course. First question: what year was the storming of the Bastille?","sequence":1},{"role":"user","text":"1789.","sequence":2},{"role":"assistant","text":"Correct, July 14th, 1789. Next: who was king at the time?","sequence":3},{"role":"tool","text":"generate_image({\"prompt\":\"The storming of the Bastille, painted\"})","sequence":4,"tool":{"name":"generate_image","status":"called","arguments":{"prompt":"The storming of the Bastille, painted"}}},{"role":"tool","text":"generate_image result:\n{\"kind\":\"generated_image\",\"prompt\":\"The storming of the Bastille, painted\",\"imageUrl\":\"https://cdn.example.com/glyph/bastille.png\"}","sequence":5,"tool":{"name":"generate_image","status":"done","result":{"kind":"generated_image","prompt":"The storming of the Bastille, painted","imageUrl":"https://cdn.example.com/glyph/bastille.png"}},"images":[{"url":"https://cdn.example.com/glyph/bastille.png","source":"generated","prompt":"The storming of the Bastille, painted"}]}]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/sessions/{id}":{"get":{"operationId":"get-session","summary":"Get a session","description":"Status, engine, duration and billing of one call.","tags":["Sessions and transcripts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"description":"Session id.","example":"live_8f2c1a7b3d9e","type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"id":"live_8f2c1a7b3d9e","conversation_id":"conv_fOl2E6E1-3caIeRZt8ZMuQ","account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","engine":"live","status":"ended","started_at":"2026-10-05T07:12:51.000Z","ended_at":"2026-10-05T07:14:22.000Z","close_reason":"user_stop","usage_seconds":91,"summary":null}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/sessions/{id}/turns":{"post":{"operationId":"append-turns","summary":"Save turns for a raw session","description":"Raw sessions only (the player saves its own). Re-sending a turn with the same id updates its text.","tags":["Sessions and transcripts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"description":"Session id.","example":"live_8f2c1a7b3d9e","type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"stored":2,"history_enabled":true}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"turns":{"description":"[{ id, role: user|assistant, text, sequence }]","type":"array","items":{"type":"object","additionalProperties":true}}},"required":["turns"]},"example":{"turns":[{"id":"t1","role":"user","text":"Hi Glyph","sequence":0},{"id":"t2","role":"assistant","text":"Hi! What are we studying?","sequence":1}]}}}}}},"/api/v1/webhooks":{"post":{"operationId":"create-webhook","summary":"Register a webhook","description":"Glyph POSTs session.ended to this URL about 20 seconds after each call ends, with the full transcript. The secret signs every delivery and is only shown now. Failed deliveries retry for 24 hours.","tags":["Webhooks"],"responses":{"201":{"description":"Success","content":{"application/json":{"example":{"id":"wh_PcjXNE-oHoQrPdZknqY4RA","url":"https://your-app.example.com/hooks/glyph","events":["session.ended"],"active":true,"created_at":"2026-10-05T07:11:41.000Z","secret":"whsec_DR7T7dbtE5416I8eYgGllX-T_MUCw-8ABTgFZlgBeos"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"description":"https URL (http://localhost allowed for testing).","type":"string"},"events":{"description":"Default [\"session.ended\"].","type":"array","items":{"type":"string"}}},"required":["url"]},"example":{"url":"https://your-app.example.com/hooks/glyph","events":["session.ended"]}}}}},"get":{"operationId":"list-webhooks","summary":"List webhooks","description":"Webhooks registered with this key. Secrets are never shown again.","tags":["Webhooks"],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"data":[{"id":"wh_PcjXNE-oHoQrPdZknqY4RA","url":"https://your-app.example.com/hooks/glyph","events":["session.ended"],"active":true,"created_at":"2026-10-05T07:11:41.000Z"}]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/webhooks/{id}/test":{"post":{"operationId":"test-webhook","summary":"Send a test delivery","description":"Queues a sample session.ended (with test: true) so you can check your receiver and signature code.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"description":"wh_...","example":"wh_PcjXNE-oHoQrPdZknqY4RA","type":"string"}}],"responses":{"202":{"description":"Success","content":{"application/json":{"example":{"id":"dlv_Qm3aX0cGk2L9sVwUe1HbOg","event":"session.ended","attempts":0,"next_attempt_at":"2026-10-05T07:14:42.000Z","delivered_at":null,"last_status":null,"last_error":null,"created_at":"2026-10-05T07:14:42.000Z","status":"pending"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/webhooks/{id}/deliveries":{"get":{"operationId":"webhook-deliveries","summary":"Recent deliveries","description":"The last 50 deliveries with status codes and errors, for debugging your receiver.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"description":"wh_...","example":"wh_PcjXNE-oHoQrPdZknqY4RA","type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"description":"1 to 100. Default 50.","type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"data":[{"id":"dlv_Qm3aX0cGk2L9sVwUe1HbOg","event":"session.ended","attempts":1,"next_attempt_at":null,"delivered_at":"2026-10-05T07:14:43.000Z","last_status":200,"last_error":null,"created_at":"2026-10-05T07:14:42.000Z","status":"delivered"}]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/webhooks/{id}":{"delete":{"operationId":"delete-webhook","summary":"Delete a webhook","description":"Stops deliveries and discards any still queued.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"description":"wh_...","example":"wh_PcjXNE-oHoQrPdZknqY4RA","type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"id":"wh_PcjXNE-oHoQrPdZknqY4RA","deleted":true}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/me":{"get":{"operationId":"me","summary":"Check your key","description":"Which key is calling: its name and scope. A personal key also returns its account.","tags":["Accounts and credits"],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"client":{"id":"glc_9aV2kQ0pLx7Rm4TzYb1NcA","name":"Tutor app","key_prefix":"glk_Xy3k9Q","scope":"organization","account_id":null,"created_at":"2026-10-01T12:00:00.000Z","last_used_at":"2026-10-05T07:11:41.000Z","revoked_at":null}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/accounts/lookup":{"get":{"operationId":"lookup-account","summary":"Look up an access code","description":"Access code to account id. Every endpoint also accepts access codes directly, so this is optional.","tags":["Accounts and credits"],"parameters":[{"name":"access_code","in":"query","required":true,"schema":{"description":"For example GLYP-G5D6-7XRW.","example":"GLYP-G5D6-7XRW","type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","access_code":"GLYP-G5D6-7XRW","active":true}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/accounts/{account}/credits":{"get":{"operationId":"credits","summary":"Credits and plan","description":"Balance, plan, available engines and enabled features. One credit is one second of voice.\n\nMCP tool: `get_credits`.","tags":["Accounts and credits"],"parameters":[{"name":"account","in":"path","required":true,"schema":{"description":"Account id, access code, or me (personal keys).","example":"GLYP-G5D6-7XRW","type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","access_code":"GLYP-G5D6-7XRW","plan":"ultra","plan_name":"Ultra","credits_remaining":19808,"credits_limit":20000,"next_credit_reset_at":"2026-11-01","credits_per_second":1,"engines":["classic","live"],"default_engine":"classic","features":{"direct_image_input":true,"session_history":true,"course_library":true}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/accounts/{account}/usage":{"get":{"operationId":"usage","summary":"Usage summary","description":"Credits used, voice minutes (Classic and Live), number of calls, a day-by-day series and a breakdown by feature for the last 7, 30, 90 or 365 days. Days are UTC. credits_added counts monthly refills and grants.\n\nMCP tool: `get_usage`.","tags":["Accounts and credits"],"parameters":[{"name":"account","in":"path","required":true,"schema":{"description":"Account id, access code, or me (personal keys).","example":"GLYP-G5D6-7XRW","type":"string"}},{"name":"days","in":"query","required":false,"schema":{"description":"7, 30 (default), 90 or 365.","type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","days":30,"from":"2026-09-10","to":"2026-10-09","totals":{"credits_used":1847,"credits_added":0,"voice_seconds":1722,"classic_seconds":640,"live_seconds":1082,"calls":14},"daily":[{"date":"2026-10-08","credits":412,"voice_seconds":377},{"date":"2026-10-09","credits":96,"voice_seconds":91}],"by_feature":[{"feature":"live_voice","label":"Live voice","credits":1082,"voice_seconds":1082,"charges":41},{"feature":"classic_voice","label":"Classic voice","credits":640,"voice_seconds":640,"charges":9},{"feature":"library_search","label":"Course library search","credits":75,"voice_seconds":0,"charges":5}]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}},"/api/v1/accounts/{account}/ledger":{"get":{"operationId":"ledger","summary":"Credit transactions","description":"Every charge with the balance before and after, newest first. Voice charges include seconds_spent.\n\nMCP tool: `get_ledger`.","tags":["Accounts and credits"],"parameters":[{"name":"account","in":"path","required":true,"schema":{"description":"Account id, access code, or me (personal keys).","example":"GLYP-G5D6-7XRW","type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"description":"1 to 100. Default 60.","type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"account_id":"3f6c2a8e-1b4d-4c7a-9e2f-5a8b7c6d4e3f","credits_remaining":19808,"credits_limit":20000,"transactions":[{"id":"298","route":"/api/live/bill","credits_charged":7,"credits_before":19815,"credits_after":19808,"tokens_input":7,"tokens_output":0,"tokens_total":7,"seconds_spent":7,"created_at":"2026-10-05T16:32:57.814Z"}]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Conversation not found."}},"required":["code","message"]}}}}}}}}}}}