{"openapi":"3.1.0","info":{"title":"Plain (BYOK) API","version":"0.1.0","description":"Plain (BYOK) lets an AI assistant read your own Plain data through the Plain API with a key you supply (Plain API key (machine user key, plainApiKey_...)). Read-only: 10 tools (get_workspace, list_open_threads, list_done_threads, get_thread, search_threads, list_label_types, list_tiers, list_tenants, list_help_centers, list_knowledge_gaps). The BYOK key travels with each request, is used for that...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-plain.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-plain/docs"},"termsOfService":"https://connectorbay.com/byok-plain/terms"},"servers":[{"url":"https://byok-plain.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-plain/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_workspace":{"post":{"operationId":"get_workspace","summary":"Show the Plain workspace the API key belongs to: id, name, public name and creation time. Use for \"Which Plain workspace","description":"Show the Plain workspace the API key belongs to: id, name, public name and creation time. Use for \"Which Plain workspace is my API key connected to\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"get_workspaceArguments","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_open_threads":{"post":{"operationId":"list_open_threads","summary":"List support threads that need the team's attention (status waiting for the team), newest first, with customer name, pri","description":"List support threads that need the team's attention (status waiting for the team), newest first, with customer name, priority, tier, tenant and labels. Needs the thread:read permission. One page per call. Use for \"Which Plain threads are waiting for us\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"first":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"First"},"after":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Cursor copied from pageInfo.endCursor of the previous answer to get the next page; leave empty for the first page.","title":"After"}},"title":"list_open_threadsArguments","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_done_threads":{"post":{"operationId":"list_done_threads","summary":"List support threads the team has finished with (status done), newest first, with customer name, priority, tier, tenant ","description":"List support threads the team has finished with (status done), newest first, with customer name, priority, tier, tenant and labels. Needs the thread:read permission. One page per call. Use for \"Which Plain threads were recently completed\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"first":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"First"},"after":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Cursor copied from pageInfo.endCursor of the previous answer to get the next page; leave empty for the first page.","title":"After"}},"title":"list_done_threadsArguments","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_thread":{"post":{"operationId":"get_thread","summary":"Get one thread by id with status, priority, customer, tier, tenant, labels, first and last message times. Use for \"Show ","description":"Get one thread by id with status, priority, customer, tier, tenant, labels, first and last message times. Use for \"Show me Plain thread th_01H8XYZ\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"thread_id":{"description":"Thread id (starts with th_), taken from list_open_threads.","maxLength":60,"title":"Thread Id","type":"string"}},"required":["thread_id"],"title":"get_threadArguments","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/search_threads":{"post":{"operationId":"search_threads","summary":"Full-text search across thread titles, descriptions and message contents. Needs the thread:read permission. One page per","description":"Full-text search across thread titles, descriptions and message contents. Needs the thread:read permission. One page per call. Use for \"Find Plain threads that mention invoices\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"term":{"description":"Text to search for.","maxLength":200,"title":"Term","type":"string"},"first":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"First"},"after":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Cursor copied from pageInfo.endCursor of the previous answer to get the next page; leave empty for the first page.","title":"After"}},"required":["term"],"title":"search_threadsArguments","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_label_types":{"post":{"operationId":"list_label_types","summary":"List the label types (tags) available for threads with colour, description and archived flag. Use for \"Which thread labe","description":"List the label types (tags) available for threads with colour, description and archived flag. Use for \"Which thread labels exist in Plain\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"first":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"First"},"after":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Cursor copied from pageInfo.endCursor of the previous answer to get the next page; leave empty for the first page.","title":"After"}},"title":"list_label_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}},"/v1/tools/list_tiers":{"post":{"operationId":"list_tiers","summary":"List the customer tiers with default thread priority and whether each is the default tier. Use for \"Which support tiers ","description":"List the customer tiers with default thread priority and whether each is the default tier. Use for \"Which support tiers exist in Plain\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"first":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"First"},"after":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Cursor copied from pageInfo.endCursor of the previous answer to get the next page; leave empty for the first page.","title":"After"}},"title":"list_tiersArguments","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_tenants":{"post":{"operationId":"list_tenants","summary":"List tenants (customer organisations) with domain, external id and tier. Use for \"Which tenants does Plain know about\".","description":"List tenants (customer organisations) with domain, external id and tier. Use for \"Which tenants does Plain know about\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"first":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"First"},"after":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Cursor copied from pageInfo.endCursor of the previous answer to get the next page; leave empty for the first page.","title":"After"}},"title":"list_tenantsArguments","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_help_centers":{"post":{"operationId":"list_help_centers","summary":"List the help centers with public and internal name, type and publication time. Use for \"Which help centers are set up i","description":"List the help centers with public and internal name, type and publication time. Use for \"Which help centers are set up in Plain\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"first":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"First"},"after":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Cursor copied from pageInfo.endCursor of the previous answer to get the next page; leave empty for the first page.","title":"After"}},"title":"list_help_centersArguments","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_knowledge_gaps":{"post":{"operationId":"list_knowledge_gaps","summary":"List knowledge gaps (topics customers asked about that the documentation does not cover) with title, description and las","description":"List knowledge gaps (topics customers asked about that the documentation does not cover) with title, description and last seen time. Use for \"What knowledge gaps has Plain found\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"first":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"First"},"after":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Cursor copied from pageInfo.endCursor of the previous answer to get the next page; leave empty for the first page.","title":"After"}},"title":"list_knowledge_gapsArguments","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}}}}