openapi: 3.1.0
info:
  title: Nice Forms API
  version: 1.0.0
  summary: Workspace HTTP API for the Nice Forms survey builder.
  description: "Create surveys, publish them, pull responses, and subscribe to webhooks for the Nice Forms product. Use this document in Zapier, n8n, Make, or any OpenAPI / LLM function-calling importer. Authenticate with a workspace API key: `Authorization: Bearer nf_live_…`. Keys are created under Account → API. Public catalog: GET /api/v1 (no key). Docs: /developers. CLI: npx nice-forms."
  contact:
    name: Nice Forms support
    url: "https://www.nice-forms.com/contact"
    email: "gettesoftware@gmail.com"
  license:
    name: Proprietary
    url: "https://www.nice-forms.com/terms"
servers:
  - url: "https://www.nice-forms.com"
    description: Nice Forms production
tags:
  - name: Workspace
    description: Identity for the current API key.
  - name: Surveys
    description: "Create, publish, and update Nice Forms surveys."
  - name: Responses
    description: "List, submit, and inspect survey answers."
  - name: Webhooks
    description: "Signed outbound events for Zapier, n8n, Slack, Teams, and CRMs."
  - name: Discovery
    description: Machine-readable catalog and this OpenAPI document.
security:
  - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: "Workspace API key created in Nice Forms under Account → API. Header: Authorization: Bearer nf_live_…"
  schemas:
    Error:
      type: object
      required:
        - error
        - code
        - message
        - hint
      properties:
        error:
          type: string
          description: Human-readable error message (same as message).
        code:
          type: string
          enum:
            - unauthorized
            - not_found
            - invalid_request
            - rate_limited
            - not_accepting_responses
            - limit_reached
            - delivery_failed
            - method_not_allowed
        message:
          type: string
        hint:
          type: string
          description: What to do next so an agent can recover without guessing.
    QuestionOption:
      type: object
      required:
        - label
      properties:
        id:
          type: string
        label:
          type: string
          maxLength: 200
        image:
          type: string
          maxLength: 2048
    Question:
      type: object
      required:
        - type
        - title
      properties:
        id:
          type: string
        type:
          type: string
          enum:
            - multiple_choice
            - checkboxes
            - text
            - comment
            - yes_no
            - number
            - mood_scale
            - dropdown
            - images
            - image_checkboxes
            - rating
            - nps
            - date
        title:
          type: string
          maxLength: 500
        description:
          type: string
          maxLength: 2000
        required:
          type: boolean
        inputKind:
          type: string
          enum:
            - text
            - name
            - email
            - url
            - tel
        displayImage:
          type: string
        customDisplayImage:
          type: string
          maxLength: 2048
        options:
          type: array
          items:
            $ref: "#/components/schemas/QuestionOption"
    Widget:
      type: object
      properties:
        enabled:
          type: boolean
        mode:
          type: string
          enum:
            - button
            - popup
            - embed
        position:
          type: string
          enum:
            - bottom-right
            - bottom-left
            - right
            - left
        buttonLabel:
          type: string
          maxLength: 32
        trigger:
          type: string
          enum:
            - none
            - delay
            - scroll
            - exit
        delaySeconds:
          type: integer
          minimum: 1
          maximum: 180
        scrollPercent:
          type: integer
          minimum: 10
          maximum: 100
        oncePerVisitor:
          type: boolean
    Survey:
      type: object
      required:
        - id
        - title
        - status
        - slug
      properties:
        id:
          type: string
        title:
          type: string
        description:
          type: string
        slug:
          type: string
        joinCode:
          type: string
        status:
          type: string
          enum:
            - draft
            - published
            - closed
        layout:
          type: string
          enum:
            - single
            - multi
        theme:
          type: string
        customThemeColor:
          type: string
        displayImage:
          type: string
        customDisplayImage:
          type: string
        customLogo:
          type: string
        collectLeads:
          type: boolean
        hideBranding:
          type: boolean
        showIntro:
          type: boolean
        questions:
          type: array
          items:
            $ref: "#/components/schemas/Question"
        widget:
          $ref: "#/components/schemas/Widget"
        responseCount:
          type: integer
        viewCount:
          type: integer
        url:
          type: string
          format: uri
        widgetScriptUrl:
          type: string
          format: uri
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    SurveyWrite:
      type: object
      properties:
        title:
          type: string
          maxLength: 200
        description:
          type: string
          maxLength: 2000
        collectLeads:
          type: boolean
        hideBranding:
          type: boolean
        showIntro:
          type: boolean
        layout:
          type: string
          enum:
            - single
            - multi
        theme:
          type: string
        customThemeColor:
          type: string
          maxLength: 7
        displayImage:
          type: string
        customDisplayImage:
          type: string
        customLogo:
          type: string
          maxLength: 2048
        questions:
          type: array
          maxItems: 50
          items:
            $ref: "#/components/schemas/Question"
        widget:
          $ref: "#/components/schemas/Widget"
        status:
          type: string
          enum:
            - draft
            - published
            - closed
    Lead:
      type: object
      properties:
        name:
          type: string
          maxLength: 200
        email:
          type: string
          maxLength: 320
    Answer:
      type: object
      required:
        - questionId
        - value
      properties:
        questionId:
          type: string
        value:
          oneOf:
            - type: string
            - type: array
              items:
                type: string
    Response:
      type: object
      required:
        - id
        - surveyId
        - answers
        - completed
        - createdAt
      properties:
        id:
          type: string
        surveyId:
          type: string
        answers:
          type: array
          items:
            $ref: "#/components/schemas/Answer"
        lead:
          oneOf:
            - $ref: "#/components/schemas/Lead"
            - type: null
        completed:
          type: boolean
        pageUrl:
          oneOf:
            - type: string
            - type: null
        pageTitle:
          oneOf:
            - type: string
            - type: null
        source:
          oneOf:
            - type: string
              enum:
                - link
                - widget
                - embed
            - type: null
        createdAt:
          type: string
          format: date-time
    Pagination:
      type: object
      properties:
        limit:
          type: integer
        hasMore:
          type: boolean
        nextCursor:
          oneOf:
            - type: string
            - type: null
    Webhook:
      type: object
      required:
        - id
        - url
        - events
      properties:
        id:
          type: string
        name:
          type: string
        url:
          type: string
          format: uri
        events:
          type: array
          items:
            type: string
            enum:
              - response.created
              - survey.published
              - survey.closed
        format:
          type: string
          enum:
            - json
            - slack
            - teams
        surveyId:
          oneOf:
            - type: string
            - type: null
        enabled:
          type: boolean
        failureCount:
          type: integer
        lastStatus:
          oneOf:
            - type: integer
            - type: null
        lastDeliveredAt:
          oneOf:
            - type: string
              format: date-time
            - type: null
        lastError:
          oneOf:
            - type: string
            - type: null
        createdAt:
          type: string
          format: date-time
        secret:
          type: string
          description: Present once on create. Used for Nice-Forms-Signature HMAC.
    WebhookWrite:
      type: object
      properties:
        name:
          type: string
          maxLength: 80
        url:
          type: string
          format: uri
          maxLength: 2048
        events:
          type: array
          minItems: 1
          maxItems: 3
          items:
            type: string
            enum:
              - response.created
              - survey.published
              - survey.closed
        format:
          type: string
          enum:
            - json
            - slack
            - teams
        surveyId:
          type: string
        enabled:
          type: boolean
    Workspace:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        plan:
          type: string
          enum:
            - basic
            - pro
    ApiKeyMeta:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        prefix:
          type: string
        lastUsedAt:
          oneOf:
            - type: string
              format: date-time
            - type: null
        createdAt:
          type: string
          format: date-time
    Results:
      type: object
      description: Aggregated counts plus per-question tallies.
      additionalProperties: true
