openapi: 3.0.1 info: title: Plain GraphQL API description: >- Plain is an API-first customer support platform exposing a single GraphQL endpoint over HTTP. This OpenAPI document models the GraphQL-over-HTTP transport: a single POST /graphql/v1 operation that accepts a GraphQL `query` (or mutation) and optional `variables`, authenticated with a Bearer API key. The full operation surface (customers, threads, timeline, messages, labels, tiers, webhooks) is defined by the GraphQL schema, not by REST paths - see graphql/plain-support-schema.graphql. termsOfService: https://www.plain.com/legal/terms-of-service contact: name: Plain Support url: https://www.plain.com/docs version: 'v1' servers: - url: https://core-api.uk.plain.com description: Plain core API (UK region) paths: /graphql/v1: post: operationId: executeGraphQL tags: - GraphQL summary: Execute a GraphQL query or mutation description: >- Executes a single GraphQL operation against Plain's API. The request body carries a GraphQL `query` string (which may contain a query or a mutation), an optional `variables` object, and an optional `operationName`. Mutations return their result and a typed `error` field in the GraphQL response data; transport- and schema-level problems are returned in the top-level `errors` array. Always returns HTTP 200 for well-formed GraphQL requests, including those whose operation produced a GraphQL error. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GraphQLRequest' examples: upsertCustomer: summary: Upsert a customer value: query: >- mutation upsertCustomer($input: UpsertCustomerInput!) { upsertCustomer(input: $input) { result customer { id fullName } error { message type code } } } variables: input: identifier: emailAddress: ada@example.com onCreate: fullName: Ada Lovelace email: email: ada@example.com isVerified: true onUpdate: fullName: value: Ada Lovelace createThread: summary: Create a thread value: query: >- mutation createThread($input: CreateThreadInput!) { createThread(input: $input) { thread { id title status } error { message type code } } } variables: input: customerIdentifier: emailAddress: ada@example.com title: Cannot reset password components: - componentText: text: I am locked out of my account. replyToThread: summary: Reply to a thread value: query: >- mutation replyToThread($input: ReplyToThreadInput!) { replyToThread(input: $input) { thread { id } error { message type code } } } variables: input: threadId: th_01HXXXXXXXXXXXXXXXXXXXXXXX textContent: We have sent you a password reset link. responses: '200': description: >- A GraphQL response. `data` holds the result of the operation; `errors` holds any transport- or schema-level errors. Note that mutation-level (business) errors are returned inside `data` on the operation's typed `error` field, not in top-level `errors`. content: application/json: schema: $ref: '#/components/schemas/GraphQLResponse' '400': description: Malformed request (invalid JSON or missing query). content: application/json: schema: $ref: '#/components/schemas/GraphQLResponse' '401': description: Missing or invalid API key. '403': description: API key lacks a required fine-grained permission. '429': description: Rate limit exceeded. components: securitySchemes: bearerAuth: type: http scheme: bearer description: >- Plain API key issued to a Machine User, sent as a Bearer token: `Authorization: Bearer plainApiKey_xxx`. schemas: GraphQLRequest: type: object required: - query properties: query: type: string description: The GraphQL query or mutation document. operationName: type: string nullable: true description: Name of the operation to run when the document defines several. variables: type: object nullable: true additionalProperties: true description: Key/value map of variables referenced by the query. GraphQLResponse: type: object properties: data: type: object nullable: true additionalProperties: true description: The data returned by the executed operation. errors: type: array nullable: true description: Transport- or schema-level GraphQL errors. items: $ref: '#/components/schemas/GraphQLError' extensions: type: object nullable: true additionalProperties: true GraphQLError: type: object properties: message: type: string path: type: array items: type: string locations: type: array items: type: object properties: line: type: integer column: type: integer extensions: type: object additionalProperties: true