> ## Documentation Index
> Fetch the complete documentation index at: https://docs.teamfollowup.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Use the public API base URL: https://api.teamfollowup.ai/api.
> Authenticate public API requests with Authorization: Bearer YOUR_API_KEY.
> Use product-owned terms: agents, campaigns, projects (GoHighLevel sub-accounts), contacts, calls, outcomes, skills, cadences, phone numbers.
> Scope requests by locationId rather than projectName.
> Read the guide linked from each API reference group before recommending an endpoint.

# Update settings or node contents

> **The normal way to change something that already exists.** Change campaign settings, the contents of existing nodes, or both, without sending the graph. **This is the endpoint for ordinary edits** — reword an SMS, point a callback at a different calendar, switch AI notes on. Because the request carries no graph, it cannot damage one.

Everything merges: keys you omit keep their stored value, and a key set to `null` is removed (RFC 7386, one level deep). Arrays replace wholesale, so send the full `tags` list rather than the one you are adding.

Send `campaignConfig`, `nodes`, or both — both land as a single write, so a settings change and a node edit cannot half-apply. At least one is required.

**Structure is not editable here.** `nodes` addresses existing ids only: it cannot add a node (`POST /outcomes/{outcome}/nodes`), remove one (`DELETE /nodes/{nodeId}`, which also re-links the chain around it) or re-wire anything (the whole-graph `PUT`). `{"nodes": {"n1": null}}` is rejected rather than treated as a delete, because removing a node is four operations and dropping the key is only one of them. `if`, `switch` and `trigger` nodes are refused for the same reason — their config IS structure, and changing a case can orphan the edge pointing at it.

Always version-guarded. Send `expectedVersion` to protect against your own read being stale; without it the write is still guarded against anything landing between this request's read and its write. Either way a lost race is a 409, never a silent overwrite.

Required API key scope: `campaign_workflows:write`.



## OpenAPI

````yaml /openapi.yaml patch /api/agent-builder/agents/{id}/campaign/workflow
openapi: 3.1.0
info:
  title: TFUAI Server API
  version: 1.0.0
  description: >-
    API reference for the TFUAI SaaS server.


    All published endpoints are mounted under `/api`. Responses use a standard
    envelope: `{ "success": true, ... }` on success and `{ "success": false,
    "error": "..." }` on failure.


    Product API modules are being launched module by module. This spec currently
    exposes only contracted public modules.


    Authenticate public API requests with an API key in the `Authorization`
    header: `Authorization: Bearer YOUR_API_KEY`.
servers:
  - url: https://api.teamfollowup.ai
    description: Production API origin. Public API paths are under /api.
