{"openapi":"3.1.0","info":{"title":"Grain (BYOK) API","version":"0.1.0","description":"Grain (BYOK) lets an AI assistant read your own Grain data through the Grain API with a key you supply (personal access token (or workspace access token)). Read-only: 7 tools (get_token_info, list_recordings, get_recording, get_recording_transcript, list_users, list_teams, list_meeting_types). The BYOK key travels with each request, is used for that one call only and is never stored, logged or...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-grain.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-grain/docs"},"termsOfService":"https://connectorbay.com/byok-grain/terms"},"servers":[{"url":"https://byok-grain.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-grain/docs"},"security":[{"upstreamKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."},"upstreamKey":{"type":"apiKey","in":"header","name":"X-Upstream-Key","description":"Your own key for the service this connector wraps (bring your own key). Used for that one call only; never stored, logged or cached."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/get_token_info":{"post":{"operationId":"get_token_info","summary":"Show what the Grain token is: its type (personal, workspace or OAuth), scope, owner name and expiry date. Use for \"Which","description":"Show what the Grain token is: its type (personal, workspace or OAuth), scope, owner name and expiry date. Use for \"Which Grain account is my token for and does it expire\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"get_token_infoArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_recordings":{"post":{"operationId":"list_recordings","summary":"List Grain recordings, newest first, with title, source, share state, dates, duration, teams, recorders and meeting type","description":"List Grain recordings, newest first, with title, source, share state, dates, duration, teams, recorders and meeting type. Filter by title, internal or external, hosted or attended, team or meeting type. Page with the cursor. Use for \"Which customer meetings did Grain record recently\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"title_search":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only recordings whose title matches this text.","title":"Title Search"},"participant_scope":{"anyOf":[{"enum":["internal","external"],"type":"string"},{"type":"null"}],"default":null,"description":"internal (team meetings) or external (customer meetings).","title":"Participant Scope"},"attendance":{"anyOf":[{"enum":["hosted","attended"],"type":"string"},{"type":"null"}],"default":null,"description":"Personal tokens only: hosted (you hosted) or attended (you were there).","title":"Attendance"},"team_id":{"anyOf":[{"maxLength":80,"type":"string"},{"type":"null"}],"default":null,"description":"Only recordings of this team (ID from list_teams).","title":"Team Id"},"meeting_type_id":{"anyOf":[{"maxLength":80,"type":"string"},{"type":"null"}],"default":null,"description":"Only recordings of this meeting type (ID from list_meeting_types).","title":"Meeting Type Id"},"include_participants":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True to include the participants of each recording (name, email, internal or external, attended).","title":"Include Participants"},"include_ai_summary":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True to include Grain's AI summary (markdown) of each recording.","title":"Include Ai Summary"},"include_ai_action_items":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True to include the AI action items of each recording.","title":"Include Ai Action Items"},"cursor":{"anyOf":[{"maxLength":500,"type":"string"},{"type":"null"}],"default":null,"description":"Cursor for the next page: the cursor from the previous answer. Leave out for the first page.","title":"Cursor"}},"title":"list_recordingsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_recording":{"post":{"operationId":"get_recording","summary":"Get one Grain recording with title, source, dates, duration, teams, recorders and optional participants, AI summary and ","description":"Get one Grain recording with title, source, dates, duration, teams, recorders and optional participants, AI summary and action items. Use for \"Summarize Grain recording pppp6666-qq77-rr88-ss99-tttt00000000\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"recording_id":{"description":"Recording ID as returned by list_recordings (id).","maxLength":80,"title":"Recording Id","type":"string"},"include_participants":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True to include the participants of each recording (name, email, internal or external, attended).","title":"Include Participants"},"include_ai_summary":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True to include Grain's AI summary (markdown) of each recording.","title":"Include Ai Summary"},"include_ai_action_items":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True to include the AI action items of each recording.","title":"Include Ai Action Items"}},"required":["recording_id"],"title":"get_recordingArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_recording_transcript":{"post":{"operationId":"get_recording_transcript","summary":"Get the transcript of a Grain recording as sections with speaker name, text and start and end time in milliseconds. Use ","description":"Get the transcript of a Grain recording as sections with speaker name, text and start and end time in milliseconds. Use for \"What was said in Grain recording pppp6666-qq77-rr88-ss99-tttt00000000\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"recording_id":{"description":"Recording ID as returned by list_recordings (id).","maxLength":80,"title":"Recording Id","type":"string"}},"required":["recording_id"],"title":"get_recording_transcriptArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_users":{"post":{"operationId":"list_users","summary":"List the users of the Grain workspace with ID, name and email. Use for \"Who is in our Grain workspace\".","description":"List the users of the Grain workspace with ID, name and email. Use for \"Who is in our Grain workspace\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"list_usersArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_teams":{"post":{"operationId":"list_teams","summary":"List the Grain teams with ID and name. Use for \"Which teams exist in Grain\".","description":"List the Grain teams with ID and name. Use for \"Which teams exist in Grain\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"list_teamsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_meeting_types":{"post":{"operationId":"list_meeting_types","summary":"List the Grain meeting types with ID, name and scope (internal or external). Use for \"What meeting types are set up in G","description":"List the Grain meeting types with ID, name and scope (internal or external). Use for \"What meeting types are set up in Grain\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"list_meeting_typesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}