Plain Webhooks API

Create, fetch, update, and delete webhook targets, choose which event types to subscribe to, and inspect delivery attempts to drive outbound integrations off thread and customer events.

OpenAPI Specification

plain-support-openapi.yml Raw ↑
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