security: []
tags:
  - name: Agents
    description: >-
      Build the conversation: identity and settings, script, lead context and
      split testing.
  - name: Analytics
    description: >-
      Understand call volume, pickup, booking and transfer metrics within the
      selected reporting scope.
  - name: Billing
    description: >-
      Balances, spend, purchases and sub-account rebilling. Reference and guides
      only; the builder chatbot has no billing playbook.
  - name: Calls
    description: >-
      Review completed calls, recordings, transcripts and campaign run history;
      distinguish observation from placing a new call.
  - name: Campaigns
    description: >-
      Configure what starts calls, who is eligible, calling windows, caller IDs,
      activation and the actions that follow each outcome.


      What runs after a call lands: for each outcome (booked, opted out, asked
      for a callback…), an ordered chain of actions — tag the contact, move a
      pipeline stage, send an SMS, book an appointment. Stored as a graph:
      `nodes` are the actions, `edges` say what follows what, and
      `dispositionEntries` maps each outcome to the node its chain starts at.


      **Pick the narrowest endpoint that does the job.**


      | To | Call | |

      | --- | --- | --- |

      | See what fires per outcome | `GET .../workflow?view=summary` | Reads as
      plain text, no graph walking |

      | Add steps to an outcome | `POST .../outcomes/{outcome}/nodes` | Server
      derives node ids, edge ids, handles, layout |

      | Change a message, tag or setting | `PATCH .../workflow` | Merges;
      carries no graph, so it cannot damage one |

      | Remove one step | `DELETE .../nodes/{nodeId}` | Also re-links the chain
      around it |

      | Author or replace the whole graph | `PUT .../workflow` | Replaces
      everything you send |


      `PUT` is the only one that can re-wire, position nodes, build an `if`,
      save an unconfigured draft, or copy a whole workflow — and the only one
      that can overwrite a change someone else made after you read it. Use it
      when you are genuinely authoring the graph, and send `expectedVersion`
      when you do. For everything else the narrower endpoints are both easier
      and safer.
  - name: Contacts
    description: >-
      Find contacts and their calls, manage do-not-call status and identify
      internal contacts excluded from reporting.
  - name: In-call Capabilities
    description: >-
      Configure actions and instructions the agent uses during a live call:
      booking, transfers, lookups and custom skills.
  - name: Master agent
    description: >-
      Run a shared agent and campaign across linked projects; manage
      inheritance, local bindings, synchronization and rollout readiness.
  - name: Native Calendar
    description: >-
      The diary of a sub-account with no CRM: its bookable calendars, the free
      slots they offer, and the appointments on them. Availability is computed
      per request against live bookings and is never cached, because a cached
      slot is one somebody else has already taken.
  - name: Native Contacts
    description: >-
      The people a sub-account with no CRM calls, and the fields it keeps on
      them. This is the system of record for those contacts: there is nowhere
      else they exist. A sub-account with a CRM keeps its contacts there and
      every operation here answers 400 for it.
  - name: Phone Numbers
    description: >-
      Find and manage caller IDs, assign numbers to campaigns and understand
      connected Twilio numbers.
  - name: Projects
    description: >-
      Understand project ownership, inspect configuration and validate the local
      resources used by a campaign.
  - name: TFU Live
    description: >-
      Build one TFU Live agent with its Brain, Voice and equipped actions;
      connect it through shared Campaigns.
  - name: Voices
    description: >-
      Browse the voice catalogue and select a voice; configure speech and
      listening behavior in Agents.
