{
  "openapi": "3.1.0",
  "info": {
    "title": "Halict API",
    "version": "1.0.0",
    "description": "Halict is a form tool. It asks one question at a time, and turns every response\ninto a case you can stage, assign, tag and follow up by email.\n\nThis API lets you read and write those forms and responses from your own systems,\nand subscribe to events so you hear about a new response the moment it arrives.\n\n## Authentication\n\nEvery endpoint takes an API key in the `Authorization` header:\n\n```\nAuthorization: Bearer qk_live_xxxxxxxx\n```\n\nIssue a key in Halict under **Settings → API Keys**. A key belongs to one workspace,\nand every call is scoped to that workspace. Keys are shown once, so store yours safely.\n\n## Events (webhooks)\n\nInstead of polling, register a URL with `POST /webhooks/subscribe` and Halict will\npost to it the moment a response arrives or its stage changes. Delete the subscription\nwith `DELETE /webhooks/subscribe/{id}` when you no longer need it.",
    "contact": {
      "name": "Halict",
      "url": "https://halict.com/contact",
      "email": "info@halict.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://halict.com/legal/terms"
    }
  },
  "servers": [
    {
      "url": "https://halict.com/api",
      "description": "Production"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Forms",
      "description": "Create forms and change whether they accept responses."
    },
    {
      "name": "Responses",
      "description": "Read the responses that arrived, and move them along."
    },
    {
      "name": "Stages",
      "description": "The stages a response moves through."
    },
    {
      "name": "Members",
      "description": "The people in the workspace, used as assignees."
    },
    {
      "name": "Webhooks",
      "description": "Subscribe to events instead of polling."
    },
    {
      "name": "AI",
      "description": "Build a whole form from a sentence."
    }
  ],
  "paths": {
    "/forms": {
      "get": {
        "tags": [
          "Forms"
        ],
        "summary": "List forms",
        "description": "Returns every form in the workspace, newest change first.",
        "operationId": "listForms",
        "responses": {
          "200": {
            "description": "The forms in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FormSummary"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Forms"
        ],
        "summary": "Create a form",
        "description": "Creates a form as a draft. Publish it with `PATCH /forms/{id}`.",
        "operationId": "createForm",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 200,
                    "examples": [
                      "Trial lesson application"
                    ]
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "folderId": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The form that was created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Form"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/forms/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "description": "Form ID."
        }
      ],
      "get": {
        "tags": [
          "Forms"
        ],
        "summary": "Get a form",
        "description": "Returns the form together with its questions.",
        "operationId": "getForm",
        "responses": {
          "200": {
            "description": "The form and its questions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FormWithFields"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The form, response or subscription does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Forms"
        ],
        "summary": "Update a form",
        "description": "Changes the title, the description or whether the form accepts responses.",
        "operationId": "updateForm",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "status": {
                    "$ref": "#/components/schemas/FormStatus"
                  },
                  "folderId": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The form after the change.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Form"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The form, response or subscription does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Forms"
        ],
        "summary": "Delete a form",
        "description": "Deletes the form and everything that came in through it.",
        "operationId": "deleteForm",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The form, response or subscription does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/forms/{formId}/responses": {
      "parameters": [
        {
          "name": "formId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "description": "Form ID."
        }
      ],
      "get": {
        "tags": [
          "Responses"
        ],
        "summary": "List responses",
        "description": "Returns the responses to one form, newest first, together with the stages and the\npeople you can assign them to.\n\nPass `flat=1` to get each answer keyed by the question it belongs to. That is the same\nshape the webhook sends, so what you see while setting an integration up matches what\narrives once it runs.",
        "operationId": "listResponses",
        "parameters": [
          {
            "name": "flat",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "description": "Add `answers` (keyed by question) and `summary` to every response."
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Match the name, the email address, a tag, or the text of any answer."
          },
          {
            "name": "stage",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "A stage ID, or `none` for the ones with no stage yet."
          },
          {
            "name": "assignee",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "An account ID, or `none` for the unassigned ones."
          },
          {
            "name": "tag",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Only the responses carrying this tag."
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Submitted at or after this moment."
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Submitted at or before this moment."
          }
        ],
        "responses": {
          "200": {
            "description": "The responses, plus the stages and members of this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResponseList"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The form, response or subscription does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/forms/{formId}/stages": {
      "parameters": [
        {
          "name": "formId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "description": "Form ID."
        }
      ],
      "get": {
        "tags": [
          "Stages"
        ],
        "summary": "List stages",
        "description": "Returns the stages a response can move through on this form.",
        "operationId": "listStages",
        "responses": {
          "200": {
            "description": "The stages of this form.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "stages": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Stage"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The form, response or subscription does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/responses/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "description": "Response ID."
        }
      ],
      "get": {
        "tags": [
          "Responses"
        ],
        "summary": "Get a response",
        "description": "Returns one response with its answers, its history and the emails around it.",
        "operationId": "getResponse",
        "responses": {
          "200": {
            "description": "The response and everything attached to it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResponseDetail"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The form, response or subscription does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Responses"
        ],
        "summary": "Update a response",
        "description": "Moves a response to another stage, hands it to someone, or replaces its tags.",
        "operationId": "updateResponse",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "stageId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "A stage of the same form, or null to clear it."
                  },
                  "assigneeId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "The account ID of a member, or null to clear it."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 30
                    },
                    "description": "Replaces every tag on the response."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "What changed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "formId": {
                      "type": "integer"
                    },
                    "changes": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The stage does not belong to this form."
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The form, response or subscription does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Responses"
        ],
        "summary": "Delete a response",
        "operationId": "deleteResponse",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The form, response or subscription does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/responses/{id}/notes": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "description": "Response ID."
        }
      ],
      "post": {
        "tags": [
          "Responses"
        ],
        "summary": "Add a note",
        "description": "Adds an internal note. The person who sent the response never sees it.",
        "operationId": "addNote",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "body"
                ],
                "properties": {
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 5000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The note that was added.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Note"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The form, response or subscription does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/members": {
      "get": {
        "tags": [
          "Members"
        ],
        "summary": "List members",
        "description": "Returns the people in the workspace. Use `accountId` as the assignee of a response.",
        "operationId": "listMembers",
        "responses": {
          "200": {
            "description": "The members of this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "members": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Member"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List subscriptions",
        "description": "Returns the subscriptions registered from outside tools.",
        "operationId": "listSubscriptions",
        "responses": {
          "200": {
            "description": "The subscriptions in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Subscription"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/subscribe": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Subscribe to an event",
        "description": "Registers a URL that Halict posts to when the event happens on that form.\nThe body it sends is described by the `WebhookEvent` schema below.",
        "operationId": "subscribe",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "formId",
                  "event",
                  "targetUrl"
                ],
                "properties": {
                  "formId": {
                    "type": "integer",
                    "description": "The form to watch."
                  },
                  "event": {
                    "$ref": "#/components/schemas/EventName"
                  },
                  "targetUrl": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2000
                  },
                  "source": {
                    "type": "string",
                    "maxLength": 40,
                    "description": "Which tool registered this, shown in Halict. For example `zapier`."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The subscription that was created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subscription"
                }
              }
            }
          },
          "400": {
            "description": "Unknown event name, or a malformed URL."
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The form, response or subscription does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "callbacks": {
          "event": {
            "{$request.body#/targetUrl}": {
              "post": {
                "summary": "The event Halict sends you",
                "description": "Halict posts this the moment the event happens. Answer with 2xx.",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/WebhookEvent"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "You received it."
                  },
                  "400": {
                    "description": "You could not use it. Halict does not retry."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/subscribe/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Subscription ID."
        }
      ],
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Unsubscribe",
        "operationId": "unsubscribe",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The form, response or subscription does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/forms/generate": {
      "post": {
        "tags": [
          "AI"
        ],
        "summary": "Build a form from a sentence",
        "description": "Writes the questions for you from a plain description, and creates the form.",
        "operationId": "generateForm",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string",
                    "maxLength": 4000,
                    "examples": [
                      "A sign-up form for a trial lesson: name, email, preferred day, and anything they want to tell us."
                    ]
                  },
                  "publish": {
                    "type": "boolean",
                    "description": "Publish it right away instead of leaving it a draft."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The form that was built.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FormWithFields"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong, or has been revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "The model could not be reached, or gave something unusable."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API key from Settings → API Keys. It starts with `qk_live_`."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "FormStatus": {
        "type": "string",
        "enum": [
          "draft",
          "published",
          "closed"
        ],
        "description": "`published` is the only one that accepts responses."
      },
      "FormSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "publicId": {
            "type": "string",
            "description": "The part that appears in the public URL, `/f/{publicId}`."
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/FormStatus"
          },
          "folderId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "responseCount": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Form": {
        "$ref": "#/components/schemas/FormSummary"
      },
      "Field": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "type": {
            "type": "string",
            "description": "short_text, long_text, email, tel, number, date, select, checkboxes, file and so on."
          },
          "label": {
            "type": "string",
            "description": "The question as the person sees it. Answers are keyed by this in `flat=1` and in webhooks."
          },
          "required": {
            "type": "boolean"
          },
          "position": {
            "type": "integer"
          },
          "options": {
            "type": [
              "object",
              "null"
            ]
          }
        }
      },
      "FormWithFields": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "publicId": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/FormStatus"
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Field"
            }
          }
        }
      },
      "Stage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "color": {
            "type": [
              "string",
              "null"
            ]
          },
          "isClosed": {
            "type": "boolean",
            "description": "Whether reaching this stage means the case is finished."
          }
        }
      },
      "Member": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": "integer",
            "description": "Use this as `assigneeId` on a response."
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": [
              "owner",
              "admin",
              "member",
              "viewer"
            ]
          }
        }
      },
      "ResponseRow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "submittedAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Worked out from the answers, or from the contact it belongs to."
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "stageId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "assigneeId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "source": {
            "type": "string"
          },
          "values": {
            "type": "object",
            "description": "The raw answers, keyed by question ID."
          },
          "answers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Only with `flat=1`. The answers keyed by the question itself."
          },
          "summary": {
            "type": "string",
            "description": "Only with `flat=1`. The answers written out, ready to paste into a notification."
          }
        }
      },
      "ResponseList": {
        "type": "object",
        "properties": {
          "form": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer"
              },
              "title": {
                "type": "string"
              }
            }
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Field"
            }
          },
          "stages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Stage"
            }
          },
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Member"
            }
          },
          "allTags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "responses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResponseRow"
            }
          }
        }
      },
      "ResponseDetail": {
        "type": "object",
        "properties": {
          "response": {
            "$ref": "#/components/schemas/ResponseRow"
          },
          "form": {
            "type": "object"
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Field"
            }
          },
          "stages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Stage"
            }
          },
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Member"
            }
          },
          "activities": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "What happened to this response, newest first."
          },
          "emails": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "What was sent to the person, with opens and clicks."
          },
          "replies": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "What they sent back."
          }
        }
      },
      "Note": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "responseId": {
            "type": "integer"
          },
          "type": {
            "type": "string",
            "enum": [
              "note"
            ]
          },
          "payload": {
            "type": "object",
            "properties": {
              "body": {
                "type": "string"
              }
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "EventName": {
        "type": "string",
        "enum": [
          "response.created",
          "response.stage_changed"
        ],
        "description": "`response.created` when a response arrives, `response.stage_changed` when it moves."
      },
      "Subscription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "formId": {
            "type": "integer"
          },
          "formTitle": {
            "type": "string"
          },
          "event": {
            "$ref": "#/components/schemas/EventName"
          },
          "targetUrl": {
            "type": "string",
            "format": "uri"
          },
          "source": {
            "type": "string"
          },
          "lastSentAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "description": "What Halict posts to your URL when the event happens.",
        "properties": {
          "event": {
            "$ref": "#/components/schemas/EventName"
          },
          "form": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer"
              },
              "title": {
                "type": "string"
              }
            }
          },
          "responseId": {
            "type": "integer"
          },
          "submittedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "stage": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "integer"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "respondent": {
            "type": "object",
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "answers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "The answers keyed by the question itself."
          },
          "summary": {
            "type": "string"
          },
          "link": {
            "type": "string",
            "format": "uri",
            "description": "Opens this response in Halict."
          }
        }
      }
    }
  }
}