{
  "components": {
    "schemas": {
      "Customer": {
        "description": "A customer: a company in Instant that the integrator created.",
        "properties": {
          "id": {
            "description": "The customer's id.",
            "format": "uuid",
            "type": "string"
          },
          "reference": {
            "description": "The integrator's own reference for the customer.",
            "type": "string"
          },
          "status": {
            "description": "paused while the integrator has paused the customer.",
            "enum": [
              "active",
              "paused"
            ],
            "type": "string"
          },
          "country": {
            "description": "The customer's ISO 3166-1 alpha-2 country code, in capitals, or null when none is recorded.",
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "description": "When the customer was created. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
            "format": "date-time",
            "type": "string"
          },
          "pausedAt": {
            "anyOf": [
              {
                "description": "When the customer was paused, or null while it is active. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "reference",
          "status",
          "country",
          "createdAt",
          "pausedAt"
        ],
        "type": "object"
      },
      "Delivery": {
        "description": "One webhook delivery, never a secret or a URL. Deliveries are kept 30 days.",
        "properties": {
          "id": {
            "description": "The delivery's id, which is its payload's id and Instant-Event-Id.",
            "format": "uuid",
            "type": "string"
          },
          "kind": {
            "enum": [
              "reply.ready",
              "run.finished",
              "approval.due",
              "task.input_needed",
              "ping.raised",
              "browser.takeover_needed",
              "connection.expired",
              "customer.paused",
              "customer.resumed",
              "connection.synced",
              "link.finished",
              "docs.updated"
            ],
            "type": "string"
          },
          "customerId": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The customer it is about, or null for docs.updated."
          },
          "customerReference": {
            "description": "The integrator's reference for the customer, or null for docs.updated.",
            "type": [
              "string",
              "null"
            ]
          },
          "memberId": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The member it is for, or null for connection.expired, connection.synced, link.finished, customer.paused, customer.resumed and docs.updated."
          },
          "item": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WebhookItem"
              },
              {
                "type": "null"
              }
            ],
            "description": "What it is about, or null for docs.updated."
          },
          "status": {
            "description": "pending until a receiver answers 2xx (delivered), or until the 7th attempt fails, the webhook is removed or 30 days pass (failed).",
            "enum": [
              "pending",
              "delivered",
              "failed"
            ],
            "type": "string"
          },
          "attempts": {
            "description": "How many attempts were made, at most 7.",
            "maximum": 9007199254740991,
            "minimum": 0,
            "type": "integer"
          },
          "lastError": {
            "anyOf": [
              {
                "pattern": "^(http_[0-9]{3}|timeout|network|redirect|url_refused|webhook_removed|expired)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the last attempt failed: http_<status>, timeout, network, redirect, url_refused, webhook_removed or expired; null when none did."
          },
          "createdAt": {
            "description": "When the delivery was created. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
            "format": "date-time",
            "type": "string"
          },
          "deliveredAt": {
            "anyOf": [
              {
                "description": "When a receiver answered 2xx, or null. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "nextAttemptAt": {
            "anyOf": [
              {
                "description": "When the next attempt is due while pending; otherwise null. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "kind",
          "customerId",
          "customerReference",
          "memberId",
          "item",
          "status",
          "attempts",
          "lastError",
          "createdAt",
          "deliveredAt",
          "nextAttemptAt"
        ],
        "type": "object"
      },
      "DocsUpdatedPayload": {
        "description": "What a docs.updated delivery posts: the docs that changed, each with its new version and where to fetch it. It concerns no customer. At most 2048 bytes.",
        "properties": {
          "id": {
            "description": "The event's id, the same on every attempt and in Instant-Event-Id: deduplicate on it.",
            "format": "uuid",
            "type": "string"
          },
          "kind": {
            "const": "docs.updated",
            "description": "docs.updated, also in Instant-Event-Kind.",
            "type": "string"
          },
          "occurredAt": {
            "description": "When Instant announced the change. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
            "format": "date-time",
            "type": "string"
          },
          "changed": {
            "description": "Each part that changed: one to four, and no api and doc twice.",
            "items": {
              "properties": {
                "api": {
                  "description": "Whose docs: integrator for this API's, customer for the customer API's.",
                  "enum": [
                    "integrator",
                    "customer"
                  ],
                  "type": "string"
                },
                "doc": {
                  "description": "openapi for the OpenAPI reference, guide for the guide.",
                  "enum": [
                    "openapi",
                    "guide"
                  ],
                  "type": "string"
                },
                "version": {
                  "description": "The part's new version: the SHA-256 of the file in hex, which is its ETag without the quotes.",
                  "pattern": "^[0-9a-f]{64}$",
                  "type": "string"
                },
                "url": {
                  "description": "Where to fetch it with the integrator credential: readOpenApi or readGuide, with api=customer for the customer API's.",
                  "type": "string"
                }
              },
              "required": [
                "api",
                "doc",
                "version",
                "url"
              ],
              "type": "object"
            },
            "maxItems": 4,
            "minItems": 1,
            "type": "array"
          }
        },
        "required": [
          "id",
          "kind",
          "occurredAt",
          "changed"
        ],
        "type": "object"
      },
      "Entity": {
        "description": "One of a customer's legal entities.",
        "properties": {
          "id": {
            "description": "The entity's id, which a selected entity access names.",
            "format": "uuid",
            "type": "string"
          },
          "name": {
            "description": "The entity's name.",
            "type": "string"
          },
          "legalName": {
            "description": "Its legal name, or null when it is not known.",
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "description": "Its ISO 3166-1 alpha-2 country code.",
            "type": "string"
          },
          "legalForm": {
            "description": "Its legal form, such as ApS, or null when it is not known.",
            "type": [
              "string",
              "null"
            ]
          },
          "functionalCurrency": {
            "description": "The ISO 4217 code of the currency its books are kept in.",
            "type": "string"
          },
          "status": {
            "description": "archived once the entity is archived; it stays in the list.",
            "enum": [
              "active",
              "archived"
            ],
            "type": "string"
          },
          "createdAt": {
            "description": "When the entity was created. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "legalName",
          "country",
          "legalForm",
          "functionalCurrency",
          "status",
          "createdAt"
        ],
        "type": "object"
      },
      "EntityAccess": {
        "description": "Which of the customer's entities the member works in: all of them, or a selection. An admin always has all. A deactivated member shows the selection that reactivating them restores.",
        "oneOf": [
          {
            "properties": {
              "mode": {
                "const": "all",
                "type": "string"
              }
            },
            "required": [
              "mode"
            ],
            "type": "object"
          },
          {
            "properties": {
              "mode": {
                "const": "selected",
                "type": "string"
              },
              "entityIds": {
                "description": "The entity ids of the selection, sorted.",
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "type": "array"
              }
            },
            "required": [
              "mode",
              "entityIds"
            ],
            "type": "object"
          }
        ]
      },
      "Error": {
        "description": "Every answer that is not a success.",
        "properties": {
          "error": {
            "description": "Instant's sentence for people. A 4xx keeps the refusal's own sentence; a 5xx always says \"Instant is temporarily unavailable. Please try again shortly.\"",
            "type": "string"
          },
          "code": {
            "description": "Stable, and what a caller branches on: VALIDATION_ERROR (400), UNAUTHENTICATED (401), FORBIDDEN (403), NOT_FOUND (404), CONFLICT (409), LIMIT_EXCEEDED (413), UNSUPPORTED_MEDIA_TYPE (415), UNREADABLE_FILE (422), RATE_LIMITED (429) and UNAVAILABLE (5xx). More codes may be added; treat one you do not know by its status.",
            "examples": [
              "VALIDATION_ERROR",
              "UNAUTHENTICATED",
              "FORBIDDEN",
              "NOT_FOUND",
              "CONFLICT",
              "LIMIT_EXCEEDED",
              "UNSUPPORTED_MEDIA_TYPE",
              "UNREADABLE_FILE",
              "RATE_LIMITED",
              "UNAVAILABLE"
            ],
            "type": "string"
          },
          "retryAfter": {
            "description": "Seconds to wait before retrying, also sent as the `Retry-After` header. Present only when there is a wait, as on a 429.",
            "maximum": 9007199254740991,
            "minimum": 1,
            "type": "integer"
          },
          "existingId": {
            "description": "On a 409 that names the object already there, such as a customer with that reference: its id.",
            "format": "uuid",
            "type": "string"
          }
        },
        "required": [
          "error",
          "code"
        ],
        "type": "object"
      },
      "IssuedMemberToken": {
        "description": "The token just issued.",
        "properties": {
          "id": {
            "description": "The token's id.",
            "format": "uuid",
            "type": "string"
          },
          "hint": {
            "description": "The secret's prefix, … and its last four hex characters, to tell tokens apart.",
            "pattern": "^[a-z]+_m_…[0-9a-f]{4}$",
            "type": "string"
          },
          "createdAt": {
            "description": "When the token was issued. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
            "format": "date-time",
            "type": "string"
          },
          "expiresAt": {
            "anyOf": [
              {
                "description": "When the token stops working, or null when it works until it is revoked. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "hint",
          "createdAt",
          "expiresAt"
        ],
        "type": "object"
      },
      "Member": {
        "description": "A person in a customer, with a role and entity access.",
        "properties": {
          "id": {
            "description": "The member's id.",
            "format": "uuid",
            "type": "string"
          },
          "reference": {
            "description": "The integrator's own reference for the member, unique across all its customers.",
            "type": "string"
          },
          "name": {
            "description": "The member's name.",
            "type": "string"
          },
          "role": {
            "description": "admin manages the company and sees every entity, user works within their entities, auditor reads.",
            "enum": [
              "admin",
              "user",
              "auditor"
            ],
            "type": "string"
          },
          "owner": {
            "description": "True for the one member who owns the customer.",
            "type": "boolean"
          },
          "language": {
            "description": "The member's language: one of the language values the requests take, or null when none is set.",
            "type": [
              "string",
              "null"
            ]
          },
          "timezone": {
            "description": "The member's IANA time zone, or null when none is set.",
            "type": [
              "string",
              "null"
            ]
          },
          "active": {
            "description": "False while the member is deactivated.",
            "type": "boolean"
          },
          "joinedAt": {
            "description": "When the member joined the customer. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
            "format": "date-time",
            "type": "string"
          },
          "deactivatedAt": {
            "anyOf": [
              {
                "description": "When the member was deactivated, or null while active. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "entityAccess": {
            "$ref": "#/components/schemas/EntityAccess"
          },
          "tokens": {
            "properties": {
              "active": {
                "description": "How many of the member's tokens are active and unexpired, at most 20.",
                "maximum": 9007199254740991,
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "active"
            ],
            "type": "object"
          }
        },
        "required": [
          "id",
          "reference",
          "name",
          "role",
          "owner",
          "language",
          "timezone",
          "active",
          "joinedAt",
          "deactivatedAt",
          "entityAccess",
          "tokens"
        ],
        "type": "object"
      },
      "MemberToken": {
        "description": "A member token, never its secret.",
        "properties": {
          "id": {
            "description": "The token's id.",
            "format": "uuid",
            "type": "string"
          },
          "hint": {
            "description": "The secret's prefix, … and its last four hex characters, to tell tokens apart.",
            "pattern": "^[a-z]+_m_…[0-9a-f]{4}$",
            "type": "string"
          },
          "status": {
            "description": "active until the token expires or is revoked; neither one works again.",
            "enum": [
              "active",
              "expired",
              "revoked"
            ],
            "type": "string"
          },
          "createdAt": {
            "description": "When the token was issued. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
            "format": "date-time",
            "type": "string"
          },
          "expiresAt": {
            "anyOf": [
              {
                "description": "When the token stops working, or null when it works until it is revoked. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "revokedAt": {
            "anyOf": [
              {
                "description": "When the token was revoked, or null. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "revokedReason": {
            "anyOf": [
              {
                "enum": [
                  "integrator",
                  "deactivated",
                  "operator"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why it was revoked: integrator through this API, deactivated when the member was deactivated, operator by the people running Instant. Null unless revoked."
          },
          "lastUsedAt": {
            "anyOf": [
              {
                "description": "When the token was last used, accurate to 5 minutes, or null when it never was. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "hint",
          "status",
          "createdAt",
          "expiresAt",
          "revokedAt",
          "revokedReason",
          "lastUsedAt"
        ],
        "type": "object"
      },
      "Webhook": {
        "description": "The integrator's webhook, never its secret.",
        "properties": {
          "url": {
            "description": "Where Instant posts the deliveries.",
            "type": "string"
          },
          "hint": {
            "description": "The signing secret's prefix, … and its last four hex characters.",
            "pattern": "^[a-z]+_w_…[0-9a-f]{4}$",
            "type": "string"
          },
          "setAt": {
            "description": "When the webhook was set, and its secret minted. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "url",
          "hint",
          "setAt"
        ],
        "type": "object"
      },
      "WebhookItem": {
        "anyOf": [
          {
            "properties": {
              "kind": {
                "const": "run",
                "type": "string"
              },
              "actionId": {
                "description": "The recurring action or background work.",
                "format": "uuid",
                "type": "string"
              },
              "runId": {
                "description": "The run.",
                "format": "uuid",
                "type": "string"
              }
            },
            "required": [
              "kind",
              "actionId",
              "runId"
            ],
            "type": "object"
          },
          {
            "properties": {
              "kind": {
                "enum": [
                  "approval",
                  "task",
                  "ping",
                  "document",
                  "partner",
                  "payment",
                  "thread",
                  "customer",
                  "bank_connection"
                ],
                "type": "string"
              },
              "id": {
                "description": "The subject's id; absent when it is not a UUID.",
                "format": "uuid",
                "type": "string"
              }
            },
            "required": [
              "kind"
            ],
            "type": "object"
          },
          {
            "properties": {
              "kind": {
                "const": "bank_connection",
                "type": "string"
              },
              "id": {
                "description": "The bank connection.",
                "format": "uuid",
                "type": "string"
              },
              "outcome": {
                "description": "connection.synced only: completed when every account was read (from the first day through yesterday for a backfill); failed when the consent ran out first, or a read asked for failed.",
                "enum": [
                  "completed",
                  "failed"
                ],
                "type": "string"
              }
            },
            "required": [
              "kind",
              "id",
              "outcome"
            ],
            "type": "object"
          },
          {
            "properties": {
              "kind": {
                "const": "bank_link",
                "type": "string"
              },
              "id": {
                "description": "The bank connection link.",
                "format": "uuid",
                "type": "string"
              },
              "outcome": {
                "description": "link.finished only: connected when the consent gave a connection; cancelled when the person cancelled; failed when the bank or its provider refused, or Instant could not complete the consent; expired when nobody opened the link in time, or its consent never came back.",
                "enum": [
                  "connected",
                  "cancelled",
                  "failed",
                  "expired"
                ],
                "type": "string"
              }
            },
            "required": [
              "kind",
              "id",
              "outcome"
            ],
            "type": "object"
          }
        ],
        "description": "What the event is about. Read it through the customer API, as the member."
      },
      "WebhookPayload": {
        "description": "What a delivery posts: ids and the integrator's own references, never a text, a title, a path, an amount or an approval code. At most 2048 bytes.",
        "properties": {
          "id": {
            "description": "The event's id, the same on every attempt and in Instant-Event-Id: deduplicate on it.",
            "format": "uuid",
            "type": "string"
          },
          "kind": {
            "description": "The kind, also in Instant-Event-Kind.",
            "enum": [
              "reply.ready",
              "run.finished",
              "approval.due",
              "task.input_needed",
              "ping.raised",
              "browser.takeover_needed",
              "connection.expired",
              "customer.paused",
              "customer.resumed",
              "connection.synced",
              "link.finished"
            ],
            "type": "string"
          },
          "occurredAt": {
            "description": "When it happened. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.",
            "format": "date-time",
            "type": "string"
          },
          "customerId": {
            "description": "The customer it is about.",
            "format": "uuid",
            "type": "string"
          },
          "customerReference": {
            "description": "The integrator's reference for the customer.",
            "maxLength": 200,
            "minLength": 1,
            "type": "string"
          },
          "memberId": {
            "description": "The member it is for; absent for connection.expired, connection.synced, link.finished, customer.paused and customer.resumed.",
            "format": "uuid",
            "type": "string"
          },
          "memberReference": {
            "description": "The integrator's reference for the member; absent when memberId is.",
            "maxLength": 200,
            "minLength": 1,
            "type": "string"
          },
          "item": {
            "$ref": "#/components/schemas/WebhookItem"
          },
          "pingId": {
            "description": "The notice that made it; only for approval.due, run.finished, task.input_needed and ping.raised.",
            "format": "uuid",
            "type": "string"
          }
        },
        "required": [
          "id",
          "kind",
          "occurredAt",
          "customerId",
          "customerReference",
          "item"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "integratorCredential": {
        "bearerFormat": "live_<100 hex>",
        "description": "`Authorization: Bearer <secret>`. A 401 answers `WWW-Authenticate: Bearer realm=\"instant-integrator-api\"`.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "externalDocs": {
    "url": "https://booksbyinstant.com/docs"
  },
  "info": {
    "description": "What an integrator's servers call to run their customers in Instant: the customers, their members and the members' tokens, the webhook Instant posts to, and the return URL. Every request carries the integrator's credential as `Authorization: Bearer <credential>`. Ids are UUIDs, matched in any case and answered in lower case; a path id that is not a UUID is the same 404 as an unknown one, and so is another integrator's object. Bodies are strict: a field a route does not take is 400. A route that takes a query is strict about it too; a route that takes none ignores one. Every answer but the docs' is `Cache-Control: no-store`; the docs answer `private, no-cache` with an ETag. A field may be added to an answer at any time, so ignore fields you do not know.",
    "title": "Instant integrator API",
    "version": "1"
  },
  "openapi": "3.1.0",
  "paths": {
    "/api/integrator/v1/customers": {
      "get": {
        "description": "The integrator's customers, newest first, a page at a time. Pages hold steady while customers are added. There is no last-use time per customer.",
        "operationId": "listCustomers",
        "parameters": [
          {
            "description": "How many to answer: a whole number from 1 to 200, without a leading zero.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "The nextCursor of the previous page.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "items": {
                      "items": {
                        "$ref": "#/components/schemas/Customer"
                      },
                      "type": "array"
                    },
                    "nextCursor": {
                      "anyOf": [
                        {
                          "format": "uuid",
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The cursor of the next page, or null on the last page."
                    }
                  },
                  "required": [
                    "items",
                    "nextCursor"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "A page of customers."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A query parameter is unknown or invalid."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "List customers",
        "tags": [
          "Customers"
        ]
      },
      "post": {
        "description": "A new customer and its first member, who owns it and is an admin. The member's first chat turn starts the company's setup conversation. Approvals need a second member: nobody approves their own submission, and every new customer has the default bill approval workflow, so a bill the only member posts waits until a second member approves it; the answer does not say so. A country without a setup of its own gets the general company setup.",
        "operationId": "createCustomer",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "reference": {
                    "description": "The integrator's own reference: 1 to 200 characters after spaces at either end are trimmed. Any other whitespace at an end (a tab, a newline, a no-break space) is refused, never trimmed.",
                    "maxLength": 1000,
                    "minLength": 1,
                    "type": "string"
                  },
                  "country": {
                    "description": "An assigned ISO 3166-1 alpha-2 code in capitals, such as DK (GB, not UK).",
                    "enum": [
                      "AD",
                      "AE",
                      "AF",
                      "AG",
                      "AI",
                      "AL",
                      "AM",
                      "AO",
                      "AQ",
                      "AR",
                      "AS",
                      "AT",
                      "AU",
                      "AW",
                      "AX",
                      "AZ",
                      "BA",
                      "BB",
                      "BD",
                      "BE",
                      "BF",
                      "BG",
                      "BH",
                      "BI",
                      "BJ",
                      "BL",
                      "BM",
                      "BN",
                      "BO",
                      "BQ",
                      "BR",
                      "BS",
                      "BT",
                      "BV",
                      "BW",
                      "BY",
                      "BZ",
                      "CA",
                      "CC",
                      "CD",
                      "CF",
                      "CG",
                      "CH",
                      "CI",
                      "CK",
                      "CL",
                      "CM",
                      "CN",
                      "CO",
                      "CR",
                      "CU",
                      "CV",
                      "CW",
                      "CX",
                      "CY",
                      "CZ",
                      "DE",
                      "DJ",
                      "DK",
                      "DM",
                      "DO",
                      "DZ",
                      "EC",
                      "EE",
                      "EG",
                      "EH",
                      "ER",
                      "ES",
                      "ET",
                      "FI",
                      "FJ",
                      "FK",
                      "FM",
                      "FO",
                      "FR",
                      "GA",
                      "GB",
                      "GD",
                      "GE",
                      "GF",
                      "GG",
                      "GH",
                      "GI",
                      "GL",
                      "GM",
                      "GN",
                      "GP",
                      "GQ",
                      "GR",
                      "GS",
                      "GT",
                      "GU",
                      "GW",
                      "GY",
                      "HK",
                      "HM",
                      "HN",
                      "HR",
                      "HT",
                      "HU",
                      "ID",
                      "IE",
                      "IL",
                      "IM",
                      "IN",
                      "IO",
                      "IQ",
                      "IR",
                      "IS",
                      "IT",
                      "JE",
                      "JM",
                      "JO",
                      "JP",
                      "KE",
                      "KG",
                      "KH",
                      "KI",
                      "KM",
                      "KN",
                      "KP",
                      "KR",
                      "KW",
                      "KY",
                      "KZ",
                      "LA",
                      "LB",
                      "LC",
                      "LI",
                      "LK",
                      "LR",
                      "LS",
                      "LT",
                      "LU",
                      "LV",
                      "LY",
                      "MA",
                      "MC",
                      "MD",
                      "ME",
                      "MF",
                      "MG",
                      "MH",
                      "MK",
                      "ML",
                      "MM",
                      "MN",
                      "MO",
                      "MP",
                      "MQ",
                      "MR",
                      "MS",
                      "MT",
                      "MU",
                      "MV",
                      "MW",
                      "MX",
                      "MY",
                      "MZ",
                      "NA",
                      "NC",
                      "NE",
                      "NF",
                      "NG",
                      "NI",
                      "NL",
                      "NO",
                      "NP",
                      "NR",
                      "NU",
                      "NZ",
                      "OM",
                      "PA",
                      "PE",
                      "PF",
                      "PG",
                      "PH",
                      "PK",
                      "PL",
                      "PM",
                      "PN",
                      "PR",
                      "PS",
                      "PT",
                      "PW",
                      "PY",
                      "QA",
                      "RE",
                      "RO",
                      "RS",
                      "RU",
                      "RW",
                      "SA",
                      "SB",
                      "SC",
                      "SD",
                      "SE",
                      "SG",
                      "SH",
                      "SI",
                      "SJ",
                      "SK",
                      "SL",
                      "SM",
                      "SN",
                      "SO",
                      "SR",
                      "SS",
                      "ST",
                      "SV",
                      "SX",
                      "SY",
                      "SZ",
                      "TC",
                      "TD",
                      "TF",
                      "TG",
                      "TH",
                      "TJ",
                      "TK",
                      "TL",
                      "TM",
                      "TN",
                      "TO",
                      "TR",
                      "TT",
                      "TV",
                      "TW",
                      "TZ",
                      "UA",
                      "UG",
                      "UM",
                      "US",
                      "UY",
                      "UZ",
                      "VA",
                      "VC",
                      "VE",
                      "VG",
                      "VI",
                      "VN",
                      "VU",
                      "WF",
                      "WS",
                      "YE",
                      "YT",
                      "ZA",
                      "ZM",
                      "ZW"
                    ],
                    "type": "string"
                  },
                  "member": {
                    "additionalProperties": false,
                    "properties": {
                      "reference": {
                        "description": "The integrator's own reference: 1 to 200 characters after spaces at either end are trimmed. Any other whitespace at an end (a tab, a newline, a no-break space) is refused, never trimmed.",
                        "maxLength": 1000,
                        "minLength": 1,
                        "type": "string"
                      },
                      "name": {
                        "description": "The member's name: 1 to 120 characters after leading and trailing whitespace is removed. With two or more words, the last is the last name.",
                        "minLength": 1,
                        "type": "string"
                      },
                      "language": {
                        "description": "One of Instant's languages.",
                        "enum": [
                          "en",
                          "de",
                          "sv",
                          "nb",
                          "da",
                          "fr",
                          "es",
                          "pl",
                          "pt-BR",
                          "it",
                          "hr",
                          "tr",
                          "he",
                          "ar",
                          "ro"
                        ],
                        "type": "string"
                      },
                      "timezone": {
                        "description": "An IANA time zone.",
                        "examples": [
                          "Europe/Copenhagen"
                        ],
                        "maxLength": 100,
                        "minLength": 1,
                        "type": "string"
                      }
                    },
                    "required": [
                      "reference",
                      "name",
                      "language"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "reference",
                  "country",
                  "member"
                ],
                "type": "object"
              }
            }
          },
          "description": "At most 4096 bytes.",
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customer": {
                      "$ref": "#/components/schemas/Customer"
                    },
                    "member": {
                      "$ref": "#/components/schemas/Member"
                    }
                  },
                  "required": [
                    "customer",
                    "member"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The customer and its member."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not one JSON object, or a field is invalid; `error` says which."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A customer with that reference already exists: the answer carries its `existingId`, so a retry after a lost answer finds what it created. Or a member with that reference already exists, and the answer has no id."
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is over 4096 bytes."
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not sent as `application/json`."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Create a customer",
        "tags": [
          "Customers"
        ]
      }
    },
    "/api/integrator/v1/customers/{id}": {
      "get": {
        "operationId": "readCustomer",
        "parameters": [
          {
            "description": "The customer's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customer": {
                      "$ref": "#/components/schemas/Customer"
                    },
                    "members": {
                      "items": {
                        "$ref": "#/components/schemas/Member"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "customer",
                    "members"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The customer and its members, oldest first."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`id` names nothing this caller can see."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Read a customer",
        "tags": [
          "Customers"
        ]
      },
      "patch": {
        "description": "`status` pauses or resumes the customer; the answer is the customer. While it is paused, Instant answers every message with a fixed sentence that the customer is paused, and runs no scheduled, background or event work; reads, decisions, uploads, connections and member changes work, and nothing is deleted. `customer.paused` or `customer.resumed` is posted to the webhook. `ownerMemberId` hands the ownership to that member and answers the customer with its members.",
        "operationId": "updateCustomer",
        "parameters": [
          {
            "description": "The customer's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "description": "Exactly one of status or ownerMemberId; both, or neither, is refused. status pauses or resumes the customer, and the same status again changes nothing. ownerMemberId hands the ownership to one of the customer's members, who must be an active admin.",
                "maxProperties": 1,
                "minProperties": 1,
                "properties": {
                  "status": {
                    "enum": [
                      "active",
                      "paused"
                    ],
                    "type": "string"
                  },
                  "ownerMemberId": {
                    "description": "The id of one of the customer's members, an active admin, who becomes its owner.",
                    "format": "uuid",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "description": "At most 4096 bytes.",
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customer": {
                      "$ref": "#/components/schemas/Customer"
                    },
                    "members": {
                      "description": "Only after an ownerMemberId handover.",
                      "items": {
                        "$ref": "#/components/schemas/Member"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "customer"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The customer; with its members after a handover."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not one JSON object, or a field is invalid; `error` says which. Also when the body has both `status` and `ownerMemberId`, or neither."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`id` names nothing this caller can see. Also when `ownerMemberId` names no member of the customer."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The new owner is not an active admin, or the company changed meanwhile: read it again."
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is over 4096 bytes."
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not sent as `application/json`."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Pause, resume or hand over a customer",
        "tags": [
          "Customers"
        ]
      }
    },
    "/api/integrator/v1/customers/{id}/entities": {
      "get": {
        "description": "The customer's legal entities, which a selected entity access names: oldest first, archived ones included, no paging. A new customer has none until its setup has made one.",
        "operationId": "listEntities",
        "parameters": [
          {
            "description": "The customer's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "entities": {
                      "items": {
                        "$ref": "#/components/schemas/Entity"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "entities"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The entities."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`id` names nothing this caller can see."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "List a customer's entities",
        "tags": [
          "Customers"
        ]
      }
    },
    "/api/integrator/v1/customers/{id}/members": {
      "get": {
        "operationId": "listMembers",
        "parameters": [
          {
            "description": "The customer's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "members": {
                      "items": {
                        "$ref": "#/components/schemas/Member"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "members"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The members, oldest first."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`id` names nothing this caller can see."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "List a customer's members",
        "tags": [
          "Members"
        ]
      },
      "post": {
        "description": "A member reference is unique across all the integrator's customers: a person in two customers is two members.",
        "operationId": "createMember",
        "parameters": [
          {
            "description": "The customer's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "description": "An admin has access to all entities, so role admin with a selection is refused, and a selection names entities of this customer only. A member can be added while the customer is paused.",
                "properties": {
                  "reference": {
                    "description": "The integrator's own reference: 1 to 200 characters after spaces at either end are trimmed. Any other whitespace at an end (a tab, a newline, a no-break space) is refused, never trimmed.",
                    "maxLength": 1000,
                    "minLength": 1,
                    "type": "string"
                  },
                  "name": {
                    "description": "The member's name: 1 to 120 characters after leading and trailing whitespace is removed. With two or more words, the last is the last name.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "role": {
                    "enum": [
                      "admin",
                      "user",
                      "auditor"
                    ],
                    "type": "string"
                  },
                  "language": {
                    "description": "One of Instant's languages.",
                    "enum": [
                      "en",
                      "de",
                      "sv",
                      "nb",
                      "da",
                      "fr",
                      "es",
                      "pl",
                      "pt-BR",
                      "it",
                      "hr",
                      "tr",
                      "he",
                      "ar",
                      "ro"
                    ],
                    "type": "string"
                  },
                  "timezone": {
                    "description": "An IANA time zone.",
                    "examples": [
                      "Europe/Copenhagen"
                    ],
                    "maxLength": 100,
                    "minLength": 1,
                    "type": "string"
                  },
                  "entityAccess": {
                    "description": "all: every entity of the customer, and it clears a selection. selected: the entities entityIds names.",
                    "oneOf": [
                      {
                        "additionalProperties": false,
                        "properties": {
                          "mode": {
                            "const": "all",
                            "type": "string"
                          }
                        },
                        "required": [
                          "mode"
                        ],
                        "type": "object"
                      },
                      {
                        "additionalProperties": false,
                        "properties": {
                          "mode": {
                            "const": "selected",
                            "type": "string"
                          },
                          "entityIds": {
                            "description": "Up to 500 of the customer's entity ids, each at most once: the same id in upper and lower case counts as twice. An empty selection reaches no entity until one is added, so a restricted member can be created before the customer has an entity.",
                            "items": {
                              "format": "uuid",
                              "type": "string"
                            },
                            "maxItems": 500,
                            "type": "array",
                            "uniqueItems": true
                          }
                        },
                        "required": [
                          "mode",
                          "entityIds"
                        ],
                        "type": "object"
                      }
                    ]
                  }
                },
                "required": [
                  "reference",
                  "name",
                  "role",
                  "language"
                ],
                "type": "object"
              }
            }
          },
          "description": "At most 32768 bytes.",
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "member": {
                      "$ref": "#/components/schemas/Member"
                    }
                  },
                  "required": [
                    "member"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The member."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not one JSON object, or a field is invalid; `error` says which. Also when `role` is admin with a selected entity access, or an entity id is not the customer's."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`id` names nothing this caller can see."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A member with that reference already exists in one of the integrator's customers; the answer has no id."
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is over 32768 bytes."
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not sent as `application/json`."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Add a member",
        "tags": [
          "Members"
        ]
      }
    },
    "/api/integrator/v1/customers/{id}/members/{memberId}": {
      "get": {
        "operationId": "readMember",
        "parameters": [
          {
            "description": "The customer's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The member's id.",
            "in": "path",
            "name": "memberId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "member": {
                      "$ref": "#/components/schemas/Member"
                    }
                  },
                  "required": [
                    "member"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The member."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`id` or `memberId` name nothing this caller can see."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Read a member",
        "tags": [
          "Members"
        ]
      },
      "patch": {
        "description": "A change of role or entity access takes effect on the member's next request; a chat turn already running ends. `active: false` deactivates the member and revokes their tokens for good; `active: true` reactivates them with their role and access, and new tokens must be issued.",
        "operationId": "updateMember",
        "parameters": [
          {
            "description": "The customer's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The member's id.",
            "in": "path",
            "name": "memberId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "description": "Send active alone (false deactivates the member, true reactivates them), or at least one of the other fields; the same values again change nothing. An admin has access to all entities, so role admin with a selection is refused, and a selection names entities of this customer only. A deactivated member's role and entity access change only after active: true; their name, language and time zone can still change. The owner stays an admin and is never deactivated, and the company keeps at least one admin.",
                "minProperties": 1,
                "properties": {
                  "name": {
                    "description": "The member's name: 1 to 120 characters after leading and trailing whitespace is removed. With two or more words, the last is the last name.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "language": {
                    "description": "One of Instant's languages.",
                    "enum": [
                      "en",
                      "de",
                      "sv",
                      "nb",
                      "da",
                      "fr",
                      "es",
                      "pl",
                      "pt-BR",
                      "it",
                      "hr",
                      "tr",
                      "he",
                      "ar",
                      "ro"
                    ],
                    "type": "string"
                  },
                  "timezone": {
                    "description": "An IANA time zone.",
                    "examples": [
                      "Europe/Copenhagen"
                    ],
                    "maxLength": 100,
                    "minLength": 1,
                    "type": "string"
                  },
                  "role": {
                    "enum": [
                      "admin",
                      "user",
                      "auditor"
                    ],
                    "type": "string"
                  },
                  "entityAccess": {
                    "description": "all: every entity of the customer, and it clears a selection. selected: the entities entityIds names.",
                    "oneOf": [
                      {
                        "additionalProperties": false,
                        "properties": {
                          "mode": {
                            "const": "all",
                            "type": "string"
                          }
                        },
                        "required": [
                          "mode"
                        ],
                        "type": "object"
                      },
                      {
                        "additionalProperties": false,
                        "properties": {
                          "mode": {
                            "const": "selected",
                            "type": "string"
                          },
                          "entityIds": {
                            "description": "Up to 500 of the customer's entity ids, each at most once: the same id in upper and lower case counts as twice. An empty selection reaches no entity until one is added, so a restricted member can be created before the customer has an entity.",
                            "items": {
                              "format": "uuid",
                              "type": "string"
                            },
                            "maxItems": 500,
                            "type": "array",
                            "uniqueItems": true
                          }
                        },
                        "required": [
                          "mode",
                          "entityIds"
                        ],
                        "type": "object"
                      }
                    ]
                  },
                  "active": {
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "description": "At most 32768 bytes.",
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "member": {
                      "$ref": "#/components/schemas/Member"
                    }
                  },
                  "required": [
                    "member"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The member."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not one JSON object, or a field is invalid; `error` says which. Also when `active` comes with another field, nothing is to change, `role` is admin with a selected entity access, or an entity id is not the customer's."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`id` or `memberId` name nothing this caller can see."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The member is deactivated and must be reactivated first; the owner would stop being an admin or be deactivated; the company would have no admin left; or it changed meanwhile."
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is over 32768 bytes."
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not sent as `application/json`."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Change, deactivate or reactivate a member",
        "tags": [
          "Members"
        ]
      }
    },
    "/api/integrator/v1/customers/{id}/members/{memberId}/tokens": {
      "get": {
        "description": "Revoked and expired tokens included; never a secret.",
        "operationId": "listMemberTokens",
        "parameters": [
          {
            "description": "The customer's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The member's id.",
            "in": "path",
            "name": "memberId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "tokens": {
                      "items": {
                        "$ref": "#/components/schemas/MemberToken"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "tokens"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The tokens, newest first."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`id` or `memberId` name nothing this caller can see."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "List a member's tokens",
        "tags": [
          "Member tokens"
        ]
      },
      "post": {
        "description": "Not idempotent: each call issues a new token. The secret is in this answer only. A token whose answer was lost is never shown again and counts toward the 20 until it is revoked or expires: list the member's tokens and revoke what nobody holds.",
        "operationId": "issueMemberToken",
        "parameters": [
          {
            "description": "The customer's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The member's id.",
            "in": "path",
            "name": "memberId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "description": "A JSON object, {} at least: a request without one is refused. A token is issued only to an active member, who has at most 20 active tokens.",
                "properties": {
                  "expiresAt": {
                    "description": "When the token stops working: an ISO 8601 date and time with its offset, such as 2027-01-31T12:00:00Z, in the future. Without one the token works until it is revoked.",
                    "format": "date-time",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "description": "At most 4096 bytes.",
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "token": {
                      "$ref": "#/components/schemas/IssuedMemberToken"
                    },
                    "secret": {
                      "description": "The member token, shown this once. Keep it on your servers, in a secret manager.",
                      "pattern": "^[a-z]+_m_[0-9a-f]{100}$",
                      "type": "string"
                    }
                  },
                  "required": [
                    "token",
                    "secret"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The token and its secret."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not one JSON object, or a field is invalid; `error` says which. Also when `expiresAt` is not in the future."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`id` or `memberId` name nothing this caller can see."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The member is deactivated, or already has 20 active tokens: revoke one first."
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is over 4096 bytes."
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not sent as `application/json`."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Issue a member token",
        "tags": [
          "Member tokens"
        ]
      }
    },
    "/api/integrator/v1/customers/{id}/members/{memberId}/tokens/{tokenId}": {
      "delete": {
        "description": "Revokes the token for good; it stays in the list with `status` revoked.",
        "operationId": "revokeMemberToken",
        "parameters": [
          {
            "description": "The customer's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The member's id.",
            "in": "path",
            "name": "memberId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The token's id.",
            "in": "path",
            "name": "tokenId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "token": {
                      "$ref": "#/components/schemas/MemberToken"
                    }
                  },
                  "required": [
                    "token"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The revoked token."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`id` or `memberId` or `tokenId` name nothing this caller can see."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The token is no longer active: it was revoked or has expired."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Revoke a member token",
        "tags": [
          "Member tokens"
        ]
      }
    },
    "/api/integrator/v1/docs/guide.md": {
      "get": {
        "description": "The guide to this API, or to the customer API with api=customer, as Instant serves it now: what the reference does not say, such as the conventions, authentication, errors and limits. It is GitHub Flavored Markdown, sent as `text/markdown; charset=utf-8; variant=GFM`. A fetch is a use of the credential, authenticated like any other request. Check at most once an hour, with If-None-Match.",
        "operationId": "readGuide",
        "parameters": [
          {
            "description": "Whose docs: integrator (the default), or customer for the customer API's, fetched with the same integrator credential.",
            "in": "query",
            "name": "api",
            "schema": {
              "default": "integrator",
              "enum": [
                "integrator",
                "customer"
              ],
              "type": "string"
            }
          },
          {
            "description": "The ETag of the copy you have. While it is current, the answer is 304, without a body.",
            "in": "header",
            "name": "If-None-Match",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "text/markdown": {
                "schema": {
                  "description": "The guide, in GitHub Flavored Markdown.",
                  "type": "string"
                }
              }
            },
            "description": "The guide.",
            "headers": {
              "Cache-Control": {
                "description": "private, no-cache: keep the copy, and ask again with If-None-Match before you use it.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "The SHA-256 of the file, in hex and in double quotes: the version of these docs. It changes when the file changes, and only then.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Content-Type-Options": {
                "description": "nosniff",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "The copy with that ETag is current.",
            "headers": {
              "Cache-Control": {
                "description": "private, no-cache: keep the copy, and ask again with If-None-Match before you use it.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "The SHA-256 of the file, in hex and in double quotes: the version of these docs. It changes when the file changes, and only then.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Content-Type-Options": {
                "description": "nosniff",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A query parameter is unknown or invalid."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Read a guide",
        "tags": [
          "Docs"
        ]
      }
    },
    "/api/integrator/v1/docs/openapi.json": {
      "get": {
        "description": "This API's OpenAPI 3.1 reference, or the customer API's with api=customer, exactly as Instant serves it now. A fetch is a use of the credential, authenticated like any other request. Check at most once an hour, with If-None-Match.",
        "operationId": "readOpenApi",
        "parameters": [
          {
            "description": "Whose docs: integrator (the default), or customer for the customer API's, fetched with the same integrator credential.",
            "in": "query",
            "name": "api",
            "schema": {
              "default": "integrator",
              "enum": [
                "integrator",
                "customer"
              ],
              "type": "string"
            }
          },
          {
            "description": "The ETag of the copy you have. While it is current, the answer is 304, without a body.",
            "in": "header",
            "name": "If-None-Match",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": {
                    "description": "The rest of the OpenAPI document: paths, webhooks and components."
                  },
                  "description": "An OpenAPI 3.1 document.",
                  "properties": {
                    "openapi": {
                      "const": "3.1.0",
                      "type": "string"
                    },
                    "info": {
                      "properties": {
                        "title": {
                          "type": "string"
                        },
                        "version": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "title",
                        "version",
                        "description"
                      ],
                      "type": "object"
                    }
                  },
                  "required": [
                    "openapi",
                    "info"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The reference.",
            "headers": {
              "Cache-Control": {
                "description": "private, no-cache: keep the copy, and ask again with If-None-Match before you use it.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "The SHA-256 of the file, in hex and in double quotes: the version of these docs. It changes when the file changes, and only then.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Content-Type-Options": {
                "description": "nosniff",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "The copy with that ETag is current.",
            "headers": {
              "Cache-Control": {
                "description": "private, no-cache: keep the copy, and ask again with If-None-Match before you use it.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "The SHA-256 of the file, in hex and in double quotes: the version of these docs. It changes when the file changes, and only then.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Content-Type-Options": {
                "description": "nosniff",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A query parameter is unknown or invalid."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Read an OpenAPI reference",
        "tags": [
          "Docs"
        ]
      }
    },
    "/api/integrator/v1/me": {
      "get": {
        "description": "Which integrator the credential belongs to: the way to check a credential.",
        "operationId": "integratorMe",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "integrator": {
                      "properties": {
                        "id": {
                          "description": "The integrator's id.",
                          "format": "uuid",
                          "type": "string"
                        },
                        "name": {
                          "description": "The integrator's name.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "name"
                      ],
                      "type": "object"
                    }
                  },
                  "required": [
                    "integrator"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The integrator."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Read the integrator",
        "tags": [
          "Integrator"
        ]
      }
    },
    "/api/integrator/v1/return-origins": {
      "get": {
        "description": "The return URL's own origin counts as registered without being listed.",
        "operationId": "readReturnOrigins",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "returnOrigins": {
                      "description": "Each origin as a browser writes it.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "returnOrigins"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The return origins, sorted; [] when none is listed."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Read the return origins",
        "tags": [
          "Return URL"
        ]
      },
      "put": {
        "description": "Replaces the list of return origins; [] clears it. The same origins again, in any order, are a 200 that changes nothing.",
        "operationId": "setReturnOrigins",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "origins": {
                    "description": "Up to ten origins your return URLs may be on, none twice, each exactly as a browser writes it: the scheme, the host in lower case, and the port only when it is not the scheme's default, with no path and no trailing slash. https, or http on a loopback address on your own machine. The return URL's own origin counts as registered without being listed. [] clears the list.",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 10,
                    "type": "array",
                    "uniqueItems": true
                  }
                },
                "required": [
                  "origins"
                ],
                "type": "object"
              }
            }
          },
          "description": "At most 4096 bytes.",
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "returnOrigins": {
                      "description": "Each origin as a browser writes it.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "returnOrigins"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The return origins, sorted."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not one JSON object, or a field is invalid; `error` says which."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is over 4096 bytes."
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not sent as `application/json`."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Set the return origins",
        "tags": [
          "Return URL"
        ]
      }
    },
    "/api/integrator/v1/return-url": {
      "delete": {
        "description": "A connection then ends on Instant's own result page. Clearing when none is set is also a 200.",
        "operationId": "clearReturnUrl",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "returnUrl": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "returnUrl"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "No return URL."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Clear the return URL",
        "tags": [
          "Return URL"
        ]
      },
      "get": {
        "operationId": "readReturnUrl",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "returnUrl": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "returnUrl"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The return URL, or null when none is set."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Read the return URL",
        "tags": [
          "Return URL"
        ]
      },
      "put": {
        "description": "Setting the same URL again is a 200 that changes nothing.",
        "operationId": "setReturnUrl",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "url": {
                    "description": "Where a member's browser comes back after a connection: an https URL without credentials. Instant never fetches it, so only its syntax is checked.",
                    "maxLength": 2000,
                    "pattern": "^https://",
                    "type": "string"
                  }
                },
                "required": [
                  "url"
                ],
                "type": "object"
              }
            }
          },
          "description": "At most 4096 bytes.",
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "returnUrl": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "returnUrl"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The return URL."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not one JSON object, or a field is invalid; `error` says which. Also when the URL is not an https URL without credentials."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is over 4096 bytes."
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not sent as `application/json`."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Set the return URL",
        "tags": [
          "Return URL"
        ]
      }
    },
    "/api/integrator/v1/webhook": {
      "delete": {
        "description": "Removes the webhook and its secret. Its pending deliveries fail with `webhook_removed`; the history stays 30 days. Removing when none is set is also a 200.",
        "operationId": "clearWebhook",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "webhook": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "webhook"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "No webhook."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Remove the webhook",
        "tags": [
          "Webhook"
        ]
      },
      "get": {
        "operationId": "readWebhook",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "webhook": {
                      "anyOf": [
                        {
                          "$ref": "#/components/schemas/Webhook"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Null when no webhook is set."
                    },
                    "deliveries": {
                      "properties": {
                        "pending": {
                          "description": "How many deliveries wait to be sent or retried.",
                          "maximum": 9007199254740991,
                          "minimum": 0,
                          "type": "integer"
                        },
                        "failed": {
                          "description": "How many deliveries failed and will not be sent again.",
                          "maximum": 9007199254740991,
                          "minimum": 0,
                          "type": "integer"
                        }
                      },
                      "required": [
                        "pending",
                        "failed"
                      ],
                      "type": "object"
                    }
                  },
                  "required": [
                    "webhook",
                    "deliveries"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The webhook, never its secret, and how many deliveries are pending and failed."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Read the webhook",
        "tags": [
          "Webhook"
        ]
      },
      "put": {
        "description": "The credential is checked before the URL, so Instant resolves no name for an unknown caller. Every call mints a new signing secret, also for the same URL, and shows it this once; the previous secret stops at once. Pending deliveries are kept and go to the new URL, signed with the new secret. When Instant cannot mint a secret right now, the answer is 503.",
        "operationId": "setWebhook",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "url": {
                    "description": "Where Instant sends the webhook deliveries: an https URL without credentials, on port 443, with a host name (never an IP address) that resolves to public addresses only. Every call mints a new signing secret, also for the same URL.",
                    "maxLength": 2000,
                    "pattern": "^https://",
                    "type": "string"
                  }
                },
                "required": [
                  "url"
                ],
                "type": "object"
              }
            }
          },
          "description": "At most 4096 bytes.",
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "webhook": {
                      "$ref": "#/components/schemas/Webhook"
                    },
                    "secret": {
                      "description": "The signing secret, shown this once. Keep it on your servers, in a secret manager.",
                      "pattern": "^[a-z]+_w_[0-9a-f]{64}$",
                      "type": "string"
                    }
                  },
                  "required": [
                    "webhook",
                    "secret"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The webhook and its new signing secret."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not one JSON object, or a field is invalid; `error` says which. Also when the URL is not a public https URL."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is over 4096 bytes."
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The body is not sent as `application/json`."
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "Set the webhook",
        "tags": [
          "Webhook"
        ]
      }
    },
    "/api/integrator/v1/webhook/deliveries": {
      "get": {
        "description": "The integrator's deliveries, newest first, a page at a time. There is no replay: a failed delivery is not sent again, so read what it was about through the customer API.",
        "operationId": "listDeliveries",
        "parameters": [
          {
            "description": "How many to answer: a whole number from 1 to 200, without a leading zero.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "The nextCursor of the previous page.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "Only the deliveries in this state.",
            "in": "query",
            "name": "status",
            "schema": {
              "enum": [
                "pending",
                "delivered",
                "failed"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "items": {
                      "items": {
                        "$ref": "#/components/schemas/Delivery"
                      },
                      "type": "array"
                    },
                    "nextCursor": {
                      "anyOf": [
                        {
                          "format": "uuid",
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The cursor of the next page, or null on the last page."
                    }
                  },
                  "required": [
                    "items",
                    "nextCursor"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "A page of deliveries."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A query parameter is unknown or invalid."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"instant-integrator-api\"",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "5XX": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Instant is temporarily unavailable. Retry later, with backoff."
          }
        },
        "summary": "List webhook deliveries",
        "tags": [
          "Webhook"
        ]
      }
    }
  },
  "security": [
    {
      "integratorCredential": []
    }
  ],
  "servers": [
    {
      "url": "https://app.booksbyinstant.com"
    }
  ],
  "tags": [
    {
      "description": "Which integrator a credential belongs to.",
      "name": "Integrator"
    },
    {
      "description": "The integrator's customers: each is a company in Instant, created with its first member, who owns it.",
      "name": "Customers"
    },
    {
      "description": "The people of a customer, each with a role and entity access.",
      "name": "Members"
    },
    {
      "description": "The secrets a member's requests to the customer API carry. The integrator issues them.",
      "name": "Member tokens"
    },
    {
      "description": "Where Instant posts what happens in the integrator's customers and when the docs change, and the deliveries it made.",
      "name": "Webhook"
    },
    {
      "description": "Where a member's browser comes back after connecting a mailbox, a calendar or a bank.",
      "name": "Return URL"
    },
    {
      "description": "This API's reference and guide, and the customer API's, as Instant serves them now.",
      "name": "Docs"
    }
  ],
  "webhooks": {
    "approval.due": {
      "post": {
        "description": "It is a member's turn in an approval round, or a scheduled run waits for its owner's approval. item is the subject's, usually a document, partner, payment or run. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "approval.due",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "A member's turn to approve"
      }
    },
    "browser.takeover_needed": {
      "post": {
        "description": "Reserved for a later use: Instant does not send this kind yet. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "browser.takeover_needed",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "Reserved: not sent yet"
      }
    },
    "connection.expired": {
      "post": {
        "description": "A bank consent ran out. item is the bank_connection; there is no member. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "connection.expired",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "A bank consent ran out"
      }
    },
    "connection.synced": {
      "post": {
        "description": "A bank connection's read ended: from its first day after the consent, again when a new or rediscovered account or an earlier first day needs a first-day read, or a read the member asked for. item is the bank_connection with outcome completed or failed; there is no member. Routine reads send nothing. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "connection.synced",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "A bank backfill or asked read ended"
      }
    },
    "customer.paused": {
      "post": {
        "description": "The integrator paused the customer. item is the customer; there is no member. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "customer.paused",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "A customer was paused"
      }
    },
    "customer.resumed": {
      "post": {
        "description": "The integrator resumed the customer. item is the customer; there is no member. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "customer.resumed",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "A customer was resumed"
      }
    },
    "docs.updated": {
      "post": {
        "description": "A production release changed a reference or a guide: this API's or the customer API's. Sent to every active integrator with a webhook, at most once an hour; changes in the meantime go out together. changed names each part that changed, its new version (its ETag without the quotes) and the URL to fetch it with the integrator credential. Like every kind it is delivered at least once: deduplicate on Instant-Event-Id. A rollback that changes what Instant serves is announced like any other change, so a version can be announced again. It concerns no customer. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "docs.updated",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocsUpdatedPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "The docs changed"
      }
    },
    "link.finished": {
      "post": {
        "description": "A bank connection link ended, once for each link: its consent gave a connection, the person cancelled, the bank or Instant could not complete it, or it expired. item is the bank_link with its outcome; there is no member. Like every kind it can arrive late, or after a later delivery. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "link.finished",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "A bank link ended"
      }
    },
    "ping.raised": {
      "post": {
        "description": "Any other notice to a member. item is its subject, or ping. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "ping.raised",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "A notice to a member"
      }
    },
    "reply.ready": {
      "post": {
        "description": "A member's chat reply is recorded: one per reply, with the reply's message id as the delivery's id. item is the thread. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "reply.ready",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "A chat reply is ready"
      }
    },
    "run.finished": {
      "post": {
        "description": "Background work or a recurring action finished for its owner. item is the run. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "run.finished",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "Background work finished"
      }
    },
    "task.input_needed": {
      "post": {
        "description": "A follow-up task stopped for its owner. item is the task. A receiver ignores an event kind it does not know: kinds are added over time.",
        "parameters": [
          {
            "description": "`t=<unix seconds>,v1=<hex>`: t is when this attempt was sent, so each retry is signed again, and v1 is the HMAC-SHA256 of `<t>.<raw request body>`, keyed with the webhook secret string as sent to you (not hex-decoded). Reject a t more than 5 minutes off.",
            "in": "header",
            "name": "Instant-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The same on every attempt of one event: delivery is at least once.",
            "in": "header",
            "name": "Instant-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "The kind of the event.",
            "in": "header",
            "name": "Instant-Event-Kind",
            "required": true,
            "schema": {
              "const": "task.input_needed",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer, or none within 10 s, is retried; 7 attempts."
          }
        },
        "security": [],
        "summary": "A task needs its owner"
      }
    }
  }
}