paths:
  /api/agent-builder/agents/{id}/campaign/workflow:
    patch:
      tags:
        - Campaigns
      summary: Update settings or node contents
      description: >-
        **The normal way to change something that already exists.** Change
        campaign settings, the contents of existing nodes, or both, without
        sending the graph. **This is the endpoint for ordinary edits** — reword
        an SMS, point a callback at a different calendar, switch AI notes on.
        Because the request carries no graph, it cannot damage one.


        Everything merges: keys you omit keep their stored value, and a key set
        to `null` is removed (RFC 7386, one level deep). Arrays replace
        wholesale, so send the full `tags` list rather than the one you are
        adding.


        Send `campaignConfig`, `nodes`, or both — both land as a single write,
        so a settings change and a node edit cannot half-apply. At least one is
        required.


        **Structure is not editable here.** `nodes` addresses existing ids only:
        it cannot add a node (`POST /outcomes/{outcome}/nodes`), remove one
        (`DELETE /nodes/{nodeId}`, which also re-links the chain around it) or
        re-wire anything (the whole-graph `PUT`). `{"nodes": {"n1": null}}` is
        rejected rather than treated as a delete, because removing a node is
        four operations and dropping the key is only one of them. `if`, `switch`
        and `trigger` nodes are refused for the same reason — their config IS
        structure, and changing a case can orphan the edge pointing at it.


        Always version-guarded. Send `expectedVersion` to protect against your
        own read being stale; without it the write is still guarded against
        anything landing between this request's read and its write. Either way a
        lost race is a 409, never a silent overwrite.


        Required API key scope: `campaign_workflows:write`.
      operationId: update-campaign-workflow
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            minLength: 1
          description: Agent id.
          example: agent_8a488fcfa8fdbf8ce8ad5ccc45
        - name: locationId
          in: query
          required: false
          schema:
            type: string
            minLength: 1
          description: Pair with campaignId; omit both for primary campaign.
          example: loc_abc123
        - name: campaignId
          in: query
          required: false
          schema:
            type: string
            minLength: 1
          description: Pair with locationId; omit both for primary campaign.
          example: cmp_123
      requestBody:
        description: Request payload. _Detailed schema pending — see the route handler._
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignWorkflowsPatchRequest'
              type: object
              additionalProperties: {}
            examples:
              default:
                value:
                  campaignConfig:
                    callbackMode: human
                    humanCallbackCalendarId: calendar_primary
                  nodes:
                    node_0:
                      config:
                        message: Thanks for booking. Reply STOP to opt out.
        required: true
      responses:
        '200':
          description: The updated workflow.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignWorkflowsReadResponse'
              examples:
                default:
                  value:
                    success: true
                    workflow:
                      locationId: loc_abc123
                      campaignId: cmp_123
                      campaignConfig:
                        callbackMode: ai
                      nodes:
                        tag_booked:
                          id: tag_booked
                          type: add-tag
                          config:
                            tags:
                              - booked_via_ai
                        sms_reminder:
                          id: sms_reminder
                          type: send-sms
                          config:
                            message: Thanks for booking! See you soon.
                      edges:
                        - id: e_booked
                          source: tag_booked
                          target: sms_reminder
                      dispositionEntries:
                        SUCCESS: tag_booked
                      version: 3
                      createdAt: '2026-07-01T09:15:22.000Z'
                      updatedAt: '2026-07-14T16:04:11.000Z'
        '400':
          description: Validation failed or the request is malformed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignWorkflowsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: VALIDATION
                    message: Workflow graph must have a nodes object.
        '401':
          description: Missing or invalid authentication.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignWorkflowsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: Unauthorized
                    message: Authentication required.
        '403':
          description: Authenticated but not permitted to access this project.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignWorkflowsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: FORBIDDEN
                    message: You do not have access to this project.
        '404':
          description: Campaign or workflow not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignWorkflowsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: NOT_FOUND
                    message: Campaign not found on this project.
        '409':
          description: The workflow changed since it was loaded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignWorkflowsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: CONFLICT
                    message: >-
                      The workflow changed since it was loaded. Re-read and
                      retry.
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignWorkflowsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: RateLimited
                    message: Rate limit exceeded. Retry after a short delay.
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignWorkflowsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: InternalError
                    message: Unexpected server error.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl --request PATCH \
              --url https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign/workflow \
              --header 'Authorization: Bearer YOUR_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{
              "campaignConfig": {
                "callbackMode": "human",
                "humanCallbackCalendarId": "calendar_primary"
              },
              "nodes": {
                "node_0": {
                  "config": {
                    "message": "Thanks for booking. Reply STOP to opt out."
                  }
                }
              }
            }'