paths:
  /api/v1:
    get:
      tags:
        - Discovery
      summary: API catalog
      operationId: getApiCatalog
      description: "List Nice Forms API endpoints, docs URL, and authentication. No API key required. Use this as a bootstrap for agents that have not loaded /openapi.json yet."
      security: []
      responses:
        200:
          description: Catalog of methods and paths.
          content:
            application/json:
              schema:
                type: object
                properties:
                  name:
                    type: string
                  version:
                    type: string
                  docs:
                    type: string
                    format: uri
                  openapi:
                    type: string
                    format: uri
                  authentication:
                    type: object
                    additionalProperties: true
                  endpoints:
                    type: array
                    items:
                      type: object
                      additionalProperties: true
  /api/v1/openapi.json:
    get:
      tags:
        - Discovery
      summary: OpenAPI document
      operationId: getOpenApiDocument
      description: "Return this OpenAPI 3.1 document as JSON. Same body as GET /openapi.json. No API key required. Import into Zapier, n8n, or an LLM tool-calling runtime."
      security: []
      responses:
        200:
          description: OpenAPI 3.1 document.
          content:
            application/json:
              schema:
                type: object
  /openapi.json:
    get:
      tags:
        - Discovery
      summary: OpenAPI document at a well-known URL
      operationId: getOpenApiDocumentWellKnown
      description: "Canonical OpenAPI 3.1 JSON for Nice Forms. Agents should fetch this path first. Identical to GET /api/v1/openapi.json. YAML twin: GET /openapi.yaml and GET /api/openapi.yaml."
      security: []
      responses:
        200:
          description: OpenAPI 3.1 document.
          content:
            application/json:
              schema:
                type: object
  /api/v1/me:
    get:
      tags:
        - Workspace
      summary: Current workspace
      operationId: getMe
      description: Return the workspace and API-key metadata for the Bearer token. Use this to verify a key before creating surveys. 401 means the key is missing or revoked — create a new key under Account → API.
      responses:
        200:
          description: Workspace and key metadata.
          content:
            application/json:
              schema:
                type: object
                properties:
                  workspace:
                    $ref: "#/components/schemas/Workspace"
                  key:
                    $ref: "#/components/schemas/ApiKeyMeta"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/surveys:
    get:
      tags:
        - Surveys
      summary: List surveys
      operationId: listSurveys
      description: "List Nice Forms surveys in the workspace. Filter with ?status=draft|published|closed. Each item includes the public URL, join code, and question list."
      parameters:
        - name: status
          in: query
          description: Optional status filter.
          schema:
            type: string
            enum:
              - draft
              - published
              - closed
      responses:
        200:
          description: Survey list.
          content:
            application/json:
              schema:
                type: object
                properties:
                  surveys:
                    type: array
                    items:
                      $ref: "#/components/schemas/Survey"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    post:
      tags:
        - Surveys
      summary: Create a survey
      operationId: createSurvey
      description: "Create a Nice Forms survey. Title defaults to Untitled survey if omitted. Questions, theme, widget, and branding can be set in the same request. Basic workspaces cannot use Pro-only question types, custom logos, or hidden branding."
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SurveyWrite"
      responses:
        201:
          description: Created survey.
          content:
            application/json:
              schema:
                type: object
                properties:
                  survey:
                    $ref: "#/components/schemas/Survey"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/surveys/{id}:
    get:
      tags:
        - Surveys
      summary: Get a survey
      operationId: getSurvey
      description: "Load one survey by id, including questions, theme, widget settings, and share URLs."
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      responses:
        200:
          description: Survey.
          content:
            application/json:
              schema:
                type: object
                properties:
                  survey:
                    $ref: "#/components/schemas/Survey"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    patch:
      tags:
        - Surveys
      summary: Update a survey
      operationId: updateSurvey
      description: Patch survey fields or replace the question list. Omitted fields stay unchanged. Status can also be set here; prefer publishSurvey / closeSurvey for those transitions.
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SurveyWrite"
      responses:
        200:
          description: Updated survey.
          content:
            application/json:
              schema:
                type: object
                properties:
                  survey:
                    $ref: "#/components/schemas/Survey"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    delete:
      tags:
        - Surveys
      summary: Delete a survey
      operationId: deleteSurvey
      description: Permanently delete a survey and its responses. This cannot be undone.
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      responses:
        200:
          description: Deleted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  id:
                    type: string
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/surveys/{id}/publish:
    post:
      tags:
        - Surveys
      summary: Publish a survey
      operationId: publishSurvey
      description: "Set status to published so the public link, QR code, join code, widget, and POST /responses accept answers. Fires survey.published webhooks."
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      responses:
        200:
          description: Published survey.
          content:
            application/json:
              schema:
                type: object
                properties:
                  survey:
                    $ref: "#/components/schemas/Survey"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/surveys/{id}/close:
    post:
      tags:
        - Surveys
      summary: Close a survey
      operationId: closeSurvey
      description: Stop accepting responses. Existing answers stay. Fires survey.closed webhooks.
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      responses:
        200:
          description: Closed survey.
          content:
            application/json:
              schema:
                type: object
                properties:
                  survey:
                    $ref: "#/components/schemas/Survey"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/surveys/{id}/duplicate:
    post:
      tags:
        - Surveys
      summary: Duplicate a survey
      operationId: duplicateSurvey
      description: "Copy a survey into a new draft, including questions and theme. Responses are not copied."
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      responses:
        201:
          description: New draft survey.
          content:
            application/json:
              schema:
                type: object
                properties:
                  survey:
                    $ref: "#/components/schemas/Survey"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/surveys/{id}/responses:
    get:
      tags:
        - Responses
      summary: List responses
      operationId: listResponses
      description: "Cursor-paginated completions for a survey. Pass since=ISO-8601 to poll only new completions (Zapier/n8n). Use limit (1–100) and cursor from pagination.nextCursor when hasMore is true."
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
        - name: limit
          in: query
          description: "Page size, default 50, max 100."
          schema:
            type: integer
            minimum: 1
            maximum: 100
        - name: cursor
          in: query
          description: Opaque cursor from the previous page.
          schema:
            type: string
        - name: since
          in: query
          description: ISO-8601 timestamp. Only responses created after this instant.
          schema:
            type: string
            format: date-time
      responses:
        200:
          description: Response list.
          content:
            application/json:
              schema:
                type: object
                properties:
                  responses:
                    type: array
                    items:
                      $ref: "#/components/schemas/Response"
                  pagination:
                    $ref: "#/components/schemas/Pagination"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    post:
      tags:
        - Responses
      summary: Submit a response
      operationId: submitResponse
      description: Record answers from your own app or website. The survey must be published. Basic workspaces still cap free responses at 50 per survey. Fires response.created webhooks.
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                answers:
                  type: array
                  items:
                    $ref: "#/components/schemas/Answer"
                lead:
                  $ref: "#/components/schemas/Lead"
                pageUrl:
                  type: string
                  maxLength: 2048
                pageTitle:
                  type: string
                  maxLength: 200
                source:
                  type: string
                  enum:
                    - link
                    - widget
                    - embed
      responses:
        201:
          description: Created response.
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    $ref: "#/components/schemas/Response"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/surveys/{id}/responses/{responseId}:
    get:
      tags:
        - Responses
      summary: Get one response
      operationId: getResponse
      description: "Load a single completion by survey id and response id, including answers and optional lead fields."
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
        - name: responseId
          in: path
          required: true
          description: Response id returned by list or submit.
          schema:
            type: string
            minLength: 1
      responses:
        200:
          description: Response.
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    $ref: "#/components/schemas/Response"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/surveys/{id}/results:
    get:
      tags:
        - Responses
      summary: Aggregated results
      operationId: getSurveyResults
      description: "Return view, drop-off, and completion counts plus per-question tallies. Same numbers as the Nice Forms results dashboard."
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      responses:
        200:
          description: Aggregated results.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Results"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/webhooks:
    get:
      tags:
        - Webhooks
      summary: List webhook subscriptions
      operationId: listWebhooks
      description: List outbound webhook subscriptions plus the event names this workspace can subscribe to.
      responses:
        200:
          description: Webhook list plus event names.
          content:
            application/json:
              schema:
                type: object
                properties:
                  events:
                    type: array
                    items:
                      type: string
                  webhooks:
                    type: array
                    items:
                      $ref: "#/components/schemas/Webhook"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    post:
      tags:
        - Webhooks
      summary: Subscribe a webhook
      operationId: createWebhook
      description: "Subscribe a Zapier REST Hook, n8n webhook, Slack/Teams incoming webhook, or CRM URL. The signing secret is returned once. Deliveries include Nice-Forms-Signature: t=<unix>,v1=<hmac>. A 410 from the destination disables the hook (Zapier REST Hook unsubscribe)."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: "#/components/schemas/WebhookWrite"
                - type: object
                  required:
                    - url
                    - events
      responses:
        201:
          description: "Created webhook, includes signing secret once."
          content:
            application/json:
              schema:
                type: object
                properties:
                  webhook:
                    $ref: "#/components/schemas/Webhook"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/webhooks/{id}:
    get:
      tags:
        - Webhooks
      summary: Get a webhook
      operationId: getWebhook
      description: Load one webhook subscription. The signing secret is never returned after create.
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      responses:
        200:
          description: Webhook.
          content:
            application/json:
              schema:
                type: object
                properties:
                  webhook:
                    $ref: "#/components/schemas/Webhook"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    patch:
      tags:
        - Webhooks
      summary: Update a webhook
      operationId: updateWebhook
      description: "Change URL, events, format, name, survey filter, or enabled flag."
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WebhookWrite"
      responses:
        200:
          description: Updated webhook.
          content:
            application/json:
              schema:
                type: object
                properties:
                  webhook:
                    $ref: "#/components/schemas/Webhook"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    delete:
      tags:
        - Webhooks
      summary: Unsubscribe a webhook
      operationId: deleteWebhook
      description: Remove a webhook subscription. Further events will not be delivered.
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      responses:
        200:
          description: Deleted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  id:
                    type: string
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/webhooks/{id}/test:
    post:
      tags:
        - Webhooks
      summary: Send a test event
      operationId: testWebhook
      description: POST a signed sample event to the destination URL and record lastStatus / lastError.
      parameters:
        - name: id
          in: path
          required: true
          description: Survey or webhook id returned by the API.
          schema:
            type: string
            minLength: 1
      responses:
        200:
          description: Updated webhook after test delivery.
          content:
            application/json:
              schema:
                type: object
                properties:
                  webhook:
                    $ref: "#/components/schemas/Webhook"
        400:
          description: Invalid request body or query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "The survey is not accepting responses, or a plan limit applies."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "The survey, response, or webhook does not exist in this workspace."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: HTTP method is not defined for this path.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: Rate limited. Honour Retry-After.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