components:
  schemas:
    CampaignWorkflowsPatchRequest:
      type: object
      additionalProperties: false
      minProperties: 1
      description: At least one of `campaignConfig` or `nodes` is required.
      properties:
        campaignConfig:
          $ref: '#/components/schemas/CampaignWorkflowsCampaignConfig'
        nodes:
          type: object
          description: >-
            Map of nodeId to the fields to merge into that node. Existing ids
            only — this cannot add, remove or re-wire a node.
          additionalProperties:
            $ref: '#/components/schemas/CampaignWorkflowsNodeEdit'
        expectedVersion:
          type: integer
          minimum: 0
          example: 3
    CampaignWorkflowsReadResponse:
      type: object
      additionalProperties: false
      required:
        - success
        - workflow
      properties:
        success:
          type: boolean
          example: true
        workflow:
          oneOf:
            - $ref: '#/components/schemas/CampaignWorkflowsWorkflow'
            - type: 'null'
        warnings:
          type: array
          description: >-
            Everything about the graph that is worth knowing and was not worth
            refusing. Empty on a clean graph. Read this after a write: a 200
            means the graph was stored, not that every node will do something.
          items:
            $ref: '#/components/schemas/CampaignWorkflowsAdvisory'
    CampaignWorkflowsErrorResponse:
      type: object
      additionalProperties: {}
      required:
        - success
        - error
        - message
      properties:
        success:
          type: boolean
        error:
          type: string
          description: >-
            Machine-readable cause. Prefer branching on the HTTP status: this
            field spans two producers and is not a single closed set.
          example: VALIDATION
        code:
          type: string
          example: VALIDATION
        message:
          type: string
          example: Workflow graph must have a nodes object.
        requiredRole:
          description: 'Present on a role-based 403: the role the route requires.'
          example: agency_admin
        requiredScope:
          type: string
          description: 'Present on a scope-based 403: the API-key scope the route requires.'
          example: campaigns:write
    CampaignWorkflowsCampaignConfig:
      type: object
      description: >-
        Campaign-level settings saved with the workflow. Documented fields cover
        supported campaign controls; additional keys (including canvas-only
        presentation state) are preserved for forward-compatible options.
      additionalProperties: {}
      properties:
        callbackMode:
          oneOf:
            - type: string
              enum:
                - ai
                - human
            - type: 'null'
          description: >-
            Who handles a callback request. `null` reads the same as absent —
            not set.
          example: ai
        humanCallbackCalendarId:
          oneOf:
            - type: string
            - type: 'null'
        noteLanguage:
          type: string
          example: en
        calendarId:
          type: string
          example: calendar_primary
        cadenceId:
          type: string
          example: cadence_three_touch
        collectAddress:
          type: boolean
          example: true
        transferNumber:
          type: string
          example: '+14155550100'
        transferToAssignedUser:
          type: boolean
          example: false
        s2lDoubleDial:
          type: boolean
          example: false
        convertedTag:
          type: string
          description: >-
            GoHighLevel tag applied when the campaign counts the lead as
            converted. Ignored on a sub-account with no CRM.
          example: booked
        aiNotes:
          type: object
          description: >-
            The "Subscribe to notes" toggles, one per outcome group. When an
            outcome's flag is true, the engine writes an AI call-summary note
            onto the GoHighLevel contact for that outcome. A sub-account with no
            CRM has no note written for it; the outcome and its summary are on
            the call record.
          additionalProperties: false
          properties:
            converted:
              type: boolean
            opt_out:
              type: boolean
            callback:
              type: boolean
            human_needed:
              type: boolean
            followup_request:
              type: boolean
            no_action:
              type: boolean
    CampaignWorkflowsNodeEdit:
      type: object
      additionalProperties: false
      minProperties: 1
      properties:
        config:
          $ref: '#/components/schemas/CampaignWorkflowsNodeConfig'
        label:
          type: string
          description: Optional display name for the node in the builder.
    CampaignWorkflowsWorkflow:
      type: object
      additionalProperties: false
      required:
        - locationId
        - campaignId
        - nodes
        - edges
        - dispositionEntries
      properties:
        locationId:
          type: string
          example: loc_9f7a123
        campaignId:
          type: string
          example: campaign_speed_to_lead_123
        campaignConfig:
          $ref: '#/components/schemas/CampaignWorkflowsCampaignConfig'
        nodes:
          type: object
          description: Workflow nodes keyed by node id.
          additionalProperties:
            $ref: '#/components/schemas/CampaignWorkflowsGraphNode'
        edges:
          type: array
          description: Directed connections between workflow nodes.
          items:
            $ref: '#/components/schemas/CampaignWorkflowsGraphEdge'
        dispositionEntries:
          type: object
          description: >-
            Maps each call outcome to the id of the node that starts its action
            chain. Keys are uppercase outcome constants: SUCCESS/BOOKED
            (booked), CONFIRMED (appointment confirmed), RESCHEDULE (rebooked),
            TRANSFER (live-transferred), TAG_APPLIED (tag objective met, on a
            GoHighLevel sub-account), CALLBACK (asked for a callback),
            INFO_ONLY/FOLLOWUP_REQUESTED (asked for information), HUMAN_NEEDED
            (asked for a person), VOICEMAIL/NO_ACTION (no outcome), KILL_SWITCH
            (opted out), FAILED_TRANSFER (transfer did not connect). Which
            outcomes an agent can emit depends on its type; the legal set per
            agent type is returned as `dispositions` by GET
            /api/v2/projects/systems. The value is the id of a node in `nodes` —
            the first node of your action chain for that outcome. The platform
            composes the canonical handler for each outcome automatically, so
            just attach your actions here; do not build your own
            trigger/detector nodes to re-detect a standard outcome. 


            `INFO_ONLY` and `FOLLOWUP_REQUESTED` are two spellings of the same
            outcome ("asked for information") and are treated as interchangeable
            at run time: outbound agent types emit `INFO_ONLY` and the inbound
            receptionist emits `FOLLOWUP_REQUESTED`, and a chain wired under
            either spelling fires for both. Use whichever the systems endpoint
            lists for your agent type. 


            A key no agent type can emit is accepted but never fires — the
            response reports it as an `unknown_outcome` warning rather than
            rejecting the write, because graphs predating a rename rely on being
            readable.
          additionalProperties:
            type: string
        version:
          type: integer
          example: 3
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    CampaignWorkflowsAdvisory:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      description: >-
        A non-fatal finding about the saved graph. Advisories never fail a
        request — an unfinished node is a legitimate draft — but each one marks
        something that will not behave the way it reads.
      properties:
        code:
          type: string
          enum:
            - node_incomplete
            - unsafe_context
            - unreachable
            - unknown_outcome
          description: >-
            `node_incomplete`: saved, but missing config it needs to do anything
            at runtime. `unsafe_context`: legal on this outcome but probably not
            what you want (the same advisory the builder shows an operator).
            `unreachable`: no outcome entry or trigger reaches it, so it never
            runs. `unknown_outcome`: the chain is wired to a disposition this
            agent type can never produce.
          example: node_incomplete
        nodeId:
          type: string
          example: sms_reminder
        outcome:
          type: string
          description: >-
            Present on `unknown_outcome`: the disposition key that will never
            fire.
          example: BOOKED_APPOINTMENT
        nodeType:
          type: string
          example: send-sms
        context:
          type: string
          description: >-
            Present on `unsafe_context`: the entry context that produced the
            finding.
          example: callback
        message:
          type: string
          example: sms_reminder.config.message is required.
    CampaignWorkflowsNodeConfig:
      type: object
      description: >-
        Node-type-specific settings. Documented fields cover supported workflow
        actions; additional keys are preserved for forward-compatible node
        options.
      additionalProperties: {}
      properties:
        signals:
          type: array
          items:
            type: string
          description: >-
            Custom boolean post-call signals a detector (`trigger`) node fires
            on. These are agent-specific post-call field names, not
            dispositions; the agent's available fields are returned as
            `postCallFields` by GET /api/v2/projects/systems, and you can define
            your own. There is no preset signal vocabulary.
          example:
            - asked_about_pricing
        tags:
          type: array
          items:
            type: string
          description: >-
            GHL tags an `add-tag`/`remove-tag` node applies. Use your own tag
            names here. The `tfu_ai_*` outcome tags (tfu_ai_booked,
            tfu_ai_standby, tfu_ai_human_needed, tfu_ai_kill_switch,
            tfu_ai_live_transfer, tfu_ai_failed_transfer, tfu_ai_cancelled) are
            applied automatically by the engine on the matching outcome and do
            not need to be set here.
          example:
            - booked_via_ai
        field:
          type: string
          description: >-
            Post-call field an `if`/`switch` node routes on (e.g. a boolean or
            category value extracted from the call).
          example: qualified
        op:
          type: string
          enum:
            - is_true
            - is_false
            - is_set
            - is_empty
            - equals
            - not_equals
            - contains
            - starts_with
            - in
            - gt
            - gte
            - lt
            - lte
        value:
          description: Value used by conditional nodes.
        cases:
          type: array
          items:
            $ref: '#/components/schemas/CampaignWorkflowsSwitchCase'
        pipelineId:
          type: string
          description: >-
            GoHighLevel pipeline a `move-stage` node moves the contact into.
            Read the ids from List GHL pipelines.
          example: pipeline_sales
        stageId:
          type: string
          description: Stage within that GoHighLevel pipeline.
          example: stage_booked
        fieldId:
          type: string
          description: >-
            GoHighLevel custom field a `set-field` node writes. Read the ids
            from List location GHL custom fields.
          example: custom_field_123
        note:
          type: string
          example: Booked from campaign call.
        message:
          type: string
          example: Thanks for calling. Our team will follow up shortly.
        subject:
          type: string
          example: Thanks for your call
        html:
          type: string
          example: <p>Thanks for your call.</p>
        calendarId:
          type: string
          example: calendar_primary
        collectAddress:
          type: boolean
          example: true
        url:
          type: string
          format: uri
          description: >-
            Receiver a `send-webhook` node posts to. Must use https. `localhost`
            and documentation domains such as `example.com` are refused on save,
            and private or internal addresses are refused at delivery.
          example: https://hooks.example.com/tfuai
    CampaignWorkflowsGraphNode:
      type: object
      additionalProperties: false
      required:
        - id
        - type
      properties:
        id:
          type: string
          example: tag_booked
        type:
          type: string
          description: >-
            Node action type. `add-tag`, `remove-tag`, `move-stage`, `send-sms`,
            `send-email` and `add-note` write into GoHighLevel and need a
            connected sub-account; `set-field`, `book-appointment`,
            `send-webhook`, `if` and `switch` work either way. The
            campaign-builder canvas also renders a "Nurture" umbrella as a
            GROUP, but `group` is an editor-only visual construct, not a
            writable node type — saving a node of type `group` is rejected.
          enum:
            - if
            - switch
            - add-tag
            - remove-tag
            - set-field
            - move-stage
            - add-note
            - send-sms
            - send-email
            - book-appointment
            - send-webhook
            - trigger
        config:
          $ref: '#/components/schemas/CampaignWorkflowsNodeConfig'
        label:
          type: string
          description: >-
            Optional display name. Carried into execution history so a step
            reads as something other than its node type.
          example: Confirmation text
    CampaignWorkflowsGraphEdge:
      type: object
      additionalProperties: false
      required:
        - id
        - source
        - target
      properties:
        id:
          type: string
          example: e_booked
        source:
          type: string
          example: tag_booked
        target:
          type: string
          example: sms_reminder
        sourceHandle:
          type: string
          description: >-
            Branch handle for conditional or switch nodes (e.g. `then`, `else`,
            a switch case id, or `default`).
          example: then
    CampaignWorkflowsSwitchCase:
      type: object
      additionalProperties: false
      required:
        - id
      description: >-
        One switch case: a stable id, which is the edge's `sourceHandle`, plus
        its test. Graphs written now carry `condition`. `value` appears on older
        graphs, where it is compared with `equals` against the switch node's
        `config.field`.
      properties:
        id:
          type: string
          example: c0
        condition:
          $ref: '#/components/schemas/CampaignWorkflowsCondition'
        value:
          description: >-
            Deprecated. Older graphs carry `value` instead of `condition`.
            Editing the workflow replaces it with `condition`. Read `condition`
            first and fall back to `value`.
          example: qualified
    CampaignWorkflowsCondition:
      type: object
      additionalProperties: false
      required:
        - field
        - op
      description: >-
        A single test against a post-call field. `value` is required for every
        operator except the unary ones (`is_true`, `is_false`, `is_set`,
        `is_empty`). The ordering operators (`gt`/`gte`/`lt`/`lte`) compare
        numerically and fail closed when either side is not a clean number.
      properties:
        field:
          type: string
          example: qualified
        op:
          type: string
          enum:
            - is_true
            - is_false
            - is_set
            - is_empty
            - equals
            - not_equals
            - contains
            - starts_with
            - in
            - gt
            - gte
            - lt
            - lte
          example: is_true
        value:
          description: Omitted for the unary operators. `in` takes an array.
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: 'Send your API key as `Authorization: Bearer YOUR_API_KEY`.'

````