openapi: 3.1.0
info:
  version: 3.0.0
  title: Reply API
  description: API for managing email sequences, contacts, and automation workflows
servers:
  - url: https://api.reply.io
security:
  - bearerAuth: []
tags:
  - name: User Account
    description: Account information and authentication verification
  - name: Accounts
    description: Manage accounts (companies/organizations)
  - name: AI Prompts
    description: Manage the AI prompts used to configure sequence steps, and preview the output a prompt produces
  - name: AI SDR Insights
    description: Read AI SDR insights for sequence contacts
  - name: AI SDR Intent Signals
    description: Read Reply industry IDs and technology slugs used in AI SDR intent-signal configuration (typeahead)
  - name: AI SDR Sequences
    description: Manage AI SDR sequences and their AI SDR-specific settings — create, read settings, partial update, autopilot enable/disable/force-start, approval mode, generated step types, and playbook/knowledge-base connections
  - name: AI SDR Web Search
    description: Find contacts via AI-driven web search and review past searches
  - name: Attachments
    description: Upload file attachments used across email templates, sequence steps, and direct emails
  - name: Account Lists
    description: Manage account lists and account membership
  - name: Background Jobs
    description: Track and cancel asynchronous background operations (e.g., email validation)
  - name: Custom Fields
    description: Manage custom contact fields
  - name: Direct Outreach
    description: Send one-off outreach directly to a contact outside of any sequence — direct emails and LinkedIn connection requests, messages, InMails, and voice messages
  - name: Contact Blacklist Rules
    description: Manage blacklist rules for domains, emails, and email exceptions
  - name: Contact Enrichment
    description: Enrich contacts with emails, phone numbers, LinkedIn data, and AI-filled custom fields
  - name: Contact Lists
    description: Manage contact lists and contact membership
  - name: Contacts
    description: Manage individual contacts
  - name: Email Accounts
    description: Manage email accounts used for sending and receiving
  - name: Email Templates
    description: Manage email templates and template folders
  - name: Email Validations
    description: Estimate and schedule asynchronous email validation jobs
  - name: Holiday Calendars
    description: Manage holiday calendars for scheduling
  - name: Inbox
    description: Manage inbox threads and per-team thread categories — list/filter, read state, replies, category assignment, and meeting-intent flagging
  - name: LinkedIn Accounts
    description: Manage LinkedIn accounts for outreach
  - name: Live Data
    description: Find new contacts via Live Data searches and read typeahead values for the Live Data / Autopilot filter sidebar
  - name: AI SDR Knowledge Bases
    description: Manage AI SDR knowledge bases — collections of documents, links, reply handlers, and reengagement cards that inform the agent's responses
  - name: AI SDR Offers
    description: Manage AI SDR offers — bundles of company-context inputs (ICP, pain points, value propositions, etc.) used to personalize outreach
  - name: AI SDR Pending Approvals
    description: Review, send, regenerate, and provide feedback on AI-generated messages awaiting human approval
  - name: AI SDR Playbooks
    description: Manage AI SDR playbooks — tone, voice, and style guides applied during personalized message generation
  - name: Reports
    description: Generate and access performance reports across email, calls, tasks, LinkedIn, and team performance
  - name: Schedules
    description: Manage email send schedules and timing
  - name: Settings
    description: Manage team and user settings
  - name: Sequence Contacts
    description: Manage contacts within sequences
  - name: Sequence Email Accounts
    description: Manage email accounts linked to sequences
  - name: Sequence Folders
    description: Organize sequences into folders
  - name: Sequence LinkedIn Accounts
    description: Manage LinkedIn accounts linked to sequences
  - name: AI SDR Sequence Preview
    description: Read and regenerate per-contact previews of the messages a sequence will send, and provide feedback on preview messages
  - name: Sequence Steps
    description: Manage individual steps in sequences
  - name: Sequence Templates
    description: Manage sequence templates
  - name: Sequences
    description: Manage email automation sequences
  - name: AI SDR Strategist
    description: Trigger AI Strategist runs
  - name: Tasks
    description: Manage tasks and to-do items
  - name: Webhooks
    description: Manage webhook subscriptions and inspect delivery history
paths:
  /v3/ai-prompts:
    get:
      tags:
        - AI Prompts
      summary: List AI prompts
      x-required-scope: sequences:read
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the AI prompts available for a given sequence step type. Pass the step type you
        are configuring and the full set is returned in one call — there is no paging. The result mixes two kinds of
        prompt: library prompts, which Reply curates and you can read but not change, and personal prompts, which you
        own and can edit or delete. Each item's scope tells you which kind it is.
      operationId: ListAiPrompts
      parameters:
        - name: stepType
          in: query
          required: true
          description: The sequence step type to list prompts for
          schema:
            type: string
            title: AI Prompt Step Type
            description: |-
              The sequence step type an AI prompt is written for. A prompt is only offered for the step type it was created
              with, and that step type cannot be changed afterwards.
            enum: &ref_0
              - commentOnRecentPost
      responses:
        '200':
          description: The prompts available for the requested step type
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: AiPrompt
                  description: An AI prompt available for configuring a sequence step.
                  properties: &ref_2
                    id:
                      type: integer
                      description: Unique identifier for the prompt
                    name:
                      type: string
                      description: Display name of the prompt
                    text:
                      type: string
                      description: The prompt instructions given to the AI
                    scope:
                      description: Whether the prompt is a read-only library prompt or your own personal prompt
                      type: string
                      title: AI Prompt Scope
                      enum: &ref_248
                        - library
                        - personal
                    stepType:
                      description: The sequence step type this prompt is written for
                      type: string
                      title: AI Prompt Step Type
                      enum: *ref_0
                  required: &ref_3
                    - id
                    - name
                    - text
                    - scope
                    - stepType
                  example: &ref_4
                    id: 123
                    name: Warm, specific comment
                    text: Write a short, genuine comment that reacts to one concrete point in the post. Avoid flattery and never pitch.
                    scope: personal
                    stepType: commentOnRecentPost
        '400':
          description: Validation error
          content:
            application/problem+json:
              schema:
                allOf: &ref_5
                  - allOf: &ref_250
                      - type: object
                        title: Problem Details
                        description: |-
                          Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                          that don't carry domain context: 401 Unauthorized (auth middleware),
                          429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                          415 (framework middleware).

                          Business and validation responses extend this envelope and add additional
                          fields — see `business-problem.model.yaml` (adds `code` slug) and
                          `validation-problem.model.yaml` (adds `errors[]` array).
                        properties: &ref_1
                          title:
                            type: string
                            description: Short, human-readable summary of the problem.
                          status:
                            type: integer
                            description: HTTP status code.
                            minimum: 100
                            maximum: 599
                          detail:
                            type: string
                            description: Human-readable explanation specific to this occurrence.
                      - type: object
                        properties:
                          errors:
                            type: array
                            description: |-
                              List of field-level validation errors. Always non-empty when this
                              envelope is returned. Each entry pins a single offending field
                              via JSON Pointer plus a sanitized detail string.
                            items:
                              type: object
                              title: Validation Error
                              description: A single field-level validation error.
                              properties: &ref_249
                                pointer:
                                  type: string
                                  description: |-
                                    JSON Pointer (RFC 6901) to the offending field — e.g.
                                    `/steps/0/subject`.

                                    * An empty string (`""`) means the error applies to the whole
                                      request body (e.g. body is missing or unparseable).
                                    * For route or query parameter failures the pointer is the parameter
                                      name (e.g. `id`, `top`).
                                  example: /steps/0/subject
                                detail:
                                  type: string
                                  description: |-
                                    Sanitized, human-readable explanation of this field's error. One of a
                                    small set of templates — `"Field is required."`, `"Value has an
                                    invalid type."`, `"Value has an invalid format."`, `"Request body is
                                    not valid JSON."`, `"The request body is required and cannot be
                                    empty."` — or a FluentValidator message on body endpoints.
                                  example: Field is required.
                    title: Validation Problem
                    description: |-
                      Input-validation error response at 400. Returned when the request body
                      fails binding, FluentValidator rules, or when route/query parameter
                      attribute validation (`[Range]`, `[Required]`) fails. Route, query, and
                      body errors are combined into a single `errors[]` array — clients should
                      not assume one error per request.
                  - example:
                      title: Validation failed
                      status: 400
                      detail: The request body contains validation errors.
                      errors:
                        - pointer: /name
                          detail: Field is required.
              example:
                title: Validation failed
                status: 400
                detail: One or more parameters did not match the expected format.
                errors:
                  - pointer: stepType
                    detail: StepType is required.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: &ref_7
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
                  - example:
                      title: Unauthorized
                      status: 401
                      detail: Authentication credentials are missing or invalid.
        '403':
          description: The API key does not grant access to AI prompts
          content:
            application/problem+json:
              schema:
                allOf: &ref_8
                  - allOf: &ref_6
                      - type: object
                        title: Problem Details
                        description: |-
                          Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                          that don't carry domain context: 401 Unauthorized (auth middleware),
                          429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                          415 (framework middleware).

                          Business and validation responses extend this envelope and add additional
                          fields — see `business-problem.model.yaml` (adds `code` slug) and
                          `validation-problem.model.yaml` (adds `errors[]` array).
                        properties: *ref_1
                      - type: object
                        properties:
                          code:
                            type: string
                            description: |-
                              Stable, machine-readable error slug in the form
                              `"<resource>.<variant>"`.

                              * `resource` is the camelCased domain — e.g. `sequence`,
                                `contact`, `inboxThread`, `blacklistDomainRule`.
                              * `variant` is the camelCased specific failure mode — e.g.
                                `notFound`, `forbidden`, `duplicateName`, `globalRuleReadOnly`.

                              Use `code` for programmatic error handling; use `detail` for
                              user-facing messages. Slugs are stable across server-side enum
                              reorderings and never change meaning under a given resource.
                            pattern: ^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)+$
                            example: sequence.notFound
                    title: Business Problem
                    description: |-
                      Domain error response carrying a stable, namespaced error slug.
                      Emitted for most 4xx responses (business 400, 403, 404, 409, …) and
                      for 503 when a downstream dependency is unavailable.
                  - example:
                      title: Forbidden
                      status: 403
                      detail: You do not have permission to access this resource.
                      code: sequence.forbidden
              example:
                title: Forbidden
                status: 403
                detail: You do not have access to this resource.
                code: aiPrompt.forbidden
        '429':
          description: Too Many Requests
          headers: &ref_9
            Retry-After:
              description: Seconds to wait before retrying
              schema:
                type: integer
                minimum: 1
          content: &ref_10
            application/problem+json:
              schema:
                allOf:
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
              example:
                title: Too Many Requests
                status: 429
                detail: Rate limit exceeded. Retry after 60 seconds.
    post:
      tags:
        - AI Prompts
      summary: Create a personal AI prompt
      x-required-scope: sequences:write
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Use this endpoint to save your own AI prompt for a sequence step type, so you can reuse it instead of retyping
        the instructions on every step. The prompt is created as a personal prompt that you can later update or delete.
        Its name must be unique among your personal prompts for that step type, and the step type is fixed at creation —
        it cannot be changed afterwards.
      operationId: CreateAiPrompt
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: AiPromptCreationRequest
              description: Request body for saving a new personal AI prompt.
              properties: &ref_251
                name:
                  type: string
                  maxLength: 256
                  description: Display name for the prompt. Must be unique among your personal prompts for the same step type.
                text:
                  type: string
                  maxLength: 2000
                  description: The prompt instructions given to the AI
                stepType:
                  description: The sequence step type this prompt is for. Fixed at creation and cannot be changed later.
                  type: string
                  title: AI Prompt Step Type
                  enum: *ref_0
              required: &ref_252
                - name
                - text
                - stepType
              example: &ref_253
                name: Warm, specific comment
                text: Write a short, genuine comment that reacts to one concrete point in the post. Avoid flattery and never pitch.
                stepType: commentOnRecentPost
      responses:
        '201':
          description: The prompt was created
          content:
            application/json:
              schema:
                type: object
                title: AiPrompt
                description: An AI prompt available for configuring a sequence step.
                properties: *ref_2
                required: *ref_3
                example: *ref_4
        '400':
          description: Request body validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: &ref_11
                      - allOf: *ref_6
                        title: Business Problem
                        description: |-
                          Domain error response carrying a stable, namespaced error slug.
                          Emitted for most 4xx responses (business 400, 403, 404, 409, …) and
                          for 503 when a downstream dependency is unavailable.
                      - example:
                          title: Bad Request
                          status: 400
                          detail: Pagination parameters are invalid.
                          code: sequence.invalidPagination
              examples:
                validation_failed:
                  summary: Request body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /text
                        detail: Text must not exceed 2000 characters.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: aiPrompt.unknown
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: The API key does not grant access to AI prompts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have access to this resource.
                code: aiPrompt.forbidden
        '409':
          description: You already have a personal prompt with this name for this step type
          content:
            application/problem+json:
              schema:
                allOf: &ref_12
                  - allOf: *ref_6
                    title: Business Problem
                    description: |-
                      Domain error response carrying a stable, namespaced error slug.
                      Emitted for most 4xx responses (business 400, 403, 404, 409, …) and
                      for 503 when a downstream dependency is unavailable.
                  - example:
                      title: Conflict
                      status: 409
                      detail: A resource with this name already exists.
                      code: sequence.duplicateName
              example:
                title: Conflict
                status: 409
                detail: A prompt named 'Warm, specific comment' already exists.
                code: aiPrompt.nameAlreadyExists
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/ai-prompts/{id}:
    put:
      tags:
        - AI Prompts
      summary: Update a personal AI prompt
      x-required-scope: sequences:write
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Use this endpoint to rename one of your personal AI prompts or rewrite its instructions. Send both the name and
        the text — the prompt is replaced with exactly what you send, so any value you omit is not preserved. The new
        name must still be unique among your personal prompts for the same step type. Only personal prompts can be
        edited; library prompts are read-only.
      operationId: UpdateAiPrompt
      parameters:
        - name: id
          in: path
          required: true
          description: AI prompt ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: AiPromptUpdateRequest
              description: |-
                Request body for updating a personal AI prompt. Both fields are required — the prompt is replaced with exactly
                what you send.
              properties: &ref_254
                name:
                  type: string
                  maxLength: 256
                  description: Display name for the prompt. Must be unique among your personal prompts for the same step type.
                text:
                  type: string
                  maxLength: 2000
                  description: The prompt instructions given to the AI
              required: &ref_255
                - name
                - text
              example: &ref_256
                name: Warm, specific comment (v2)
                text: Write a short, genuine comment that reacts to one concrete point in the post. Keep it under 30 words.
      responses:
        '200':
          description: The updated prompt
          content:
            application/json:
              schema:
                type: object
                title: AiPrompt
                description: An AI prompt available for configuring a sequence step.
                properties: *ref_2
                required: *ref_3
                example: *ref_4
        '400':
          description: Route-parameter or request-body validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Request body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: Name is required.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: aiPrompt.unknown
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: The prompt is a library prompt and cannot be edited
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Library prompts are read-only.
                code: aiPrompt.communityPromptReadOnly
        '404':
          description: AI prompt not found
          content:
            application/problem+json:
              schema:
                allOf: &ref_13
                  - allOf: *ref_6
                    title: Business Problem
                    description: |-
                      Domain error response carrying a stable, namespaced error slug.
                      Emitted for most 4xx responses (business 400, 403, 404, 409, …) and
                      for 503 when a downstream dependency is unavailable.
                  - example:
                      title: Not Found
                      status: 404
                      detail: The requested resource was not found.
                      code: sequence.notFound
              example:
                title: Not Found
                status: 404
                detail: AI prompt not found
                code: aiPrompt.notFound
        '409':
          description: You already have a personal prompt with this name for this step type
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A prompt named 'Warm, specific comment' already exists.
                code: aiPrompt.nameAlreadyExists
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - AI Prompts
      summary: Delete a personal AI prompt
      x-required-scope: sequences:write
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Use this endpoint to remove one of your personal AI prompts once you no longer need it. Sequence steps already
        configured with this prompt keep the prompt text they were saved with and continue to run. Only personal prompts
        can be deleted; library prompts are read-only.
      operationId: DeleteAiPrompt
      parameters:
        - name: id
          in: path
          required: true
          description: AI prompt ID
          schema:
            type: integer
      responses:
        '204':
          description: The prompt was deleted. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route-parameter validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: One or more parameters did not match the expected format.
                errors:
                  - pointer: id
                    detail: The 'id' parameter must be a positive.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: The prompt is a library prompt and cannot be deleted
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Library prompts are read-only.
                code: aiPrompt.communityPromptReadOnly
        '404':
          description: AI prompt not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: AI prompt not found
                code: aiPrompt.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/ai-prompts/preview/sample:
    post:
      tags:
        - AI Prompts
      summary: Preview a comment prompt against a sample post
      x-required-scope: sequences:operate
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint to try out a comment prompt against a generic sample post while you are still writing it.
        Nothing is fetched from LinkedIn and no Reply credits are spent, so this is the cheap way to iterate on wording.
        Pass sequenceId if the prompt text contains sequence variables and you want them filled in for the preview.
        Check outcome to see whether a comment was produced: generated means commentText holds the result, while any
        other value explains why the AI produced nothing. The number of sample previews you can run per day is capped.
      operationId: PreviewAiPromptOnSamplePost
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: AiPromptSamplePreviewRequest
              description: Request body for previewing a comment prompt against a generic sample post.
              properties: &ref_257
                promptText:
                  type: string
                  maxLength: 2000
                  description: The prompt instructions to test
                skipTopics:
                  type: array
                  items:
                    type: string
                  description: Topics the AI should refuse to comment on. A post matching one of these returns the `aiSkip` outcome.
                sequenceId:
                  type: integer
                  minimum: 1
                  nullable: true
                  description: |-
                    Sequence to resolve variables against when `promptText` contains sequence variables. Omit if the prompt has
                    no variables.
              required: &ref_258
                - promptText
              example: &ref_259
                promptText: Write a short, genuine comment that reacts to one concrete point in the post. Avoid flattery and never pitch.
                skipTopics:
                  - politics
                  - religion
                  - personal topics
                sequenceId: 4521
      responses:
        '200':
          description: The preview result
          content:
            application/json:
              schema:
                type: object
                title: AiPromptPreviewResponse
                description: |-
                  The result of a comment preview. Read `outcome` first — it tells you whether a comment was produced and, if not,
                  why.
                properties: &ref_14
                  outcome:
                    description: Whether a comment was generated, and why not if it was skipped
                    type: string
                    title: Comment Preview Outcome
                    enum: &ref_260
                      - generated
                      - noRecentPosts
                      - postsUnavailable
                      - commentingRestricted
                      - reshareNoText
                      - noPostContent
                      - aiSkip
                  commentText:
                    type: string
                    nullable: true
                    description: The generated comment. Populated only when `outcome` is `generated`.
                  postText:
                    type: string
                    nullable: true
                    description: The text of the post the comment was written for
                  detectedTopic:
                    type: string
                    nullable: true
                    description: The topic the AI detected in the post. Useful for checking why a post was skipped.
                  postUrl:
                    type: string
                    nullable: true
                    description: Link to the post the comment was written for
                required: &ref_15
                  - outcome
                example: &ref_16
                  outcome: generated
                  commentText: The point about onboarding friction really lands — we saw the same drop-off until we cut the setup steps in half.
                  postText: After six months of user interviews, the biggest blocker we found wasn't pricing. It was onboarding friction.
                  detectedTopic: product onboarding
                  postUrl: https://www.linkedin.com/feed/update/urn:li:activity:7100000000000000000
        '400':
          description: Request body validation failure, or the prompt text could not be rendered.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Request body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /promptText
                        detail: PromptText is required.
                prompt_render_failed:
                  summary: The prompt text could not be rendered
                  value:
                    title: Bad Request
                    status: 400
                    detail: Failed to render the prompt.
                    code: linkedInCommentPreview.promptRenderFailed
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Comment previews are not available for this account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Comment on a recent post preview is not available.
                code: linkedInCommentPreview.featureDisabled
        '429':
          description: The daily cap on sample previews has been reached
          content:
            application/problem+json:
              schema:
                description: Too Many Requests
                headers: *ref_9
                content: *ref_10
              example:
                title: Too Many Requests
                status: 429
                detail: The daily limit of sample comment generations is reached. Please try again tomorrow.
                code: linkedInCommentPreview.dailySampleLimitReached
  /v3/ai-prompts/preview/linkedin-post:
    post:
      tags:
        - AI Prompts
      summary: Preview a comment prompt against a LinkedIn post
      x-required-scope: sequences:operate
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint to test a comment prompt against a real person's latest LinkedIn post. Pass the profile you
        want to comment on and the connected LinkedIn account to look it up with; postText and postUrl in the response
        show which post the comment was written for. One Reply credit is held before generation starts and is spent
        whatever the result, including when no comment is produced, so prefer the sample preview while you are still
        iterating on wording. Check outcome to see what happened: generated means commentText holds the result, while
        any other value explains why the AI produced nothing.
      operationId: PreviewAiPromptOnLinkedInPost
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: AiPromptLinkedInPostPreviewRequest
              description: |-
                Request body for previewing a comment prompt against a real person's latest LinkedIn post. One Reply credit is
                spent per call, whatever the outcome.
              properties: &ref_261
                promptText:
                  type: string
                  maxLength: 2000
                  description: The prompt instructions to test
                linkedInProfileUrl:
                  type: string
                  description: URL of the LinkedIn profile whose latest post the comment is written for
                linkedInAccountId:
                  type: integer
                  minimum: 1
                  description: ID of the connected LinkedIn account used to look up the post
                skipTopics:
                  type: array
                  items:
                    type: string
                  description: Topics the AI should refuse to comment on. A post matching one of these returns the `aiSkip` outcome.
                skipIfNoPostsInDays:
                  type: integer
                  minimum: 1
                  maximum: 90
                  nullable: true
                  description: |-
                    Treat the profile as having nothing to comment on when its latest post is older than this many days, returning
                    the `noRecentPosts` outcome.
                sequenceId:
                  type: integer
                  minimum: 1
                  nullable: true
                  description: |-
                    Sequence to resolve variables against when `promptText` contains sequence variables. Omit if the prompt has
                    no variables.
              required: &ref_262
                - promptText
                - linkedInProfileUrl
                - linkedInAccountId
              example: &ref_263
                promptText: Write a short, genuine comment that reacts to one concrete point in the post. Avoid flattery and never pitch.
                linkedInProfileUrl: https://www.linkedin.com/in/alex-johnson
                linkedInAccountId: 456
                skipTopics:
                  - politics
                  - religion
                skipIfNoPostsInDays: 30
                sequenceId: 4521
      responses:
        '200':
          description: The preview result
          content:
            application/json:
              schema:
                type: object
                title: AiPromptPreviewResponse
                description: |-
                  The result of a comment preview. Read `outcome` first — it tells you whether a comment was produced and, if not,
                  why.
                properties: *ref_14
                required: *ref_15
                example: *ref_16
        '400':
          description: |-
            Request body validation failure, or a business rule rejection — an unusable profile URL, too few Reply
            credits, a LinkedIn account that cannot be used, or a prompt that could not be rendered.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Request body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /linkedInProfileUrl
                        detail: LinkedInProfileUrl is required.
                invalid_linkedin_url:
                  summary: The profile URL is not a usable LinkedIn profile
                  value:
                    title: Bad Request
                    status: 400
                    detail: The LinkedIn profile URL is not valid.
                    code: linkedInCommentPreview.invalidLinkedInUrl
                insufficient_credits:
                  summary: Not enough Reply credits
                  value:
                    title: Bad Request
                    status: 400
                    detail: You don't have enough Reply credits to generate a preview from a LinkedIn profile.
                    code: linkedInCommentPreview.insufficientCredits
                linkedin_account_inactive:
                  summary: The LinkedIn account cannot be used right now
                  value:
                    title: Bad Request
                    status: 400
                    detail: The LinkedIn account is not active.
                    code: linkedInCommentPreview.linkedInAccountInactive
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Comment previews are not available for this account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Comment on a recent post preview is not available.
                code: linkedInCommentPreview.featureDisabled
        '404':
          description: LinkedIn account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: LinkedIn account not found
                code: linkedInCommentPreview.linkedInAccountNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/ai-sdr/{sequence_id}/contacts/{contact_id}/ai-insights:
    get:
      tags:
        - AI SDR Insights
      summary: Get AI insights for a contact
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        Returns the AI-generated insights summary for a single (sequence, contact) pair. The summary is rendered as Markdown.

        Only available after at least one personalized message has been generated for the contact in this sequence. Returns `404` otherwise.

        Requires the AI SDR feature on the caller's team.
      operationId: GetContactAiInsights
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
        - name: contact_id
          in: path
          required: true
          description: Contact id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: AI insights for the contact
          content:
            application/json:
              schema:
                type: object
                properties:
                  summary:
                    type: string
                    description: Markdown-formatted insights summary
                    readOnly: true
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
        '404':
          description: Sequence or contact not found, or no personalized message has been generated yet for this contact
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
  /v3/ai-sdr/intent-signals/industries:
    get:
      tags:
        - AI SDR Intent Signals
      summary: Industries typeahead
      x-required-scope: ai-sdr:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of Reply industry IDs used in intent-signal configuration (e.g. `technologyUsed.industryId`, `jobHiring.industries[]`).

        Distinct taxonomy from the Live Data filter-value industries — those are string-only Sales Navigator industries.

        Requires the AI SDR feature on the caller's team.
      operationId: ListIntentSignalIndustries
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match on industry name
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of industries
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Intent Signal Industry
                      description: A single industry entry from the typeahead list, used in intent-signal configuration.
                      properties: &ref_264
                        id:
                          type: integer
                          description: Reply industry id. Use this value when wiring `technologyUsed.industryId` or `jobHiring.industries[]` on an intent signal.
                          readOnly: true
                        name:
                          type: string
                          description: Display name of the industry.
                      example: &ref_265
                        id: 47
                        name: Software Development
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: salesAgentIntentSignals.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: salesAgentIntentSignals.forbidden
        '502':
          description: Upstream service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: 'Upstream service failure: ...'
                code: salesAgentIntentSignals.upstreamFailure
  /v3/ai-sdr/intent-signals/technologies:
    get:
      tags:
        - AI SDR Intent Signals
      summary: Technologies typeahead
      x-required-scope: ai-sdr:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of Reply technology slugs used in intent-signal configuration (e.g. `technologyUsed.technologies[]`). The slug is the persisted identifier; name is display-only.

        Requires the AI SDR feature on the caller's team.
      operationId: ListIntentSignalTechnologies
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match on technology name
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of technologies
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Intent Signal Technology
                      description: A single technology entry from the typeahead list, used in intent-signal configuration.
                      properties: &ref_266
                        slug:
                          type: string
                          description: Persisted identifier — use this value in `technologyUsed.technologies[]`.
                          readOnly: true
                        name:
                          type: string
                          description: Display name of the technology.
                      example: &ref_267
                        slug: salesforce
                        name: Salesforce
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: salesAgentIntentSignals.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: salesAgentIntentSignals.forbidden
        '502':
          description: Upstream service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: 'Upstream service failure: ...'
                code: salesAgentIntentSignals.upstreamFailure
  /v3/ai-sdr/knowledge-bases:
    get:
      tags:
        - AI SDR Knowledge Bases
      summary: List knowledge bases
      x-required-scope: ai-sdr:read
      description: |-
        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of knowledge bases visible to the caller.

        Requires the AI SDR feature on the caller's team.
      operationId: ListKnowledgeBases
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match on knowledge base name
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of knowledge bases
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: KnowledgeBaseListItem
                      description: Summary representation of a knowledge base returned in list responses.
                      properties: &ref_268
                        id:
                          type: integer
                          format: int64
                          description: Unique identifier for the knowledge base
                          readOnly: true
                        name:
                          type: string
                          description: Display name of the knowledge base
                          readOnly: true
                        updatedAt:
                          type: string
                          format: date-time
                          description: Timestamp of the last modification
                          readOnly: true
                        ownerUserId:
                          type: integer
                          nullable: true
                          description: User ID of the owner. `null` when the owner has been removed from the team.
                          readOnly: true
                      example: &ref_269
                        id: 4821
                        name: Product knowledge base v3
                        updatedAt: '2026-05-10T14:32:11Z'
                        ownerUserId: 1234
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: 'Invalid pagination: ''top'' must not exceed 1000.'
                code: knowledgeBase.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
    post:
      tags:
        - AI SDR Knowledge Bases
      summary: Create a knowledge base
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Creates a new knowledge base. Only `name` is required.

        Requires the AI SDR feature on the caller's team.
      operationId: CreateKnowledgeBase
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: KnowledgeBaseCreationRequest
              description: Request body for creating a new knowledge base.
              required: &ref_270
                - name
              properties: &ref_271
                name:
                  type: string
                  description: Display name of the knowledge base
                  minLength: 1
                  maxLength: 128
                instructions:
                  type: string
                  description: Free-form instructions applied when the knowledge base is referenced by AI SDR generations.
                  maxLength: 2000
              example: &ref_272
                name: Product knowledge base v3
                instructions: Reference internal launch deck before answering pricing questions.
      responses:
        '201':
          description: Knowledge base created successfully
          content:
            application/json:
              schema:
                type: object
                title: KnowledgeBase
                description: Detailed representation of a knowledge base.
                properties: &ref_17
                  id:
                    type: integer
                    format: int64
                    description: Unique identifier for the knowledge base
                    readOnly: true
                  name:
                    type: string
                    description: Display name of the knowledge base
                  instructions:
                    type: string
                    description: Free-form instructions applied when the knowledge base is referenced by AI SDR generations.
                  updatedAt:
                    type: string
                    format: date-time
                    description: Timestamp of the last modification
                    readOnly: true
                  ownerUserId:
                    type: integer
                    nullable: true
                    description: User ID of the owner. `null` when the owner has been removed from the team.
                    readOnly: true
                example: &ref_18
                  id: 4821
                  name: Product knowledge base v3
                  instructions: Reference internal launch deck before answering pricing questions.
                  updatedAt: '2026-05-10T14:32:11Z'
                  ownerUserId: 1234
        '400':
          description: Validation failure on the request body
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /name
                    detail: '''name'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{id}:
    get:
      tags:
        - AI SDR Knowledge Bases
      summary: Get a knowledge base
      x-required-scope: ai-sdr:read
      description: |-
        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a single knowledge base by id.

        Requires the AI SDR feature on the caller's team.
      operationId: GetKnowledgeBase
      parameters:
        - name: id
          in: path
          required: true
          description: Knowledge base id
          schema:
            type: integer
            format: int64
            minimum: 1
      responses:
        '200':
          description: Knowledge base found
          content:
            application/json:
              schema:
                type: object
                title: KnowledgeBase
                description: Detailed representation of a knowledge base.
                properties: *ref_17
                example: *ref_18
        '400':
          description: Invalid `id` (not a positive integer)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /id
                    detail: '''id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
    patch:
      tags:
        - AI SDR Knowledge Bases
      summary: Update a knowledge base
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Partial update — send only the fields you want to change. At least one field must be present.

        Requires the AI SDR feature on the caller's team.
      operationId: UpdateKnowledgeBase
      parameters:
        - name: id
          in: path
          required: true
          description: Knowledge base id
          schema:
            type: integer
            format: int64
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: KnowledgeBasePatchRequest
              description: Partial update for a knowledge base. Send only the fields you want to change; absent fields retain their current value. At least one field must be present.
              properties: &ref_273
                name:
                  type: string
                  description: Updated display name (non-empty)
                  minLength: 1
                  maxLength: 128
                instructions:
                  type: string
                  description: Updated instructions. Empty string allowed (clears the instructions).
                  maxLength: 2000
              example: &ref_274
                instructions: 'Updated: reference Q3 launch deck instead of internal v2.'
      responses:
        '200':
          description: Knowledge base updated successfully
          content:
            application/json:
              schema:
                type: object
                title: KnowledgeBase
                description: Detailed representation of a knowledge base.
                properties: *ref_17
                example: *ref_18
        '400':
          description: Validation failure on the request body
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /
                    detail: At least one field must be provided.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
    delete:
      tags:
        - AI SDR Knowledge Bases
      summary: Delete a knowledge base
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Deletes a knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: DeleteKnowledgeBase
      parameters:
        - name: id
          in: path
          required: true
          description: Knowledge base id
          schema:
            type: integer
            format: int64
            minimum: 1
      responses:
        '204':
          description: Knowledge base deleted successfully
        '400':
          description: Invalid `id` (not a positive integer)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /id
                    detail: '''id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{id}/duplicate:
    post:
      tags:
        - AI SDR Knowledge Bases
      summary: Duplicate a knowledge base
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Creates a copy of an existing knowledge base, including its links, documents, reply handlers, and reengagement cards.

        Requires the AI SDR feature on the caller's team.
      operationId: DuplicateKnowledgeBase
      parameters:
        - name: id
          in: path
          required: true
          description: Knowledge base id to duplicate
          schema:
            type: integer
            format: int64
            minimum: 1
      responses:
        '201':
          description: Knowledge base duplicated successfully
          content:
            application/json:
              schema:
                type: object
                title: KnowledgeBase
                description: Detailed representation of a knowledge base.
                properties: *ref_17
                example: *ref_18
        '400':
          description: Invalid `id` (not a positive integer)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /id
                    detail: '''id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Source knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/links:
    get:
      tags:
        - AI SDR Knowledge Bases
      summary: List links
      x-required-scope: ai-sdr:read
      description: |-
        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of web links attached to a knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: ListKnowledgeBaseLinks
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          description: Parent knowledge base id
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match on link URL
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of links
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: KnowledgeBaseLink
                      description: A web link attached to a knowledge base.
                      properties: &ref_19
                        id:
                          type: string
                          format: uuid
                          description: Unique identifier for the link
                          readOnly: true
                        createdAt:
                          type: string
                          format: date-time
                          description: Timestamp when the link was added
                          readOnly: true
                        url:
                          type: string
                          description: The URL associated with the link
                          readOnly: true
                      example: &ref_20
                        id: 9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a
                        createdAt: '2026-05-10T14:32:11Z'
                        url: https://docs.example.com/product/launch
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination or path parameters
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Path parameter validation
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: /knowledge_base_id
                        detail: '''knowledge_base_id'' must be a positive integer.'
                business_invalid_pagination:
                  summary: Pagination rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: 'Invalid pagination: ''top'' must not exceed 1000.'
                    code: knowledgeBase.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
    post:
      tags:
        - AI SDR Knowledge Bases
      summary: Add a link
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Adds a web link to a knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: AddKnowledgeBaseLink
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          description: Parent knowledge base id
          schema:
            type: integer
            format: int64
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: KnowledgeBaseLinkCreationRequest
              description: Request body for adding a web link to a knowledge base.
              required: &ref_275
                - url
              properties: &ref_276
                url:
                  type: string
                  description: The URL to attach
                  minLength: 1
                  maxLength: 256
              example: &ref_277
                url: https://docs.example.com/product/launch
      responses:
        '201':
          description: Link added successfully
          content:
            application/json:
              schema:
                type: object
                title: KnowledgeBaseLink
                description: A web link attached to a knowledge base.
                properties: *ref_19
                example: *ref_20
        '400':
          description: Validation failure on the request body or upstream rejection (invalid URL shape)
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /url
                        detail: '''url'' must not be empty.'
                business_invalid_links:
                  summary: Upstream rejected the URL
                  value:
                    title: Bad Request
                    status: 400
                    detail: URL is not reachable or not allowed.
                    code: knowledgeBase.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/links/{link_id}:
    delete:
      tags:
        - AI SDR Knowledge Bases
      summary: Delete a link
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Removes a link from a knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: DeleteKnowledgeBaseLink
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          description: Parent knowledge base id
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: link_id
          in: path
          required: true
          description: Link id
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Link deleted successfully
        '400':
          description: Invalid path parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /knowledge_base_id
                    detail: '''knowledge_base_id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base or link not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Link '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a' not found in knowledge base '4821'
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/documents:
    get:
      tags:
        - AI SDR Knowledge Bases
      summary: List documents
      x-required-scope: ai-sdr:read
      description: |-
        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of file documents attached to a knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: ListKnowledgeBaseDocuments
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          description: Parent knowledge base id
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match on document name
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of documents
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: KnowledgeBaseDocument
                      description: A file document attached to a knowledge base.
                      properties: &ref_21
                        id:
                          type: string
                          format: uuid
                          description: Unique identifier for the document
                          readOnly: true
                        createdAt:
                          type: string
                          format: date-time
                          description: Timestamp when the document was uploaded
                          readOnly: true
                        name:
                          type: string
                          description: Original name of the uploaded file
                          readOnly: true
                      example: &ref_22
                        id: 9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a
                        createdAt: '2026-05-10T14:32:11Z'
                        name: product-launch-deck.pdf
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination or path parameters
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Path parameter validation
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: /knowledge_base_id
                        detail: '''knowledge_base_id'' must be a positive integer.'
                business_invalid_pagination:
                  summary: Pagination rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: 'Invalid pagination: ''top'' must not exceed 1000.'
                    code: knowledgeBase.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
    post:
      tags:
        - AI SDR Knowledge Bases
      summary: Upload a document
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Uploads a file document to a knowledge base. Maximum upload size: 100 MB.

        Requires the AI SDR feature on the caller's team.
      operationId: UploadKnowledgeBaseDocument
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          description: Parent knowledge base id
          schema:
            type: integer
            format: int64
            minimum: 1
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: The file to upload
      responses:
        '201':
          description: Document uploaded successfully
          content:
            application/json:
              schema:
                type: object
                title: KnowledgeBaseDocument
                description: A file document attached to a knowledge base.
                properties: *ref_21
                example: *ref_22
        '400':
          description: Missing/empty file or upstream rejection (unsupported format, file too large)
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                empty_file:
                  summary: Empty file
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /file
                        detail: File must not be empty.
                business_unsupported_format:
                  summary: Upstream rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: File format is not supported.
                    code: knowledgeBase.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/documents/{document_id}:
    delete:
      tags:
        - AI SDR Knowledge Bases
      summary: Delete a document
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Removes a document from a knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: DeleteKnowledgeBaseDocument
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          description: Parent knowledge base id
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: document_id
          in: path
          required: true
          description: Document id
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Document deleted successfully
        '400':
          description: Invalid path parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /knowledge_base_id
                    detail: '''knowledge_base_id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base or document not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Document '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a' not found in knowledge base '4821'
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/reply-handlers:
    get:
      tags:
        - AI SDR Knowledge Bases
      summary: List reply handlers
      x-required-scope: ai-sdr:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of reply handlers attached to a knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: ListReplyHandlers
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: top
          in: query
          required: false
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          schema:
            type: integer
        - name: search
          in: query
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of reply handlers
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: ReplyHandlerListItem
                      description: Summary representation of a reply handler returned in list responses.
                      properties: &ref_278
                        id:
                          type: string
                          format: uuid
                          description: Unique identifier for the reply handler
                          readOnly: true
                        typeOfQuestion:
                          type: string
                          description: Short label describing the type of incoming reply this handler covers
                          readOnly: true
                        instructions:
                          type: string
                          description: Instructions for how to handle replies of this type
                          readOnly: true
                        createdAt:
                          type: string
                          format: date-time
                          description: Timestamp when the reply handler was created
                          readOnly: true
                        deliveryMode:
                          description: How generated replies for this handler are delivered
                          readOnly: true
                          type: string
                          title: Reply handler delivery mode
                          enum: &ref_23
                            - draft
                            - auto
                            - stopAndNotify
                      example: &ref_279
                        id: 9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a
                        typeOfQuestion: Pricing inquiry
                        instructions: Quote our published tiered pricing; offer a discovery call for enterprise.
                        createdAt: '2026-05-10T14:32:11Z'
                        deliveryMode: draft
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination or path parameters
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Path parameter validation
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: /knowledge_base_id
                        detail: '''knowledge_base_id'' must be a positive integer.'
                business_invalid_pagination:
                  summary: Pagination rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: 'Invalid pagination: ''top'' must not exceed 1000.'
                    code: knowledgeBase.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
    post:
      tags:
        - AI SDR Knowledge Bases
      summary: Create a reply handler
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Creates a new reply handler attached to a knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: CreateReplyHandler
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: ReplyHandlerCreationRequest
              description: Request body for creating a new reply handler.
              required: &ref_280
                - typeOfQuestion
                - instructions
              properties: &ref_281
                typeOfQuestion:
                  type: string
                  minLength: 1
                  maxLength: 256
                  description: Short label describing the type of incoming reply this handler covers
                instructions:
                  type: string
                  minLength: 1
                  maxLength: 2048
                  description: Instructions for how to handle replies of this type
                sampleAnswer:
                  type: string
                  maxLength: 1024
                  description: Optional sample answer used as a few-shot example
                toneOfVoice:
                  type: string
                  title: Tone of voice
                  description: Tone applied to generated replies and reengagement messages.
                  enum: &ref_24
                    - confident
                    - persuasive
                    - witty
                    - straightforward
                    - empathetic
                responseLength:
                  type: string
                  title: Response length
                  description: Target length of generated replies and reengagement messages.
                  enum: &ref_25
                    - superShort
                    - short
                    - medium
                    - long
                links:
                  type: array
                  description: Reference URLs (max 10; each non-empty, max 256 chars)
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 256
                deliveryMode:
                  description: How generated replies for this handler are delivered. Defaults to `draft` when omitted.
                  type: string
                  title: Reply handler delivery mode
                  enum: *ref_23
                additionalNotificationEmail:
                  type: string
                  nullable: true
                  format: email
                  maxLength: 128
                  description: Extra recipient notified when a reply is handled with `stopAndNotify`. Ignored for other delivery modes.
              example: &ref_282
                typeOfQuestion: Pricing inquiry
                instructions: Quote our published tiered pricing; offer a discovery call for enterprise.
                sampleAnswer: Thanks for asking! Our tiered pricing starts at $X...
                toneOfVoice: confident
                responseLength: medium
                links:
                  - https://example.com/pricing
                deliveryMode: draft
      responses:
        '201':
          description: Reply handler created successfully
          content:
            application/json:
              schema:
                type: object
                title: ReplyHandler
                description: Detailed representation of a reply handler.
                properties: &ref_26
                  id:
                    type: string
                    format: uuid
                    description: Unique identifier for the reply handler
                    readOnly: true
                  typeOfQuestion:
                    type: string
                    description: Short label describing the type of incoming reply this handler covers
                  instructions:
                    type: string
                    description: Instructions for how to handle replies of this type
                  sampleAnswer:
                    type: string
                    description: Optional sample answer used as a few-shot example
                  toneOfVoice:
                    description: Tone applied to generated replies
                    type: string
                    title: Tone of voice
                    enum: *ref_24
                  responseLength:
                    description: Target length for generated replies
                    type: string
                    title: Response length
                    enum: *ref_25
                  links:
                    type: array
                    description: Reference URLs the AI SDR can quote when generating a reply
                    items:
                      type: string
                  media:
                    type: array
                    description: Media items attached to this reply handler. Managed via the `/media` sub-resource.
                    items:
                      type: object
                      title: KnowledgeBaseMedia
                      description: A media file attached to a reply handler or reengagement card.
                      properties: &ref_28
                        id:
                          type: integer
                          format: int64
                          description: Unique identifier for the media item
                          readOnly: true
                        fileName:
                          type: string
                          description: Original name of the uploaded file
                          readOnly: true
                        size:
                          type: integer
                          description: Size in kilobytes
                          readOnly: true
                      example: &ref_29
                        id: 12345
                        fileName: demo-screenshot.png
                        size: 248
                    readOnly: true
                  deliveryMode:
                    description: How generated replies for this handler are delivered
                    type: string
                    title: Reply handler delivery mode
                    enum: *ref_23
                  additionalNotificationEmail:
                    type: string
                    nullable: true
                    description: Extra recipient notified when a reply is handled with `stopAndNotify`. Ignored for other delivery modes.
                  createdAt:
                    type: string
                    format: date-time
                    description: Timestamp when the reply handler was created
                    readOnly: true
                example: &ref_27
                  id: 9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a
                  typeOfQuestion: Pricing inquiry
                  instructions: Quote our published tiered pricing; offer a discovery call for enterprise.
                  sampleAnswer: Thanks for asking! Our tiered pricing starts at $X...
                  toneOfVoice: confident
                  responseLength: medium
                  links:
                    - https://example.com/pricing
                  media:
                    - id: 12345
                      fileName: pricing-tiers.png
                      size: 248
                  deliveryMode: draft
                  additionalNotificationEmail: null
                  createdAt: '2026-05-10T14:32:11Z'
        '400':
          description: Validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /typeOfQuestion
                    detail: '''typeOfQuestion'' must not be empty.'
                  - pointer: /instructions
                    detail: '''instructions'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available, or the `stopAndNotify` delivery mode is not enabled for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                feature_not_available:
                  summary: AI SDR feature not enabled
                  value:
                    title: Forbidden
                    status: 403
                    detail: AI SDR feature is not available for your team
                    code: knowledgeBase.forbidden
                stop_and_notify_not_enabled:
                  summary: stopAndNotify delivery mode not enabled
                  value:
                    title: Forbidden
                    status: 403
                    detail: The 'stopAndNotify' delivery mode is not enabled for your team.
                    code: knowledgeBase.stopAndNotifyNotEnabled
        '404':
          description: Knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/reply-handlers/{reply_handler_id}:
    get:
      tags:
        - AI SDR Knowledge Bases
      summary: Get a reply handler
      x-required-scope: ai-sdr:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a single reply handler by id.

        Requires the AI SDR feature on the caller's team.
      operationId: GetReplyHandler
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: reply_handler_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Reply handler found
          content:
            application/json:
              schema:
                type: object
                title: ReplyHandler
                description: Detailed representation of a reply handler.
                properties: *ref_26
                example: *ref_27
        '400':
          description: Invalid path parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /knowledge_base_id
                    detail: '''knowledge_base_id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base or reply handler not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Reply handler '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
    patch:
      tags:
        - AI SDR Knowledge Bases
      summary: Update a reply handler
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Partial update — send only the fields you want to change. At least one field must be present. Media is not patched here; use the `/media` sub-resource.

        Requires the AI SDR feature on the caller's team.
      operationId: UpdateReplyHandler
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: reply_handler_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: ReplyHandlerPatchRequest
              description: Partial update for a reply handler. Send only the fields you want to change; absent fields retain their current value. At least one field must be present. Media is not patched here — manage it via the `/media` sub-resource.
              properties: &ref_283
                typeOfQuestion:
                  type: string
                  minLength: 1
                  maxLength: 256
                instructions:
                  type: string
                  minLength: 1
                  maxLength: 2048
                sampleAnswer:
                  type: string
                  maxLength: 1024
                toneOfVoice:
                  type: string
                  title: Tone of voice
                  description: Tone applied to generated replies and reengagement messages.
                  enum: *ref_24
                responseLength:
                  type: string
                  title: Response length
                  description: Target length of generated replies and reengagement messages.
                  enum: *ref_25
                links:
                  type: array
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 256
                deliveryMode:
                  description: How generated replies for this handler are delivered
                  type: string
                  title: Reply handler delivery mode
                  enum: *ref_23
                additionalNotificationEmail:
                  type: string
                  nullable: true
                  format: email
                  maxLength: 128
                  description: Extra recipient notified when a reply is handled with `stopAndNotify`. Ignored for other delivery modes.
              example: &ref_284
                instructions: Updated playbook — also link the v2 pricing page.
                links:
                  - https://example.com/pricing-v2
      responses:
        '200':
          description: Reply handler updated successfully
          content:
            application/json:
              schema:
                type: object
                title: ReplyHandler
                description: Detailed representation of a reply handler.
                properties: *ref_26
                example: *ref_27
        '400':
          description: Validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /
                    detail: At least one field must be provided.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available, or the `stopAndNotify` delivery mode is not enabled for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                feature_not_available:
                  summary: AI SDR feature not enabled
                  value:
                    title: Forbidden
                    status: 403
                    detail: AI SDR feature is not available for your team
                    code: knowledgeBase.forbidden
                stop_and_notify_not_enabled:
                  summary: stopAndNotify delivery mode not enabled
                  value:
                    title: Forbidden
                    status: 403
                    detail: The 'stopAndNotify' delivery mode is not enabled for your team.
                    code: knowledgeBase.stopAndNotifyNotEnabled
        '404':
          description: Knowledge base or reply handler not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Reply handler '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
    delete:
      tags:
        - AI SDR Knowledge Bases
      summary: Delete a reply handler
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Deletes a reply handler.

        Requires the AI SDR feature on the caller's team.
      operationId: DeleteReplyHandler
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: reply_handler_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Reply handler deleted successfully
        '400':
          description: Invalid path parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /knowledge_base_id
                    detail: '''knowledge_base_id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base or reply handler not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Reply handler '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/reply-handlers/{reply_handler_id}/media:
    post:
      tags:
        - AI SDR Knowledge Bases
      summary: Upload reply handler media
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Attaches a media file to a reply handler. Maximum upload size: 100 MB.

        Requires the AI SDR feature on the caller's team.
      operationId: UploadReplyHandlerMedia
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: reply_handler_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: The file to upload
      responses:
        '201':
          description: Media uploaded and attached
          content:
            application/json:
              schema:
                type: object
                title: KnowledgeBaseMedia
                description: A media file attached to a reply handler or reengagement card.
                properties: *ref_28
                example: *ref_29
        '400':
          description: Missing/empty file or upstream rejection (unsupported format, file too large)
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                empty_file:
                  summary: Empty file
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /file
                        detail: File must not be empty.
                business_invalid_parameter:
                  summary: Upstream rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: File format is not supported.
                    code: knowledgeBase.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base or reply handler not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Reply handler '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/reply-handlers/{reply_handler_id}/media/{media_id}:
    delete:
      tags:
        - AI SDR Knowledge Bases
      summary: Delete reply handler media
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Removes a media item from a reply handler.

        Requires the AI SDR feature on the caller's team.
      operationId: DeleteReplyHandlerMedia
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: reply_handler_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: media_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
      responses:
        '204':
          description: Media deleted successfully
        '400':
          description: Invalid path parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /media_id
                    detail: '''media_id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base, reply handler, or media not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Media '12345' not found on reply handler '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a'
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/reengagement-cards:
    get:
      tags:
        - AI SDR Knowledge Bases
      summary: List reengagement cards
      x-required-scope: ai-sdr:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of reengagement cards attached to a knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: ListReengagementCards
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: top
          in: query
          required: false
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          schema:
            type: integer
        - name: search
          in: query
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of reengagement cards
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: ReengagementCardListItem
                      description: Summary representation of a reengagement card returned in list responses.
                      properties: &ref_285
                        id:
                          type: string
                          format: uuid
                          description: Unique identifier for the reengagement card
                          readOnly: true
                        name:
                          type: string
                          description: Display name of the card
                          readOnly: true
                        instructions:
                          type: string
                          description: Instructions for what the reengagement message should say
                          readOnly: true
                        sendAfter:
                          type: integer
                          description: Number of days after the last contact before this card fires
                          readOnly: true
                        createdAt:
                          type: string
                          format: date-time
                          description: Timestamp when the card was created
                          readOnly: true
                        isEnabled:
                          type: boolean
                          description: Whether the card is currently active
                          readOnly: true
                        deliveryMode:
                          description: How generated reengagement messages for this card are delivered
                          readOnly: true
                          type: string
                          title: Reengagement card delivery mode
                          enum: &ref_30
                            - draft
                            - auto
                      example: &ref_286
                        id: 9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a
                        name: 30-day silent prospect
                        instructions: Gentle nudge with new case study; no hard ask.
                        sendAfter: 30
                        createdAt: '2026-05-10T14:32:11Z'
                        isEnabled: true
                        deliveryMode: draft
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination or path parameters
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Path parameter validation
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: /knowledge_base_id
                        detail: '''knowledge_base_id'' must be a positive integer.'
                business_invalid_pagination:
                  summary: Pagination rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: 'Invalid pagination: ''top'' must not exceed 1000.'
                    code: knowledgeBase.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
    post:
      tags:
        - AI SDR Knowledge Bases
      summary: Create a reengagement card
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Creates a new reengagement card attached to a knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: CreateReengagementCard
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: ReengagementCardCreationRequest
              description: Request body for creating a new reengagement card.
              required: &ref_287
                - name
                - instructions
                - sendAfter
              properties: &ref_288
                name:
                  type: string
                  minLength: 1
                  maxLength: 256
                  description: Display name of the card
                instructions:
                  type: string
                  minLength: 1
                  maxLength: 2048
                  description: Instructions for what the reengagement message should say
                sendAfter:
                  type: integer
                  minimum: 1
                  description: Number of days after the last contact before this card fires
                sampleAnswer:
                  type: string
                  maxLength: 1024
                  description: Optional sample reengagement message used as a few-shot example
                toneOfVoice:
                  type: string
                  title: Tone of voice
                  description: Tone applied to generated replies and reengagement messages.
                  enum: *ref_24
                responseLength:
                  type: string
                  title: Response length
                  description: Target length of generated replies and reengagement messages.
                  enum: *ref_25
                links:
                  type: array
                  description: Reference URLs (max 10; each non-empty, max 256 chars)
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 256
                isEnabled:
                  type: boolean
                  description: Whether the card should be created in the enabled state (defaults to `true` on create)
                deliveryMode:
                  description: How generated reengagement messages for this card are delivered. Defaults to `draft` when omitted.
                  type: string
                  title: Reengagement card delivery mode
                  enum: *ref_30
              example: &ref_289
                name: 30-day silent prospect
                instructions: Gentle nudge with new case study; no hard ask.
                sendAfter: 30
                toneOfVoice: empathetic
                responseLength: short
                links:
                  - https://example.com/case-study-northstar
                isEnabled: true
                deliveryMode: draft
      responses:
        '201':
          description: Reengagement card created successfully
          content:
            application/json:
              schema:
                type: object
                title: ReengagementCard
                description: Detailed representation of a reengagement card.
                properties: &ref_31
                  id:
                    type: string
                    format: uuid
                    description: Unique identifier for the reengagement card
                    readOnly: true
                  name:
                    type: string
                    description: Display name of the card
                  instructions:
                    type: string
                    description: Instructions for what the reengagement message should say
                  sampleAnswer:
                    type: string
                    description: Optional sample reengagement message used as a few-shot example
                  sendAfter:
                    type: integer
                    minimum: 1
                    description: Number of days after the last contact before this card fires
                  toneOfVoice:
                    type: string
                    title: Tone of voice
                    description: Tone applied to generated replies and reengagement messages.
                    enum: *ref_24
                  responseLength:
                    type: string
                    title: Response length
                    description: Target length of generated replies and reengagement messages.
                    enum: *ref_25
                  links:
                    type: array
                    description: Reference URLs the AI SDR can quote when generating a reengagement message
                    items:
                      type: string
                  media:
                    type: array
                    description: Media items attached to this card. Managed via the `/media` sub-resource.
                    items:
                      type: object
                      title: KnowledgeBaseMedia
                      description: A media file attached to a reply handler or reengagement card.
                      properties: *ref_28
                      example: *ref_29
                    readOnly: true
                  isEnabled:
                    type: boolean
                    description: Whether the card is currently active
                  deliveryMode:
                    description: How generated reengagement messages for this card are delivered
                    type: string
                    title: Reengagement card delivery mode
                    enum: *ref_30
                  createdAt:
                    type: string
                    format: date-time
                    description: Timestamp when the card was created
                    readOnly: true
                example: &ref_32
                  id: 9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a
                  name: 30-day silent prospect
                  instructions: Gentle nudge with new case study; no hard ask.
                  sampleAnswer: Hi {{firstName}}, just sharing a quick case study...
                  sendAfter: 30
                  toneOfVoice: empathetic
                  responseLength: short
                  links:
                    - https://example.com/case-study-northstar
                  media:
                    - id: 12345
                      fileName: case-study-thumbnail.png
                      size: 248
                  isEnabled: true
                  deliveryMode: draft
                  createdAt: '2026-05-10T14:32:11Z'
        '400':
          description: Validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /name
                    detail: '''name'' must not be empty.'
                  - pointer: /sendAfter
                    detail: '''sendAfter'' must be greater than or equal to 1.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '4821' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/reengagement-cards/{reengagement_card_id}:
    get:
      tags:
        - AI SDR Knowledge Bases
      summary: Get a reengagement card
      x-required-scope: ai-sdr:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a single reengagement card by id.

        Requires the AI SDR feature on the caller's team.
      operationId: GetReengagementCard
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: reengagement_card_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Reengagement card found
          content:
            application/json:
              schema:
                type: object
                title: ReengagementCard
                description: Detailed representation of a reengagement card.
                properties: *ref_31
                example: *ref_32
        '400':
          description: Invalid path parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /knowledge_base_id
                    detail: '''knowledge_base_id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base or reengagement card not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Reengagement card '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
    patch:
      tags:
        - AI SDR Knowledge Bases
      summary: Update a reengagement card
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Partial update — send only the fields you want to change. At least one field must be present. Media is not patched here; use the `/media` sub-resource.

        Requires the AI SDR feature on the caller's team.
      operationId: UpdateReengagementCard
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: reengagement_card_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: ReengagementCardPatchRequest
              description: Partial update for a reengagement card. Send only the fields you want to change; absent fields retain their current value. At least one field must be present. Media is not patched here — manage it via the `/media` sub-resource.
              properties: &ref_290
                name:
                  type: string
                  minLength: 1
                  maxLength: 256
                instructions:
                  type: string
                  minLength: 1
                  maxLength: 2048
                sampleAnswer:
                  type: string
                  maxLength: 1024
                sendAfter:
                  type: integer
                  minimum: 1
                toneOfVoice:
                  type: string
                  title: Tone of voice
                  description: Tone applied to generated replies and reengagement messages.
                  enum: *ref_24
                responseLength:
                  type: string
                  title: Response length
                  description: Target length of generated replies and reengagement messages.
                  enum: *ref_25
                links:
                  type: array
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 256
                isEnabled:
                  type: boolean
                deliveryMode:
                  description: How generated reengagement messages for this card are delivered
                  type: string
                  title: Reengagement card delivery mode
                  enum: *ref_30
              example: &ref_291
                isEnabled: false
                sendAfter: 45
      responses:
        '200':
          description: Reengagement card updated successfully
          content:
            application/json:
              schema:
                type: object
                title: ReengagementCard
                description: Detailed representation of a reengagement card.
                properties: *ref_31
                example: *ref_32
        '400':
          description: Validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /
                    detail: At least one field must be provided.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base or reengagement card not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Reengagement card '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
    delete:
      tags:
        - AI SDR Knowledge Bases
      summary: Delete a reengagement card
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Deletes a reengagement card.

        Requires the AI SDR feature on the caller's team.
      operationId: DeleteReengagementCard
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: reengagement_card_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Reengagement card deleted successfully
        '400':
          description: Invalid path parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /knowledge_base_id
                    detail: '''knowledge_base_id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base or reengagement card not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Reengagement card '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/reengagement-cards/{reengagement_card_id}/media:
    post:
      tags:
        - AI SDR Knowledge Bases
      summary: Upload reengagement card media
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Attaches a media file to a reengagement card. Maximum upload size: 100 MB.

        Requires the AI SDR feature on the caller's team.
      operationId: UploadReengagementCardMedia
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: reengagement_card_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: The file to upload
      responses:
        '201':
          description: Media uploaded and attached
          content:
            application/json:
              schema:
                type: object
                title: KnowledgeBaseMedia
                description: A media file attached to a reply handler or reengagement card.
                properties: *ref_28
                example: *ref_29
        '400':
          description: Missing/empty file or upstream rejection (unsupported format, file too large)
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                empty_file:
                  summary: Empty file
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /file
                        detail: File must not be empty.
                business_invalid_parameter:
                  summary: Upstream rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: File format is not supported.
                    code: knowledgeBase.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base or reengagement card not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Reengagement card '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a' not found
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/knowledge-bases/{knowledge_base_id}/reengagement-cards/{reengagement_card_id}/media/{media_id}:
    delete:
      tags:
        - AI SDR Knowledge Bases
      summary: Delete reengagement card media
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Removes a media item from a reengagement card.

        Requires the AI SDR feature on the caller's team.
      operationId: DeleteReengagementCardMedia
      parameters:
        - name: knowledge_base_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
        - name: reengagement_card_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: media_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
      responses:
        '204':
          description: Media deleted successfully
        '400':
          description: Invalid path parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /media_id
                    detail: '''media_id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: knowledgeBase.forbidden
        '404':
          description: Knowledge base, reengagement card, or media not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Media '12345' not found on reengagement card '9c1f8a7e-0b3a-4d11-9b9c-2c4f8a7e0b3a'
                code: knowledgeBase.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: knowledgeBase.upstreamFailure
  /v3/ai-sdr/offers:
    get:
      tags:
        - AI SDR Offers
      summary: List offers
      x-required-scope: ai-sdr:read
      description: |-
        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of offers visible to the caller.

        Requires the AI SDR feature on the caller's team.
      operationId: ListOffers
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match on offer name
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of offers
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: OfferListItem
                      description: Summary representation of an offer returned in list responses.
                      properties: &ref_292
                        id:
                          type: integer
                          format: int64
                          description: Unique identifier for the offer
                          readOnly: true
                        name:
                          type: string
                          description: Display name of the offer
                          readOnly: true
                      example: &ref_293
                        id: 4821
                        name: Q3 Enterprise Outbound
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: 'Invalid pagination: ''top'' must not exceed 1000.'
                code: offer.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: offer.forbidden
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: offer.upstreamFailure
    post:
      tags:
        - AI SDR Offers
      summary: Create an offer
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Creates a new offer. Only `name` is strictly required; all other fields default to empty.

        Requires the AI SDR feature on the caller's team.
      operationId: CreateOffer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: OfferCreationRequest
              description: Request body for creating a new offer.
              required: &ref_294
                - name
              properties: &ref_295
                name:
                  type: string
                  description: Display name of the offer
                  minLength: 1
                  maxLength: 200
                companyName:
                  type: string
                  description: The company being represented in outreach
                  maxLength: 200
                companyDescription:
                  type: string
                  description: Short description of what the company does
                  maxLength: 3000
                icp:
                  type: string
                  description: Ideal Customer Profile
                  maxLength: 1000
                reasonForOutreach:
                  type: string
                  description: Free-form rationale for the outreach
                  maxLength: 1000
                caseStudies:
                  type: array
                  description: Case studies (max 10; each non-empty, max 1000 chars)
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 1000
                painPoints:
                  type: array
                  description: Customer pain points (max 10; each non-empty, max 1000 chars)
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 1000
                proofPoints:
                  type: array
                  description: Proof points (max 10; each non-empty, max 1000 chars)
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 1000
                valuePropositions:
                  type: array
                  description: Value propositions (max 10; each non-empty, max 1000 chars)
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 1000
                callToActions:
                  type: array
                  description: Call-to-action phrasings (max 10; each non-empty, max 1000 chars)
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 1000
              example: &ref_296
                name: Q3 Enterprise Outbound
                companyName: Acme Robotics
                companyDescription: AI-driven warehouse automation for mid-market logistics.
                icp: Director of Operations at logistics companies with 200+ warehouse staff
                reasonForOutreach: Q3 push into mid-market logistics.
                caseStudies:
                  - Reduced order-pick errors 38% at NorthStar Logistics
                painPoints:
                  - Manual pick-pack errors driving customer churn
                proofPoints:
                  - Used by 4 of top 10 mid-market 3PLs
                valuePropositions:
                  - 30% pick-rate improvement in 90 days
                callToActions:
                  - 15-min demo this week?
      responses:
        '201':
          description: Offer created successfully
          content:
            application/json:
              schema:
                type: object
                title: Offer
                description: Detailed representation of an offer — the bundle of company-context inputs the AI SDR uses to personalize outreach. Returned by get/create/update responses.
                properties: &ref_33
                  id:
                    type: integer
                    format: int64
                    description: Unique identifier for the offer
                    readOnly: true
                  name:
                    type: string
                    description: Display name of the offer
                  companyName:
                    type: string
                    description: The company being represented in outreach
                  companyDescription:
                    type: string
                    description: Short description of what the company does
                  icp:
                    type: string
                    description: Ideal Customer Profile — who the offer is meant for
                  reasonForOutreach:
                    type: string
                    description: Free-form rationale shown to the AI SDR for why this outreach is being made
                  caseStudies:
                    type: array
                    description: Case studies that demonstrate the company's value
                    items:
                      type: string
                  painPoints:
                    type: array
                    description: Customer pain points this offer addresses
                    items:
                      type: string
                  proofPoints:
                    type: array
                    description: Proof points that back up the offer's claims
                    items:
                      type: string
                  valuePropositions:
                    type: array
                    description: Value propositions presented in messaging
                    items:
                      type: string
                  callToActions:
                    type: array
                    description: Call-to-action phrasings the AI SDR can use
                    items:
                      type: string
                example: &ref_34
                  id: 4821
                  name: Q3 Enterprise Outbound
                  companyName: Acme Robotics
                  companyDescription: AI-driven warehouse automation for mid-market logistics.
                  icp: Director of Operations at logistics companies with 200+ warehouse staff
                  reasonForOutreach: Q3 push into mid-market logistics — Acme just closed a marquee customer in this segment.
                  caseStudies:
                    - Reduced order-pick errors 38% at NorthStar Logistics
                  painPoints:
                    - Manual pick-pack errors driving customer churn
                    - Labor cost rising 12% YoY
                  proofPoints:
                    - Used by 4 of top 10 mid-market 3PLs
                  valuePropositions:
                    - 30% pick-rate improvement in 90 days
                  callToActions:
                    - 15-min demo this week?
        '400':
          description: Validation failure on the request body or upstream variable-validation rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: '''name'' must not be empty.'
                      - pointer: /caseStudies
                        detail: '''caseStudies'' must contain 10 items or fewer.'
                business_invalid_parameter:
                  summary: Upstream variable-validation rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Variable 'icp' exceeded the maximum length allowed by the upstream service.
                    code: offer.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: offer.forbidden
        '502':
          description: Upstream AI SDR service failure or read-back failure after create
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              examples:
                upstream_failure:
                  summary: Upstream R3 failure
                  value:
                    title: Bad Gateway
                    status: 502
                    detail: Upstream service returned an unexpected error
                    code: offer.upstreamFailure
                read_back_failed:
                  summary: Created but read-back returned null
                  value:
                    title: Bad Gateway
                    status: 502
                    detail: Offer '4821' was created but could not be read back
                    code: offer.upstreamFailure
  /v3/ai-sdr/offers/{id}:
    get:
      tags:
        - AI SDR Offers
      summary: Get an offer
      x-required-scope: ai-sdr:read
      description: |-
        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a single offer by id.

        Requires the AI SDR feature on the caller's team.
      operationId: GetOffer
      parameters:
        - name: id
          in: path
          required: true
          description: Offer id
          schema:
            type: integer
            format: int64
            minimum: 1
      responses:
        '200':
          description: Offer found
          content:
            application/json:
              schema:
                type: object
                title: Offer
                description: Detailed representation of an offer — the bundle of company-context inputs the AI SDR uses to personalize outreach. Returned by get/create/update responses.
                properties: *ref_33
                example: *ref_34
        '400':
          description: Invalid `id` (not a positive integer)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /id
                    detail: '''id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: offer.forbidden
        '404':
          description: Offer not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Offer '4821' not found
                code: offer.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: offer.upstreamFailure
    patch:
      tags:
        - AI SDR Offers
      summary: Update an offer
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Partial update — send only the fields you want to change. Array fields, if present, fully replace the current value (no item-level merge). At least one field must be present.

        Requires the AI SDR feature on the caller's team.
      operationId: UpdateOffer
      parameters:
        - name: id
          in: path
          required: true
          description: Offer id
          schema:
            type: integer
            format: int64
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: OfferPatchRequest
              description: |-
                Partial update for an offer. Send only the fields you want to change; absent fields retain their current value. At least one field must be present.

                All array fields, if present, fully replace the current value (no item-level merge).
              properties: &ref_297
                name:
                  type: string
                  description: Updated display name (non-empty)
                  minLength: 1
                  maxLength: 200
                companyName:
                  type: string
                  maxLength: 200
                companyDescription:
                  type: string
                  maxLength: 3000
                icp:
                  type: string
                  maxLength: 1000
                reasonForOutreach:
                  type: string
                  maxLength: 1000
                caseStudies:
                  type: array
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 1000
                painPoints:
                  type: array
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 1000
                proofPoints:
                  type: array
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 1000
                valuePropositions:
                  type: array
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 1000
                callToActions:
                  type: array
                  maxItems: 10
                  items:
                    type: string
                    minLength: 1
                    maxLength: 1000
              example: &ref_298
                name: Q4 Enterprise Outbound
                reasonForOutreach: Refocused on mid-market after Q3 results.
      responses:
        '200':
          description: Offer updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Offer
                description: Detailed representation of an offer — the bundle of company-context inputs the AI SDR uses to personalize outreach. Returned by get/create/update responses.
                properties: *ref_33
                example: *ref_34
        '400':
          description: Validation failure or upstream variable-validation rejection
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /
                        detail: At least one field must be provided.
                business_invalid_parameter:
                  summary: Upstream variable-validation rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Variable 'icp' exceeded the maximum length allowed by the upstream service.
                    code: offer.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: offer.forbidden
        '404':
          description: Offer not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Offer '4821' not found
                code: offer.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: offer.upstreamFailure
    delete:
      tags:
        - AI SDR Offers
      summary: Delete an offer
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Deletes an offer.

        Requires the AI SDR feature on the caller's team.
      operationId: DeleteOffer
      parameters:
        - name: id
          in: path
          required: true
          description: Offer id
          schema:
            type: integer
            format: int64
            minimum: 1
      responses:
        '204':
          description: Offer deleted successfully
        '400':
          description: Invalid `id` (not a positive integer)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /id
                    detail: '''id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: offer.forbidden
        '404':
          description: Offer not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Offer '4821' not found
                code: offer.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: offer.upstreamFailure
  /v3/ai-sdr/offers/{id}/duplicate:
    post:
      tags:
        - AI SDR Offers
      summary: Duplicate an offer
      x-required-scope: ai-sdr:write
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by early August 2026.
        </Warning>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Creates a copy of an existing offer, including its company-context fields (ICP, reason for outreach, case studies, pain points, proof points, value propositions, and calls to action). The copy is returned in the response body.

        Requires the AI SDR feature on the caller's team.
      operationId: DuplicateOffer
      parameters:
        - name: id
          in: path
          required: true
          description: Id of the offer to duplicate
          schema:
            type: integer
            format: int64
            minimum: 1
      responses:
        '201':
          description: Offer duplicated successfully
          content:
            application/json:
              schema:
                type: object
                title: Offer
                description: Detailed representation of an offer — the bundle of company-context inputs the AI SDR uses to personalize outreach. Returned by get/create/update responses.
                properties: *ref_33
                example: *ref_34
        '400':
          description: Invalid `id` (not a positive integer)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: /id
                    detail: '''id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or offer duplication is not enabled for the team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Offer duplication is not enabled for your team
                code: offer.forbidden
        '404':
          description: Source offer not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Offer '4821' not found
                code: offer.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: offer.upstreamFailure
  /v3/ai-sdr/offers/generate:
    post:
      tags:
        - AI SDR Offers
      summary: Generate an offer
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Generates an offer from a prompt or company URL, optionally seeded with previously uploaded attachments. The generated offer is persisted directly — clients do not need a separate create call.

        Returns a background job to poll via `GET /v3/background-jobs/{jobId}`; on completion its `jsonDataResult` carries the generated offer (`offerId` plus the same company-context fields returned by `GET /v3/ai-sdr/offers/{id}`).

        Requires the AI SDR feature on the caller's team.
      operationId: GenerateOffer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - prompt
              properties:
                prompt:
                  type: string
                  maxLength: 2000
                  description: Prompt or company URL to seed the generation
                attachmentIds:
                  type: array
                  description: Ids of attachments previously uploaded via `POST /v3/ai-sdr/offers/generation-attachments` (max 10)
                  items:
                    type: integer
                providerLLM:
                  type: string
                  description: LLM provider to generate with. Defaults to `claude` when omitted.
                  enum:
                    - claude
                    - openAi
                    - gemini
                    - mistral
      responses:
        '202':
          description: Generation accepted; poll the returned job for progress and the generated offer
          content:
            application/json:
              schema:
                type: object
                required:
                  - jobId
                properties:
                  jobId:
                    type: string
                    format: uuid
                    description: Background job id; poll `GET /v3/background-jobs/{jobId}`.
        '400':
          description: Request body validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /prompt
                    detail: '''prompt'' must not be empty.'
                  - pointer: /attachmentIds
                    detail: AttachmentIds cannot contain more than 10 items.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: offer.forbidden
        '502':
          description: Upstream AI SDR service failure while starting the generation
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: offer.upstreamFailure
  /v3/ai-sdr/offers/generation-attachments:
    post:
      tags:
        - AI SDR Offers
      summary: Upload an attachment for offer generation
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Uploads a single attachment whose id can be passed in `attachmentIds` of `POST /v3/ai-sdr/offers/generate` to seed the generation. Maximum size 10 MB; supported formats are `.txt`, `.pdf`, `.doc`, `.docx`, and `.rtf`.

        Requires the AI SDR feature on the caller's team.
      operationId: UploadOfferGenerationAttachment
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
      responses:
        '200':
          description: Attachment uploaded
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                    readOnly: true
                  name:
                    type: string
                    readOnly: true
        '400':
          description: Missing file, file exceeding the 10 MB limit, or an unsupported file format
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Attachment exceeds the maximum allowed size of 10485760 bytes
                code: offer.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: offer.forbidden
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: offer.upstreamFailure
  /v3/ai-sdr/approvals:
    get:
      tags:
        - AI SDR Pending Approvals
      summary: List pending approvals
      x-required-scope: ai-sdr:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of AI-generated messages awaiting human approval before being sent.

        Requires the AI SDR feature on the caller's team.
      operationId: ListApprovals
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: sequenceId
          in: query
          required: false
          description: Filter by sequence id
          schema:
            type: integer
        - name: userId
          in: query
          required: false
          description: Filter by approval owner (user id)
          schema:
            type: integer
        - name: channel
          in: query
          required: false
          description: Filter by message channel
          schema:
            type: string
            enum:
              - email
              - linkedIn
        - name: sortMode
          in: query
          required: false
          description: Order of returned items (default `newestFirst`)
          schema:
            type: string
            enum:
              - newestFirst
              - oldestFirst
      responses:
        '200':
          description: Paginated list of pending approvals
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        sequenceId:
                          type: integer
                          readOnly: true
                        contactId:
                          type: integer
                          readOnly: true
                        contactFullName:
                          type: string
                          readOnly: true
                        contactTitle:
                          type: string
                          readOnly: true
                        contactCompany:
                          type: string
                          readOnly: true
                        sequenceName:
                          type: string
                          readOnly: true
                        channel:
                          type: string
                          enum:
                            - email
                            - linkedIn
                          readOnly: true
                        stepDisplayName:
                          type: string
                          readOnly: true
                        messageSubject:
                          type:
                            - string
                            - 'null'
                          readOnly: true
                        messageContent:
                          type: string
                          readOnly: true
                        isRegenerating:
                          type: boolean
                          readOnly: true
                        createdAt:
                          type: string
                          format: date-time
                          readOnly: true
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: salesAgentApproval.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: salesAgentApproval.forbidden
  /v3/ai-sdr/approvals/send-bulk:
    post:
      tags:
        - AI SDR Pending Approvals
      summary: Send a batch of pending approvals
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Approves and sends the queued AI-generated messages for up to 20 (sequence, contact) pairs in one call. Bodies and subjects cannot be overridden in bulk — use the per-contact endpoint for that.

        Requires the AI SDR feature on the caller's team.
      operationId: SendApprovalsBulk
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - items
              properties:
                items:
                  type: array
                  minItems: 1
                  maxItems: 20
                  items:
                    type: object
                    required:
                      - sequenceId
                      - contactId
                    properties:
                      sequenceId:
                        type: integer
                        minimum: 1
                      contactId:
                        type: integer
                        minimum: 1
      responses:
        '204':
          description: Bulk send accepted
        '400':
          description: Request body validation failed
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /items
                    detail: Items must contain at most 20 items.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: salesAgentApproval.forbidden
        '404':
          description: No pending approval exists for one or more of the given (sequence, contact) pairs
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: 'No pending approval found for: (sequence 100, contact 200)'
                code: salesAgentApproval.notFound
  /v3/sequences/ai-sdr/{sequence_id}/contacts/{contact_id}/approval:
    get:
      tags:
        - AI SDR Pending Approvals
      summary: Get pending approval for a contact
      x-required-scope: ai-sdr:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns the pending AI-generated message for a single (sequence, contact) pair, including the prior message thread for context.

        Requires the AI SDR feature on the caller's team.
      operationId: GetApprovalByContact
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
        - name: contact_id
          in: path
          required: true
          description: Contact id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Pending approval found
          content:
            application/json:
              schema:
                type: object
                properties:
                  sequenceId:
                    type: integer
                    readOnly: true
                  contactId:
                    type: integer
                    readOnly: true
                  contactFullName:
                    type: string
                    readOnly: true
                  contactTitle:
                    type: string
                    readOnly: true
                  contactCompany:
                    type: string
                    readOnly: true
                  sequenceName:
                    type: string
                    readOnly: true
                  channel:
                    type: string
                    enum:
                      - email
                      - linkedIn
                    readOnly: true
                  stepDisplayName:
                    type: string
                    readOnly: true
                  messageSubject:
                    type:
                      - string
                      - 'null'
                    readOnly: true
                  messageContent:
                    type: string
                    readOnly: true
                  isRegenerating:
                    type: boolean
                    readOnly: true
                  createdAt:
                    type: string
                    format: date-time
                    readOnly: true
                  previousMessages:
                    type: array
                    readOnly: true
                    items:
                      type: object
                      properties:
                        channel:
                          type: string
                          enum:
                            - email
                            - linkedIn
                          readOnly: true
                        senderName:
                          type: string
                          readOnly: true
                        senderEmail:
                          type:
                            - string
                            - 'null'
                          readOnly: true
                        subject:
                          type:
                            - string
                            - 'null'
                          readOnly: true
                        body:
                          type: string
                          readOnly: true
                        sentAt:
                          type: string
                          format: date-time
                          readOnly: true
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: salesAgentApproval.forbidden
        '404':
          description: No pending approval exists for the given (sequence, contact) pair
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: No pending approval found for sequence 100 and contact 200.
                code: salesAgentApproval.notFound
    delete:
      tags:
        - AI SDR Pending Approvals
      summary: Reject (delete) a pending approval
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Discards the pending AI-generated message for a contact and removes the contact from the sequence. The queued draft and its personalization step are deleted.

        Requires the AI SDR feature on the caller's team.
      operationId: DeleteApproval
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
        - name: contact_id
          in: path
          required: true
          description: Contact id
          schema:
            type: integer
            minimum: 1
      responses:
        '204':
          description: Approval discarded and contact removed from the sequence
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: salesAgentApproval.forbidden
        '404':
          description: No pending approval exists for the given (sequence, contact) pair
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: No pending approval found for sequence 100 and contact 200.
                code: salesAgentApproval.notFound
  /v3/sequences/ai-sdr/{sequence_id}/contacts/{contact_id}/approval/send:
    post:
      tags:
        - AI SDR Pending Approvals
      summary: Send a pending approval
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Approves and sends the queued AI-generated message for a single (sequence, contact) pair. Optionally override the draft body and/or subject before sending.

        Requires the AI SDR feature on the caller's team.
      operationId: SendApproval
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
        - name: contact_id
          in: path
          required: true
          description: Contact id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                body:
                  type: string
                  description: Override the draft body before sending
                subject:
                  type: string
                  description: Override the draft subject before sending
      responses:
        '204':
          description: Message sent
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: salesAgentApproval.forbidden
        '404':
          description: No pending approval exists for the given (sequence, contact) pair
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: No pending approval found for sequence 100 and contact 200.
                code: salesAgentApproval.notFound
  /v3/sequences/ai-sdr/{sequence_id}/contacts/{contact_id}/approval/regenerate:
    post:
      tags:
        - AI SDR Pending Approvals
      summary: Regenerate a pending approval
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Starts a background job that regenerates the AI-generated message for a single (sequence, contact) pair, and returns the job id. Optionally pass freeform `recommendations` to steer the regeneration.

        Poll `GET /v3/background-jobs/{jobId}` for status; when the job finishes, its result holds the regenerated `subject` and `body`.

        Requires the AI SDR feature on the caller's team.
      operationId: RegenerateApproval
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
        - name: contact_id
          in: path
          required: true
          description: Contact id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                recommendations:
                  type: string
                  description: Freeform guidance to steer the regenerated message
      responses:
        '202':
          description: Regeneration started; poll the returned background job for the result
          content:
            application/json:
              schema:
                type: object
                properties:
                  jobId:
                    type: string
                    format: uuid
                    readOnly: true
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: salesAgentApproval.forbidden
        '404':
          description: No pending approval exists for the given (sequence, contact) pair
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: No pending approval found for sequence 100 and contact 200.
                code: salesAgentApproval.notFound
        '502':
          description: Upstream service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: 'Upstream service failure: ...'
                code: salesAgentApproval.upstreamFailure
  /v3/sequences/ai-sdr/{sequence_id}/contacts/{contact_id}/approval/feedback:
    post:
      tags:
        - AI SDR Pending Approvals
      summary: Submit feedback on a pending approval
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        Records a thumbs-up / thumbs-down reaction on the queued AI-generated message, with optional dislike reasons and a freeform comment. Used as a training signal for the AI SDR. No step identifier is needed — the approval is unique per (sequence, contact).

        Requires the AI SDR feature on the caller's team.
      operationId: SubmitApprovalFeedback
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
        - name: contact_id
          in: path
          required: true
          description: Contact id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - vote
              properties:
                vote:
                  type: string
                  enum:
                    - like
                    - dislike
                dislikeReasons:
                  type: array
                  description: Categorized reasons when `vote` is `dislike`. The exact enum is still being finalized — coming soon.
                  items:
                    type: string
                comment:
                  type: string
                  description: Freeform comment from the user
      responses:
        '204':
          description: Feedback recorded
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
        '404':
          description: No pending approval exists for the given (sequence, contact) pair
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
  /v3/ai-sdr/playbooks:
    get:
      tags:
        - AI SDR Playbooks
      summary: List playbooks
      x-required-scope: ai-sdr:read
      description: |-
        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of playbooks visible to the caller. When `type` is omitted, results from all three scopes (`global`, `organization`, `team`) are merged.

        Requires the AI SDR feature on the caller's team.
      operationId: ListPlaybooks
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: type
          in: query
          required: false
          description: Filter to a single scope. Omit to merge all scopes.
          schema:
            type: string
            title: Playbook scope
            description: |-
              Identifies the visibility scope of a playbook.

              - `global` — Reply-curated, read-only across all teams.
              - `organization` — visible to every team in the caller's organization.
              - `team` — visible to the caller's team only.

              `global` playbooks are never created or modified via the API; only `organization` and `team` are accepted on create.
            enum: &ref_35
              - global
              - organization
              - team
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match on playbook name
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of playbooks
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: PlaybookListItem
                      description: Summary representation of a playbook returned in list responses.
                      properties: &ref_299
                        id:
                          type: string
                          description: |-
                            Composite identifier formatted as `{prefix}-{numericId}` where the prefix encodes the playbook scope:
                            `g` for `global`, `o` for `organization`, `t` for `team` (e.g. `g-1`, `o-42`, `t-7`).
                          readOnly: true
                        name:
                          type: string
                          description: Display name of the playbook
                          readOnly: true
                        description:
                          type: string
                          description: Short description of the playbook's purpose
                          readOnly: true
                        type:
                          allOf:
                            - type: string
                              title: Playbook scope
                              description: |-
                                Identifies the visibility scope of a playbook.

                                - `global` — Reply-curated, read-only across all teams.
                                - `organization` — visible to every team in the caller's organization.
                                - `team` — visible to the caller's team only.

                                `global` playbooks are never created or modified via the API; only `organization` and `team` are accepted on create.
                              enum: *ref_35
                          description: Visibility scope of the playbook. Set on create and immutable thereafter.
                          readOnly: true
                        lastUpdatedAt:
                          type: string
                          format: date-time
                          description: Timestamp of the last modification
                          readOnly: true
                        authorUserId:
                          type: integer
                          nullable: true
                          description: User ID of the playbook author. `null` for `global` playbooks and when the original author is no longer a team member.
                          readOnly: true
                      example: &ref_300
                        id: t-7
                        name: Outbound playbook v2
                        description: Tone and pacing for cold outreach
                        type: team
                        lastUpdatedAt: '2026-05-10T14:32:11Z'
                        authorUserId: 4821
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: 'Invalid pagination: ''top'' must not exceed 1000.'
                code: playbook.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: playbook.forbidden
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: playbook.upstreamFailure
    post:
      tags:
        - AI SDR Playbooks
      summary: Create a playbook
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Creates a new playbook in the `organization` or `team` scope. `global` playbooks are Reply-curated and cannot be created via the API.

        Requires the AI SDR feature on the caller's team.
      operationId: CreatePlaybook
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: PlaybookCreationRequest
              description: Request body for creating a new playbook.
              required: &ref_301
                - name
                - description
                - body
                - type
              properties: &ref_302
                name:
                  type: string
                  description: Display name of the playbook
                  minLength: 1
                  maxLength: 128
                description:
                  type: string
                  description: Short description of the playbook's purpose. Empty string allowed.
                  maxLength: 1000
                body:
                  type: string
                  description: Full playbook body — typically Markdown or plain text instructions the AI SDR follows when this playbook is applied. Empty string allowed.
                type:
                  allOf:
                    - type: string
                      title: Playbook scope
                      description: |-
                        Identifies the visibility scope of a playbook.

                        - `global` — Reply-curated, read-only across all teams.
                        - `organization` — visible to every team in the caller's organization.
                        - `team` — visible to the caller's team only.

                        `global` playbooks are never created or modified via the API; only `organization` and `team` are accepted on create.
                      enum: *ref_35
                  description: |-
                    Visibility scope for the new playbook. Only `organization` and `team` are accepted —
                    `global` playbooks are Reply-curated and cannot be created via the API.
              example: &ref_303
                name: Outbound playbook v2
                description: Tone and pacing for cold outreach
                body: |-
                  ## Voice
                  Friendly, concise, never desperate.

                  ## Pacing
                  Two touches per week max.
                type: team
      responses:
        '201':
          description: Playbook created successfully
          content:
            application/json:
              schema:
                type: object
                title: Playbook
                description: Detailed representation of a playbook, returned by get/create/update responses.
                properties: &ref_36
                  id:
                    type: string
                    description: |-
                      Composite identifier formatted as `{prefix}-{numericId}` where the prefix encodes the playbook scope:
                      `g` for `global`, `o` for `organization`, `t` for `team` (e.g. `g-1`, `o-42`, `t-7`).
                    readOnly: true
                  name:
                    type: string
                    description: Display name of the playbook
                  description:
                    type: string
                    description: Short description of the playbook's purpose
                  body:
                    type: string
                    description: Full playbook body — typically Markdown or plain text instructions the AI SDR follows when this playbook is applied.
                  type:
                    allOf:
                      - type: string
                        title: Playbook scope
                        description: |-
                          Identifies the visibility scope of a playbook.

                          - `global` — Reply-curated, read-only across all teams.
                          - `organization` — visible to every team in the caller's organization.
                          - `team` — visible to the caller's team only.

                          `global` playbooks are never created or modified via the API; only `organization` and `team` are accepted on create.
                        enum: *ref_35
                    description: Visibility scope of the playbook. Set on create and immutable thereafter.
                    readOnly: true
                  lastUpdatedAt:
                    type: string
                    format: date-time
                    description: Timestamp of the last modification
                    readOnly: true
                  authorUserId:
                    type: integer
                    nullable: true
                    description: User ID of the playbook author. `null` for `global` playbooks and when the original author is no longer a team member.
                    readOnly: true
                  styleFiles:
                    type: array
                    description: Style files attached to the playbook. Managed via the `/style-files` sub-resource — uploads are immediate, deletes are immediate; the field is read-only on the playbook payload.
                    items:
                      type: object
                      title: PlaybookStyleFile
                      description: A single style file attached to a playbook. Style files are reference documents (PDFs, text excerpts, etc.) that inform tone and voice when the playbook is applied.
                      properties: &ref_38
                        id:
                          type: integer
                          format: int64
                          description: Unique identifier for the style file
                          readOnly: true
                        fileName:
                          type: string
                          description: Original name of the uploaded file
                          readOnly: true
                      example: &ref_39
                        id: 12345
                        fileName: tone-guide.pdf
                    readOnly: true
                example: &ref_37
                  id: t-7
                  name: Outbound playbook v2
                  description: Tone and pacing for cold outreach
                  body: |-
                    ## Voice
                    Friendly, concise, never desperate.

                    ## Pacing
                    Two touches per week max.
                  type: team
                  lastUpdatedAt: '2026-05-10T14:32:11Z'
                  authorUserId: 4821
                  styleFiles:
                    - id: 12345
                      fileName: tone-guide.pdf
        '400':
          description: 'Validation failure on the request body or a business rule rejection (e.g. `type: "global"`).'
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: '''name'' must not be empty.'
                business_invalid_type:
                  summary: Global type rejected on create
                  value:
                    title: Bad Request
                    status: 400
                    detail: Playbook type must be 'organization' or 'team'. Global playbooks cannot be created via the API.
                    code: playbook.invalidType
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: playbook.forbidden
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: playbook.upstreamFailure
  /v3/ai-sdr/playbooks/{id}:
    get:
      tags:
        - AI SDR Playbooks
      summary: Get a playbook
      x-required-scope: ai-sdr:read
      description: |-
        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns a single playbook by its composite id (`g-N` / `o-N` / `t-N`).

        Requires the AI SDR feature on the caller's team.
      operationId: GetPlaybook
      parameters:
        - name: id
          in: path
          required: true
          description: Composite playbook id (`g-N` for global, `o-N` for organization, `t-N` for team)
          schema:
            type: string
      responses:
        '200':
          description: Playbook found
          content:
            application/json:
              schema:
                type: object
                title: Playbook
                description: Detailed representation of a playbook, returned by get/create/update responses.
                properties: *ref_36
                example: *ref_37
        '400':
          description: Malformed playbook id
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Playbook id 'foo-7' is not a valid composite identifier.
                code: playbook.invalidIdFormat
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: playbook.forbidden
        '404':
          description: Playbook not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Playbook 't-99' not found
                code: playbook.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: playbook.upstreamFailure
    patch:
      tags:
        - AI SDR Playbooks
      summary: Update a playbook
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Partial update — send only the fields you want to change. `type` is immutable.

        Requires the AI SDR feature on the caller's team.
      operationId: UpdatePlaybook
      parameters:
        - name: id
          in: path
          required: true
          description: Composite playbook id (`g-N` / `o-N` / `t-N`)
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: PlaybookPatchRequest
              description: |-
                Partial update for a playbook. Send only the fields you want to change; absent fields retain their current value. At least one of `name`, `description`, or `body` must be present.

                `type` is immutable after creation and cannot be patched.
              properties: &ref_304
                name:
                  type: string
                  description: Updated display name
                  minLength: 1
                  maxLength: 128
                description:
                  type: string
                  description: Updated description. Empty string allowed (clears the description).
                  maxLength: 1000
                body:
                  type: string
                  description: Updated body. Empty string allowed (clears the body).
              example: &ref_305
                name: Outbound playbook v3
                description: Refined tone and pacing for cold outreach
      responses:
        '200':
          description: Playbook updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Playbook
                description: Detailed representation of a playbook, returned by get/create/update responses.
                properties: *ref_36
                example: *ref_37
        '400':
          description: Validation failure or malformed playbook id
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /
                        detail: At least one field must be provided.
                business_invalid_id:
                  summary: Malformed id
                  value:
                    title: Bad Request
                    status: 400
                    detail: Playbook id 'foo-7' is not a valid composite identifier.
                    code: playbook.invalidIdFormat
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: playbook.forbidden
        '404':
          description: Playbook not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Playbook 't-99' not found
                code: playbook.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: playbook.upstreamFailure
    delete:
      tags:
        - AI SDR Playbooks
      summary: Delete a playbook
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Deletes a playbook. `global` playbooks cannot be deleted via the API.

        Requires the AI SDR feature on the caller's team.
      operationId: DeletePlaybook
      parameters:
        - name: id
          in: path
          required: true
          description: Composite playbook id (`o-N` / `t-N`)
          schema:
            type: string
      responses:
        '204':
          description: Playbook deleted successfully
        '400':
          description: Malformed playbook id
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Playbook id 'foo-7' is not a valid composite identifier.
                code: playbook.invalidIdFormat
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: playbook.forbidden
        '404':
          description: Playbook not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Playbook 't-99' not found
                code: playbook.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: playbook.upstreamFailure
  /v3/ai-sdr/playbooks/{id}/duplicate:
    post:
      tags:
        - AI SDR Playbooks
      summary: Duplicate a playbook
      x-required-scope: ai-sdr:write
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by early August 2026.
        </Warning>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Creates a copy of an existing playbook and returns the new playbook in the response body. `global` playbooks can also be duplicated.

        Requires the AI SDR feature on the caller's team.
      operationId: DuplicatePlaybook
      parameters:
        - name: id
          in: path
          required: true
          description: Composite id of the playbook to duplicate (`g-N` for global, `o-N` for organization, `t-N` for team)
          schema:
            type: string
      responses:
        '201':
          description: Playbook duplicated successfully
          content:
            application/json:
              schema:
                type: object
                title: Playbook
                description: Detailed representation of a playbook, returned by get/create/update responses.
                properties: *ref_36
                example: *ref_37
        '400':
          description: Malformed playbook id
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Playbook id 'foo-7' is not a valid composite identifier.
                code: playbook.invalidIdFormat
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, playbook duplication is not enabled for the team, or the caller lacks permission to duplicate this playbook
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Playbook duplication is not enabled for your team
                code: playbook.forbidden
        '404':
          description: Source playbook not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Playbook 't-99' not found
                code: playbook.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: playbook.upstreamFailure
  /v3/ai-sdr/playbooks/{playbook_id}/style-files:
    post:
      tags:
        - AI SDR Playbooks
      summary: Upload a style file
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Uploads a style file (reference document) to a playbook. Style files inform tone and voice when the playbook is applied. Maximum upload size: 100 MB.

        Requires the AI SDR feature on the caller's team.
      operationId: UploadPlaybookStyleFile
      parameters:
        - name: playbook_id
          in: path
          required: true
          description: Composite playbook id (`o-N` / `t-N`)
          schema:
            type: string
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: The file to upload
      responses:
        '201':
          description: Style file uploaded successfully
          content:
            application/json:
              schema:
                type: object
                title: PlaybookStyleFile
                description: A single style file attached to a playbook. Style files are reference documents (PDFs, text excerpts, etc.) that inform tone and voice when the playbook is applied.
                properties: *ref_38
                example: *ref_39
        '400':
          description: Missing/empty file, malformed playbook id, or upstream rejection (file too large, unsupported format)
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                empty_file:
                  summary: Empty file
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /file
                        detail: File must not be empty.
                business_invalid_parameter:
                  summary: Upstream rejection (file too large)
                  value:
                    title: Bad Request
                    status: 400
                    detail: Uploaded file exceeds the maximum allowed size.
                    code: playbook.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: playbook.forbidden
        '404':
          description: Playbook not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Playbook 't-99' not found
                code: playbook.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: playbook.upstreamFailure
  /v3/ai-sdr/playbooks/{playbook_id}/style-files/{style_file_id}:
    delete:
      tags:
        - AI SDR Playbooks
      summary: Delete a style file
      x-required-scope: ai-sdr:write
      description: |-
        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Removes a style file from a playbook.

        Requires the AI SDR feature on the caller's team.
      operationId: DeletePlaybookStyleFile
      parameters:
        - name: playbook_id
          in: path
          required: true
          description: Composite playbook id (`o-N` / `t-N`)
          schema:
            type: string
        - name: style_file_id
          in: path
          required: true
          description: Style file id
          schema:
            type: integer
            format: int64
            minimum: 1
      responses:
        '204':
          description: Style file deleted successfully
        '400':
          description: Malformed playbook id
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Playbook id 'foo-7' is not a valid composite identifier.
                code: playbook.invalidIdFormat
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: playbook.forbidden
        '404':
          description: Playbook or style file not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Style file '12345' not found in playbook 't-99'
                code: playbook.notFound
        '502':
          description: Upstream AI SDR service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: playbook.upstreamFailure
  /v3/sequences/ai-sdr/{sequence_id}/contacts/{contact_id}/preview/steps/{step_id}/feedback:
    post:
      tags:
        - AI SDR Sequence Preview
      summary: Submit feedback on a preview step
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        Records a thumbs-up / thumbs-down reaction on the AI-generated message for a specific step in a contact's preview, with optional dislike reasons and a freeform comment. Used as a training signal for the AI SDR.

        Requires the AI SDR feature on the caller's team.
      operationId: SubmitPreviewStepFeedback
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
        - name: contact_id
          in: path
          required: true
          description: Contact id
          schema:
            type: integer
            minimum: 1
        - name: step_id
          in: path
          required: true
          description: Sequence step id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - vote
              properties:
                vote:
                  type: string
                  enum:
                    - like
                    - dislike
                dislikeReasons:
                  type: array
                  description: Categorized reasons when `vote` is `dislike`. The exact enum is still being finalized — coming soon.
                  items:
                    type: string
                comment:
                  type: string
                  description: Freeform comment from the user
      responses:
        '204':
          description: Feedback recorded
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
        '404':
          description: Sequence, contact, step, or preview message not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
  /v3/sequences/ai-sdr/{sequence_id}/contacts/{contact_id}/preview/personalize:
    post:
      tags:
        - AI SDR Sequence Preview
      summary: Personalize the preview for a contact
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Kicks off (or re-runs) AI personalization for a single contact in an AI SDR sequence.

        Personalization runs step-by-step in the background. The whole step chain for the contact is tracked by a single background job: the response returns its `jobId`, and progress advances as `personalizedSteps / totalSteps`. Poll the generic `GET /v3/background-jobs/{id}` endpoint for status and progress; on completion the job's `jsonDataResult` carries `{ sequenceId, contactId, personalizedSteps, totalSteps }`. A chain that ended early (for example, the contact was removed mid-chain) reports `personalizedSteps < totalSteps`.

        Requires the AI SDR feature on the caller's team.
      operationId: PersonalizeSequencePreview
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
        - name: contact_id
          in: path
          required: true
          description: Contact id
          schema:
            type: integer
            minimum: 1
      responses:
        '202':
          description: Personalization accepted; poll the returned job for progress
          content:
            application/json:
              schema:
                type: object
                required:
                  - jobId
                properties:
                  jobId:
                    type: string
                    format: uuid
                    description: Background job id; poll `GET /v3/background-jobs/{id}`.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR personalization is not available for this sequence.
                code: salesAgentPreview.forbidden
        '404':
          description: Sequence or contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact 200 was not found in sequence 100.
                code: salesAgentPreview.notFound
        '409':
          description: |-
            Personalization could not be started. The `code` distinguishes the cause:
            `salesAgentPreview.noPersonalizableSteps` (the sequence has no steps with AI personalization enabled),
            `salesAgentPreview.activePersonalizationsLimitExceeded` (the sequence is already at its active-personalization limit),
            or `salesAgentPreview.alreadyInProgress` (personalization for this contact is already running).
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Personalization is already in progress for contact 200 in sequence 100.
                code: salesAgentPreview.alreadyInProgress
        '500':
          description: Personalization could not be started due to an unexpected internal error
          content:
            application/problem+json:
              schema:
                allOf: *ref_6
                title: Business Problem
                description: |-
                  Domain error response carrying a stable, namespaced error slug.
                  Emitted for most 4xx responses (business 400, 403, 404, 409, …) and
                  for 503 when a downstream dependency is unavailable.
              example:
                title: Internal Server Error
                status: 500
                detail: Personalization could not be started for contact 200 in sequence 100 due to internal error
                code: salesAgentPreview.unknown
        '502':
          description: Upstream service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: 'Upstream service failure: ...'
                code: salesAgentPreview.upstreamFailure
  /v3/sequences/ai-sdr:
    post:
      tags:
        - AI SDR Sequences
      summary: Create an AI SDR sequence
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Creates a new AI SDR sequence with its full AI SDR settings payload. The sequence is seeded either from a saved offer (`offerId`) or from inline offer-context inputs (`offerGenerationInputs`) — exactly one is required.

        Sequence steps are generated by the AI SDR — clients do not pass `steps` here. Generic sequence fields (`name`, `scheduleId`, `settings`, `emailAccounts`, `linkedInAccounts`) are accepted and applied after the AI SDR-specific setup.

        Requires the AI SDR feature on the caller's team.
      operationId: CreateAiSdrSequence
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: AI SDR sequence — create
              description: |-
                Create a new AI SDR sequence with its full AI SDR settings. Generic sequence fields (`name`, `scheduleId`, `settings`, `emailAccounts`, `linkedInAccounts`) are accepted here too — sequence steps are NOT, because the AI SDR generates steps automatically.

                Exactly one of `offerId` or `offerGenerationInputs` must be provided.

                At most one intent signal per `type` is allowed.
              required: &ref_317
                - name
                - sequenceStructureSetup
              properties: &ref_318
                name:
                  type: string
                  minLength: 1
                  maxLength: 255
                  description: Display name of the sequence
                scheduleId:
                  type: integer
                  minimum: 1
                  nullable: true
                  description: Id of the send schedule to use
                settings:
                  allOf:
                    - type: object
                      title: Sequence Settings
                      description: Settings configuration for a sequence
                      required: &ref_45
                        - emailsCountPerDay
                        - daysToFinishProspect
                        - emailSendingDelaySeconds
                        - dailyThrottling
                        - disableOpensTracking
                        - repliesHandlingType
                        - enableLinksTracking
                      properties: &ref_46
                        emailsCountPerDay:
                          type: integer
                          description: Maximum number of emails sent daily
                        daysToFinishProspect:
                          type: integer
                          description: Days taken for a prospect to finish
                        emailSendingDelaySeconds:
                          type: integer
                          description: Delay between sending emails in seconds
                        dailyThrottling:
                          type: integer
                          description: Number of prospects processed within 24-hour period
                        useDailyThrottling:
                          type: boolean
                          description: Whether daily throttling is enabled
                        disableOpensTracking:
                          type: boolean
                          description: Whether to disable email open tracking
                        repliesHandlingType:
                          type: string
                          enum:
                            - markAsFinished
                            - continueSending
                          description: How replies are handled
                        enableLinksTracking:
                          type: boolean
                          description: Whether to enable link tracking
                        isSendingPlainTextEnabled:
                          type: boolean
                          description: Whether to send emails as plain text instead of HTML
                        isListUnsubscribeHeaderEnabled:
                          type: boolean
                          description: Whether to include a List-Unsubscribe header in all emails from this sequence
                        isSameDomainSendingLimitEnabled:
                          type: boolean
                          description: Whether to limit the number of contacts from the same domain contacted per day
                        numberOfSameDomainSendingLimit:
                          type: integer
                          nullable: true
                          description: Maximum number of same-domain contacts per day (applicable when `isSameDomainSendingLimitEnabled` is true)
                        matchProspectToEmailAccountProvider:
                          type: boolean
                          description: Whether to match prospect email provider to sender email provider
                        callIsAutomatic:
                          type: boolean
                          description: Whether calls are handled automatically in this sequence
                        taskIsAutomatic:
                          type: boolean
                          description: Whether tasks are handled automatically in this sequence
                        generatedTaskOwner:
                          type: string
                          nullable: true
                          enum:
                            - contact
                            - sequence
                          default: sequence
                          description: Who owns generated tasks — the contact owner or the sequence owner. Defaults to `sequence` when omitted.
                  nullable: true
                  description: Generic sequence settings (throttling, tracking, replies handling). Optional — sensible defaults are applied when omitted.
                emailAccounts:
                  type: array
                  nullable: true
                  description: Email account ids to link to the sequence
                  items:
                    type: integer
                    format: int64
                    minimum: 1
                linkedInAccounts:
                  type: array
                  nullable: true
                  description: LinkedIn account ids to link to the sequence
                  items:
                    type: integer
                    minimum: 1
                offerId:
                  type: integer
                  format: int64
                  minimum: 1
                  nullable: true
                  description: Id of an existing offer to seed the sequence from. Mutually exclusive with `offerGenerationInputs`.
                offerGenerationInputs:
                  allOf:
                    - type: object
                      title: Offer generation inputs
                      description: |-
                        Inline offer-context inputs used when the sequence is created without referencing a saved offer. Mirrors the shape of an offer.

                        On create, exactly one of `offerId` or `offerGenerationInputs` must be provided.
                      properties: &ref_49
                        companyName:
                          type: string
                          maxLength: 200
                          description: Name of the company being represented
                        companyDescription:
                          type: string
                          maxLength: 3000
                          description: Short description of what the company does
                        icp:
                          type: string
                          maxLength: 1000
                          description: Ideal Customer Profile — who the outreach is meant for
                        reasonForOutreach:
                          type: string
                          maxLength: 1000
                          description: Free-form rationale shown to the AI SDR for why this outreach is being made
                        caseStudies:
                          type: array
                          maxItems: 10
                          description: Case studies that demonstrate the company's value
                          items:
                            type: string
                            minLength: 1
                            maxLength: 1000
                        painPoints:
                          type: array
                          maxItems: 10
                          description: Customer pain points this outreach addresses
                          items:
                            type: string
                            minLength: 1
                            maxLength: 1000
                        proofPoints:
                          type: array
                          maxItems: 10
                          description: Proof points that back up the offer's claims
                          items:
                            type: string
                            minLength: 1
                            maxLength: 1000
                        valuePropositions:
                          type: array
                          maxItems: 10
                          description: Value propositions presented in messaging
                          items:
                            type: string
                            minLength: 1
                            maxLength: 1000
                        callToActions:
                          type: array
                          maxItems: 10
                          description: Call-to-action phrasings the AI SDR can use
                          items:
                            type: string
                            minLength: 1
                            maxLength: 1000
                  nullable: true
                  description: Inline offer-context inputs. Mutually exclusive with `offerId`.
                toneOfVoice:
                  allOf:
                    - type: object
                      title: Tone of voice settings (request)
                      description: Tone-of-voice configuration on create/patch. All fields are optional on create — omitted fields fall back to defaults (English (US), Confident tone, Medium length, Man).
                      properties: &ref_61
                        language:
                          allOf:
                            - type: string
                              title: Sales agent language
                              description: Language used by the AI SDR when generating outreach messages.
                              enum: &ref_50
                                - englishUS
                                - englishUK
                                - spanish
                                - albanian
                                - armenian
                                - bengali
                                - bosnian
                                - bulgarian
                                - catalan
                                - chinese
                                - croatian
                                - czech
                                - danish
                                - dutch
                                - estonian
                                - finnish
                                - french
                                - georgian
                                - german
                                - greek
                                - hindi
                                - hungarian
                                - icelandic
                                - indonesian
                                - italian
                                - japanese
                                - kazakh
                                - korean
                                - latvian
                                - lithuanian
                                - macedonian
                                - malay
                                - mongolian
                                - norwegian
                                - persian
                                - polish
                                - portugueseEU
                                - portugueseBR
                                - romanian
                                - serbian
                                - slovak
                                - slovenian
                                - swedish
                                - thai
                                - turkish
                                - ukrainian
                                - vietnamese
                                - arabic
                                - uzbek
                                - hebrew
                          nullable: true
                        toneOfVoice:
                          allOf:
                            - type: string
                              title: Sales agent tone of voice
                              description: Tone of voice used by the AI SDR when generating outreach messages.
                              enum: &ref_51
                                - confident
                                - persuasive
                                - witty
                                - straightforward
                                - empathetic
                          nullable: true
                        messageLength:
                          allOf:
                            - type: string
                              title: Personalized message length
                              description: Target length for AI-generated personalized messages.
                              enum: &ref_52
                                - superShort
                                - short
                                - medium
                                - long
                          nullable: true
                        gender:
                          allOf:
                            - type: string
                              title: Sales agent gender
                              description: Gender used by the AI SDR persona when generating outreach messages.
                              enum: &ref_53
                                - man
                                - woman
                          nullable: true
                  nullable: true
                  description: Tone-of-voice configuration. Omitted fields fall back to defaults (English (US), Confident, Medium, Man).
                sequenceStructureSetup:
                  type: object
                  title: Sequence structure setup
                  description: Shape of the sequence steps the AI SDR should generate on create.
                  required: &ref_306
                    - generatedStepTypes
                  properties: &ref_307
                    generatedStepTypes:
                      type: array
                      minItems: 1
                      description: Step channels the AI SDR is allowed to generate. Must be non-empty and contain no duplicates.
                      items:
                        type: string
                        title: Generated step type
                        description: Channel of a step the AI SDR is allowed to generate when building the sequence.
                        enum: &ref_54
                          - email
                          - linkedIn
                          - call
                          - linkedInInMail
                          - linkedInAiVoice
                    generateConditional:
                      type: boolean
                      nullable: true
                      description: When `true`, the AI SDR generates conditional branches between steps and the step count is derived from the branching structure. Defaults to `true` when omitted.
                    numberOfSteps:
                      type: integer
                      minimum: 1
                      maximum: 10
                      nullable: true
                      description: Target number of steps to generate (1-10). Applies only when `generateConditional` is `false`; ignored otherwise. Defaults to `5` when omitted.
                providerLLM:
                  allOf:
                    - type: string
                      title: AI content provider
                      description: LLM provider that generates the outreach content for the AI SDR sequence.
                      enum: &ref_55
                        - claude
                        - openAi
                        - gemini
                        - mistral
                  nullable: true
                  description: LLM provider that generates the outreach content. Defaults to `claude` when omitted.
                personalizationPoints:
                  allOf:
                    - type: object
                      title: Personalization points
                      description: Which research signals the AI SDR is allowed to weave into personalized messages. Every leaf is optional; absent flags are treated as "no preference / keep the current value".
                      properties: &ref_56
                        basicResearch:
                          type: boolean
                          nullable: true
                          description: Allow lightweight, low-cost personalization based on basic contact and company facts
                        companyResearch:
                          type: object
                          nullable: true
                          description: Per-aspect toggles for company-level research signals
                          properties:
                            description:
                              type: boolean
                              nullable: true
                            mission:
                              type: boolean
                              nullable: true
                            techStack:
                              type: boolean
                              nullable: true
                            tenKReport:
                              type: boolean
                              nullable: true
                            recentReportForInvestors:
                              type: boolean
                              nullable: true
                            financialReport:
                              type: boolean
                              nullable: true
                            fundraisingResearch:
                              type: boolean
                              nullable: true
                            challenges:
                              type: boolean
                              nullable: true
                            recentNews:
                              type: boolean
                              nullable: true
                            predictChallengesAndCompetitors:
                              type: boolean
                              nullable: true
                            productsServicesDeepDive:
                              type: boolean
                              nullable: true
                            mergersAcquisitions:
                              type: boolean
                              nullable: true
                            customerReviews:
                              type: boolean
                              nullable: true
                        prospectResearch:
                          type: object
                          nullable: true
                          description: Per-aspect toggles for prospect-level research signals
                          properties:
                            aboutSection:
                              type: boolean
                              nullable: true
                            hobbiesInterests:
                              type: boolean
                              nullable: true
                            quotes:
                              type: boolean
                              nullable: true
                            achievements:
                              type: boolean
                              nullable: true
                            careerSummary:
                              type: boolean
                              nullable: true
                            jobResponsibilitiesInCurrentCompany:
                              type: boolean
                              nullable: true
                            achievementsInCurrentCompany:
                              type: boolean
                              nullable: true
                        industryResearch:
                          type: object
                          nullable: true
                          description: Per-aspect toggles for industry-level research signals
                          properties:
                            recentIndustryNews:
                              type: boolean
                              nullable: true
                            industryTrends:
                              type: boolean
                              nullable: true
                            competitorsOverviewNews:
                              type: boolean
                              nullable: true
                        contactFields:
                          type: object
                          nullable: true
                          description: Which contact-record fields the AI SDR may reference. Default fields and custom fields are selected independently — `defaultFields` is an array of enum values, `customFieldIds` is an array of integer ids.
                          properties:
                            enabled:
                              type: boolean
                              nullable: true
                              description: Master toggle for using contact fields in personalization
                            defaultFields:
                              type: array
                              nullable: true
                              description: Built-in contact fields to reference. Must contain no duplicates.
                              items:
                                type: string
                                title: Contact default field
                                description: Built-in contact field selectable for AI SDR personalization.
                                enum: &ref_308
                                  - firstName
                                  - lastName
                                  - title
                                  - companySize
                                  - industry
                                  - city
                                  - state
                                  - country
                            customFieldIds:
                              type: array
                              nullable: true
                              description: Ids of custom contact fields to reference. Each id must be positive; the array must contain no duplicates.
                              items:
                                type: integer
                                minimum: 1
                        customResearch:
                          type: object
                          nullable: true
                          description: Free-form custom research instructions the AI SDR may follow
                          properties:
                            enabled:
                              type: boolean
                              nullable: true
                              description: Master toggle for using custom research
                            instructions:
                              type: string
                              nullable: true
                              maxLength: 2000
                              description: Free-form prompt describing the custom research the AI SDR should perform
                  nullable: true
                  description: Research signals the AI SDR is allowed to use in personalized messages
                autopilot:
                  allOf:
                    - type: object
                      title: Autopilot settings (create)
                      description: Autopilot configuration applied at sequence-create time. When `enabled` is `true`, the sequence is set to actively search for and add new contacts immediately after creation.
                      required: &ref_311
                        - enabled
                      properties: &ref_312
                        enabled:
                          type: boolean
                          description: Whether autopilot is enabled for the sequence
                        filters:
                          allOf:
                            - type: object
                              title: Autopilot filters
                              description: |-
                                Account- and contact-level filter configuration used by autopilot when searching for new contacts to add to the sequence.

                                Most collections are capped at 25 items. `accountKeywords` and `contactKeywords` are always present and non-null in responses even when empty (`{ "values": [], "type": "or" }`).
                              properties: &ref_57
                                accountListIds:
                                  type: array
                                  maxItems: 25
                                  description: Saved account-list ids the search is scoped to
                                  items:
                                    type: object
                                    title: Integer filter value
                                    description: A single integer value used in an autopilot filter, with include/exclude polarity.
                                    required: &ref_161
                                      - value
                                    properties: &ref_162
                                      value:
                                        type: integer
                                        minimum: 1
                                        description: The literal integer id to match
                                      type:
                                        allOf:
                                          - type: string
                                            title: Filter polarity
                                            description: Whether matching values are included in or excluded from the autopilot search.
                                            enum: &ref_40
                                              - include
                                              - exclude
                                        description: Whether the value is included in or excluded from the search. Defaults to `include`.
                                industries:
                                  type: array
                                  maxItems: 25
                                  description: Industry filters
                                  items:
                                    type: object
                                    title: Filter value
                                    description: A single string value used in an autopilot filter, with include/exclude polarity.
                                    required: &ref_41
                                      - value
                                    properties: &ref_42
                                      value:
                                        type: string
                                        maxLength: 200
                                        description: The literal value to match (non-empty)
                                      type:
                                        allOf:
                                          - type: string
                                            title: Filter polarity
                                            description: Whether matching values are included in or excluded from the autopilot search.
                                            enum: *ref_40
                                        description: Whether the value is included in or excluded from the search. Defaults to `include`.
                                companyLocations:
                                  type: array
                                  maxItems: 25
                                  description: Company location filters
                                  items:
                                    type: object
                                    title: Filter value
                                    description: A single string value used in an autopilot filter, with include/exclude polarity.
                                    required: *ref_41
                                    properties: *ref_42
                                companySizes:
                                  type: array
                                  maxItems: 25
                                  description: Company size bands to include
                                  items:
                                    type: string
                                    title: Company size
                                    description: Headcount band used when filtering companies for autopilot search.
                                    enum: &ref_163
                                      - none
                                      - selfEmployed
                                      - ten
                                      - fifty
                                      - twoHundred
                                      - fiveHundred
                                      - oneThousand
                                      - fiveThousand
                                      - tenThousand
                                      - overTenThousand
                                headcountGrowth:
                                  allOf:
                                    - type: object
                                      title: Headcount growth range
                                      description: |-
                                        Min/max range applied to the company's total headcount growth (percent). Either bound may be omitted.

                                        When both are provided, `min` must be less than or equal to `max`.
                                      properties: &ref_164
                                        min:
                                          type: integer
                                          minimum: 0
                                          nullable: true
                                          description: Lower bound (inclusive), percent
                                        max:
                                          type: integer
                                          minimum: 0
                                          nullable: true
                                          description: Upper bound (inclusive), percent
                                  nullable: true
                                  description: Overall company headcount growth range
                                departmentHeadcountGrowth:
                                  allOf:
                                    - type: object
                                      title: Department headcount growth range
                                      description: |-
                                        Min/max range applied to a specific department's headcount growth (percent). Either bound may be omitted.

                                        When both are provided, `min` must be less than or equal to `max`.
                                      required: &ref_165
                                        - department
                                      properties: &ref_166
                                        min:
                                          type: integer
                                          minimum: 0
                                          nullable: true
                                          description: Lower bound (inclusive), percent
                                        max:
                                          type: integer
                                          minimum: 0
                                          nullable: true
                                          description: Upper bound (inclusive), percent
                                        department:
                                          type: string
                                          maxLength: 200
                                          description: Department name the growth range applies to (non-empty)
                                  nullable: true
                                  description: Per-department headcount growth range
                                minRevenue:
                                  allOf:
                                    - type: string
                                      title: Company revenue tier
                                      description: Annual revenue tier used when filtering companies for autopilot search.
                                      enum: &ref_43
                                        - zeroMillion
                                        - halfMillion
                                        - oneMillion
                                        - twoAndHalfMillion
                                        - fiveMillion
                                        - tenMillion
                                        - twentyMillion
                                        - fiftyMillion
                                        - oneHundredMillion
                                        - fiveHundredMillion
                                        - oneThousandMillion
                                        - overOneThousandMillion
                                  nullable: true
                                  description: Minimum company revenue tier
                                maxRevenue:
                                  allOf:
                                    - type: string
                                      title: Company revenue tier
                                      description: Annual revenue tier used when filtering companies for autopilot search.
                                      enum: *ref_43
                                  nullable: true
                                  description: Maximum company revenue tier. When both `minRevenue` and `maxRevenue` are provided, `minRevenue` must be less than or equal to `maxRevenue`.
                                accountKeywords:
                                  allOf:
                                    - type: object
                                      title: Keyword filter
                                      description: |-
                                        Boolean keyword filter applied to account or contact searches.

                                        In responses this field is always present and non-null even when no keywords are configured (`{ "values": [], "type": "or" }`).
                                      properties: &ref_44
                                        values:
                                          type: array
                                          maxItems: 25
                                          description: Keyword values combined according to `type`
                                          items:
                                            type: object
                                            title: Filter value
                                            description: A single string value used in an autopilot filter, with include/exclude polarity.
                                            required: *ref_41
                                            properties: *ref_42
                                        type:
                                          allOf:
                                            - type: string
                                              title: Keyword combination
                                              description: Boolean combinator applied across keyword filter values.
                                              enum: &ref_309
                                                - or
                                                - and
                                          description: Boolean combinator across `values`. Defaults to `or`.
                                  description: Free-text keyword filter applied at the account level. Always present and non-null in responses.
                                isHiringOnLinkedIn:
                                  type: boolean
                                  description: When `true`, restrict to companies currently hiring on LinkedIn. `false` (the default) applies no filter — it is treated the same as omitting the field.
                                contactLocations:
                                  type: array
                                  maxItems: 25
                                  description: Contact location filters
                                  items:
                                    type: object
                                    title: Filter value
                                    description: A single string value used in an autopilot filter, with include/exclude polarity.
                                    required: *ref_41
                                    properties: *ref_42
                                jobTitles:
                                  type: array
                                  maxItems: 25
                                  description: Contact job-title filters
                                  items:
                                    type: object
                                    title: Filter value
                                    description: A single string value used in an autopilot filter, with include/exclude polarity.
                                    required: *ref_41
                                    properties: *ref_42
                                departments:
                                  type: array
                                  maxItems: 25
                                  description: Contact department filters
                                  items:
                                    type: object
                                    title: Filter value
                                    description: A single string value used in an autopilot filter, with include/exclude polarity.
                                    required: *ref_41
                                    properties: *ref_42
                                seniorities:
                                  type: array
                                  maxItems: 25
                                  description: Seniority slugs to include
                                  items:
                                    type: string
                                    minLength: 1
                                    maxLength: 200
                                yearsInCompany:
                                  type: array
                                  maxItems: 25
                                  description: Tenure bands to include
                                  items:
                                    type: string
                                    title: Years in current company
                                    description: Tenure band used when filtering contacts for autopilot search.
                                    enum: &ref_310
                                      - none
                                      - lessThanOneYear
                                      - oneToTwoYears
                                      - threeToFiveYears
                                      - sixToTenYears
                                      - moreThanTenYears
                                contactKeywords:
                                  allOf:
                                    - type: object
                                      title: Keyword filter
                                      description: |-
                                        Boolean keyword filter applied to account or contact searches.

                                        In responses this field is always present and non-null even when no keywords are configured (`{ "values": [], "type": "or" }`).
                                      properties: *ref_44
                                  description: Free-text keyword filter applied at the contact level. Always present and non-null in responses.
                                changedJobIn90Days:
                                  type: boolean
                                  description: When `true`, restrict to contacts who changed jobs in the past 90 days. `false` (the default) applies no filter — it is treated the same as omitting the field.
                          nullable: true
                          description: Autopilot account/contact filter configuration
                        referenceUrl:
                          type: string
                          nullable: true
                          description: Optional reference URL used to seed the autopilot search
                        maxPeoplePerCompany:
                          type: integer
                          minimum: 1
                          nullable: true
                          description: Maximum contacts to add per company
                        maxPeopleToAddPerDay:
                          type: integer
                          minimum: 1
                          nullable: true
                          description: Maximum contacts to add per day
                        searchContactPhones:
                          type: boolean
                          nullable: true
                          description: When `true`, enrich phone numbers during search
                        addContactsWithoutEmailAddresses:
                          type: boolean
                          nullable: true
                          description: When `true`, contacts without an email address are still added to the sequence
                  nullable: true
                  description: Autopilot configuration applied immediately after sequence creation
                playbookId:
                  type: string
                  minLength: 1
                  nullable: true
                  description: 'Composite playbook id (`{prefix}-{numericId}`) to attach to the sequence. Prefix encodes the playbook scope: `g` for global, `o` for organization, `t` for team (e.g. `g-1`, `o-42`, `t-7`).'
                knowledgeBaseId:
                  type: integer
                  format: int64
                  minimum: 1
                  nullable: true
                  description: Id of a knowledge base to connect to the sequence
                approvalMode:
                  allOf:
                    - type: object
                      title: Approval mode (create)
                      description: Initial approval mode for the sequence — whether AI-generated messages require human approval before being sent.
                      required: &ref_313
                        - enabled
                      properties: &ref_314
                        enabled:
                          type: boolean
                          description: When `true`, messages require human approval before sending
                  nullable: true
                  description: Initial approval-mode setting. Cannot be changed via the AI SDR sequence PATCH — use `PUT .../approval-mode` after creation.
                intentSignals:
                  type: array
                  nullable: true
                  description: Intent signals to attach. At most one per `type`.
                  items:
                    type: object
                    title: Intent signal
                    description: |-
                      Tagged-union intent signal. Exactly one of `postEngagers`, `competitorFollowers`, `technologyUsed`, `jobHiring` is populated, matching `type`. The other three must be omitted or `null`.

                      A sequence may have at most one signal per `type`. `technologyUsed` and `jobHiring` are mutually exclusive — a sequence may include at most one of the two.
                    required: &ref_58
                      - type
                    properties: &ref_59
                      type:
                        type: string
                        title: Intent signal type
                        description: |-
                          Discriminator selecting which intent-signal sub-object is populated.

                          - `linkedInPostEngagers` — populate `postEngagers`.
                          - `competitorFollowers` — populate `competitorFollowers`.
                          - `technologyUsed` — populate `technologyUsed`.
                          - `jobHiring` — populate `jobHiring`.
                        enum: &ref_315
                          - linkedInPostEngagers
                          - competitorFollowers
                          - technologyUsed
                          - jobHiring
                      postEngagers:
                        type: object
                        nullable: true
                        description: Populated when `type` = `linkedInPostEngagers`.
                        required:
                          - mode
                        properties:
                          mode:
                            type: string
                            title: LinkedIn post engagers mode
                            description: |-
                              Selects which sub-object of the LinkedIn post engagers signal is populated.

                              - `monitorProfiles` — populate `monitorProfiles`.
                              - `monitorPosts` — populate `monitorPosts`.
                            enum: &ref_316
                              - monitorProfiles
                              - monitorPosts
                          icpFitPercentage:
                            type: integer
                            description: Minimum ICP fit percentage to consider an engager. Must be one of `20`, `40`, `60`, `80`, `100`.
                            enum:
                              - 20
                              - 40
                              - 60
                              - 80
                              - 100
                          monitorProfiles:
                            type: object
                            nullable: true
                            description: Populated when `mode` = `monitorProfiles`.
                            required:
                              - monitorForDays
                            properties:
                              monitorForDays:
                                type: integer
                                description: Window over which to track engagement. Must be one of `2`, `3`, `5`, `7`, `15`, `30`.
                                enum:
                                  - 2
                                  - 3
                                  - 5
                                  - 7
                                  - 15
                                  - 30
                              profiles:
                                type: array
                                maxItems: 10
                                description: LinkedIn profiles to monitor (at most 10)
                                items:
                                  type: object
                                  required:
                                    - linkedInUrl
                                  properties:
                                    linkedInUrl:
                                      type: string
                                      minLength: 1
                                      maxLength: 2048
                                      description: Public LinkedIn profile URL
                                    numberOfPosts:
                                      type: integer
                                      description: How many recent posts of this profile to monitor. Must be one of `3`, `5`, `10`, `15`, `20`.
                                      enum:
                                        - 3
                                        - 5
                                        - 10
                                        - 15
                                        - 20
                          monitorPosts:
                            type: object
                            nullable: true
                            description: Populated when `mode` = `monitorPosts`.
                            properties:
                              postUrls:
                                type: array
                                maxItems: 10
                                description: Public LinkedIn post URLs to monitor (at most 10)
                                items:
                                  type: string
                                  minLength: 1
                                  maxLength: 2048
                      competitorFollowers:
                        type: object
                        nullable: true
                        description: Populated when `type` = `competitorFollowers`.
                        properties:
                          linkedInUrls:
                            type: array
                            maxItems: 10
                            description: Competitor LinkedIn company URLs (at most 10)
                            items:
                              type: string
                              minLength: 1
                              maxLength: 2048
                          entitiesToFind:
                            type: integer
                            minimum: 100
                            maximum: 500
                            description: Number of follower contacts to surface (100-500)
                          icpFitPercentage:
                            type: integer
                            description: Minimum ICP fit percentage. Must be one of `20`, `40`, `60`, `80`, `100`.
                            enum:
                              - 20
                              - 40
                              - 60
                              - 80
                              - 100
                      technologyUsed:
                        type: object
                        nullable: true
                        description: Populated when `type` = `technologyUsed`.
                        properties:
                          industryId:
                            type: integer
                            minimum: 1
                            nullable: true
                            description: Optional industry filter
                          technologies:
                            type: array
                            maxItems: 10
                            description: Technology slugs to match (at most 10)
                            items:
                              type: string
                              minLength: 1
                              maxLength: 200
                          useAndLogicInTechnologies:
                            type: boolean
                            description: When `true`, all listed technologies must be present (AND); otherwise any match (OR).
                          entitiesToFind:
                            type: integer
                            minimum: 1
                            maximum: 500
                            description: Number of matching contacts to surface (1-500)
                      jobHiring:
                        type: object
                        nullable: true
                        description: Populated when `type` = `jobHiring`.
                        required:
                          - keyword
                        properties:
                          keyword:
                            type: string
                            minLength: 1
                            maxLength: 200
                            description: Job-posting keyword to match
                          industries:
                            type: array
                            maxItems: 10
                            description: Industry ids to scope the search (at most 10)
                            items:
                              type: integer
                              minimum: 1
                          entitiesToFind:
                            type: integer
                            minimum: 1
                            maximum: 500
                            description: Number of matching contacts to surface (1-500)
      responses:
        '201':
          description: AI SDR sequence created
          content:
            application/json:
              schema:
                title: Sequence Creation Response
                description: The sequence returned after creation, including its AI SDR settings.
                allOf: &ref_339
                  - title: Sequence
                    description: Full representation of a sequence, including its schedule and the email and LinkedIn accounts used to send from it.
                    allOf: &ref_189
                      - type: object
                        properties: &ref_185
                          id:
                            type: integer
                            readOnly: true
                            description: Unique identifier for the sequence
                          ownerUserId:
                            type: integer
                            readOnly: true
                            description: Identifier of the user who owns the sequence
                          name:
                            type: string
                            description: Name of the sequence
                          created:
                            type: string
                            format: date-time
                            readOnly: true
                            description: Sequence creation timestamp with timezone offset
                          status:
                            type: string
                            enum:
                              - new
                              - active
                              - paused
                            readOnly: true
                            description: Current status of the sequence
                          isArchived:
                            type: boolean
                            readOnly: true
                            description: Indicates if the sequence is archived
                          health:
                            type: string
                            description: |-
                              Overall health status of the sequence. Indicates whether the sequence can operate normally or has issues that need attention.

                              - `healthy` — Sequence is functioning normally with no issues
                              - `stalled` — Sequence has stalled and is not progressing
                              - `degraded` — Sequence is running but with reduced effectiveness
                              - `blocked` — Sequence cannot proceed due to critical issues
                            enum: &ref_319
                              - healthy
                              - stalled
                              - degraded
                              - blocked
                            readOnly: true
                        example: &ref_186
                          id: 12345
                          ownerUserId: 42
                          name: Sales Outreach
                          created: '2024-03-08T10:00:00+00:00'
                          status: active
                          isArchived: false
                          health: healthy
                      - type: object
                        properties:
                          scheduleId:
                            type: integer
                            description: Schedule ID
                          emailAccounts:
                            type: array
                            items:
                              type: object
                              properties: &ref_320
                                id:
                                  type: integer
                                  format: int64
                                  description: Email account ID
                                email:
                                  type: string
                                  description: Email address
                              required: &ref_321
                                - id
                                - email
                            description: Email accounts used to send emails for this sequence
                          linkedInAccounts:
                            type: array
                            items:
                              type: object
                              title: Sequence LinkedIn Account
                              description: A LinkedIn account linked to a sequence
                              properties: &ref_202
                                id:
                                  type: integer
                                  description: Unique identifier for the LinkedIn account
                                name:
                                  type: string
                                  description: Name of the LinkedIn account
                                profileUrl:
                                  type: string
                                  nullable: true
                                  description: LinkedIn profile URL
                                status:
                                  type: string
                                  enum:
                                    - disabled
                                    - enabled
                                    - dailyLimitReached
                                    - cookieInvalid
                                  description: Current status of the LinkedIn account
                              example: &ref_203
                                id: 42
                                name: John Doe
                                profileUrl: https://www.linkedin.com/in/johndoe
                                status: enabled
                            description: LinkedIn accounts linked to this sequence
                          settings:
                            type: object
                            title: Sequence Settings
                            description: Settings configuration for a sequence
                            required: *ref_45
                            properties: *ref_46
                          steps:
                            type: array
                            items:
                              title: Sequence Step
                              discriminator: &ref_187
                                propertyName: type
                                mapping:
                                  email: '#/components/schemas/email.type'
                                  linkedIn: '#/components/schemas/linkedin.type'
                                  call: '#/components/schemas/call.type'
                                  sms: '#/components/schemas/sms.type'
                                  whatsApp: '#/components/schemas/whatsapp.type'
                                  zapier: '#/components/schemas/zapier.type'
                                  task: '#/components/schemas/task.type'
                                  condition: '#/components/schemas/condition.type'
                              oneOf: &ref_188
                                - type: object
                                  title: Email
                                  description: Email step with variant configuration
                                  properties: &ref_323
                                    id:
                                      type: integer
                                      nullable: true
                                      readOnly: true
                                      description: Unique identifier for the step
                                    parentId:
                                      type: integer
                                      nullable: true
                                      description: ID of the parent step (for branching)
                                    ifConditionPositive:
                                      type: boolean
                                      nullable: true
                                      description: Whether this step is on the positive branch of a condition
                                    type:
                                      type: string
                                      enum:
                                        - email
                                      description: Step type discriminator
                                    delayInMinutes:
                                      type: integer
                                      minimum: 0
                                      description: Delay in minutes before executing this step
                                    executionMode:
                                      type: string
                                      description: Execution mode for the email step
                                      enum:
                                        - automatic
                                        - manual
                                    variants:
                                      type: array
                                      description: Array of email variants (A/B test versions)
                                      items:
                                        type: object
                                        title: Email Variant
                                        description: Individual email variant within an email step.
                                        properties: &ref_322
                                          id:
                                            type: integer
                                            description: Unique identifier for this email variant
                                          subject:
                                            type: string
                                            nullable: true
                                            description: Email subject line.
                                          message:
                                            type: string
                                            nullable: true
                                            description: Email message content.
                                          attachmentIds:
                                            type: array
                                            nullable: true
                                            writeOnly: true
                                            maxItems: 3
                                            items:
                                              type: integer
                                            description: |-
                                              **Write-only.** IDs of previously uploaded attachments to attach to this variant. Upload files via `POST /v3/attachments` first to obtain attachment IDs.
                                              A variant may carry up to 3 attachments. Omit to leave attachments unset.
                                              Not returned on read — use `hasAttachments` to detect presence.
                                          hasAttachments:
                                            type: boolean
                                            readOnly: true
                                            description: Whether the variant has any attachments. Returned on read; ignored on write.
                                  required: &ref_324
                                    - type
                                    - delayInMinutes
                                    - executionMode
                                    - variants
                                - title: LinkedIn
                                  description: LinkedIn step with action type sub-discriminator. Uses type "linkedIn" with a second discriminator actionType to select the specific LinkedIn action.
                                  discriminator: &ref_333
                                    propertyName: actionType
                                    mapping:
                                      message: '#/components/schemas/linkedin-message.type'
                                      connect: '#/components/schemas/linkedin-connect.type'
                                      inMail: '#/components/schemas/linkedin-inmail.type'
                                      viewProfile: '#/components/schemas/linkedin-view-profile.type'
                                      endorseSkills: '#/components/schemas/linkedin-endorse-skills.type'
                                      voiceMessage: '#/components/schemas/linkedin-voice-message.type'
                                      likeRecentPosts: '#/components/schemas/linkedin-like-recent-posts.type'
                                      followProfile: '#/components/schemas/linkedin-follow-profile.type'
                                      commentOnRecentPost: '#/components/schemas/linkedin-comment-on-recent-post.type'
                                  oneOf: &ref_334
                                    - type: object
                                      title: LinkedIn Message
                                      description: LinkedIn message action step
                                      properties: &ref_325
                                        id:
                                          type: integer
                                          nullable: true
                                          readOnly: true
                                          description: Unique identifier for the step
                                        parentId:
                                          type: integer
                                          nullable: true
                                          description: ID of the parent step (for branching)
                                        ifConditionPositive:
                                          type: boolean
                                          nullable: true
                                          description: Whether this step is on the positive branch of a condition
                                        type:
                                          type: string
                                          enum:
                                            - linkedIn
                                          description: Step type discriminator
                                        actionType:
                                          type: string
                                          enum:
                                            - message
                                          description: LinkedIn action type discriminator
                                        delayInMinutes:
                                          type: integer
                                          minimum: 0
                                          description: Delay in minutes before executing this step
                                        executionMode:
                                          type: string
                                          description: Execution mode for the action
                                          enum:
                                            - automatic
                                            - manual
                                        variants:
                                          type: array
                                          description: Array of LinkedIn message variants (A/B test versions)
                                          items:
                                            type: object
                                            title: LinkedIn Variant
                                            description: Individual LinkedIn message/connect variant
                                            properties: &ref_47
                                              id:
                                                type: integer
                                                description: Unique identifier for this LinkedIn variant
                                              message:
                                                type: string
                                                description: Message content
                                              isEnabled:
                                                type: boolean
                                                description: Indicates whether the variant is enabled
                                            required: &ref_48
                                              - message
                                              - isEnabled
                                      required: &ref_326
                                        - type
                                        - actionType
                                        - delayInMinutes
                                        - executionMode
                                        - variants
                                    - type: object
                                      title: LinkedIn Connect
                                      description: LinkedIn connect action step
                                      properties: &ref_327
                                        id:
                                          type: integer
                                          nullable: true
                                          readOnly: true
                                          description: Unique identifier for the step
                                        parentId:
                                          type: integer
                                          nullable: true
                                          description: ID of the parent step (for branching)
                                        ifConditionPositive:
                                          type: boolean
                                          nullable: true
                                          description: Whether this step is on the positive branch of a condition
                                        type:
                                          type: string
                                          enum:
                                            - linkedIn
                                          description: Step type discriminator
                                        actionType:
                                          type: string
                                          enum:
                                            - connect
                                          description: LinkedIn action type discriminator
                                        delayInMinutes:
                                          type: integer
                                          minimum: 0
                                          description: Delay in minutes before executing this step
                                        executionMode:
                                          type: string
                                          description: Execution mode for the action
                                          enum:
                                            - automatic
                                            - manual
                                        variants:
                                          type: array
                                          description: Array of LinkedIn connect variants (A/B test versions). Message is optional, max 300 characters.
                                          items:
                                            type: object
                                            title: LinkedIn Variant
                                            description: Individual LinkedIn message/connect variant
                                            properties: *ref_47
                                            required: *ref_48
                                      required: &ref_328
                                        - type
                                        - actionType
                                        - delayInMinutes
                                        - executionMode
                                        - variants
                                    - type: object
                                      title: LinkedIn InMail
                                      description: LinkedIn InMail action step
                                      properties: &ref_331
                                        id:
                                          type: integer
                                          nullable: true
                                          readOnly: true
                                          description: Unique identifier for the step
                                        parentId:
                                          type: integer
                                          nullable: true
                                          description: ID of the parent step (for branching)
                                        ifConditionPositive:
                                          type: boolean
                                          nullable: true
                                          description: Whether this step is on the positive branch of a condition
                                        type:
                                          type: string
                                          enum:
                                            - linkedIn
                                          description: Step type discriminator
                                        actionType:
                                          type: string
                                          enum:
                                            - inMail
                                          description: LinkedIn action type discriminator
                                        delayInMinutes:
                                          type: integer
                                          minimum: 0
                                          description: Delay in minutes before executing this step
                                        executionMode:
                                          type: string
                                          description: Execution mode for the InMail
                                          enum:
                                            - automatic
                                            - manual
                                        variants:
                                          type: array
                                          description: Array of LinkedIn InMail variants (A/B test versions)
                                          items:
                                            type: object
                                            title: LinkedIn InMail Variant
                                            description: Individual LinkedIn InMail variant
                                            properties: &ref_329
                                              id:
                                                type: integer
                                                description: Unique identifier for this LinkedIn InMail variant
                                              subject:
                                                type: string
                                                description: InMail subject line
                                              message:
                                                type: string
                                                description: InMail message content
                                              isEnabled:
                                                type: boolean
                                                description: Indicates whether the variant is enabled
                                            required: &ref_330
                                              - subject
                                              - message
                                              - isEnabled
                                      required: &ref_332
                                        - type
                                        - actionType
                                        - delayInMinutes
                                        - executionMode
                                        - variants
                                    - type: object
                                      title: LinkedIn View Profile
                                      description: LinkedIn view profile action step
                                      properties: &ref_206
                                        id:
                                          type: integer
                                          nullable: true
                                          readOnly: true
                                          description: Unique identifier for the step
                                        parentId:
                                          type: integer
                                          nullable: true
                                          description: ID of the parent step (for branching)
                                        ifConditionPositive:
                                          type: boolean
                                          nullable: true
                                          description: Whether this step is on the positive branch of a condition
                                        type:
                                          type: string
                                          enum:
                                            - linkedIn
                                          description: Step type discriminator
                                        actionType:
                                          type: string
                                          enum:
                                            - viewProfile
                                          description: LinkedIn action type discriminator
                                        delayInMinutes:
                                          type: integer
                                          minimum: 0
                                          description: Delay in minutes before executing this step
                                        executionMode:
                                          type: string
                                          description: Execution mode for the action
                                          enum:
                                            - automatic
                                            - manual
                                        description:
                                          type: string
                                          description: Description or notes for the profile view
                                      required: &ref_207
                                        - type
                                        - actionType
                                        - delayInMinutes
                                        - executionMode
                                    - type: object
                                      title: LinkedIn Endorse Skills
                                      description: LinkedIn endorse skills action step
                                      properties: &ref_208
                                        id:
                                          type: integer
                                          nullable: true
                                          readOnly: true
                                          description: Unique identifier for the step
                                        parentId:
                                          type: integer
                                          nullable: true
                                          description: ID of the parent step (for branching)
                                        ifConditionPositive:
                                          type: boolean
                                          nullable: true
                                          description: Whether this step is on the positive branch of a condition
                                        type:
                                          type: string
                                          enum:
                                            - linkedIn
                                          description: Step type discriminator
                                        actionType:
                                          type: string
                                          enum:
                                            - endorseSkills
                                          description: LinkedIn action type discriminator
                                        delayInMinutes:
                                          type: integer
                                          minimum: 0
                                          description: Delay in minutes before executing this step
                                        numberOfSkills:
                                          type: integer
                                          minimum: 1
                                          maximum: 3
                                          description: Number of skills to endorse (1-3)
                                      required: &ref_209
                                        - type
                                        - actionType
                                        - delayInMinutes
                                        - numberOfSkills
                                    - type: object
                                      title: LinkedIn Voice Message
                                      description: LinkedIn voice message action step
                                      properties: &ref_210
                                        id:
                                          type: integer
                                          nullable: true
                                          readOnly: true
                                          description: Unique identifier for the step
                                        parentId:
                                          type: integer
                                          nullable: true
                                          description: ID of the parent step (for branching)
                                        ifConditionPositive:
                                          type: boolean
                                          nullable: true
                                          description: Whether this step is on the positive branch of a condition
                                        type:
                                          type: string
                                          enum:
                                            - linkedIn
                                          description: Step type discriminator
                                        actionType:
                                          type: string
                                          enum:
                                            - voiceMessage
                                          description: LinkedIn action type discriminator
                                        delayInMinutes:
                                          type: integer
                                          minimum: 0
                                          description: Delay in minutes before executing this step
                                        audioFile:
                                          type: string
                                          description: The audio file URL for the voice message
                                      required: &ref_211
                                        - type
                                        - actionType
                                        - delayInMinutes
                                        - audioFile
                                    - type: object
                                      title: LinkedIn Like Recent Posts
                                      description: LinkedIn like recent posts action step
                                      properties: &ref_212
                                        id:
                                          type: integer
                                          nullable: true
                                          readOnly: true
                                          description: Unique identifier for the step
                                        parentId:
                                          type: integer
                                          nullable: true
                                          description: ID of the parent step (for branching)
                                        ifConditionPositive:
                                          type: boolean
                                          nullable: true
                                          description: Whether this step is on the positive branch of a condition
                                        type:
                                          type: string
                                          enum:
                                            - linkedIn
                                          description: Step type discriminator
                                        actionType:
                                          type: string
                                          enum:
                                            - likeRecentPosts
                                          description: LinkedIn action type discriminator
                                        delayInMinutes:
                                          type: integer
                                          minimum: 0
                                          description: Delay in minutes before executing this step
                                      required: &ref_213
                                        - type
                                        - actionType
                                        - delayInMinutes
                                    - type: object
                                      title: LinkedIn Follow Profile
                                      description: LinkedIn follow profile action step
                                      properties: &ref_214
                                        id:
                                          type: integer
                                          nullable: true
                                          readOnly: true
                                          description: Unique identifier for the step
                                        parentId:
                                          type: integer
                                          nullable: true
                                          description: ID of the parent step (for branching)
                                        ifConditionPositive:
                                          type: boolean
                                          nullable: true
                                          description: Whether this step is on the positive branch of a condition
                                        type:
                                          type: string
                                          enum:
                                            - linkedIn
                                          description: Step type discriminator
                                        actionType:
                                          type: string
                                          enum:
                                            - followProfile
                                          description: LinkedIn action type discriminator
                                        delayInMinutes:
                                          type: integer
                                          minimum: 0
                                          description: Delay in minutes before executing this step
                                      required: &ref_215
                                        - type
                                        - actionType
                                        - delayInMinutes
                                    - type: object
                                      title: LinkedIn Comment On Recent Post
                                      description: |-
                                        LinkedIn comment on a recent post action step. The AI writes a comment on the contact's most recent post using the
                                        instructions in `aiPromptText`. Use the AI prompt preview endpoints to check what a prompt produces before saving
                                        it on a step. How many of these comments an account posts per day is governed by that LinkedIn account's own daily
                                        limits, not by this step.
                                      properties: &ref_216
                                        id:
                                          type: integer
                                          nullable: true
                                          readOnly: true
                                          description: Unique identifier for the step
                                        parentId:
                                          type: integer
                                          nullable: true
                                          description: ID of the parent step (for branching)
                                        ifConditionPositive:
                                          type: boolean
                                          nullable: true
                                          description: Whether this step is on the positive branch of a condition
                                        type:
                                          type: string
                                          enum:
                                            - linkedIn
                                          description: Step type discriminator
                                        actionType:
                                          type: string
                                          enum:
                                            - commentOnRecentPost
                                          description: LinkedIn action type discriminator
                                        delayInMinutes:
                                          type: integer
                                          minimum: 0
                                          description: Delay in minutes before executing this step
                                        aiPromptText:
                                          type: string
                                          description: The instructions the AI follows when writing the comment
                                        skipIfNoPostsInDays:
                                          type: integer
                                          nullable: true
                                          description: Skip the contact when their most recent post is older than this many days
                                        skipTopics:
                                          type: array
                                          items:
                                            type: string
                                          description: Topics the AI should refuse to comment on. The step is skipped when the post matches one of these.
                                      required: &ref_217
                                        - type
                                        - actionType
                                        - delayInMinutes
                                        - aiPromptText
                                - type: object
                                  title: Call
                                  description: Call step with script/notes
                                  properties: &ref_218
                                    id:
                                      type: integer
                                      nullable: true
                                      readOnly: true
                                      description: Unique identifier for the step
                                    parentId:
                                      type: integer
                                      nullable: true
                                      description: ID of the parent step (for branching)
                                    ifConditionPositive:
                                      type: boolean
                                      nullable: true
                                      description: Whether this step is on the positive branch of a condition
                                    type:
                                      type: string
                                      enum:
                                        - call
                                      description: Step type discriminator
                                    delayInMinutes:
                                      type: integer
                                      minimum: 0
                                      description: Delay in minutes before executing this step
                                    message:
                                      type: string
                                      description: Notes or script for the call
                                  required: &ref_219
                                    - type
                                    - delayInMinutes
                                - type: object
                                  title: SMS
                                  description: SMS step with message content
                                  properties: &ref_220
                                    id:
                                      type: integer
                                      nullable: true
                                      readOnly: true
                                      description: Unique identifier for the step
                                    parentId:
                                      type: integer
                                      nullable: true
                                      description: ID of the parent step (for branching)
                                    ifConditionPositive:
                                      type: boolean
                                      nullable: true
                                      description: Whether this step is on the positive branch of a condition
                                    type:
                                      type: string
                                      enum:
                                        - sms
                                      description: Step type discriminator
                                    delayInMinutes:
                                      type: integer
                                      minimum: 0
                                      description: Delay in minutes before executing this step
                                    executionMode:
                                      type: string
                                      description: Execution mode for the SMS step
                                      enum:
                                        - automatic
                                        - manual
                                    message:
                                      type: string
                                      description: SMS message content
                                  required: &ref_221
                                    - type
                                    - delayInMinutes
                                    - executionMode
                                    - message
                                - type: object
                                  title: WhatsApp
                                  description: WhatsApp step with message content
                                  properties: &ref_222
                                    id:
                                      type: integer
                                      nullable: true
                                      readOnly: true
                                      description: Unique identifier for the step
                                    parentId:
                                      type: integer
                                      nullable: true
                                      description: ID of the parent step (for branching)
                                    ifConditionPositive:
                                      type: boolean
                                      nullable: true
                                      description: Whether this step is on the positive branch of a condition
                                    type:
                                      type: string
                                      enum:
                                        - whatsApp
                                      description: Step type discriminator
                                    delayInMinutes:
                                      type: integer
                                      minimum: 0
                                      description: Delay in minutes before executing this step
                                    message:
                                      type: string
                                      description: WhatsApp message content
                                  required: &ref_223
                                    - type
                                    - delayInMinutes
                                    - message
                                - type: object
                                  title: Zapier
                                  description: Zapier integration step
                                  properties: &ref_224
                                    id:
                                      type: integer
                                      nullable: true
                                      readOnly: true
                                      description: Unique identifier for the step
                                    parentId:
                                      type: integer
                                      nullable: true
                                      description: ID of the parent step (for branching)
                                    ifConditionPositive:
                                      type: boolean
                                      nullable: true
                                      description: Whether this step is on the positive branch of a condition
                                    type:
                                      type: string
                                      enum:
                                        - zapier
                                      description: Step type discriminator
                                    delayInMinutes:
                                      type: integer
                                      minimum: 0
                                      description: Delay in minutes before executing this step
                                    name:
                                      type: string
                                      description: Name of the Zapier step
                                    action:
                                      type: string
                                      description: Zapier action type
                                      enum:
                                        - immediately
                                        - wait
                                  required: &ref_225
                                    - type
                                    - delayInMinutes
                                    - name
                                    - action
                                - type: object
                                  title: Task
                                  description: Task step for manual actions
                                  properties: &ref_226
                                    id:
                                      type: integer
                                      nullable: true
                                      readOnly: true
                                      description: Unique identifier for the step
                                    parentId:
                                      type: integer
                                      nullable: true
                                      description: ID of the parent step (for branching)
                                    ifConditionPositive:
                                      type: boolean
                                      nullable: true
                                      description: Whether this step is on the positive branch of a condition
                                    type:
                                      type: string
                                      enum:
                                        - task
                                      description: Step type discriminator
                                    delayInMinutes:
                                      type: integer
                                      minimum: 0
                                      description: Delay in minutes before executing this step
                                    actionType:
                                      type: string
                                      description: Type of task action to perform
                                      enum:
                                        - toDo
                                        - meeting
                                    description:
                                      type: string
                                      description: Task description or instructions
                                  required: &ref_227
                                    - type
                                    - delayInMinutes
                                    - actionType
                                    - description
                                - type: object
                                  title: Condition
                                  description: Condition step that evaluates rules before proceeding
                                  properties: &ref_228
                                    id:
                                      type: integer
                                      nullable: true
                                      readOnly: true
                                      description: Unique identifier for the step
                                    parentId:
                                      type: integer
                                      nullable: true
                                      description: ID of the parent step (for branching)
                                    ifConditionPositive:
                                      type: boolean
                                      nullable: true
                                      description: Whether this step is on the positive branch of a condition
                                    type:
                                      type: string
                                      enum:
                                        - condition
                                      description: Step type discriminator
                                    delayInMinutes:
                                      type: integer
                                      minimum: 0
                                      description: Delay in minutes before executing this step
                                    waitInMinutes:
                                      type: integer
                                      minimum: 0
                                      description: Wait time in minutes for condition evaluation
                                    conditions:
                                      type: array
                                      description: Array of condition templates to evaluate
                                      items:
                                        type: object
                                        title: ConditionTemplate
                                        description: Template defining a condition with property and rules
                                        properties:
                                          property:
                                            type: string
                                            description: Property name to evaluate
                                          rules:
                                            type: array
                                            description: Set of rules to apply to the property
                                            items:
                                              type: object
                                              title: ConditionRule
                                              description: Rule defining operator and value for condition
                                              properties:
                                                operator:
                                                  type: string
                                                  description: Comparison operator (e.g., `isSet`, `isNotSet`, `equals`, etc.)
                                                value:
                                                  type: string
                                                  nullable: true
                                                  description: Value to compare against. Null for operators like `isSet`/`isNotSet`.
                                              required:
                                                - operator
                                        required:
                                          - property
                                          - rules
                                  required: &ref_229
                                    - type
                                    - delayInMinutes
                                    - waitInMinutes
                                    - conditions
                            description: Array of sequence steps
                    example: &ref_190
                      id: 123
                      ownerUserId: 42
                      name: Sales Outreach 2024
                      status: active
                      created: '2024-03-08T14:30:00+00:00'
                      isArchived: false
                      health: degraded
                      scheduleId: 1
                      emailAccounts:
                        - id: 1
                          email: sales@company.com
                        - id: 2
                          email: outreach@company.com
                      linkedInAccounts:
                        - id: 42
                          name: John Doe
                          profileUrl: https://www.linkedin.com/in/johndoe
                          status: enabled
                      settings:
                        emailsCountPerDay: 50
                        daysToFinishProspect: 14
                        emailSendingDelaySeconds: 30
                        dailyThrottling: 200
                        disableOpensTracking: false
                        repliesHandlingType: markAsFinished
                        enableLinksTracking: true
                      steps:
                        - id: 1323
                          type: email
                          delayInMinutes: 0
                          executionMode: automatic
                          variants:
                            - id: 1
                              subject: Quick question about {{companyName}}
                              message: <p>Hi {{firstName}},</p><p>I noticed you are leading initiatives at {{companyName}} and wanted to reach out.</p><p>Best regards, John</p>
                        - id: 43432
                          type: linkedIn
                          actionType: message
                          delayInMinutes: 2880
                          executionMode: automatic
                          variants:
                            - id: 2
                              message: Hi {{firstName}}, I noticed your great work at {{companyName}}. Would love to connect!
                              isEnabled: true
                  - type: object
                    description: AI SDR sequence creation response — extends the generic sequence response with the AI SDR-specific settings under `aiSdr`.
                    properties:
                      aiSdr:
                        type: object
                        title: AI SDR sequence settings
                        description: AI SDR-specific settings of a sequence. Returned by `GET .../settings` and `PATCH .../settings`. Generic sequence fields (name, schedule, accounts, etc.) come from the generic `GET /v3/sequences/{id}` and are NOT included here.
                        properties: &ref_60
                          offerId:
                            type: integer
                            format: int64
                            nullable: true
                            description: Id of the saved offer the sequence was seeded from. `null` when the sequence was created with inline `offerGenerationInputs`.
                            readOnly: true
                          offerGenerationInputs:
                            type: object
                            title: Offer generation inputs
                            description: |-
                              Inline offer-context inputs used when the sequence is created without referencing a saved offer. Mirrors the shape of an offer.

                              On create, exactly one of `offerId` or `offerGenerationInputs` must be provided.
                            properties: *ref_49
                          toneOfVoice:
                            type: object
                            title: Tone of voice (response)
                            description: Tone-of-voice configuration as returned in sequence responses. All four fields are always populated.
                            properties: &ref_335
                              language:
                                type: string
                                title: Sales agent language
                                description: Language used by the AI SDR when generating outreach messages.
                                enum: *ref_50
                              toneOfVoice:
                                type: string
                                title: Sales agent tone of voice
                                description: Tone of voice used by the AI SDR when generating outreach messages.
                                enum: *ref_51
                              messageLength:
                                type: string
                                title: Personalized message length
                                description: Target length for AI-generated personalized messages.
                                enum: *ref_52
                              gender:
                                type: string
                                title: Sales agent gender
                                description: Gender used by the AI SDR persona when generating outreach messages.
                                enum: *ref_53
                          generatedStepTypes:
                            type: array
                            description: Step channels the AI SDR is allowed to generate
                            items:
                              type: string
                              title: Generated step type
                              description: Channel of a step the AI SDR is allowed to generate when building the sequence.
                              enum: *ref_54
                          providerLLM:
                            type: string
                            title: AI content provider
                            description: LLM provider that generates the outreach content for the AI SDR sequence.
                            enum: *ref_55
                          personalizationPoints:
                            type: object
                            title: Personalization points
                            description: Which research signals the AI SDR is allowed to weave into personalized messages. Every leaf is optional; absent flags are treated as "no preference / keep the current value".
                            properties: *ref_56
                          autopilot:
                            type: object
                            title: Autopilot settings (response)
                            description: Autopilot configuration as returned in sequence responses.
                            properties: &ref_337
                              status:
                                type: string
                                title: Autopilot status
                                description: |-
                                  Current autopilot status of the AI SDR sequence.

                                  - `enabled` — autopilot is actively searching and adding contacts.
                                  - `disabled` — autopilot is turned off.
                                  - `paused` — autopilot is paused.
                                  - `disabledByLackOfContacts` — autopilot was auto-disabled because no matching contacts were found.
                                  - `disabledByContactsLimitExceeded` — autopilot was auto-disabled because the team contacts limit was reached.
                                enum: &ref_336
                                  - enabled
                                  - disabled
                                  - paused
                                  - disabledByLackOfContacts
                                  - disabledByContactsLimitExceeded
                              isSearchInProgress:
                                type: boolean
                                description: Whether an autopilot contact search is currently running for this sequence
                              filters:
                                allOf:
                                  - type: object
                                    title: Autopilot filters
                                    description: |-
                                      Account- and contact-level filter configuration used by autopilot when searching for new contacts to add to the sequence.

                                      Most collections are capped at 25 items. `accountKeywords` and `contactKeywords` are always present and non-null in responses even when empty (`{ "values": [], "type": "or" }`).
                                    properties: *ref_57
                                description: Autopilot account/contact filter configuration. Always present.
                              referenceUrl:
                                type: string
                                nullable: true
                                description: Optional reference URL used to seed the autopilot search
                              maxPeoplePerCompany:
                                type: integer
                                description: Maximum contacts to add per company
                              maxPeopleToAddPerDay:
                                type: integer
                                description: Maximum contacts to add per day
                              searchContactPhones:
                                type: boolean
                                description: Whether phone numbers are enriched during search
                              addContactsWithoutEmailAddresses:
                                type: boolean
                                description: Whether contacts without an email address are still added to the sequence
                          playbookId:
                            type: string
                            nullable: true
                            description: Composite id of the attached playbook (`{prefix}-{numericId}`), or `null` when no playbook is attached.
                            readOnly: true
                          knowledgeBaseId:
                            type: integer
                            format: int64
                            nullable: true
                            description: Id of the connected knowledge base, or `null` when none is connected.
                            readOnly: true
                          approvalMode:
                            type: object
                            title: Approval mode (response)
                            description: Current approval-mode state of the sequence.
                            properties: &ref_338
                              enabled:
                                type: boolean
                                description: When `true`, AI-generated messages require human approval before sending
                          intentSignals:
                            type: array
                            description: Configured intent signals. At most one per `type`.
                            items:
                              type: object
                              title: Intent signal
                              description: |-
                                Tagged-union intent signal. Exactly one of `postEngagers`, `competitorFollowers`, `technologyUsed`, `jobHiring` is populated, matching `type`. The other three must be omitted or `null`.

                                A sequence may have at most one signal per `type`. `technologyUsed` and `jobHiring` are mutually exclusive — a sequence may include at most one of the two.
                              required: *ref_58
                              properties: *ref_59
        '400':
          description: Validation failure on the request body, or invalid offer / playbook / knowledge-base / autopilot filters / intent signal referenced in the body.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /sequenceStructureSetup/generatedStepTypes
                        detail: '''GeneratedStepTypes'' must not be empty.'
                      - pointer: /
                        detail: Provide exactly one of OfferId or OfferGenerationInputs.
                      - pointer: /
                        detail: Email-only sequences cannot add contacts without email addresses.
                invalid_offer:
                  summary: Referenced offer not found
                  value:
                    title: Bad Request
                    status: 400
                    detail: Offer '4821' not found.
                    code: salesAgentSequence.invalidOffer
                invalid_playbook_id_format:
                  summary: Playbook id is not a valid composite id
                  value:
                    title: Bad Request
                    status: 400
                    detail: PlaybookId 'foo-7' is not a valid composite playbook ID.
                    code: salesAgentSequence.invalidIdFormat
                invalid_autopilot_filters:
                  summary: Autopilot filters rejected by upstream
                  value:
                    title: Bad Request
                    status: 400
                    detail: Autopilot filters are invalid.
                    code: salesAgentSequence.invalidAutopilotFilters
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller lacks permission to create AI SDR sequences.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: A referenced entity (offer, knowledge base) was not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Knowledge base '1024' not found.
                code: salesAgentSequence.invalidKnowledgeBase
        '409':
          description: Autopilot search throttled by the upstream service.
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Autopilot search is currently throttled; retry later.
                code: salesAgentSequence.autopilotSearchThrottled
        '502':
          description: Upstream AI SDR service failure (including read-back failure after create).
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              examples:
                upstream_failure:
                  summary: Upstream R3 failure
                  value:
                    title: Bad Gateway
                    status: 502
                    detail: Upstream service failure.
                    code: salesAgentSequence.upstreamFailure
                read_back_failed:
                  summary: Created but read-back failed
                  value:
                    title: Bad Gateway
                    status: 502
                    detail: Created sequence not retrievable.
                    code: salesAgentSequence.upstreamFailure
  /v3/sequences/ai-sdr/{sequence_id}/settings:
    get:
      tags:
        - AI SDR Sequences
      summary: Read AI SDR sequence settings
      x-required-scope: ai-sdr:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns the AI SDR-specific settings of a sequence. Mirrors the shape of the create/patch body. Generic sequence fields (name, schedule, etc.) are read via `GET /v3/sequences/{id}`.

        Requires the AI SDR feature on the caller's team.
      operationId: GetAiSdrSequenceSettings
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: AI SDR sequence settings
          content:
            application/json:
              schema:
                type: object
                title: AI SDR sequence settings
                description: AI SDR-specific settings of a sequence. Returned by `GET .../settings` and `PATCH .../settings`. Generic sequence fields (name, schedule, accounts, etc.) come from the generic `GET /v3/sequences/{id}` and are NOT included here.
                properties: *ref_60
        '400':
          description: Sequence exists but is not an AI SDR sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Sequence '4821' is not an AI SDR sequence.
                code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence '4821' not found.
                code: salesAgentSequence.notFound
        '502':
          description: Upstream AI SDR service failure, or a legacy stored value cannot be represented in the v3 API.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              examples:
                upstream_failure:
                  summary: Upstream R3 failure
                  value:
                    title: Bad Gateway
                    status: 502
                    detail: Upstream service failure.
                    code: salesAgentSequence.upstreamFailure
                unsupported_legacy_value:
                  summary: Legacy stored value cannot be represented
                  value:
                    title: Bad Gateway
                    status: 502
                    detail: A stored value uses a legacy code that the v3 API cannot represent.
                    code: salesAgentSequence.unsupportedLegacyValue
    patch:
      tags:
        - AI SDR Sequences
      summary: Update AI SDR sequence settings
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Partial update of AI SDR-specific sequence settings (generation inputs, tone of voice, personalization points, provider LLM, autopilot config, intent signals).

        PATCH semantics: a field absent from the body is skipped; a field explicitly set to `null` is rejected. `intentSignals`, when present, fully replaces the current list. `autopilot.filters`, when present, fully replaces the current filters object. At least one field must be present.

        Out of scope for this PATCH (use the dedicated sub-resources instead): name and other generic sequence fields, approval mode, generated step types, attached playbook, connected knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: UpdateAiSdrSequenceSettings
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: AI SDR sequence — patch
              description: |-
                Partial update of AI SDR-specific sequence settings. Generic sequence fields (name, schedule, accounts, settings) are NOT updated here — use the generic `PATCH /v3/sequences/{id}`. Approval mode is NOT updated here — use `PUT .../approval-mode`. Generated step types are NOT updated here — use `PUT .../generated-step-types`. Playbook and knowledge-base attachments are NOT updated here — use the dedicated sub-resources.

                PATCH semantics:
                - Field absent from the body: skip; current value is retained.
                - Field present with `null`: rejected.
                - `offerId` and `offerGenerationInputs` are mutually exclusive — only one may be present.
                - `intentSignals`, when present, fully replaces the current list. At most one signal per `type`; `technologyUsed` and `jobHiring` are mutually exclusive.
                - `offerGenerationInputs`, `toneOfVoice` and `personalizationPoints`, when present, are deep-merged at the leaf level — array fields inside them fully replace.

                At least one field must be present in the body.
              properties: &ref_342
                offerId:
                  type: integer
                  format: int64
                  minimum: 1
                  description: Switch the sequence to a different saved offer. Mutually exclusive with `offerGenerationInputs`.
                offerGenerationInputs:
                  type: object
                  title: Offer generation inputs (patch)
                  description: |-
                    Partial update for the inline offer-context inputs of an AI SDR sequence.

                    - Field absent from the body: skip; current value is retained.
                    - Field present with `null`: rejected.
                    - Array fields, when present, fully replace the current value (no item-level merge) and must contain 1-10 items.
                  properties: &ref_340
                    companyName:
                      type: string
                      maxLength: 200
                    companyDescription:
                      type: string
                      maxLength: 3000
                    icp:
                      type: string
                      maxLength: 1000
                    reasonForOutreach:
                      type: string
                      maxLength: 1000
                    caseStudies:
                      type: array
                      minItems: 1
                      maxItems: 10
                      items:
                        type: string
                        minLength: 1
                        maxLength: 1000
                    painPoints:
                      type: array
                      minItems: 1
                      maxItems: 10
                      items:
                        type: string
                        minLength: 1
                        maxLength: 1000
                    proofPoints:
                      type: array
                      minItems: 1
                      maxItems: 10
                      items:
                        type: string
                        minLength: 1
                        maxLength: 1000
                    valuePropositions:
                      type: array
                      minItems: 1
                      maxItems: 10
                      items:
                        type: string
                        minLength: 1
                        maxLength: 1000
                    callToActions:
                      type: array
                      minItems: 1
                      maxItems: 10
                      items:
                        type: string
                        minLength: 1
                        maxLength: 1000
                toneOfVoice:
                  type: object
                  title: Tone of voice settings (request)
                  description: Tone-of-voice configuration on create/patch. All fields are optional on create — omitted fields fall back to defaults (English (US), Confident tone, Medium length, Man).
                  properties: *ref_61
                providerLLM:
                  type: string
                  title: AI content provider
                  description: LLM provider that generates the outreach content for the AI SDR sequence.
                  enum: *ref_55
                personalizationPoints:
                  type: object
                  title: Personalization points
                  description: Which research signals the AI SDR is allowed to weave into personalized messages. Every leaf is optional; absent flags are treated as "no preference / keep the current value".
                  properties: *ref_56
                autopilot:
                  type: object
                  title: Autopilot settings (patch)
                  description: |-
                    Partial update of autopilot configuration.

                    - Field absent from the body: skip; current value is retained.
                    - Field present with `null`: rejected.
                    - `filters`, when present, fully replaces the current filters object (no field-level merge inside the filters tree).
                    - The autopilot on/off toggle is NOT changed here — use `POST .../autopilot/enable` or `POST .../autopilot/disable`.
                  properties: &ref_341
                    filters:
                      type: object
                      title: Autopilot filters
                      description: |-
                        Account- and contact-level filter configuration used by autopilot when searching for new contacts to add to the sequence.

                        Most collections are capped at 25 items. `accountKeywords` and `contactKeywords` are always present and non-null in responses even when empty (`{ "values": [], "type": "or" }`).
                      properties: *ref_57
                    referenceUrl:
                      type: string
                    maxPeoplePerCompany:
                      type: integer
                      minimum: 1
                    maxPeopleToAddPerDay:
                      type: integer
                      minimum: 1
                    searchContactPhones:
                      type: boolean
                    addContactsWithoutEmailAddresses:
                      type: boolean
                intentSignals:
                  type: array
                  description: Replaces the full list of intent signals on the sequence. At most one signal per `type`; `technologyUsed` and `jobHiring` are mutually exclusive.
                  items:
                    type: object
                    title: Intent signal
                    description: |-
                      Tagged-union intent signal. Exactly one of `postEngagers`, `competitorFollowers`, `technologyUsed`, `jobHiring` is populated, matching `type`. The other three must be omitted or `null`.

                      A sequence may have at most one signal per `type`. `technologyUsed` and `jobHiring` are mutually exclusive — a sequence may include at most one of the two.
                    required: *ref_58
                    properties: *ref_59
      responses:
        '200':
          description: AI SDR sequence settings after update
          content:
            application/json:
              schema:
                type: object
                title: AI SDR sequence settings
                description: AI SDR-specific settings of a sequence. Returned by `GET .../settings` and `PATCH .../settings`. Generic sequence fields (name, schedule, accounts, etc.) come from the generic `GET /v3/sequences/{id}` and are NOT included here.
                properties: *ref_60
        '400':
          description: Validation failure on the request body, or referenced offer / autopilot filters / intent signal rejected, or sequence is not an AI SDR sequence.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /
                        detail: At least one field must be provided.
                mutually_exclusive:
                  summary: offerId and offerGenerationInputs are mutually exclusive
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /
                        detail: OfferId and OfferGenerationInputs are mutually exclusive.
                invalid_offer:
                  summary: Switched-to offer not found
                  value:
                    title: Bad Request
                    status: 400
                    detail: Offer '4821' not found.
                    code: salesAgentSequence.invalidOffer
                invalid_autopilot_filters:
                  summary: Autopilot filters rejected
                  value:
                    title: Bad Request
                    status: 400
                    detail: Autopilot filters are invalid.
                    code: salesAgentSequence.invalidAutopilotFilters
                invalid_intent_signal:
                  summary: Intent signals rejected
                  value:
                    title: Bad Request
                    status: 400
                    detail: Intent signal payload is invalid.
                    code: salesAgentSequence.invalidIntentSignal
                not_ai_sdr:
                  summary: Sequence is not an AI SDR sequence
                  value:
                    title: Bad Request
                    status: 400
                    detail: Sequence '4821' is not an AI SDR sequence.
                    code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence '4821' not found.
                code: salesAgentSequence.notFound
        '409':
          description: Autopilot search throttled by the upstream service.
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Autopilot search is currently throttled; retry later.
                code: salesAgentSequence.autopilotSearchThrottled
        '502':
          description: Upstream AI SDR service failure.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service failure.
                code: salesAgentSequence.upstreamFailure
  /v3/sequences/ai-sdr/{sequence_id}/autopilot/enable:
    post:
      tags:
        - AI SDR Sequences
      summary: Enable autopilot
      x-required-scope: ai-sdr:operate
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:operate` scope (or a broader one that includes it)._</small>

        Enables autopilot on the sequence. No-op when autopilot is already enabled.

        Requires the AI SDR feature on the caller's team.
      operationId: EnableAiSdrSequenceAutopilot
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      responses:
        '204':
          description: Autopilot enabled (or was already enabled)
        '400':
          description: Sequence exists but is not an AI SDR sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Sequence '4821' is not an AI SDR sequence.
                code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence '4821' not found.
                code: salesAgentSequence.notFound
  /v3/sequences/ai-sdr/{sequence_id}/autopilot/disable:
    post:
      tags:
        - AI SDR Sequences
      summary: Disable autopilot
      x-required-scope: ai-sdr:operate
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:operate` scope (or a broader one that includes it)._</small>

        Disables autopilot on the sequence. No-op when autopilot is already disabled.

        Requires the AI SDR feature on the caller's team.
      operationId: DisableAiSdrSequenceAutopilot
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      responses:
        '204':
          description: Autopilot disabled (or was already disabled)
        '400':
          description: Sequence exists but is not an AI SDR sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Sequence '4821' is not an AI SDR sequence.
                code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence '4821' not found.
                code: salesAgentSequence.notFound
  /v3/sequences/ai-sdr/{sequence_id}/autopilot/force-start:
    post:
      tags:
        - AI SDR Sequences
      summary: Force-start an autopilot search
      x-required-scope: ai-sdr:operate
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:operate` scope (or a broader one that includes it)._</small>

        Force-starts an autopilot contact search for the sequence, bypassing the normal schedule. Autopilot must already be enabled; rejected with 409 otherwise.

        Requires the AI SDR feature on the caller's team.
      operationId: ForceStartAiSdrSequenceAutopilot
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      responses:
        '204':
          description: Autopilot search started
        '400':
          description: Sequence is not an AI SDR sequence, or current autopilot filters are invalid.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              examples:
                not_ai_sdr:
                  summary: Sequence is not an AI SDR sequence
                  value:
                    title: Bad Request
                    status: 400
                    detail: Sequence '4821' is not an AI SDR sequence.
                    code: salesAgentSequence.invalidParameter
                invalid_filters:
                  summary: Stored autopilot filters rejected
                  value:
                    title: Bad Request
                    status: 400
                    detail: Autopilot filters are invalid.
                    code: salesAgentSequence.invalidAutopilotFilters
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence '4821' not found.
                code: salesAgentSequence.notFound
        '409':
          description: Autopilot is not enabled (including when it was auto-disabled because the contacts limit was exceeded or no matching contacts were found), or an autopilot search is currently throttled.
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              examples:
                not_enabled:
                  summary: Autopilot is not enabled
                  value:
                    title: Conflict
                    status: 409
                    detail: Autopilot is not enabled for sequence '4821'; enable it before forcing a search.
                    code: salesAgentSequence.autopilotNotEnabled
                throttled:
                  summary: Autopilot search throttled
                  value:
                    title: Conflict
                    status: 409
                    detail: Autopilot search is currently throttled; retry later.
                    code: salesAgentSequence.autopilotSearchThrottled
                disabled_by_contacts_limit:
                  summary: Autopilot disabled because the contacts limit was exceeded
                  value:
                    title: Conflict
                    status: 409
                    detail: Autopilot for sequence '4821' was disabled because the contacts limit was exceeded.
                    code: salesAgentSequence.autopilotDisabledByContactsLimit
                disabled_by_lack_of_contacts:
                  summary: Autopilot disabled because no matching contacts were found
                  value:
                    title: Conflict
                    status: 409
                    detail: Autopilot for sequence '4821' was disabled because no matching contacts were found.
                    code: salesAgentSequence.autopilotDisabledByLackOfContacts
        '502':
          description: Upstream AI SDR service failure.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service failure.
                code: salesAgentSequence.upstreamFailure
  /v3/sequences/ai-sdr/{sequence_id}/autopilot/preview:
    post:
      tags:
        - AI SDR Sequences
      summary: Preview autopilot results
      x-required-scope: ai-sdr:operate
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:operate` scope (or a broader one that includes it)._</small>

        Previews the expected autopilot results for the sequence. Clients pass the autopilot filter config in the body — they are NOT required to save it to the sequence first (supports try-before-save in the filter UI).

        Returns a background job to poll via `GET /v3/background-jobs/{id}`; on completion its `jsonDataResult` carries `{ contactsCount, companiesCount, sampleContacts }`, where `sampleContacts` is a capped sample of matching contacts.

        Requires the AI SDR feature on the caller's team.
      operationId: PreviewAutopilot
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Autopilot preview request
              description: Autopilot filter configuration to preview. Does not need to be saved to the sequence first — supports try-before-save in the filter UI.
              required: &ref_343
                - filters
              properties: &ref_344
                filters:
                  type: object
                  title: Autopilot filters
                  description: |-
                    Account- and contact-level filter configuration used by autopilot when searching for new contacts to add to the sequence.

                    Most collections are capped at 25 items. `accountKeywords` and `contactKeywords` are always present and non-null in responses even when empty (`{ "values": [], "type": "or" }`).
                  properties: *ref_57
                maxPeoplePerCompany:
                  type: integer
                  minimum: 1
                  nullable: true
                  description: Maximum contacts to consider per company
                maxPeopleToAddPerDay:
                  type: integer
                  minimum: 1
                  nullable: true
                  description: Maximum contacts to add per day
                referenceUrl:
                  type: string
                  nullable: true
                  description: Optional reference URL used to seed the search
      responses:
        '202':
          description: Preview accepted; poll the returned job for progress and results
          content:
            application/json:
              schema:
                type: object
                required:
                  - jobId
                properties:
                  jobId:
                    type: string
                    format: uuid
                    description: Background job id; poll `GET /v3/background-jobs/{id}`.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
        '404':
          description: Sequence not found, or the sequence is not an AI SDR sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
  /v3/sequences/ai-sdr/{sequence_id}/approval-mode:
    put:
      tags:
        - AI SDR Sequences
      summary: Set the approval mode
      x-required-scope: ai-sdr:operate
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:operate` scope (or a broader one that includes it)._</small>

        Sets the sequence's approval mode — whether AI-generated messages require human approval before sending. Settable only via this dedicated PUT (or at create time); NOT in the AI SDR sequence PATCH.

        When disabling (`enabled` = `false`), `approveAllPendingContacts` may be set to `true` to immediately approve all currently-pending contacts. `approveAllPendingContacts` is rejected when enabling.

        Requires the AI SDR feature on the caller's team.
      operationId: SetAiSdrSequenceApprovalMode
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Approval mode — set
              description: |-
                Sets the sequence's approval mode.

                When disabling (`enabled` = `false`), `approveAllPendingContacts` may be provided to immediately approve all pending contacts. When enabling (`enabled` = `true`), `approveAllPendingContacts` must be omitted.
              required: &ref_345
                - enabled
              properties: &ref_346
                enabled:
                  type: boolean
                  description: When `true`, AI-generated messages require human approval before sending
                approveAllPendingContacts:
                  type: boolean
                  nullable: true
                  description: When disabling approval mode, set to `true` to immediately approve all currently-pending contacts. Only accepted when `enabled` is `false`.
      responses:
        '204':
          description: Approval mode updated
        '400':
          description: Validation failure on the request body, or sequence is not an AI SDR sequence.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /approveAllPendingContacts
                        detail: ApproveAllPendingContacts only accepted when disabling approval mode.
                not_ai_sdr:
                  summary: Sequence is not an AI SDR sequence
                  value:
                    title: Bad Request
                    status: 400
                    detail: Sequence '4821' is not an AI SDR sequence.
                    code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence '4821' not found.
                code: salesAgentSequence.notFound
        '502':
          description: Upstream AI SDR service failure.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service failure.
                code: salesAgentSequence.upstreamFailure
  /v3/sequences/ai-sdr/{sequence_id}/generated-step-types:
    put:
      tags:
        - AI SDR Sequences
      summary: Set generated step types
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Replaces the step channels the AI SDR is allowed to generate, and triggers regeneration of the sequence's steps using the new mix.

        Rejected with 409 once the sequence has already acted on contacts (sent emails or LinkedIn messages, generated tasks, etc.).

        Requires the AI SDR feature on the caller's team.
      operationId: SetAiSdrSequenceGeneratedStepTypes
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Generated step types — set
              description: Replaces the channels of steps the AI SDR is allowed to generate, and regenerates the sequence steps using the new mix. Rejected (409) when the sequence has already acted on contacts (sent emails or LinkedIn messages, generated tasks, etc.).
              required: &ref_347
                - generatedStepTypes
              properties: &ref_348
                generatedStepTypes:
                  type: array
                  minItems: 1
                  description: Step channels the AI SDR is allowed to generate. Non-empty, no duplicates.
                  items:
                    type: string
                    title: Generated step type
                    description: Channel of a step the AI SDR is allowed to generate when building the sequence.
                    enum: *ref_54
      responses:
        '204':
          description: Step types updated and regeneration triggered
        '400':
          description: Validation failure on the request body, or sequence is not an AI SDR sequence, or invalid step-type payload rejected by upstream.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /generatedStepTypes
                        detail: '''GeneratedStepTypes'' must not be empty.'
                not_ai_sdr:
                  summary: Sequence is not an AI SDR sequence
                  value:
                    title: Bad Request
                    status: 400
                    detail: Sequence '4821' is not an AI SDR sequence.
                    code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence '4821' not found.
                code: salesAgentSequence.notFound
        '409':
          description: Step types cannot be regenerated because the sequence has already acted on contacts.
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: 'Cannot regenerate step types: sequence has already acted on contacts (sent emails, LinkedIn messages, SMS, or generated tasks).'
                code: salesAgentSequence.stepTypesRegenerationBlocked
        '502':
          description: Upstream AI SDR service failure.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service failure.
                code: salesAgentSequence.upstreamFailure
  /v3/sequences/ai-sdr/{sequence_id}/playbook:
    get:
      tags:
        - AI SDR Sequences
      summary: Get the sequence's playbook
      x-required-scope: ai-sdr:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns the playbook attached to the sequence. Each sequence is attached to at most one playbook.

        Requires the AI SDR feature on the caller's team.
      operationId: GetAiSdrSequencePlaybook
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Playbook attached to the sequence
          content:
            application/json:
              schema:
                type: object
                title: Sequence playbook summary
                description: Compact representation of the playbook attached to a sequence.
                properties: &ref_349
                  id:
                    type: string
                    description: 'Composite playbook id (`{prefix}-{numericId}`) where the prefix encodes the playbook scope: `g` for global, `o` for organization, `t` for team.'
                    readOnly: true
                  name:
                    type: string
                    description: Display name of the playbook
                    readOnly: true
                  type:
                    allOf:
                      - type: string
                        title: Playbook scope
                        description: |-
                          Identifies the visibility scope of a playbook.

                          - `global` — Reply-curated, read-only across all teams.
                          - `organization` — visible to every team in the caller's organization.
                          - `team` — visible to the caller's team only.

                          `global` playbooks are never created or modified via the API; only `organization` and `team` are accepted on create.
                        enum: *ref_35
                    description: Visibility scope of the playbook
                    readOnly: true
                example: &ref_350
                  id: t-7
                  name: Outbound playbook v2
                  type: team
        '400':
          description: Sequence exists but is not an AI SDR sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Sequence '4821' is not an AI SDR sequence.
                code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found, or no playbook is attached to the sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              examples:
                sequence_not_found:
                  summary: Sequence not found
                  value:
                    title: Not Found
                    status: 404
                    detail: Sequence '4821' not found.
                    code: salesAgentSequence.notFound
                no_playbook:
                  summary: No playbook attached
                  value:
                    title: Not Found
                    status: 404
                    detail: No playbook connected to sequence '4821'.
                    code: salesAgentSequence.notFound
        '502':
          description: Upstream AI SDR service failure.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service failure.
                code: salesAgentSequence.upstreamFailure
    put:
      tags:
        - AI SDR Sequences
      summary: Attach a playbook to the sequence
      x-required-scope: ai-sdr:operate
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:operate` scope (or a broader one that includes it)._</small>

        Attaches a playbook to the sequence by composite id. Replaces any previously-attached playbook.

        Requires the AI SDR feature on the caller's team.
      operationId: SetAiSdrSequencePlaybook
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Sequence playbook — set
              description: Attaches a playbook to the sequence by composite id. Replaces any previously-attached playbook.
              required: &ref_351
                - playbookId
              properties: &ref_352
                playbookId:
                  type: string
                  minLength: 1
                  description: 'Composite playbook id (`{prefix}-{numericId}`) where the prefix encodes the playbook scope: `g` for global, `o` for organization, `t` for team (e.g. `g-1`, `o-42`, `t-7`).'
      responses:
        '204':
          description: Playbook attached
        '400':
          description: Validation failure, invalid playbook id format, referenced playbook not found, or sequence is not an AI SDR sequence.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /playbookId
                        detail: '''PlaybookId'' must not be empty.'
                invalid_id_format:
                  summary: Playbook id not a valid composite id
                  value:
                    title: Bad Request
                    status: 400
                    detail: PlaybookId 'foo-7' is not a valid composite playbook ID.
                    code: salesAgentSequence.invalidIdFormat
                invalid_playbook:
                  summary: Referenced playbook not found
                  value:
                    title: Bad Request
                    status: 400
                    detail: Playbook 't-7' not found.
                    code: salesAgentSequence.invalidPlaybook
                not_ai_sdr:
                  summary: Sequence is not an AI SDR sequence
                  value:
                    title: Bad Request
                    status: 400
                    detail: Sequence '4821' is not an AI SDR sequence.
                    code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence '4821' not found.
                code: salesAgentSequence.notFound
        '502':
          description: Upstream AI SDR service failure.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service failure.
                code: salesAgentSequence.upstreamFailure
    delete:
      tags:
        - AI SDR Sequences
      summary: Detach the playbook from the sequence
      x-required-scope: ai-sdr:operate
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:operate` scope (or a broader one that includes it)._</small>

        Detaches the playbook attached to the sequence. Returns 404 if no playbook is attached.

        Requires the AI SDR feature on the caller's team.
      operationId: ClearAiSdrSequencePlaybook
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      responses:
        '204':
          description: Playbook detached
        '400':
          description: Sequence exists but is not an AI SDR sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Sequence '4821' is not an AI SDR sequence.
                code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found, or no playbook is attached to the sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              examples:
                sequence_not_found:
                  summary: Sequence not found
                  value:
                    title: Not Found
                    status: 404
                    detail: Sequence '4821' not found.
                    code: salesAgentSequence.notFound
                no_playbook:
                  summary: No playbook attached to the sequence
                  value:
                    title: Not Found
                    status: 404
                    detail: No playbook connected to sequence '4821'.
                    code: salesAgentSequence.notFound
        '502':
          description: Upstream AI SDR service failure.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service failure.
                code: salesAgentSequence.upstreamFailure
  /v3/sequences/ai-sdr/{sequence_id}/knowledge-base:
    get:
      tags:
        - AI SDR Sequences
      summary: Get the sequence's knowledge base
      x-required-scope: ai-sdr:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:read` scope (or a broader one that includes it)._</small>

        Returns the knowledge base connected to the sequence. Each sequence is connected to at most one knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: GetAiSdrSequenceKnowledgeBase
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Knowledge base connected to the sequence
          content:
            application/json:
              schema:
                type: object
                title: Sequence knowledge base summary
                description: Compact representation of the knowledge base connected to a sequence.
                properties: &ref_353
                  id:
                    type: integer
                    format: int64
                    description: Id of the knowledge base
                    readOnly: true
                  name:
                    type: string
                    description: Display name of the knowledge base
                    readOnly: true
                example: &ref_354
                  id: 1024
                  name: Acme product docs
        '400':
          description: Sequence exists but is not an AI SDR sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Sequence '4821' is not an AI SDR sequence.
                code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found, or no knowledge base is connected to the sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              examples:
                sequence_not_found:
                  summary: Sequence not found
                  value:
                    title: Not Found
                    status: 404
                    detail: Sequence '4821' not found.
                    code: salesAgentSequence.notFound
                no_knowledge_base:
                  summary: No knowledge base connected
                  value:
                    title: Not Found
                    status: 404
                    detail: No knowledge base connected to sequence '4821'.
                    code: salesAgentSequence.notFound
        '502':
          description: Upstream AI SDR service failure.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service failure.
                code: salesAgentSequence.upstreamFailure
    put:
      tags:
        - AI SDR Sequences
      summary: Connect a knowledge base to the sequence
      x-required-scope: ai-sdr:operate
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:operate` scope (or a broader one that includes it)._</small>

        Connects a knowledge base to the sequence by id. Replaces any previously-connected knowledge base.

        Requires the AI SDR feature on the caller's team.
      operationId: SetAiSdrSequenceKnowledgeBase
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Sequence knowledge base — set
              description: Connects a knowledge base to the sequence by id. Replaces any previously-connected knowledge base.
              required: &ref_355
                - knowledgeBaseId
              properties: &ref_356
                knowledgeBaseId:
                  type: integer
                  format: int64
                  minimum: 1
                  description: Id of the knowledge base to connect
      responses:
        '204':
          description: Knowledge base connected
        '400':
          description: Validation failure, referenced knowledge base not found, or sequence is not an AI SDR sequence.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /knowledgeBaseId
                        detail: '''KnowledgeBaseId'' must be greater than ''0''.'
                invalid_knowledge_base:
                  summary: Referenced knowledge base not found
                  value:
                    title: Bad Request
                    status: 400
                    detail: Knowledge base '1024' not found.
                    code: salesAgentSequence.invalidKnowledgeBase
                not_ai_sdr:
                  summary: Sequence is not an AI SDR sequence
                  value:
                    title: Bad Request
                    status: 400
                    detail: Sequence '4821' is not an AI SDR sequence.
                    code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence '4821' not found.
                code: salesAgentSequence.notFound
        '502':
          description: Upstream AI SDR service failure.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service failure.
                code: salesAgentSequence.upstreamFailure
    delete:
      tags:
        - AI SDR Sequences
      summary: Disconnect the knowledge base from the sequence
      x-required-scope: ai-sdr:operate
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:operate` scope (or a broader one that includes it)._</small>

        Disconnects the knowledge base connected to the sequence. Returns 404 if no knowledge base is connected.

        Requires the AI SDR feature on the caller's team.
      operationId: ClearAiSdrSequenceKnowledgeBase
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
      responses:
        '204':
          description: Knowledge base disconnected
        '400':
          description: Sequence exists but is not an AI SDR sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Sequence '4821' is not an AI SDR sequence.
                code: salesAgentSequence.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team, or the caller does not have access to this sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team.
                code: salesAgentSequence.forbidden
        '404':
          description: Sequence not found, or no knowledge base is connected to the sequence.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              examples:
                sequence_not_found:
                  summary: Sequence not found
                  value:
                    title: Not Found
                    status: 404
                    detail: Sequence '4821' not found.
                    code: salesAgentSequence.notFound
                no_knowledge_base:
                  summary: No knowledge base connected to the sequence
                  value:
                    title: Not Found
                    status: 404
                    detail: No knowledge base connected to sequence '4821'.
                    code: salesAgentSequence.notFound
        '502':
          description: Upstream AI SDR service failure.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service failure.
                code: salesAgentSequence.upstreamFailure
  /v3/ai-sdr/strategist/start:
    post:
      tags:
        - AI SDR Strategist
      summary: Start a strategist run
      x-required-scope: ai-sdr:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `ai-sdr:write` scope (or a broader one that includes it)._</small>

        Starts an AI Strategist run for the caller's team. The strategist generates sequence ideas and creates a sequence for each one.

        Returns a background job to poll via `GET /v3/background-jobs/{jobId}`; on completion its `jsonDataResult` carries `{ sequenceIds }` — the ids of the sequences created from the generated ideas.

        Requires the AI SDR feature on the caller's team.
      operationId: StartStrategist
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - companyName
              properties:
                companyName:
                  type: string
                  maxLength: 200
                  description: Company the strategist generates ideas for
                companyUrl:
                  type: string
                  maxLength: 256
                  description: Optional company website used to enrich the generated ideas
      responses:
        '202':
          description: Strategist run accepted; poll the returned job for progress and results
          content:
            application/json:
              schema:
                type: object
                required:
                  - jobId
                properties:
                  jobId:
                    type: string
                    format: uuid
                    description: Background job id; poll `GET /v3/background-jobs/{jobId}`.
        '400':
          description: Request body validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /companyName
                    detail: '''companyName'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: AI SDR feature is not available for your team
                code: strategist.forbidden
        '409':
          description: A strategist run could not be started (for example, another run is already in progress for the team)
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Conflict
                status: 409
                detail: Cannot start a new generation while another is in progress
                code: strategist.generationInitFailed
        '502':
          description: Upstream AI SDR service failure while starting the run
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Upstream service returned an unexpected error
                code: strategist.upstreamFailure
  /v3/ai-web-search/start:
    post:
      tags:
        - AI SDR Web Search
      summary: Start an AI web search
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        Kicks off an AI-driven web search to find contacts for a sequence.
      operationId: StartAiWebSearch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Coming soon — full request shape is still being finalized.
      responses:
        '202':
          description: Search accepted
          content:
            application/json:
              schema:
                type: object
                description: Coming soon — full response shape is still being finalized.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
  /v3/ai-web-search/searches:
    get:
      tags:
        - AI SDR Web Search
      summary: List AI web searches for a sequence
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        Returns AI web searches started for a given sequence.
      operationId: ListAiWebSearches
      parameters:
        - name: sequenceId
          in: query
          required: true
          description: Sequence id to filter by
          schema:
            type: integer
            minimum: 1
        - name: top
          in: query
          required: false
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          schema:
            type: integer
      responses:
        '200':
          description: Paginated list of searches
          content:
            application/json:
              schema:
                type: object
                description: Coming soon — full response shape is still being finalized.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
  /v3/contact-accounts:
    get:
      tags:
        - Accounts
      operationId: GetContactAccounts
      summary: List accounts
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of accounts.
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Filter accounts by name
          schema:
            type: string
        - name: sort_by
          in: query
          required: false
          description: Field name to sort by
          schema:
            type: string
        - name: sort_direction
          in: query
          required: false
          description: Sort direction (asc or desc)
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of accounts
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Contact Account
                      description: A contact account representing a company or organization
                      additionalProperties: false
                      properties: &ref_63
                        id:
                          type: integer
                          readOnly: true
                          description: Unique identifier of the contact account
                        ownerUserId:
                          type: integer
                          description: ID of the user who owns this contact account
                        name:
                          type: string
                          description: Contact account name
                        description:
                          type: string
                          nullable: true
                          description: Optional description of the contact account
                        domainName:
                          type: string
                          nullable: true
                          description: Primary domain name
                        domainSecondary:
                          type: string
                          nullable: true
                          description: Secondary domain name
                        industry:
                          type: string
                          nullable: true
                          description: Industry of the company
                        companySize:
                          type: string
                          nullable: true
                          description: Company size range
                          enum:
                            - Empty
                            - SelfEmployed
                            - 2-10
                            - 11-50
                            - 51-200
                            - 201-500
                            - 501-1000
                            - 1001-5000
                            - 5001-10000
                            - 10001+
                        country:
                          type: string
                          nullable: true
                          description: Country of the company
                        state:
                          type: string
                          nullable: true
                          description: State or province
                        city:
                          type: string
                          nullable: true
                          description: City
                        timeZoneId:
                          type: string
                          nullable: true
                          description: Time zone identifier
                        linkedInUrl:
                          type: string
                          nullable: true
                          description: LinkedIn profile URL
                        phone:
                          type: string
                          nullable: true
                          description: Phone number
                        twitterUrl:
                          type: string
                          nullable: true
                          description: Twitter profile URL
                        logoUrl:
                          type: string
                          nullable: true
                          description: Company logo URL
                        email:
                          type: string
                          nullable: true
                          description: Contact email address
                        stage:
                          nullable: true
                          description: Current stage of the contact account
                          type: object
                          title: Contact Account Stage
                          additionalProperties: false
                          properties: &ref_62
                            id:
                              type: integer
                              description: Stage identifier
                            name:
                              type: string
                              description: Stage name
                            colorId:
                              type: integer
                              description: Color identifier for the stage
                        linkedProspectsCount:
                          type: integer
                          readOnly: true
                          description: Number of contacts linked to this account
                        createdDate:
                          type: string
                          format: date-time
                          readOnly: true
                          description: Date when the account was created
                        lastActivityDate:
                          type: string
                          format: date-time
                          readOnly: true
                          description: Date of the last activity on this account
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: contactAccount.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to view accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Accounts
      operationId: CreateContactAccount
      summary: Create an account
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Creates a new account.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Create Contact Account Request
              description: Request body for creating a contact account
              additionalProperties: false
              required: &ref_66
                - name
              properties: &ref_67
                name:
                  type: string
                  description: Contact account name
                description:
                  type: string
                  nullable: true
                  description: Optional description
                domainName:
                  type: string
                  nullable: true
                  description: Primary domain name
                domainSecondary:
                  type: string
                  nullable: true
                  description: Secondary domain name
                industry:
                  type: string
                  nullable: true
                  description: Industry of the company
                companySize:
                  type: string
                  nullable: true
                  description: Company size range
                  enum:
                    - Empty
                    - SelfEmployed
                    - 2-10
                    - 11-50
                    - 51-200
                    - 201-500
                    - 501-1000
                    - 1001-5000
                    - 5001-10000
                    - 10001+
                country:
                  type: string
                  nullable: true
                  description: Country of the company
                state:
                  type: string
                  nullable: true
                  description: State or province
                city:
                  type: string
                  nullable: true
                  description: City
                timeZoneId:
                  type: string
                  nullable: true
                  description: Time zone identifier
                linkedInUrl:
                  type: string
                  nullable: true
                  description: LinkedIn profile URL
                phone:
                  type: string
                  nullable: true
                  description: Phone number
                twitterUrl:
                  type: string
                  nullable: true
                  description: Twitter profile URL
                logoUrl:
                  type: string
                  nullable: true
                  description: Company logo URL
                email:
                  type: string
                  nullable: true
                  description: Contact email address
      responses:
        '201':
          description: Account created successfully
          content:
            application/json:
              schema:
                type: object
                title: Contact Account Details
                description: A single contact account, including the resolved email provider
                additionalProperties: false
                properties: &ref_64
                  id:
                    type: integer
                    readOnly: true
                    description: Unique identifier of the contact account
                  ownerUserId:
                    type: integer
                    description: ID of the user who owns this contact account
                  name:
                    type: string
                    description: Contact account name
                  description:
                    type: string
                    nullable: true
                    description: Optional description of the contact account
                  domainName:
                    type: string
                    nullable: true
                    description: Primary domain name
                  domainSecondary:
                    type: string
                    nullable: true
                    description: Secondary domain name
                  industry:
                    type: string
                    nullable: true
                    description: Industry of the company
                  companySize:
                    type: string
                    nullable: true
                    description: Company size range
                    enum:
                      - Empty
                      - SelfEmployed
                      - 2-10
                      - 11-50
                      - 51-200
                      - 201-500
                      - 501-1000
                      - 1001-5000
                      - 5001-10000
                      - 10001+
                  country:
                    type: string
                    nullable: true
                    description: Country of the company
                  state:
                    type: string
                    nullable: true
                    description: State or province
                  city:
                    type: string
                    nullable: true
                    description: City
                  timeZoneId:
                    type: string
                    nullable: true
                    description: Time zone identifier
                  linkedInUrl:
                    type: string
                    nullable: true
                    description: LinkedIn profile URL
                  phone:
                    type: string
                    nullable: true
                    description: Phone number
                  twitterUrl:
                    type: string
                    nullable: true
                    description: Twitter profile URL
                  logoUrl:
                    type: string
                    nullable: true
                    description: Company logo URL
                  email:
                    type: string
                    nullable: true
                    description: Contact email address
                  emailProvider:
                    type: string
                    nullable: true
                    readOnly: true
                    description: |-
                      Email hosting provider for the account's primary domain, resolved from the domain's MX records.
                      `null` when the account has no domain or the provider could not be determined.
                    enum:
                      - other
                      - gSuite
                      - office
                      - zoho
                      - mimecast
                      - proofpoint
                      - yandex
                      - ovh
                      - goDaddy
                      - ionos
                      - gandi
                      - hostinger
                      - oneAndOne
                      - amazon
                      - barracuda
                      - spamexperts
                      - hotmail
                      - liveCom
                      - yahoo
                      - bloomberg
                      - gmail
                      - outlook
                      - ciscoSecureEmail
                      - titanMail
                      - protonmail
                      - namecheap
                      - appleMail
                      - linkedin
                  stage:
                    nullable: true
                    description: Current stage of the contact account
                    type: object
                    title: Contact Account Stage
                    additionalProperties: false
                    properties: *ref_62
                  linkedProspectsCount:
                    type: integer
                    readOnly: true
                    description: Number of contacts linked to this account
                  createdDate:
                    type: string
                    format: date-time
                    readOnly: true
                    description: Date when the account was created
                  lastActivityDate:
                    type: string
                    format: date-time
                    readOnly: true
                    description: Date of the last activity on this account
                example: &ref_65
                  id: 12345
                  ownerUserId: 42
                  name: Acme Corporation
                  description: Enterprise software company
                  domainName: acme.com
                  domainSecondary: acme.io
                  industry: Software
                  companySize: 51-200
                  country: United States
                  state: California
                  city: San Francisco
                  timeZoneId: America/Los_Angeles
                  linkedInUrl: https://www.linkedin.com/company/acme
                  phone: +1-415-555-0100
                  twitterUrl: https://twitter.com/acme
                  logoUrl: https://cdn.example.com/logos/acme.png
                  email: info@acme.com
                  emailProvider: office
                  stage:
                    id: 3
                    name: Qualified
                    colorId: 2
                  linkedProspectsCount: 17
                  createdDate: '2026-01-15T09:30:00Z'
                  lastActivityDate: '2026-06-20T14:05:00Z'
        '400':
          description: |-
            Validation failure on the request body, or a business-rule rejection
            (e.g. invalid field combination).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: Name is required.
                business_invalid_input:
                  summary: Business rejection — invalid input
                  value:
                    title: Bad Request
                    status: 400
                    detail: The request body contains validation errors.
                    code: contactAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to create accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-accounts/filter:
    post:
      tags:
        - Accounts
      operationId: FilterContactAccounts
      summary: Filter accounts
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a paginated, filtered list of accounts using advanced filter criteria.
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Contact Account Filter Request
              description: Request body for filtering contact accounts with advanced criteria
              additionalProperties: false
              properties: &ref_359
                search:
                  type: string
                  nullable: true
                  description: Search term to filter accounts by name
                sortBy:
                  type: string
                  nullable: true
                  description: Field name to sort by
                sortDirection:
                  type: string
                  nullable: true
                  description: Sort direction
                  enum:
                    - asc
                    - desc
                listId:
                  type: integer
                  nullable: true
                  description: Filter by contact list ID
                filters:
                  type: array
                  nullable: true
                  description: Advanced filter conditions
                  items:
                    type: object
                    title: Account Filter Item
                    description: A single filter condition for contact account queries
                    additionalProperties: false
                    required: &ref_357
                      - property
                      - condition
                      - values
                    properties: &ref_358
                      property:
                        type: string
                        description: Field to filter on
                        enum:
                          - OwnerId
                          - Name
                          - Description
                          - DomainName
                          - DomainSecondary
                          - Industry
                          - Country
                          - State
                          - City
                          - LinkedInUrl
                          - TwitterUrl
                          - CreatedDate
                          - LastActivityDate
                          - CompanySize
                          - TimeZoneId
                          - NumericPhoneNumber
                          - LastActivityDateFrom
                          - LastActivityDateTo
                          - Stage
                          - NumberOfContacts
                          - Sequence
                      condition:
                        type: string
                        description: Filter operation to apply
                        enum:
                          - Equals
                          - NotEquals
                          - In
                          - NotIn
                          - CollectionContains
                          - CollectionNotContains
                          - GreaterThan
                          - LowerThan
                          - GreaterEqualThan
                          - LowerEqualThan
                          - IsNull
                          - IsNotNull
                      values:
                        description: Filter value(s); type depends on the property being filtered
      responses:
        '200':
          description: Paginated list of accounts matching filter criteria
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Contact Account
                      description: A contact account representing a company or organization
                      additionalProperties: false
                      properties: *ref_63
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
        '400':
          description: Filter body validation failure, or invalid pagination from the service layer.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Filter body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /filters/0/field
                        detail: Filter field is not recognised.
                business_invalid_pagination:
                  summary: Business rejection — invalid pagination
                  value:
                    title: Bad Request
                    status: 400
                    detail: Parameter 'top' must be between 1 and 1000
                    code: contactAccount.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to view accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-accounts/{id}:
    get:
      tags:
        - Accounts
      operationId: GetContactAccountById
      summary: Get an account
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a single account by ID.
      parameters:
        - name: id
          in: path
          required: true
          description: Account ID
          schema:
            type: integer
      responses:
        '200':
          description: Account details
          content:
            application/json:
              schema:
                type: object
                title: Contact Account Details
                description: A single contact account, including the resolved email provider
                additionalProperties: false
                properties: *ref_64
                example: *ref_65
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to view this account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '404':
          description: Account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Account with ID 42 not found.
                code: contactAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Accounts
      operationId: UpdateContactAccount
      summary: Update an account
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Updates an existing account.
      parameters:
        - name: id
          in: path
          required: true
          description: Account ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Update Contact Account Request
              description: Request body for updating a contact account
              additionalProperties: false
              required: &ref_360
                - name
              properties: &ref_361
                name:
                  type: string
                  description: Contact account name
                description:
                  type: string
                  nullable: true
                  description: Optional description
                domainName:
                  type: string
                  nullable: true
                  description: Primary domain name
                domainSecondary:
                  type: string
                  nullable: true
                  description: Secondary domain name
                industry:
                  type: string
                  nullable: true
                  description: Industry of the company
                companySize:
                  type: string
                  nullable: true
                  description: Company size range
                  enum:
                    - Empty
                    - SelfEmployed
                    - 2-10
                    - 11-50
                    - 51-200
                    - 201-500
                    - 501-1000
                    - 1001-5000
                    - 5001-10000
                    - 10001+
                country:
                  type: string
                  nullable: true
                  description: Country of the company
                state:
                  type: string
                  nullable: true
                  description: State or province
                city:
                  type: string
                  nullable: true
                  description: City
                timeZoneId:
                  type: string
                  nullable: true
                  description: Time zone identifier
                linkedInUrl:
                  type: string
                  nullable: true
                  description: LinkedIn profile URL
                phone:
                  type: string
                  nullable: true
                  description: Phone number
                twitterUrl:
                  type: string
                  nullable: true
                  description: Twitter profile URL
                logoUrl:
                  type: string
                  nullable: true
                  description: Company logo URL
                email:
                  type: string
                  nullable: true
                  description: Contact email address
                ownerUserId:
                  type: integer
                  description: ID of the user who owns this contact account
      responses:
        '200':
          description: Account updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Contact Account Details
                description: A single contact account, including the resolved email provider
                additionalProperties: false
                properties: *ref_64
                example: *ref_65
        '400':
          description: Route parameter / body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: Name is required.
                business_invalid_input:
                  summary: Business rejection — invalid input
                  value:
                    title: Bad Request
                    status: 400
                    detail: The request body contains validation errors.
                    code: contactAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to update this account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '404':
          description: Account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Account with ID 42 not found.
                code: contactAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Accounts
      operationId: DeleteContactAccount
      summary: Delete an account
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Deletes an existing account.
      parameters:
        - name: id
          in: path
          required: true
          description: Account ID
          schema:
            type: integer
      responses:
        '204':
          description: Account deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to delete this account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '404':
          description: Account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Account with ID 42 not found.
                code: contactAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-accounts/bulk:
    post:
      tags:
        - Accounts
      operationId: BulkCreateContactAccounts
      summary: Bulk create accounts
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Creates multiple accounts. Non-atomic — some may succeed while others fail.
        Each item in the response array contains the created ID or error details.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Bulk Create Accounts Request
              description: Request body for bulk creating accounts
              additionalProperties: false
              required: &ref_362
                - items
              properties: &ref_363
                items:
                  type: array
                  description: List of contact accounts to create
                  items:
                    type: object
                    title: Create Contact Account Request
                    description: Request body for creating a contact account
                    additionalProperties: false
                    required: *ref_66
                    properties: *ref_67
      responses:
        '200':
          description: |-
            Array of creation results, one per input item.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 3 | `InvalidInput` — validation failed for this item |
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Create Item Result
                  description: Result of a single item in a bulk create operation
                  additionalProperties: false
                  properties: &ref_364
                    id:
                      type: integer
                      nullable: true
                      description: ID of the created item, null if creation failed
                    error:
                      type: integer
                      nullable: true
                      description: Error code if creation failed
                    errorDetails:
                      type: string
                      nullable: true
                      description: Human-readable error description if creation failed
        '400':
          description: Request body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /items/0/name
                        detail: Name is required.
                business_invalid_input:
                  summary: Business rejection — invalid input
                  value:
                    title: Bad Request
                    status: 400
                    detail: The request body contains validation errors.
                    code: contactAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to create accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-accounts/bulk-delete:
    post:
      tags:
        - Accounts
      operationId: BulkDeleteContactAccounts
      summary: Bulk delete accounts
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Deletes multiple accounts by ID. Non-atomic — some may succeed while others fail.
        Items not in the response dictionary succeeded.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Bulk Delete Accounts Request
              description: Request body for bulk deleting accounts
              additionalProperties: false
              required: &ref_365
                - ids
              properties: &ref_366
                ids:
                  type: array
                  description: List of contact account IDs to delete
                  items:
                    type: integer
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by account ID. Empty object `{}` means all succeeded.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 1 | `NotFound` — account does not exist |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: &ref_68
                    error:
                      type: string
                      description: |-
                        Resource-specific error variant in camelCase (e.g. `notFound`,
                        `forbidden`, `duplicateName`). The set of possible values is documented
                        per endpoint in the "Per-item error codes" table — each value
                        corresponds to a variant of the resource's server-side error enum.
                    errorDetails:
                      type: string
                      nullable: true
                      description: Human-readable error description.
        '400':
          description: Request body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /ids
                        detail: At least one ID is required.
                business_invalid_input:
                  summary: Business rejection — invalid input
                  value:
                    title: Bad Request
                    status: 400
                    detail: The request body contains validation errors.
                    code: contactAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to delete accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-accounts/{id}/owner:
    put:
      tags:
        - Accounts
      operationId: UpdateContactAccountOwner
      summary: Update account owner
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Changes the owner of an account. The new owner must be a member of the caller's team — an `ownerUserId` outside the team returns 400 `contactAccount.invalidInput` (404 is reserved for "account row missing").
      parameters:
        - name: id
          in: path
          required: true
          description: Account ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Update Contact Account Owner Request
              description: Request body for updating the owner of a contact account
              additionalProperties: false
              required: &ref_367
                - userId
              properties: &ref_368
                userId:
                  type: integer
                  description: ID of the new owner user
      responses:
        '200':
          description: Account owner updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Contact Account Details
                description: A single contact account, including the resolved email provider
                additionalProperties: false
                properties: *ref_64
                example: *ref_65
        '400':
          description: |-
            Route parameter / body validation failure, or a business-rule rejection.
            A non-existent `userId` on the body (i.e. the supplied user is not a
            member of the caller's team) is reported as a `contactAccount.invalidInput`
            rejection — 404 is reserved for "account row missing".
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /userId
                        detail: userId must be a positive integer.
                business_invalid_input:
                  summary: Business rejection — invalid input
                  value:
                    title: Bad Request
                    status: 400
                    detail: The request body contains validation errors.
                    code: contactAccount.invalidInput
                owner_not_team_member:
                  summary: '`userId` is not a member of the team'
                  value:
                    title: Bad Request
                    status: 400
                    detail: OwnerUserId 999999999 is not a member of the team.
                    code: contactAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to change the account owner
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '404':
          description: Account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Account with ID 42 not found.
                code: contactAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-accounts/{id}/contacts:
    get:
      tags:
        - Accounts
      operationId: GetContactAccountContacts
      summary: List contacts for an account
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of contacts linked to the specified account.
      parameters:
        - name: id
          in: path
          required: true
          description: Account ID
          schema:
            type: integer
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
      responses:
        '200':
          description: Paginated list of contacts linked to the account
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Contact Account Contact
                      description: A contact linked to a contact account
                      additionalProperties: false
                      properties: &ref_369
                        id:
                          type: integer
                          readOnly: true
                          description: Unique identifier of the contact
                        email:
                          type: string
                          nullable: true
                          description: Contact email address
                        firstName:
                          type: string
                          nullable: true
                          description: Contact first name
                        lastName:
                          type: string
                          nullable: true
                          description: Contact last name
                        title:
                          type: string
                          nullable: true
                          description: Contact job title
                        company:
                          type: string
                          nullable: true
                          description: Contact company name
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection (e.g. invalid pagination).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
                business_invalid_pagination:
                  summary: Business rejection — invalid pagination
                  value:
                    title: Bad Request
                    status: 400
                    detail: Parameter 'top' must be between 1 and 1000
                    code: contactAccount.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to view this account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '404':
          description: Account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Account with ID 42 not found.
                code: contactAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-accounts/{id}/contact-links/bulk:
    post:
      tags:
        - Accounts
      operationId: BulkAddContactsToContactAccount
      summary: Bulk add contacts to an account
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Adds multiple contacts to the specified account. Non-atomic — some may succeed while others fail.
        Items not in the response dictionary succeeded.
      parameters:
        - name: id
          in: path
          required: true
          description: Account ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Contact IDs Request
              description: Request body containing a list of contact IDs
              additionalProperties: false
              required: &ref_69
                - contactIds
              properties: &ref_70
                contactIds:
                  type: array
                  description: List of contact IDs
                  maxItems: 1000
                  items:
                    type: integer
                    minimum: 1
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by contact ID. Empty object `{}` means all succeeded.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 1 | `NotFound` — contact does not exist |
            | 3 | `InvalidInput` — contact could not be added |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Route parameter / body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactIds
                        detail: At least one contact ID is required.
                business_invalid_input:
                  summary: Business rejection — invalid input
                  value:
                    title: Bad Request
                    status: 400
                    detail: The request body contains validation errors.
                    code: contactAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to modify this account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '404':
          description: Account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Account with ID 42 not found.
                code: contactAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-accounts/{id}/contact-links/bulk-delete:
    post:
      tags:
        - Accounts
      operationId: BulkRemoveContactsFromContactAccount
      summary: Bulk remove contacts from an account
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Removes multiple contacts from the specified account. Non-atomic — some may succeed while others fail.
        Items not in the response dictionary succeeded.
      parameters:
        - name: id
          in: path
          required: true
          description: Account ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Contact IDs Request
              description: Request body containing a list of contact IDs
              additionalProperties: false
              required: *ref_69
              properties: *ref_70
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by contact ID. Empty object `{}` means all succeeded.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 1 | `NotFound` — contact does not exist or is not linked to this account |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Route parameter / body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactIds
                        detail: At least one contact ID is required.
                business_invalid_input:
                  summary: Business rejection — invalid input
                  value:
                    title: Bad Request
                    status: 400
                    detail: The request body contains validation errors.
                    code: contactAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to modify this account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to perform this operation.
                code: contactAccount.forbidden
        '404':
          description: Account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Account with ID 42 not found.
                code: contactAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-account-lists:
    get:
      tags:
        - Account Lists
      operationId: GetContactAccountLists
      summary: List account lists
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of account lists for the current user's team.
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Filter account lists by name (case-insensitive substring match)
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of account lists
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Contact Account List
                      description: Account list entity
                      additionalProperties: false
                      properties: &ref_71
                        id:
                          type: integer
                          readOnly: true
                          description: Unique identifier of the account list
                        name:
                          type: string
                          description: Account list name
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: contactAccountList.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Account Lists
      operationId: CreateContactAccountList
      summary: Create an account list
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Creates a new account list for the current user's team. Names must be 3–128 characters and unique per team.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Create Contact Account List Request
              additionalProperties: false
              required: &ref_370
                - name
              properties: &ref_371
                name:
                  type: string
                  minLength: 3
                  maxLength: 128
                  description: Account list name (3 to 128 characters, unique per team)
      responses:
        '201':
          description: Account list created successfully
          content:
            application/json:
              schema:
                type: object
                title: Contact Account List
                description: Account list entity
                additionalProperties: false
                properties: *ref_71
        '400':
          description: |-
            Validation failure on the request body (e.g. name length out of range),
            or a business-rule rejection from the service layer.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: Name must be at least 3 characters.
                business_name_too_short:
                  summary: Business rejection — name too short
                  value:
                    title: Bad Request
                    status: 400
                    detail: Name must be at least 3 characters.
                    code: contactAccountList.nameTooShort
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '409':
          description: An account list with the given name already exists in this team
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A list with this name already exists.
                code: contactAccountList.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-account-lists/{id}:
    get:
      tags:
        - Account Lists
      operationId: GetContactAccountListById
      summary: Get an account list
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a single account list by ID.
      parameters:
        - name: id
          in: path
          required: true
          description: Account list ID
          schema:
            type: integer
      responses:
        '200':
          description: Account list details
          content:
            application/json:
              schema:
                type: object
                title: Contact Account List
                description: Account list entity
                additionalProperties: false
                properties: *ref_71
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Account list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactAccountList.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Account Lists
      operationId: UpdateContactAccountList
      summary: Update an account list
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Updates an existing account list name. Names must be 3–128 characters and unique per team.
      parameters:
        - name: id
          in: path
          required: true
          description: Account list ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Update Contact Account List Request
              additionalProperties: false
              required: &ref_372
                - name
              properties: &ref_373
                name:
                  type: string
                  minLength: 3
                  maxLength: 128
                  description: New account list name (3 to 128 characters, unique per team)
      responses:
        '200':
          description: Account list updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Contact Account List
                description: Account list entity
                additionalProperties: false
                properties: *ref_71
        '400':
          description: |-
            Route parameter / body validation failure, or a business-rule rejection
            (e.g. name length out of range).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: Name must not exceed 128 characters.
                business_name_too_long:
                  summary: Business rejection — name too long
                  value:
                    title: Bad Request
                    status: 400
                    detail: Name must not exceed 128 characters.
                    code: contactAccountList.nameTooLong
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Account list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactAccountList.notFound
        '409':
          description: An account list with the given name already exists in this team
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A list with this name already exists.
                code: contactAccountList.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Account Lists
      operationId: DeleteContactAccountList
      summary: Delete an account list
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Deletes an existing account list. The accounts themselves are not deleted —
        only their membership in this list is removed.
      parameters:
        - name: id
          in: path
          required: true
          description: Account list ID
          schema:
            type: integer
      responses:
        '204':
          description: Account list deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route parameter validation failure (e.g. `id` not a positive integer)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Account list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactAccountList.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-account-lists/{id}/move-accounts:
    post:
      tags:
        - Account Lists
      operationId: MoveAccountsToContactAccountList
      summary: Move accounts to an account list
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Moves accounts to the specified account list, removing them from any other lists they belong to.
        This is a non-atomic operation: successfully moved accounts are not rolled back if some fail.
        The response contains only the failed items with their error details.
      parameters:
        - name: id
          in: path
          required: true
          description: Account list ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Contact Account List Account IDs Request
              additionalProperties: false
              required: &ref_72
                - accountIds
              properties: &ref_73
                accountIds:
                  type: array
                  minItems: 1
                  maxItems: 1000
                  description: Account IDs to add or move (1 to 1000 items)
                  items:
                    type: integer
                    minimum: 1
      responses:
        '200':
          description: |-
            Move operation completed. Response is a dictionary keyed by account ID.
            Only failed items appear; missing IDs were moved successfully.

            Possible per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 7 | `AccountNotProcessed` — account could not be moved (e.g. wrong team, deleted, invalid ID) |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Route parameter or request body validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Account list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactAccountList.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-account-lists/{id}/add-accounts:
    post:
      tags:
        - Account Lists
      operationId: AddAccountsToContactAccountList
      summary: Add accounts to an account list
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Adds accounts to the specified account list, preserving any other list memberships.
        This is a non-atomic operation: successfully added accounts are not rolled back if some fail.
        The response contains only the failed items with their error details.
      parameters:
        - name: id
          in: path
          required: true
          description: Account list ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Contact Account List Account IDs Request
              additionalProperties: false
              required: *ref_72
              properties: *ref_73
      responses:
        '200':
          description: |-
            Add operation completed. Response is a dictionary keyed by account ID.
            Only failed items appear; missing IDs were added successfully.

            Possible per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 7 | `AccountNotProcessed` — account could not be added (e.g. wrong team, deleted, invalid ID) |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Route parameter or request body validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Account list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactAccountList.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/attachments:
    post:
      tags:
        - Attachments
      operationId: UploadAttachment
      summary: Upload attachment
      x-required-scope: other:write
      description: |-
        <small>_Requires the `other:write` scope (or a broader one that includes it)._</small>

        Uploads a single file as a `multipart/form-data` request and returns its attachment id. Use the returned `id` in `attachmentIds` arrays on email-template, sequence-step, and inbox-message endpoints to attach the file to outbound communications.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: File to upload. Must be non-empty.
      responses:
        '200':
          description: File uploaded
          content:
            application/json:
              schema:
                type: object
                title: Attachment
                description: Uploaded file attachment usable across email templates, sequence steps, and direct emails.
                required: &ref_144
                  - id
                  - fileName
                  - size
                properties: &ref_145
                  id:
                    type: integer
                    description: Attachment identifier — pass this in `attachmentIds` arrays on email-template, sequence-step, and inbox-message endpoints.
                  fileName:
                    type: string
                    description: Original file name as supplied by the upload.
                  size:
                    type: integer
                    description: File size in kilobytes (rounded up).
        '400':
          description: File is missing or empty.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: File is required.
                code: attachment.emptyFile
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Attachments feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Attachments feature is not available for this user.
                code: attachment.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/attachments/voice:
    post:
      tags:
        - Attachments
      operationId: UploadVoiceAttachment
      summary: Upload voice attachment
      description: Uploads an audio file as a `multipart/form-data` request, converts it to LinkedIn voice format, and returns the attachment metadata including the duration. Use the returned `id` to attach the voice message to LinkedIn voice outreach endpoints.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: Audio file to upload. Must be non-empty and no longer than 60 seconds.
      responses:
        '200':
          description: Voice attachment uploaded and converted
          content:
            application/json:
              schema:
                type: object
                title: VoiceAttachment
                description: Uploaded voice message attachment.
                required: &ref_374
                  - id
                  - fileName
                  - lengthInSeconds
                properties: &ref_375
                  id:
                    type: integer
                    description: Attachment identifier.
                  fileName:
                    type: string
                    description: Original file name as supplied by the upload.
                  lengthInSeconds:
                    type: integer
                    description: Duration of the voice message in seconds.
        '400':
          description: |-
            File is missing, empty, too long, or could not be converted.

            | `code` | Meaning |
            |---|---|
            | `attachment.emptyFile` | No file provided or file is empty |
            | `attachment.fileTooLong` | Voice message exceeds the 60-second limit |
            | `attachment.conversionError` | Audio file could not be converted to LinkedIn voice format |
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              examples:
                empty_file:
                  summary: File is empty
                  value:
                    title: Bad Request
                    status: 400
                    detail: File is required.
                    code: attachment.emptyFile
                file_too_long:
                  summary: Voice message exceeds 60 seconds
                  value:
                    title: Bad Request
                    status: 400
                    detail: Voice message must not exceed 60 seconds.
                    code: attachment.fileTooLong
                conversion_error:
                  summary: Audio conversion failed
                  value:
                    title: Bad Request
                    status: 400
                    detail: Audio file could not be converted to LinkedIn voice format.
                    code: attachment.conversionError
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Attachments feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Attachments feature is not available for this user.
                code: attachment.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/background-jobs:
    get:
      tags:
        - Background Jobs
      operationId: GetBackgroundJobs
      summary: List background jobs
      x-required-scope: other:read
      description: |-
        <small>_Requires the `other:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of background jobs created by the current user. Optionally filter by category suffix.
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 200)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: category
          in: query
          required: false
          description: Category suffix to filter by — prefix-matched against `r2/bg-jobs/{suffix}`. For example, pass `email-validation` to list only email-validation jobs. Omit to list all of the user's background jobs.
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of background jobs
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Background Job List Item
                      description: Compact list-item shape for background jobs. Omits the raw `jsonData` / `jsonDataResult` payloads (use the single-job endpoint to retrieve them).
                      properties: &ref_376
                        jobId:
                          type: string
                          format: uuid
                          description: Unique identifier for the background job
                          readOnly: true
                        status:
                          type: string
                          description: Current job status. One of `Scheduled`, `Processing`, `Done`, `Failed`, `Expired`, `Cancelled`, or `Unknown` for unrecognized terminal states.
                          enum:
                            - Scheduled
                            - Processing
                            - Done
                            - Failed
                            - Expired
                            - Cancelled
                            - Unknown
                          readOnly: true
                        category:
                          type: string
                          nullable: true
                          description: Job category, e.g. `r2/bg-jobs/email-validation`
                          readOnly: true
                        startedAt:
                          type: string
                          format: date-time
                          description: When the job started
                          readOnly: true
                        finishedAt:
                          type: string
                          format: date-time
                          nullable: true
                          description: When the job reached a terminal state, or null if still running
                          readOnly: true
                        progress:
                          type: number
                          format: double
                          nullable: true
                          minimum: 0
                          maximum: 1
                          description: Job progress in `[0..1]`. Null if the job hasn't reported progress yet.
                          readOnly: true
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 200
                code: backgroundJob.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
        '503':
          description: Upstream background-jobs service is temporarily unavailable
          content:
            application/problem+json:
              schema:
                allOf: &ref_74
                  - allOf: *ref_6
                    title: Business Problem
                    description: |-
                      Domain error response carrying a stable, namespaced error slug.
                      Emitted for most 4xx responses (business 400, 403, 404, 409, …) and
                      for 503 when a downstream dependency is unavailable.
                  - example:
                      title: Service Unavailable
                      status: 503
                      detail: Background-jobs service is temporarily unavailable.
                      code: backgroundJob.upstreamUnavailable
              example:
                title: Service Unavailable
                status: 503
                detail: Background-jobs service is temporarily unavailable.
                code: backgroundJob.upstreamUnavailable
  /v3/background-jobs/{jobId}:
    get:
      tags:
        - Background Jobs
      operationId: GetBackgroundJobById
      summary: Get a background job
      x-required-scope: other:read
      description: |-
        <small>_Requires the `other:read` scope (or a broader one that includes it)._</small>

        Returns the full record for a background job, including raw input (`jsonData`) and result (`jsonDataResult`) JSON payloads when available.
      parameters:
        - name: jobId
          in: path
          required: true
          description: Background job identifier (must be a non-empty GUID)
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Background job record
          content:
            application/json:
              schema:
                type: object
                title: Background Job
                description: A long-running background operation tracked by the API. Includes status, progress, timing, and the raw input/result JSON payloads.
                properties: &ref_377
                  jobId:
                    type: string
                    format: uuid
                    description: Unique identifier for the background job
                    readOnly: true
                  status:
                    type: string
                    description: Current job status. One of `Scheduled`, `Processing`, `Done`, `Failed`, `Expired`, `Cancelled`, or `Unknown` for unrecognized terminal states.
                    enum:
                      - Scheduled
                      - Processing
                      - Done
                      - Failed
                      - Expired
                      - Cancelled
                      - Unknown
                    readOnly: true
                  category:
                    type: string
                    nullable: true
                    description: Job category, e.g. `r2/bg-jobs/email-validation`. Use the suffix (`email-validation`) when filtering the list endpoint.
                    readOnly: true
                  startedAt:
                    type: string
                    format: date-time
                    description: When the job started
                    readOnly: true
                  finishedAt:
                    type: string
                    format: date-time
                    nullable: true
                    description: When the job reached a terminal state, or null if still running
                    readOnly: true
                  progress:
                    type: number
                    format: double
                    nullable: true
                    minimum: 0
                    maximum: 1
                    description: Job progress in `[0..1]`. Null if the job hasn't reported progress yet.
                    readOnly: true
                  jsonData:
                    type: string
                    nullable: true
                    description: Raw JSON of the input parameters captured at job creation. Opaque — shape is per-category.
                    readOnly: true
                  jsonDataResult:
                    type: string
                    nullable: true
                    description: Raw JSON of the job result. Populated only when `status` is terminal (`Done` / `Failed`). Opaque — shape is per-category.
                    readOnly: true
        '400':
          description: Invalid job identifier (e.g., empty GUID)
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Job id must be a non-empty GUID.
                code: backgroundJob.invalidJobId
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Background job not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: The requested background job was not found.
                code: backgroundJob.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
        '503':
          description: Upstream background-jobs service is temporarily unavailable
          content:
            application/problem+json:
              schema:
                allOf: *ref_74
  /v3/background-jobs/{jobId}/cancel:
    post:
      tags:
        - Background Jobs
      operationId: CancelBackgroundJob
      summary: Cancel a background job
      x-required-scope: other:operate
      description: |-
        <small>_Requires the `other:operate` scope (or a broader one that includes it)._</small>

        Requests cancellation of a background job. Idempotent — cancelling an already-terminal job returns 204 without effect on the worker. The request body is optional; if provided, the `reason` is recorded alongside the cancellation event.
      parameters:
        - name: jobId
          in: path
          required: true
          description: Background job identifier (must be a non-empty GUID)
          schema:
            type: string
            format: uuid
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              title: Background Job Cancel
              description: Optional payload for cancelling a background job. The body itself is optional — `POST` with an empty body is valid.
              properties: &ref_378
                reason:
                  type: string
                  nullable: true
                  description: Optional human-readable reason for the cancellation, recorded with the job
      responses:
        '204':
          description: Cancellation requested successfully (or already cancelled — idempotent)
        '400':
          description: Invalid job identifier
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Job id must be a non-empty GUID.
                code: backgroundJob.invalidJobId
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Background job not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: The requested background job was not found.
                code: backgroundJob.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
        '503':
          description: Upstream background-jobs service is temporarily unavailable
          content:
            application/problem+json:
              schema:
                allOf: *ref_74
  /v3/contacts:
    get:
      tags:
        - Contacts
      summary: List all contacts
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to browse your contacts or look one up by its email or LinkedIn URL. Results are returned as a page controlled by the top and skip query parameters; omit both to get the first page. Pass email and/or linkedIn to narrow the results to contacts matching those exact identifiers. For richer, rule-based filtering use the filter endpoint instead.
      operationId: GetContacts
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of contacts to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of contacts to skip
          schema:
            type: integer
        - name: email
          in: query
          required: false
          description: Filter contacts by email address
          schema:
            type: string
        - name: linkedIn
          in: query
          required: false
          description: Filter contacts by LinkedIn profile URL
          schema:
            type: string
      responses:
        '200':
          description: List of contacts retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Contact
                      description: Contact response model
                      properties: &ref_75
                        id:
                          type: integer
                          readOnly: true
                          description: Unique ID
                        email:
                          type: string
                          format: email
                          description: Primary email address
                        domain:
                          type: string
                          readOnly: true
                          description: Email domain (derived from email)
                        firstName:
                          type: string
                          description: First name
                        lastName:
                          type: string
                          description: Last name
                        phone:
                          type: string
                          description: Phone number
                        title:
                          type: string
                          description: Job title
                        company:
                          type: string
                          description: Organization name
                        companySize:
                          type: string
                          enum:
                            - empty
                            - selfEmployed
                            - ten
                            - fifty
                            - twoHundred
                            - fiveHundred
                            - oneThousand
                            - fiveThousand
                            - tenThousand
                            - overTenThousand
                          description: Organization employee count range
                        industry:
                          type: string
                          description: Business sector
                        city:
                          type: string
                          description: City of residence
                        state:
                          type: string
                          description: State/province
                        country:
                          type: string
                          description: Country
                        timeZoneId:
                          type: string
                          description: Timezone identifier
                        linkedInUrl:
                          type: string
                          format: uri
                          description: LinkedIn profile URL
                        linkedInSalesNavigatorUrl:
                          type: string
                          format: uri
                          description: Sales Navigator URL
                        linkedInRecruiterUrl:
                          type: string
                          format: uri
                          description: Recruiter URL
                        phoneStatus:
                          type: string
                          enum:
                            - pending
                            - invalid
                            - valid
                            - validationFailed
                            - notValidated
                          description: Phone validation status
                        notes:
                          type: string
                          description: Additional information
                        ownerUserId:
                          type: integer
                          description: ID of the user who owns this contact
                        accountId:
                          type: integer
                          nullable: true
                          description: ID of the contact account this contact belongs to
                        isOptedOut:
                          type: boolean
                          readOnly: true
                          description: Whether the contact has opted out of communications
                        callStatus:
                          type: string
                          allOf:
                            - type: string
                              title: Contact Call Status
                              description: Contact-level call status. Set via `PATCH /v3/contacts/{id}` (`callStatus` field). Pass `none` to clear.
                              enum: &ref_77
                                - none
                                - toCall
                                - called
                          description: Contact-level call status
                        meetingStatus:
                          type: string
                          allOf:
                            - type: string
                              title: Contact Meeting Status
                              description: Contact-level meeting status. Set via `PATCH /v3/contacts/{id}` (`meetingStatus` field). Pass `none` to clear.
                              enum: &ref_78
                                - none
                                - meetingBooked
                          description: Contact-level meeting status
                        addingDate:
                          type: string
                          format: date-time
                          readOnly: true
                          nullable: true
                          description: Date the contact was added
                        createdAt:
                          type: string
                          format: date-time
                          readOnly: true
                          nullable: true
                          description: Creation timestamp
                        lastModifiedAt:
                          type: string
                          format: date-time
                          readOnly: true
                          nullable: true
                          description: Last modification timestamp
                        customFields:
                          type: array
                          items:
                            type: object
                            properties:
                              key:
                                type: string
                                description: Field identifier
                              value:
                                type: string
                                nullable: true
                                description: Field content
                            required:
                              - key
                          description: User-defined fields
                      example: &ref_76
                        id: 12345
                        email: john.doe@company.com
                        firstName: John
                        lastName: Doe
                        title: Senior Product Manager
                        company: Tech Solutions Inc
                        domain: company.com
                        companySize: oneThousand
                        city: San Francisco
                        state: CA
                        country: United States
                        timeZoneId: America/Los_Angeles
                        phone: +1-415-555-0123
                        phoneStatus: valid
                        linkedInUrl: https://www.linkedin.com/in/johndoe
                        linkedInSalesNavigatorUrl: https://www.linkedin.com/sales/profile/123456
                        linkedInRecruiterUrl: https://www.linkedin.com/recruiter/profile/789012
                        industry: Software & Technology
                        notes: Met at SaaS Conference 2024
                        ownerUserId: 42
                        accountId: 100
                        isOptedOut: false
                        callStatus: toCall
                        meetingStatus: none
                        addingDate: '2024-03-08T10:00:00+00:00'
                        createdAt: '2024-03-08T10:00:00'
                        lastModifiedAt: '2024-03-10T15:30:00'
                        customFields:
                          - key: leadSource
                            value: Conference
                          - key: budget
                            value: 100k-250k
                  hasMore:
                    type: boolean
                    description: Indicates if there are more items to fetch
        '400':
          description: Invalid pagination parameters or other business rejection
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Invalid requested page view.
                code: contact.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view contacts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewProspect] are denied for userId 123.
                code: contact.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Contacts
      summary: Create a contact
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to add a single new contact to your account — for example when capturing a lead from your own application. Provide any known profile fields and custom field values; the contact is created under your ownership and returned with its assigned id. To add many contacts at once, or to update existing ones by a match key, use the import endpoint instead.
      operationId: CreateContact
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Contact Creation Request
              description: Request model for creating a new contact. All fields are optional — at minimum provide email or a LinkedIn URL.
              properties: &ref_379
                email:
                  type: string
                  format: email
                  description: Primary email address
                firstName:
                  type: string
                  description: First name
                lastName:
                  type: string
                  description: Last name
                phone:
                  type: string
                  description: Phone number
                phone2:
                  type: string
                  description: Secondary phone number
                title:
                  type: string
                  description: Job title
                company:
                  type: string
                  description: Organization name
                companySize:
                  type: string
                  enum:
                    - Empty
                    - SelfEmployed
                    - Ten
                    - Fifty
                    - TwoHundred
                    - FiveHundred
                    - OneThousand
                    - FiveThousand
                    - TenThousand
                    - OverTenThousand
                  description: Organization employee count range
                industry:
                  type: string
                  description: Business sector
                city:
                  type: string
                  description: City of residence
                state:
                  type: string
                  description: State/province
                country:
                  type: string
                  description: Country
                timeZoneId:
                  type: string
                  description: Timezone identifier
                linkedInUrl:
                  type: string
                  format: uri
                  description: LinkedIn profile URL
                linkedInSalesNavigatorUrl:
                  type: string
                  format: uri
                  description: Sales Navigator URL
                linkedInRecruiterUrl:
                  type: string
                  format: uri
                  description: Recruiter URL
                notes:
                  type: string
                  description: Additional information
                accountId:
                  type: integer
                  nullable: true
                  description: ID of the contact account to link this contact to
                customFields:
                  type: array
                  items:
                    type: object
                    properties:
                      key:
                        type: string
                        description: Field identifier
                      value:
                        type: string
                        nullable: true
                        description: Field content
                    required:
                      - key
                  description: User-defined fields
              example: &ref_380
                email: john.doe@company.com
                firstName: John
                lastName: Doe
                title: Senior Product Manager
                company: Tech Solutions Inc
                phone: +1-415-555-0123
                linkedInUrl: https://www.linkedin.com/in/johndoe
                accountId: 100
                customFields:
                  - key: leadSource
                    value: Conference
      responses:
        '201':
          description: Contact created successfully
          content:
            application/json:
              schema:
                type: object
                title: Contact
                description: Contact response model
                properties: *ref_75
                example: *ref_76
        '400':
          description: |-
            Validation failure on the request body, or a business rule rejection
            (e.g. contact already exists, missing required identifier).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /email
                        detail: '''email'' is not a valid email address.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: A contact must have at least an email or a LinkedIn URL.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create contacts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [AddProspect] are denied for userId 123.
                code: contact.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/{id}:
    get:
      tags:
        - Contacts
      summary: Get a contact
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the full record of a single contact, identified by its Reply contact id — including profile fields, owner, opt-out, call and meeting status, and all custom field values.
      operationId: GetContactById
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
      responses:
        '200':
          description: Contact details retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Contact
                description: Contact response model
                properties: *ref_75
                example: *ref_76
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this contact
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewProspect] are denied for userId 123.
                code: contact.forbidden
        '404':
          description: Contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact with ID 42 not found.
                code: contact.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    patch:
      tags:
        - Contacts
      summary: Update a contact
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to change specific fields on an existing contact without resending the whole record. Only the properties present in the request body are updated; omitted properties are left unchanged, while sending an explicit null clears a nullable field. Use it to correct profile data, reassign ownership, or set opt-out, call, and meeting status.
      operationId: UpdateContact
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Contact Patch Request
              description: |-
                Request model for updating an existing contact.
                All fields are optional — only include the fields you want to change (PATCH semantics).
              properties: &ref_79
                email:
                  type: string
                  format: email
                  description: Primary email address
                firstName:
                  type: string
                  description: First name
                lastName:
                  type: string
                  description: Last name
                phone:
                  type: string
                  description: Phone number
                phone2:
                  type: string
                  description: Secondary phone number
                title:
                  type: string
                  description: Job title
                company:
                  type: string
                  description: Organization name
                companySize:
                  type: string
                  enum:
                    - Empty
                    - SelfEmployed
                    - Ten
                    - Fifty
                    - TwoHundred
                    - FiveHundred
                    - OneThousand
                    - FiveThousand
                    - TenThousand
                    - OverTenThousand
                  description: Organization employee count range
                industry:
                  type: string
                  description: Business sector
                city:
                  type: string
                  description: City of residence
                state:
                  type: string
                  description: State/province
                country:
                  type: string
                  description: Country
                timeZoneId:
                  type: string
                  description: Timezone identifier
                linkedInUrl:
                  type: string
                  format: uri
                  description: LinkedIn profile URL
                linkedInSalesNavigatorUrl:
                  type: string
                  format: uri
                  description: Sales Navigator URL
                linkedInRecruiterUrl:
                  type: string
                  format: uri
                  description: Recruiter URL
                notes:
                  type: string
                  description: Additional information
                isOptedOut:
                  type: boolean
                  nullable: true
                  description: Set or clear the contact's opted-out flag (suppresses all communications when `true`).
                callStatus:
                  type: string
                  nullable: true
                  allOf:
                    - type: string
                      title: Contact Call Status
                      description: Contact-level call status. Set via `PATCH /v3/contacts/{id}` (`callStatus` field). Pass `none` to clear.
                      enum: *ref_77
                  description: Contact-level call status. Pass `none` to clear.
                meetingStatus:
                  type: string
                  nullable: true
                  allOf:
                    - type: string
                      title: Contact Meeting Status
                      description: Contact-level meeting status. Set via `PATCH /v3/contacts/{id}` (`meetingStatus` field). Pass `none` to clear.
                      enum: *ref_78
                  description: Contact-level meeting status. Pass `none` to clear.
                ownerUserId:
                  type: integer
                  nullable: true
                  description: Change the owner of this contact. The new owner must be a member of the caller's team; otherwise the request fails with `404`.
                accountId:
                  type: integer
                  nullable: true
                  description: ID of the contact account to link this contact to
                customFields:
                  type: array
                  description: |-
                    Custom fields to update. Fields can be identified by `id` or `name`.
                    Unlike the response model which uses `key`/`value`, the patch model accepts `id`, `name`, and `value`.
                  items:
                    type: object
                    properties:
                      id:
                        type: integer
                        nullable: true
                        description: Custom field ID
                      name:
                        type: string
                        nullable: true
                        description: Custom field name (alternative to id)
                      value:
                        type: string
                        nullable: true
                        description: Field content
              example: &ref_80
                firstName: Jane
                company: New Company Inc
                ownerUserId: 55
                customFields:
                  - id: 1
                    value: Updated Value
                  - name: leadSource
                    value: Referral
      responses:
        '200':
          description: Contact updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Contact
                description: Contact response model
                properties: *ref_75
                example: *ref_76
        '400':
          description: |-
            Validation failure on the route parameter or request body, or a
            business rule rejection. When the request changes ownership and the
            supplied `ownerUserId` does not resolve to a member of the caller's team,
            a `contact.invalidInput` business rejection is returned (the contact itself
            exists — the invalid value is on the body, not the path).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /email
                        detail: '''email'' is not a valid email address.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
                owner_not_team_member:
                  summary: Owner change with an `ownerUserId` that is not a team member
                  value:
                    title: Bad Request
                    status: 400
                    detail: OwnerUserId 999999999 is not a member of the team.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to update this contact
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewProspect] are denied for userId 123.
                code: contact.forbidden
        '404':
          description: Contact not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact with ID 42 not found.
                code: contact.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Contacts
      summary: Delete a contact
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to remove a single contact from your account by its id. To remove several contacts in one call, use the bulk-delete endpoint instead.
      operationId: DeleteContact
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
      responses:
        '204':
          description: Contact deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete this contact
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [DeleteProspect] are denied for userId 123.
                code: contact.forbidden
        '404':
          description: Contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact with ID 42 not found.
                code: contact.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/import:
    post:
      tags:
        - Contacts
      operationId: ImportContacts
      summary: Import contacts
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to add or update many contacts in one call — for example when syncing contacts from another system. Each item uses the same fields as the contact update model. Use options to control deduplication, list assignment, and other import behavior: which keys identify an existing contact (email plus any of LinkedIn URL, phone, name, company, or custom fields), whether matched contacts are overwritten or skipped, whether previously deleted contacts are restored, and which lists or sequence the imported contacts are added to. The response reports how many contacts were added, updated, skipped, or failed, with a per-item outcome.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Contacts Import Request
              description: Import contacts by providing an array of contact objects with optional import settings
              required: &ref_381
                - items
              properties: &ref_382
                items:
                  type: array
                  minItems: 1
                  description: Array of contact objects to import. Uses the same fields as the contact patch model.
                  items:
                    type: object
                    title: Contact Patch Request
                    description: |-
                      Request model for updating an existing contact.
                      All fields are optional — only include the fields you want to change (PATCH semantics).
                    properties: *ref_79
                    example: *ref_80
                options:
                  type: object
                  description: Import settings
                  properties:
                    overwriteExisting:
                      type: boolean
                      default: false
                      description: Whether to overwrite existing contacts that match
                    skipExisting:
                      type: boolean
                      default: false
                      description: Whether to skip existing contacts that match
                    skipWithoutEmails:
                      type: boolean
                      default: false
                      description: Whether to skip contacts that have no email address
                    detectTimeZone:
                      type: boolean
                      default: false
                      description: Whether to auto-detect timezone based on location data
                    restoreDeleted:
                      type: boolean
                      default: false
                      description: Whether to restore previously deleted contacts
                    listIds:
                      type: array
                      items:
                        type: integer
                      description: List IDs to add imported contacts to
                    sequenceId:
                      type: integer
                      nullable: true
                      description: Sequence ID to enroll imported contacts in
                    keys:
                      type: object
                      description: |-
                        Deduplication keys — fields used to identify existing contacts.
                        By default, email is the primary key. Enable additional keys for multi-field matching.
                      properties:
                        linkedInUrl:
                          type: boolean
                          default: false
                          description: Use LinkedIn URL as a deduplication key
                        phone:
                          type: boolean
                          default: false
                          description: Use phone number as a deduplication key
                        firstName:
                          type: boolean
                          default: false
                          description: Use first name as a deduplication key
                        lastName:
                          type: boolean
                          default: false
                          description: Use last name as a deduplication key
                        company:
                          type: boolean
                          default: false
                          description: Use company name as a deduplication key
                        customFieldIds:
                          type: array
                          items:
                            type: integer
                          description: Custom field IDs to use as deduplication keys
              example: &ref_383
                items:
                  - email: john@example.com
                    firstName: John
                    lastName: Doe
                    company: Acme
                  - email: jane@example.com
                    firstName: Jane
                    lastName: Smith
                    company: Globex
                options:
                  overwriteExisting: false
                  skipExisting: true
                  detectTimeZone: true
                  listIds:
                    - 10
                    - 20
      responses:
        '200':
          description: Contacts import processed successfully
          content:
            application/json:
              schema:
                type: object
                title: Contacts Import Response
                description: Summary of a processed contacts import request with per-item results
                properties: &ref_384
                  items:
                    type: array
                    description: Per-item result for each contact in the import request (same order as input)
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          nullable: true
                          description: Contact ID (null if the contact was not created/found)
                        status:
                          type: string
                          enum:
                            - created
                            - updated
                            - skipped
                            - failed
                            - restored
                          description: Result status for this item
                        error:
                          type: string
                          nullable: true
                          description: Error message if the item failed
                  added:
                    type: integer
                    description: Number of contacts created
                  updated:
                    type: integer
                    description: Number of contacts updated
                  skipped:
                    type: integer
                    description: Number of contacts skipped
                  failed:
                    type: integer
                    description: Number of contacts that failed
                example: &ref_385
                  items:
                    - id: 12345
                      status: created
                      error: null
                    - id: 12346
                      status: updated
                      error: null
                    - id: null
                      status: failed
                      error: Email is required
                  added: 1
                  updated: 1
                  skipped: 0
                  failed: 1
        '400':
          description: |-
            Validation failure on the request body, or a business rule rejection
            (e.g. import limit exceeded).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /items
                        detail: '''items'' must not be empty.'
                business_limit_exceeded:
                  summary: Import limit exceeded
                  value:
                    title: Bad Request
                    status: 400
                    detail: Maximum 1000 items per import request.
                    code: contact.limitExceeded
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to import contacts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [AddProspect] are denied for userId 123.
                code: contact.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/filter:
    post:
      tags:
        - Contacts
      operationId: FilterContacts
      summary: Filter contacts
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need a filtered, sorted page of contacts that a plain email or LinkedIn lookup cannot express. Combine field rules (property, condition, value) with optional scoping by list, sequence, or sequence step, a free-text search term, and a sort order. Results are paged with the top and skip query parameters. To get only the total for the same criteria, use filter/count.
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of contacts to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of contacts to skip
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                rules:
                  type: array
                  items:
                    type: object
                    required:
                      - property
                      - condition
                    properties:
                      property:
                        type: string
                        description: Contact property to filter on
                      condition:
                        type: string
                        description: Filter condition
                      value:
                        type: string
                        nullable: true
                        description: Filter value
                listId:
                  type: integer
                  nullable: true
                  description: Filter by contact list ID
                sequenceId:
                  type: integer
                  nullable: true
                  description: Filter by sequence ID
                sequenceStepId:
                  type: integer
                  nullable: true
                  description: Filter by sequence step ID
                searchTerm:
                  type: string
                  nullable: true
                  description: Free-text search term
                sortBy:
                  type: string
                  nullable: true
                  description: Field to sort by
                sortDirection:
                  type: string
                  nullable: true
                  description: Sort direction (asc or desc)
      responses:
        '200':
          description: Filtered contacts retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Contact
                      description: Contact response model
                      properties: *ref_75
                      example: *ref_76
                  hasMore:
                    type: boolean
                    description: Indicates if there are more items to fetch
        '400':
          description: |-
            Validation failure on the request body or query, or a business rule
            rejection (e.g. invalid pagination).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /rules/0/property
                        detail: '''property'' must not be empty.'
                business_invalid_pagination:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid requested page view.
                    code: contact.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to filter contacts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewProspect] are denied for userId 123.
                code: contact.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/filter/count:
    post:
      tags:
        - Contacts
      operationId: FilterContactsCount
      summary: Count filtered contacts
      x-required-scope: contacts:read
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need only the number of contacts that match a set of filter criteria — for example to show a total or decide whether to page through the results — without fetching the contacts themselves. It accepts the same request body as the filter endpoint.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                rules:
                  type: array
                  items:
                    type: object
                    required:
                      - property
                      - condition
                    properties:
                      property:
                        type: string
                        description: Contact property to filter on
                      condition:
                        type: string
                        description: Filter condition
                      value:
                        type: string
                        nullable: true
                        description: Filter value
                listId:
                  type: integer
                  nullable: true
                  description: Filter by contact list ID
                sequenceId:
                  type: integer
                  nullable: true
                  description: Filter by sequence ID
                sequenceStepId:
                  type: integer
                  nullable: true
                  description: Filter by sequence step ID
                searchTerm:
                  type: string
                  nullable: true
                  description: Free-text search term
      responses:
        '200':
          description: Count retrieved successfully
          content:
            application/json:
              schema:
                type: object
                required: &ref_191
                  - count
                properties: &ref_192
                  count:
                    type: integer
                    description: Total number of matching items.
                    example: 42
        '400':
          description: Validation failure on the request body or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /rules/0/property
                        detail: '''property'' must not be empty.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid filter parameters.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to filter contacts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to view contacts.
                code: contact.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/bulk-delete:
    post:
      tags:
        - Contacts
      operationId: BulkDeleteContacts
      summary: Bulk delete contacts
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to remove several contacts in a single call. Contacts are processed independently: the response maps each contact id that could not be deleted to the reason it was skipped.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - ids
              properties:
                ids:
                  type: array
                  items:
                    type: integer
                  description: List of contact IDs to delete
      responses:
        '200':
          description: |-
            Non-atomic result. The response body is a dictionary keyed by contact id listing per-item failures. Empty object `{}` means all contacts were deleted successfully.

            Per-item failures use the `ContactError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `notFound` | Contact does not exist, or is not visible to the caller |
            | `forbidden` | Caller is not allowed to delete this contact |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
                description: Dictionary of per-item failures keyed by contact id. Empty object `{}` means all succeeded.
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /ids
                        detail: '''ids'' must not be empty.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/{id}/sequences:
    get:
      tags:
        - Contacts
      operationId: GetContactSequences
      summary: Get sequences for a contact
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to see which sequences a contact is enrolled in, together with each sequence's name, the contact's status in it, the current step, and when they were added.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
      responses:
        '200':
          description: Contact sequences retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    sequenceId:
                      type: integer
                    sequenceName:
                      type: string
                    statusInSequence:
                      type: string
                      enum:
                        - active
                        - paused
                        - finished
                        - outOfOffice
                      description: Workflow status of the contact within this sequence
                    currentStep:
                      nullable: true
                      description: |-
                        Position of the contact in the sequence's step graph (`stepId` + `displayName`).
                        `null` for memberships outside of an active step.
                      type: object
                      title: Sequence Step Info
                      properties: &ref_386
                        stepId:
                          type: integer
                          nullable: true
                          description: Database id of the current step. `null` if the contact has no current step (finished or archived).
                        displayName:
                          type: string
                          nullable: true
                          description: Human-readable label for the step. `"Finished"` when the contact is finished.
                      example: &ref_387
                        stepId: 5821
                        displayName: Email step 2
                    addingDate:
                      type: string
                      format: date-time
                      nullable: true
                    emailAccountId:
                      type: integer
                      format: int64
                      nullable: true
                    linkedInAccountId:
                      type: integer
                      format: int64
                      nullable: true
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this contact
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewProspect] are denied for userId 123.
                code: contact.forbidden
        '404':
          description: Contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact with ID 42 not found.
                code: contact.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/{id}/activities:
    get:
      tags:
        - Contacts
      operationId: GetContactActivities
      summary: Get activities for a contact
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need a contact's activity history — the emails, calls, status changes, and other tracked events recorded on its timeline. Results are paged with the top and skip query parameters.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
        - name: top
          in: query
          required: false
          description: Maximum number of activities to return
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of activities to skip
          schema:
            type: integer
      responses:
        '200':
          description: Contact activities retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          format: int64
                        date:
                          type: string
                          format: date-time
                        activityType:
                          type: string
                        sourceType:
                          type: string
                        userName:
                          type: string
                          nullable: true
                        userId:
                          type: integer
                        content:
                          type: object
                          nullable: true
                  hasMore:
                    type: boolean
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this contact
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewProspect] are denied for userId 123.
                code: contact.forbidden
        '404':
          description: Contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact with ID 42 not found.
                code: contact.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/{id}/inbox-threads:
    get:
      tags:
        - Contacts
      operationId: GetContactInboxThreads
      summary: Get inbox threads for a contact
      x-required-scope: contacts:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the email conversation threads exchanged with a contact, grouped as they appear in your inbox. Results are paged with the top and skip query parameters.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
        - name: top
          in: query
          required: false
          description: Maximum number of threads to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of threads to skip
          schema:
            type: integer
      responses:
        '200':
          description: Contact inbox threads retrieved successfully
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - hasMore
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Contact Inbox Thread
                      description: Inbox thread summary as it appears on a single contact's timeline. A trimmed thread shape — no message history or body preview.
                      required: &ref_388
                        - id
                        - channel
                        - isRead
                        - lastActivityDate
                        - hasMeetingIntent
                        - status
                      properties: &ref_389
                        id:
                          type: integer
                        channel:
                          type: string
                          enum:
                            - unknown
                            - email
                            - linkedIn
                        isRead:
                          type: boolean
                        subject:
                          type: string
                          nullable: true
                          description: Subject of the last message in the thread (email only).
                        lastActivityDate:
                          type: string
                          format: date-time
                        sequence:
                          type: object
                          allOf:
                            - type: object
                              title: Inbox Thread Sequence
                              description: Minimal sequence reference attached to an inbox thread.
                              required: &ref_133
                                - id
                                - name
                              properties: &ref_134
                                id:
                                  type: integer
                                name:
                                  type: string
                          nullable: true
                        category:
                          type: object
                          allOf:
                            - type: object
                              title: Inbox Thread Category Reference
                              description: Minimal category reference embedded in thread responses.
                              required: &ref_135
                                - id
                                - name
                              properties: &ref_136
                                id:
                                  type: integer
                                name:
                                  type: string
                          nullable: true
                        hasMeetingIntent:
                          type: boolean
                        status:
                          type: object
                          title: Inbox Thread Status
                          description: Aggregated thread state, derived from the latest message.
                          required: &ref_137
                            - state
                          properties: &ref_138
                            state:
                              type: string
                              enum:
                                - ok
                                - needsAttention
                              description: |-
                                Thread-level status:
                                - `ok` — nothing requires user attention.
                                - `needsAttention` — the latest outbound message failed to send and the thread needs review.
                  hasMore:
                    type: boolean
                    description: Indicates if there are more items to fetch
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection (e.g. invalid pagination).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_invalid_pagination:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid requested page view.
                    code: inboxThread.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '404':
          description: Contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact with ID 42 not found.
                code: inboxThread.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/set-replied:
    post:
      operationId: SetContactsReplied
      tags:
        - Contacts
      summary: Mark or unmark contacts as replied
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Marks the given contacts as replied (`isReplied: true`) or clears the replied flag (`isReplied: false`) across **every sequence** they are currently enrolled in.

        To restrict the change to a single sequence, use `POST /v3/sequences/{id}/contacts/set-replied` instead.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contactIds
                - isReplied
              properties:
                contactIds:
                  type: array
                  items:
                    type: integer
                  minItems: 1
                  maxItems: 100
                  description: Contact IDs to update. At least one, at most 100. Each ID must be positive.
                isReplied:
                  type: boolean
                  description: '`true` marks the contacts as replied; `false` clears the replied flag.'
      responses:
        '200':
          description: |-
            Non-atomic result. The response body is a dictionary keyed by contact id listing per-item failures. Empty object `{}` means all contacts were updated successfully.

            Per-item failures use the `ContactError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `notFound` | Contact does not exist |
            | `forbidden` | Caller lacks permission for this contact |
            | `sequenceNotFound` | Derived sequence not accessible |
            | `invalidInput` | Value rejected for this contact |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
                description: Dictionary of per-item failures keyed by contact id. Empty object `{}` means all succeeded.
        '400':
          description: |-
            Validation failure on the request body (missing/empty `contactIds`,
            non-positive ids, more than 100 ids, missing `isReplied`), or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactIds
                        detail: ContactIds must contain between 1 and 100 positive integers.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks the required feature scope to change contact status.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageProspect] are denied for userId 123.
                code: contact.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/set-bounced:
    post:
      operationId: SetContactsBounced
      tags:
        - Contacts
      summary: Mark or unmark contacts as bounced
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Marks the given contacts as bounced (`isBounced: true`) or clears the bounced flag (`isBounced: false`) across **every sequence** they are currently enrolled in.

        When clearing the flag (`isBounced: false`), `resendEmails` is required: pass `true` to retry the previously bounced step or `false` to leave the schedule untouched. When marking as bounced (`isBounced: true`), `resendEmails` must be omitted.

        To restrict the change to a single sequence, use `POST /v3/sequences/{id}/contacts/set-bounced` instead.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contactIds
                - isBounced
              properties:
                contactIds:
                  type: array
                  items:
                    type: integer
                  minItems: 1
                  maxItems: 100
                  description: Contact IDs to update. At least one, at most 100. Each ID must be positive.
                isBounced:
                  type: boolean
                  description: '`true` marks the contacts as bounced; `false` clears the bounced flag.'
                resendEmails:
                  type: boolean
                  nullable: true
                  description: |-
                    Required (non-null) when `isBounced=false`; **must be omitted** when `isBounced=true`.
                    When `true`, the previously bounced step is rescheduled for retry.
      responses:
        '200':
          description: |-
            Non-atomic result. The response body is a dictionary keyed by contact id listing per-item failures. Empty object `{}` means all contacts were updated successfully.

            Per-item failures use the `ContactError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `notFound` | Contact does not exist |
            | `forbidden` | Caller lacks permission for this contact |
            | `sequenceNotFound` | Derived sequence not accessible |
            | `invalidInput` | Value rejected for this contact |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
                description: Dictionary of per-item failures keyed by contact id. Empty object `{}` means all succeeded.
        '400':
          description: |-
            Validation failure on the request body (missing/empty `contactIds`,
            non-positive ids, more than 100 ids, missing `isBounced`, or
            `resendEmails` violating the `isBounced` pairing rule), or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /resendEmails
                        detail: resendEmails is required when isBounced is false.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks the required feature scope to change contact status.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageProspect] are denied for userId 123.
                code: contact.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/set-status-in-sequence:
    post:
      operationId: SetContactsStatusInSequence
      tags:
        - Contacts
      summary: Set contacts' in-sequence status
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Sets the in-sequence status (`active` / `paused` / `finished` / `outOfOffice`) for the given contacts across **every sequence** they are currently enrolled in.

        Replied and Bounced are **not** values of this enum — use `POST /v3/contacts/set-replied` or `POST /v3/contacts/set-bounced` for those.

        To restrict the change to a single sequence, use `POST /v3/sequences/{id}/contacts/set-status-in-sequence` instead.

        `paused` requires the contact to currently be `active` in the sequence — pausing from any other state is reported per-item as `invalidStatusTransition`. The other targets (`active`, `finished`, `outOfOffice`) accept any current state.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contactIds
                - statusInSequence
              properties:
                contactIds:
                  type: array
                  items:
                    type: integer
                  minItems: 1
                  maxItems: 100
                  description: Contact IDs to update. At least one, at most 100. Each ID must be positive.
                statusInSequence:
                  allOf:
                    - type: string
                      title: In-Sequence Status (writable)
                      description: |-
                        In-sequence status values that can be set via `POST /v3/contacts/set-status-in-sequence` and `POST /v3/sequences/{id}/contacts/set-status-in-sequence`.

                        Replied and Bounced are not values of this enum — they are flipped via the dedicated `set-replied` / `set-bounced` endpoints. OptedOut, Called/ToCall, and MeetingBooked are contact-level (not in-sequence) and are flipped via `PATCH /v3/contacts/{id}` (`isOptedOut`, `callStatus`, `meetingStatus`).
                      enum: &ref_197
                        - active
                        - paused
                        - finished
                        - outOfOffice
                  description: Target in-sequence status to set.
      responses:
        '200':
          description: |-
            Non-atomic result. The response body is a dictionary keyed by contact id listing per-item failures. Empty object `{}` means all contacts were updated successfully.

            Per-item failures use the `ContactError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `notFound` | Contact does not exist |
            | `forbidden` | Caller lacks permission for this contact |
            | `sequenceNotFound` | Derived sequence not accessible |
            | `invalidInput` | Value rejected for this contact |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
                description: Dictionary of per-item failures keyed by contact id. Empty object `{}` means all succeeded.
        '400':
          description: |-
            Validation failure on the request body (missing/empty `contactIds`,
            non-positive ids, more than 100 ids, or unsupported
            `statusInSequence` value), or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /statusInSequence
                        detail: 'Invalid statusInSequence value ''replied''. Allowed: active, paused, finished, outOfOffice.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks the required feature scope to change contact status.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageProspect] are denied for userId 123.
                code: contact.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/{id}/statuses:
    get:
      operationId: GetContactStatuses
      tags:
        - Contacts
      summary: Get a contact's statuses
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns the contact's current global flags (`isOptedOut`, `callStatus`, `meetingStatus`) plus per-sequence status (`statusInSequence`) and email disposition (`isReplied`, `isBounced`) for each sequence the contact is enrolled in.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
      responses:
        '200':
          description: Contact statuses retrieved successfully
          content:
            application/json:
              schema:
                type: object
                required:
                  - contactId
                  - isOptedOut
                  - callStatus
                  - meetingStatus
                  - sequences
                properties:
                  contactId:
                    type: integer
                    description: Contact ID
                  isOptedOut:
                    type: boolean
                    description: Whether the contact has opted out of all communications
                  callStatus:
                    type: string
                    title: Contact Call Status
                    description: Contact-level call status. Set via `PATCH /v3/contacts/{id}` (`callStatus` field). Pass `none` to clear.
                    enum: *ref_77
                  meetingStatus:
                    type: string
                    title: Contact Meeting Status
                    description: Contact-level meeting status. Set via `PATCH /v3/contacts/{id}` (`meetingStatus` field). Pass `none` to clear.
                    enum: *ref_78
                  sequences:
                    type: array
                    description: Per-sequence status for every sequence the contact is enrolled in. Empty when the contact is not in any sequence.
                    items:
                      type: object
                      required:
                        - sequenceId
                        - sequenceName
                        - statusInSequence
                        - emailDisposition
                      properties:
                        sequenceId:
                          type: integer
                        sequenceName:
                          type: string
                        statusInSequence:
                          type: string
                          title: In-Sequence Status (full)
                          description: All in-sequence status values that can appear in the `statusInSequence` field of `GET /v3/contacts/{id}/statuses` (per-sequence entries). Includes derived values (e.g. `inactive`, `contacted`, `opened`, `clicked`, `autoReplied`) that the API does not allow you to set directly — only the values in `contact-status.enum.yaml` are writable.
                          enum: &ref_390
                            - active
                            - paused
                            - inactive
                            - invalidEmail
                            - outOfOffice
                            - finished
                            - contacted
                            - opened
                            - clicked
                            - autoReplied
                            - bounced
                            - replied
                        emailDisposition:
                          type: object
                          required:
                            - isReplied
                            - isBounced
                          properties:
                            isReplied:
                              type: boolean
                            isBounced:
                              type: boolean
              example:
                contactId: 12345
                isOptedOut: false
                callStatus: toCall
                meetingStatus: none
                sequences:
                  - sequenceId: 100
                    sequenceName: Sales Outreach
                    statusInSequence: active
                    emailDisposition:
                      isReplied: false
                      isBounced: false
                  - sequenceId: 101
                    sequenceName: Re-engagement
                    statusInSequence: finished
                    emailDisposition:
                      isReplied: true
                      isBounced: false
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact with ID 42 not found.
                code: contact.notFound
  /v3/contacts/owner:
    put:
      tags:
        - Contacts
      operationId: ChangeContactsOwner
      summary: Change contacts owner
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Changes the owner of one or more contacts to a different team member
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contactIds
                - userId
              properties:
                contactIds:
                  type: array
                  items:
                    type: integer
                  description: Array of contact IDs to reassign
                userId:
                  type: integer
                  description: Target user ID to assign as owner
                reassignTasks:
                  type: boolean
                  default: false
                  description: Whether to also reassign tasks associated with these contacts
      responses:
        '200':
          description: Owner changed successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  isSuccess:
                    type: boolean
                  affectedIds:
                    type: array
                    items:
                      type: integer
                    description: IDs of contacts whose owner was changed
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactIds
                        detail: '''contactIds'' must not be empty.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to change contact owner
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to change contact owner.
                code: contact.forbidden
        '404':
          description: One or more contacts not found, or target user is not a member of the team
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: User 7 is not a member of the team.
                code: contact.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/{id}/notes:
    post:
      tags:
        - Contacts
      operationId: AddContactNote
      summary: Add a note to a contact
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Adds a note to an existing contact
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - notes
              properties:
                notes:
                  type: string
                  description: Note content
      responses:
        '204':
          description: Note added successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Validation failure on the route parameter or request body, or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /notes
                        detail: '''notes'' must not be empty.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this contact
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageProspect] are denied for userId 123.
                code: contact.forbidden
        '404':
          description: Contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact with ID 42 not found.
                code: contact.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/{id}/move-to-sequence:
    post:
      tags:
        - Contacts
      operationId: MoveContactToSequence
      summary: Move a contact to a sequence
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Moves a contact to a different sequence, optionally removing from existing sequences
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - sequenceId
              properties:
                sequenceId:
                  type: integer
                  description: Target sequence ID to move the contact to
                removeFromExisting:
                  type: boolean
                  default: false
                  description: Whether to remove the contact from their current sequence
                startStepId:
                  type: integer
                  nullable: true
                  description: Optional step ID to start from in the target sequence
                ignoreStepDelay:
                  type: boolean
                  default: false
                  description: If true, skip the configured delay before the first step and start processing immediately
                startFrom:
                  type: string
                  format: date-time
                  nullable: true
                  description: Optional date when contact processing should begin. If not provided, processing starts immediately.
      responses:
        '204':
          description: Contact moved to sequence successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Validation failure on the route parameter or request body, or a
            business rule rejection (e.g. contact could not be added to the
            sequence).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /sequenceId
                        detail: '''sequenceId'' must be greater than 0.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Contact could not be added to the sequence.
                    code: contact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this contact
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageProspect] are denied for userId 123.
                code: contact.forbidden
        '404':
          description: Contact or sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence not found.
                code: contact.sequenceNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/domains:
    get:
      tags:
        - Contact Blacklist Rules
      operationId: GetBlacklistDomainRules
      summary: List domain blacklist rules
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of domain blacklist rules.
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Filter rules by pattern
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of domain blacklist rules
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Domain Blacklist Rule
                      description: A blacklist rule that blocks a domain pattern
                      additionalProperties: false
                      properties: &ref_81
                        id:
                          type: integer
                          readOnly: true
                          description: Unique identifier of the rule
                        pattern:
                          type: string
                          description: Domain pattern to blacklist
                        isGlobal:
                          type: boolean
                          readOnly: true
                          description: Whether this is a global (system-wide) rule
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: blacklistDomainRule.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewBlacklist] are denied for userId 123.
                code: blacklistDomainRule.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Contact Blacklist Rules
      operationId: CreateBlacklistDomainRule
      summary: Create a domain blacklist rule
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Creates a new domain blacklist rule.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Create Domain Blacklist Rule Request
              description: Request body for creating a domain blacklist rule
              additionalProperties: false
              required: &ref_82
                - pattern
              properties: &ref_83
                pattern:
                  type: string
                  description: Domain pattern to blacklist. Must be a valid domain format (e.g., `example.com`, `spam-domain.net`)
                  example: example.com
      responses:
        '201':
          description: Domain blacklist rule created successfully
          content:
            application/json:
              schema:
                type: object
                title: Domain Blacklist Rule
                description: A blacklist rule that blocks a domain pattern
                additionalProperties: false
                properties: *ref_81
        '400':
          description: Request body validation failure (e.g. pattern is not a valid domain)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /pattern
                    detail: Pattern is not a valid domain.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistDomainRule.forbidden
        '409':
          description: A rule with the given pattern already exists, or rule could not be added
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              examples:
                duplicate:
                  summary: Duplicate pattern
                  value:
                    title: Conflict
                    status: 409
                    detail: A rule with this pattern already exists.
                    code: blacklistDomainRule.duplicate
                not_added:
                  summary: Rule could not be added (other reason)
                  value:
                    title: Conflict
                    status: 409
                    detail: The rule could not be added.
                    code: blacklistDomainRule.notAdded
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/domains/{id}:
    get:
      tags:
        - Contact Blacklist Rules
      operationId: GetBlacklistDomainRuleById
      summary: Get a domain blacklist rule
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a single domain blacklist rule by ID.
      parameters:
        - name: id
          in: path
          required: true
          description: Domain blacklist rule ID
          schema:
            type: integer
      responses:
        '200':
          description: Domain blacklist rule details
          content:
            application/json:
              schema:
                type: object
                title: Domain Blacklist Rule
                description: A blacklist rule that blocks a domain pattern
                additionalProperties: false
                properties: *ref_81
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewBlacklist] are denied for userId 123.
                code: blacklistDomainRule.forbidden
        '404':
          description: Domain blacklist rule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Domain blacklist rule with ID 5 not found.
                code: blacklistDomainRule.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Contact Blacklist Rules
      operationId: UpdateBlacklistDomainRule
      summary: Update a domain blacklist rule
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Updates an existing domain blacklist rule.
      parameters:
        - name: id
          in: path
          required: true
          description: Domain blacklist rule ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Update Domain Blacklist Rule Request
              description: Request body for updating a domain blacklist rule
              additionalProperties: false
              required: &ref_391
                - pattern
              properties: &ref_392
                pattern:
                  type: string
                  description: Domain pattern to blacklist. Must be a valid domain format (e.g., `example.com`, `spam-domain.net`)
                  example: example.com
      responses:
        '200':
          description: Domain blacklist rule updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Domain Blacklist Rule
                description: A blacklist rule that blocks a domain pattern
                additionalProperties: false
                properties: *ref_81
        '400':
          description: Route parameter / body validation failure (e.g. pattern is not a valid domain)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /pattern
                    detail: Pattern is not a valid domain.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistDomainRule.forbidden
        '404':
          description: Domain blacklist rule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Domain blacklist rule with ID 5 not found.
                code: blacklistDomainRule.notFound
        '409':
          description: A rule with the given pattern already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A rule with this pattern already exists.
                code: blacklistDomainRule.duplicate
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Contact Blacklist Rules
      operationId: DeleteBlacklistDomainRule
      summary: Delete a domain blacklist rule
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Deletes an existing domain blacklist rule. Global rules (seeded by the system) cannot be deleted.
      parameters:
        - name: id
          in: path
          required: true
          description: Domain blacklist rule ID
          schema:
            type: integer
      responses:
        '204':
          description: Domain blacklist rule deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Global (system) rule cannot be deleted
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Global rules are read-only and cannot be deleted.
                code: blacklistDomainRule.globalRuleReadOnly
        '404':
          description: Domain blacklist rule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Domain blacklist rule with ID 5 not found.
                code: blacklistDomainRule.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/domains/bulk:
    post:
      tags:
        - Contact Blacklist Rules
      operationId: BulkCreateBlacklistDomainRules
      summary: Bulk create domain blacklist rules
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Creates multiple domain blacklist rules. Non-atomic — some may succeed while others fail.
        Each item in the response array contains the created ID or error details.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                title: Create Domain Blacklist Rule Request
                description: Request body for creating a domain blacklist rule
                additionalProperties: false
                required: *ref_82
                properties: *ref_83
      responses:
        '200':
          description: |-
            Array of creation results, one per input item.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 2 | `Duplicate` — a rule with this pattern already exists |
            | 4 | `InvalidPattern` — pattern is not a valid domain |
            | 5 | `NotAdded` — rule could not be added (other reason) |
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Create Item Result
                  description: Result of a single item in a bulk create operation
                  additionalProperties: false
                  properties: &ref_87
                    id:
                      type: integer
                      nullable: true
                      readOnly: true
                      description: ID of the created rule, null if creation failed
                    error:
                      type: integer
                      nullable: true
                      readOnly: true
                      description: Error code if creation failed
                    errorDetails:
                      type: string
                      nullable: true
                      readOnly: true
                      description: Human-readable error description if creation failed
        '400':
          description: Request body validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /0/pattern
                    detail: Pattern is not a valid domain.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistDomainRule.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/domains/bulk-delete:
    post:
      tags:
        - Contact Blacklist Rules
      operationId: BulkDeleteBlacklistDomainRules
      summary: Bulk delete domain blacklist rules
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Deletes multiple domain blacklist rules by ID. Non-atomic — some may succeed while others fail.
        Items not in the response dictionary succeeded.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Bulk Delete Blacklist Rules Request
              description: Request body for bulk deleting blacklist rules
              additionalProperties: false
              required: &ref_88
                - ids
              properties: &ref_89
                ids:
                  type: array
                  description: List of rule IDs to delete
                  items:
                    type: integer
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by rule ID. Empty object `{}` means all succeeded.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 1 | `NotFound` — rule does not exist |
            | 3 | `GlobalRuleReadOnly` — rule is global (system-seeded) and cannot be deleted |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Request body validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /ids
                    detail: At least one ID is required.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistDomainRule.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/emails:
    get:
      tags:
        - Contact Blacklist Rules
      operationId: GetBlacklistEmailRules
      summary: List email blacklist rules
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of email blacklist rules.
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Filter rules by pattern
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of email blacklist rules
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Email Blacklist Rule
                      description: A blacklist rule that blocks an email pattern
                      additionalProperties: false
                      properties: &ref_84
                        id:
                          type: integer
                          readOnly: true
                          description: Unique identifier of the rule
                        pattern:
                          type: string
                          description: Email pattern to blacklist
                        isGlobal:
                          type: boolean
                          readOnly: true
                          description: Whether this is a global (system-wide) rule
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: blacklistEmailRule.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewBlacklist] are denied for userId 123.
                code: blacklistEmailRule.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Contact Blacklist Rules
      operationId: CreateBlacklistEmailRule
      summary: Create an email blacklist rule
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Creates a new email blacklist rule.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Create Email Blacklist Rule Request
              description: Request body for creating an email blacklist rule
              additionalProperties: false
              required: &ref_85
                - pattern
              properties: &ref_86
                pattern:
                  type: string
                  description: Email pattern to blacklist. Must be a valid email format (e.g., `spam@example.com`)
                  example: spam@example.com
      responses:
        '201':
          description: Email blacklist rule created successfully
          content:
            application/json:
              schema:
                type: object
                title: Email Blacklist Rule
                description: A blacklist rule that blocks an email pattern
                additionalProperties: false
                properties: *ref_84
        '400':
          description: Request body validation failure (e.g. pattern is not a valid email)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /pattern
                    detail: Pattern is not a valid email.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistEmailRule.forbidden
        '409':
          description: A rule with the given pattern already exists, or rule could not be added
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              examples:
                duplicate:
                  summary: Duplicate pattern
                  value:
                    title: Conflict
                    status: 409
                    detail: A rule with this pattern already exists.
                    code: blacklistEmailRule.duplicate
                not_added:
                  summary: Rule could not be added (other reason)
                  value:
                    title: Conflict
                    status: 409
                    detail: The rule could not be added.
                    code: blacklistEmailRule.notAdded
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/emails/{id}:
    get:
      tags:
        - Contact Blacklist Rules
      operationId: GetBlacklistEmailRuleById
      summary: Get an email blacklist rule
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a single email blacklist rule by ID.
      parameters:
        - name: id
          in: path
          required: true
          description: Email blacklist rule ID
          schema:
            type: integer
      responses:
        '200':
          description: Email blacklist rule details
          content:
            application/json:
              schema:
                type: object
                title: Email Blacklist Rule
                description: A blacklist rule that blocks an email pattern
                additionalProperties: false
                properties: *ref_84
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewBlacklist] are denied for userId 123.
                code: blacklistEmailRule.forbidden
        '404':
          description: Email blacklist rule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email blacklist rule with ID 5 not found.
                code: blacklistEmailRule.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Contact Blacklist Rules
      operationId: UpdateBlacklistEmailRule
      summary: Update an email blacklist rule
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Updates an existing email blacklist rule.
      parameters:
        - name: id
          in: path
          required: true
          description: Email blacklist rule ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Update Email Blacklist Rule Request
              description: Request body for updating an email blacklist rule
              additionalProperties: false
              required: &ref_393
                - pattern
              properties: &ref_394
                pattern:
                  type: string
                  description: Email pattern to blacklist. Must be a valid email format (e.g., `spam@example.com`)
                  example: spam@example.com
      responses:
        '200':
          description: Email blacklist rule updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Email Blacklist Rule
                description: A blacklist rule that blocks an email pattern
                additionalProperties: false
                properties: *ref_84
        '400':
          description: Route parameter / body validation failure (e.g. pattern is not a valid email)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /pattern
                    detail: Pattern is not a valid email.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistEmailRule.forbidden
        '404':
          description: Email blacklist rule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email blacklist rule with ID 5 not found.
                code: blacklistEmailRule.notFound
        '409':
          description: A rule with the given pattern already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A rule with this pattern already exists.
                code: blacklistEmailRule.duplicate
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Contact Blacklist Rules
      operationId: DeleteBlacklistEmailRule
      summary: Delete an email blacklist rule
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Deletes an existing email blacklist rule. Global rules (seeded by the system) cannot be deleted.
      parameters:
        - name: id
          in: path
          required: true
          description: Email blacklist rule ID
          schema:
            type: integer
      responses:
        '204':
          description: Email blacklist rule deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Global (system) rule cannot be deleted
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Global rules are read-only and cannot be deleted.
                code: blacklistEmailRule.globalRuleReadOnly
        '404':
          description: Email blacklist rule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email blacklist rule with ID 5 not found.
                code: blacklistEmailRule.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/emails/bulk:
    post:
      tags:
        - Contact Blacklist Rules
      operationId: BulkCreateBlacklistEmailRules
      summary: Bulk create email blacklist rules
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Creates multiple email blacklist rules. Non-atomic — some may succeed while others fail.
        Each item in the response array contains the created ID or error details.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                title: Create Email Blacklist Rule Request
                description: Request body for creating an email blacklist rule
                additionalProperties: false
                required: *ref_85
                properties: *ref_86
      responses:
        '200':
          description: |-
            Array of creation results, one per input item.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 2 | `Duplicate` — a rule with this pattern already exists |
            | 4 | `InvalidPattern` — pattern is not a valid email |
            | 5 | `NotAdded` — rule could not be added (other reason) |
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Create Item Result
                  description: Result of a single item in a bulk create operation
                  additionalProperties: false
                  properties: *ref_87
        '400':
          description: Request body validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /0/pattern
                    detail: Pattern is not a valid email.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistEmailRule.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/emails/bulk-delete:
    post:
      tags:
        - Contact Blacklist Rules
      operationId: BulkDeleteBlacklistEmailRules
      summary: Bulk delete email blacklist rules
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Deletes multiple email blacklist rules by ID. Non-atomic — some may succeed while others fail.
        Items not in the response dictionary succeeded.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Bulk Delete Blacklist Rules Request
              description: Request body for bulk deleting blacklist rules
              additionalProperties: false
              required: *ref_88
              properties: *ref_89
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by rule ID. Empty object `{}` means all succeeded.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 1 | `NotFound` — rule does not exist |
            | 3 | `GlobalRuleReadOnly` — rule is global (system-seeded) and cannot be deleted |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Request body validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /ids
                    detail: At least one ID is required.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistEmailRule.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/email-exceptions:
    get:
      tags:
        - Contact Blacklist Rules
      operationId: GetBlacklistEmailExceptionRules
      summary: List email exception blacklist rules
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of email exception blacklist rules.
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Filter rules by pattern
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of email exception blacklist rules
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Email Exception Blacklist Rule
                      description: An exception rule that allows an email pattern even if it matches a blacklist rule
                      additionalProperties: false
                      properties: &ref_90
                        id:
                          type: integer
                          readOnly: true
                          description: Unique identifier of the rule
                        pattern:
                          type: string
                          description: Email pattern to allow as exception
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: blacklistEmailExceptionRule.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewBlacklist] are denied for userId 123.
                code: blacklistEmailExceptionRule.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Contact Blacklist Rules
      operationId: CreateBlacklistEmailExceptionRule
      summary: Create an email exception blacklist rule
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Creates a new email exception blacklist rule.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Create Email Exception Blacklist Rule Request
              description: Request body for creating an email exception blacklist rule
              additionalProperties: false
              required: &ref_91
                - pattern
              properties: &ref_92
                pattern:
                  type: string
                  description: Email address to allow as exception. Must be a valid email format (e.g., `user@example.com`)
                  example: user@example.com
      responses:
        '201':
          description: Email exception blacklist rule created successfully
          content:
            application/json:
              schema:
                type: object
                title: Email Exception Blacklist Rule
                description: An exception rule that allows an email pattern even if it matches a blacklist rule
                additionalProperties: false
                properties: *ref_90
        '400':
          description: Request body validation failure (e.g. pattern is not a valid email)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /pattern
                    detail: Pattern is not a valid email.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistEmailExceptionRule.forbidden
        '409':
          description: A rule with the given pattern already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A rule with this pattern already exists.
                code: blacklistEmailExceptionRule.duplicate
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/email-exceptions/{id}:
    get:
      tags:
        - Contact Blacklist Rules
      operationId: GetBlacklistEmailExceptionRuleById
      summary: Get an email exception blacklist rule
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a single email exception blacklist rule by ID.
      parameters:
        - name: id
          in: path
          required: true
          description: Email exception blacklist rule ID
          schema:
            type: integer
      responses:
        '200':
          description: Email exception blacklist rule details
          content:
            application/json:
              schema:
                type: object
                title: Email Exception Blacklist Rule
                description: An exception rule that allows an email pattern even if it matches a blacklist rule
                additionalProperties: false
                properties: *ref_90
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewBlacklist] are denied for userId 123.
                code: blacklistEmailExceptionRule.forbidden
        '404':
          description: Email exception blacklist rule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email exception blacklist rule with ID 5 not found.
                code: blacklistEmailExceptionRule.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Contact Blacklist Rules
      operationId: UpdateBlacklistEmailExceptionRule
      summary: Update an email exception blacklist rule
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Updates an existing email exception blacklist rule.
      parameters:
        - name: id
          in: path
          required: true
          description: Email exception blacklist rule ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Update Email Exception Blacklist Rule Request
              description: Request body for updating an email exception blacklist rule
              additionalProperties: false
              required: &ref_395
                - pattern
              properties: &ref_396
                pattern:
                  type: string
                  description: Email address to allow as exception. Must be a valid email format (e.g., `user@example.com`)
                  example: user@example.com
      responses:
        '200':
          description: Email exception blacklist rule updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Email Exception Blacklist Rule
                description: An exception rule that allows an email pattern even if it matches a blacklist rule
                additionalProperties: false
                properties: *ref_90
        '400':
          description: Route parameter / body validation failure (e.g. pattern is not a valid email)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /pattern
                    detail: Pattern is not a valid email.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistEmailExceptionRule.forbidden
        '404':
          description: Email exception blacklist rule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email exception blacklist rule with ID 5 not found.
                code: blacklistEmailExceptionRule.notFound
        '409':
          description: A rule with the given pattern already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A rule with this pattern already exists.
                code: blacklistEmailExceptionRule.duplicate
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Contact Blacklist Rules
      operationId: DeleteBlacklistEmailExceptionRule
      summary: Delete an email exception blacklist rule
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Deletes an existing email exception blacklist rule.
      parameters:
        - name: id
          in: path
          required: true
          description: Email exception blacklist rule ID
          schema:
            type: integer
      responses:
        '204':
          description: Email exception blacklist rule deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistEmailExceptionRule.forbidden
        '404':
          description: Email exception blacklist rule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email exception blacklist rule with ID 5 not found.
                code: blacklistEmailExceptionRule.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/email-exceptions/bulk:
    post:
      tags:
        - Contact Blacklist Rules
      operationId: BulkCreateBlacklistEmailExceptionRules
      summary: Bulk create email exception blacklist rules
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Creates multiple email exception blacklist rules. Non-atomic — some may succeed while others fail.
        Each item in the response array contains the created ID or error details.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                title: Create Email Exception Blacklist Rule Request
                description: Request body for creating an email exception blacklist rule
                additionalProperties: false
                required: *ref_91
                properties: *ref_92
      responses:
        '200':
          description: |-
            Array of creation results, one per input item.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 2 | `Duplicate` — a rule with this pattern already exists |
            | 4 | `InvalidPattern` — pattern is not a valid email |
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Create Item Result
                  description: Result of a single item in a bulk create operation
                  additionalProperties: false
                  properties: *ref_87
        '400':
          description: Request body validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /0/pattern
                    detail: Pattern is not a valid email.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistEmailExceptionRule.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-blacklist-rules/email-exceptions/bulk-delete:
    post:
      tags:
        - Contact Blacklist Rules
      operationId: BulkDeleteBlacklistEmailExceptionRules
      summary: Bulk delete email exception blacklist rules
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Deletes multiple email exception blacklist rules by ID. Non-atomic — some may succeed while others fail.
        Items not in the response dictionary succeeded.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Bulk Delete Blacklist Rules Request
              description: Request body for bulk deleting blacklist rules
              additionalProperties: false
              required: *ref_88
              properties: *ref_89
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by rule ID. Empty object `{}` means all succeeded.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 1 | `NotFound` — rule does not exist |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Request body validation failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /ids
                    detail: At least one ID is required.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage blacklist rules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageBlacklist] are denied for userId 123.
                code: blacklistEmailExceptionRule.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/enrich-by-email:
    post:
      tags:
        - Contact Enrichment
      summary: Enrich contacts by email
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        Enriches contact data using each contact's existing email address.

        Consumes credits from the Reply credit pool — 1 credit per contact.
      operationId: EnrichContactsByEmail
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Coming soon — full request shape is still being finalized.
      responses:
        '202':
          description: Enrichment accepted
          content:
            application/json:
              schema:
                type: object
                description: Coming soon — full response shape is still being finalized.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
  /v3/contacts/find-emails:
    post:
      tags:
        - Contact Enrichment
      summary: Find missing email addresses
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        Finds missing email addresses for contacts that currently don't have one.

        Consumes credits from the Reply credit pool — 2 credits per contact.
      operationId: FindContactEmails
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Coming soon — full request shape is still being finalized.
      responses:
        '202':
          description: Find-emails job accepted
          content:
            application/json:
              schema:
                type: object
                description: Coming soon — full response shape is still being finalized.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: '`BulkActionsForDataFinder` feature is not available for the caller''s team'
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
  /v3/contacts/find-phones:
    post:
      tags:
        - Contact Enrichment
      summary: Find phone numbers
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        Finds phone numbers for contacts.

        Consumes credits from the Reply credit pool — 3 credits per contact.
      operationId: FindContactPhones
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Coming soon — full request shape is still being finalized.
      responses:
        '202':
          description: Find-phones job accepted
          content:
            application/json:
              schema:
                type: object
                description: Coming soon — full response shape is still being finalized.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: '`BulkActionsForDataFinder` feature is not available for the caller''s team'
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
  /v3/contacts/enrich-by-linkedin:
    post:
      tags:
        - Contact Enrichment
      summary: Enrich contacts by LinkedIn URL
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        Enriches contact data using each contact's LinkedIn URL. Optionally also finds email and/or phone in the same call.

        Consumes credits from the Reply credit pool: 1 per contact, plus (when find-email is enabled) 2 and (when find-phone is enabled) 3 per contact.
      operationId: EnrichContactsByLinkedIn
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Coming soon — full request shape is still being finalized.
      responses:
        '202':
          description: Enrichment accepted
          content:
            application/json:
              schema:
                type: object
                description: Coming soon — full response shape is still being finalized.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: '`CleanUpAndEnrichDataByLinkedinUrl` feature is not available for the caller''s team'
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
  /v3/contacts/enrich-ai-custom-fields:
    post:
      tags:
        - Contact Enrichment
      summary: Fill AI custom fields
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        Fills configured AI custom field values for contacts using AI.

        Consumes credits from the Reply credit pool — 1 credit per contact-field combination.
      operationId: EnrichContactsWithAiCustomFields
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Coming soon — full request shape is still being finalized.
      responses:
        '202':
          description: Enrichment accepted
          content:
            application/json:
              schema:
                type: object
                description: Coming soon — full response shape is still being finalized.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: '`AiCustomFields` feature is not available for the caller''s team'
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
  /v3/contact-lists:
    get:
      tags:
        - Contact Lists
      operationId: GetContactLists
      summary: List contact lists
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to browse the contact lists you can work with — the lists you own plus any shared with your team. Results are returned as a page controlled by the top and skip query parameters; omit both to get the first page. Pass search to keep only the lists whose name contains the given text.
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Filter contact lists by name
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of contact lists
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Contact List
                      description: Contact list entity
                      additionalProperties: false
                      properties: &ref_93
                        id:
                          type: integer
                          readOnly: true
                          description: Unique identifier of the contact list
                        name:
                          type: string
                          description: Contact list name
                        isShared:
                          type: boolean
                          description: Whether the contact list is shared across the team
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: contactsList.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view contact lists
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewContactList] are denied for userId 123.
                code: contactsList.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Contact Lists
      operationId: CreateContactList
      summary: Create a contact list
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need a new contact list to group contacts under. Provide the list name and set isShared to make it visible to your whole team straight away, or leave it false to keep the list private to you. The created list is returned with its assigned id. List names must be unique.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Create Contact List Request
              additionalProperties: false
              required: &ref_397
                - name
              properties: &ref_398
                name:
                  type: string
                  description: Contact list name
                isShared:
                  type: boolean
                  description: Whether the contact list should be shared
                  default: false
      responses:
        '201':
          description: Contact list created successfully
          content:
            application/json:
              schema:
                type: object
                title: Contact List
                description: Contact list entity
                additionalProperties: false
                properties: *ref_93
        '400':
          description: |-
            Request body validation failure, or a business-rule rejection
            (e.g. name length out of range).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: Name must be at least 2 characters.
                business_name_too_short:
                  summary: Business rejection — name too short
                  value:
                    title: Bad Request
                    status: 400
                    detail: Name must be at least 2 characters.
                    code: contactsList.nameTooShort
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create contact lists
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageContactList] are denied for userId 123.
                code: contactsList.forbidden
        '409':
          description: A contact list with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A list with this name already exists.
                code: contactsList.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-lists/{id}:
    get:
      tags:
        - Contact Lists
      operationId: GetContactListById
      summary: Get a contact list
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the details of a single contact list, identified by its id — its name and whether it is shared with your team.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact list ID
          schema:
            type: integer
      responses:
        '200':
          description: Contact list details
          content:
            application/json:
              schema:
                type: object
                title: Contact List
                description: Contact list entity
                additionalProperties: false
                properties: *ref_93
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User does not have access to this list
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have access to this list.
                code: contactsList.forbidden
        '404':
          description: Contact list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactsList.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Contact Lists
      operationId: UpdateContactList
      summary: Update a contact list
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to rename an existing contact list. Only the name can be changed here — the list's contacts and its shared state are left untouched; use the share and unshare endpoints to change visibility. The new name must be unique.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact list ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Update Contact List Request
              additionalProperties: false
              required: &ref_399
                - name
              properties: &ref_400
                name:
                  type: string
                  description: New contact list name
      responses:
        '200':
          description: Contact list updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Contact List
                description: Contact list entity
                additionalProperties: false
                properties: *ref_93
        '400':
          description: Route parameter / body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: Name is required.
                business_name_is_empty:
                  summary: Business rejection — empty name
                  value:
                    title: Bad Request
                    status: 400
                    detail: Name must not be empty.
                    code: contactsList.nameIsEmpty
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User does not have access to this list
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have access to this list.
                code: contactsList.forbidden
        '404':
          description: Contact list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactsList.notFound
        '409':
          description: A contact list with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A list with this name already exists.
                code: contactsList.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Contact Lists
      operationId: DeleteContactList
      summary: Delete a contact list
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to remove a contact list by its id. A shared list can only be deleted by the user who created it.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact list ID
          schema:
            type: integer
      responses:
        '204':
          description: Contact list deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User does not have permission to delete this list
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to delete this list.
                code: contactsList.forbidden
        '404':
          description: Contact list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactsList.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-lists/{id}/share:
    post:
      tags:
        - Contact Lists
      operationId: ShareContactList
      summary: Share a contact list
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to make one of your private contact lists visible to the rest of your team. To reverse it later, use the unshare endpoint.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact list ID
          schema:
            type: integer
      responses:
        '204':
          description: Contact list shared successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Sharing is not available for this team edition
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Sharing is not available for your team edition.
                code: contactsList.accessChangeRejected
        '404':
          description: Contact list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactsList.notFound
        '409':
          description: A shared list with this name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A shared list with this name already exists.
                code: contactsList.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-lists/{id}/unshare:
    post:
      tags:
        - Contact Lists
      operationId: UnshareContactList
      summary: Unshare a contact list
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to take a shared contact list back out of team visibility and make it private to you again.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact list ID
          schema:
            type: integer
      responses:
        '204':
          description: Contact list unshared successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Sharing is not available for this team edition
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Sharing is not available for your team edition.
                code: contactsList.accessChangeRejected
        '404':
          description: Contact list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactsList.notFound
        '409':
          description: A list with this name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A list with this name already exists.
                code: contactsList.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-lists/{id}/move-contacts:
    post:
      tags:
        - Contact Lists
      operationId: MoveContactsToContactList
      summary: Move contacts to a contact list
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the supplied contacts to end up in this list and in no other — each contact is removed from every list it currently belongs to and placed in this one. To keep their existing memberships, use the add-contacts endpoint instead. Contacts are processed one by one and successful moves are kept even when others fail; the response returns only the contact ids that were not processed, each with its error details.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact list ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contactIds
              properties:
                contactIds:
                  type: array
                  items:
                    type: integer
                  description: Array of contact IDs to move
      responses:
        '200':
          description: |-
            Move operation completed. Response is a dictionary keyed by contact ID.
            Only failed items appear; missing IDs were moved successfully.

            Possible per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 8 | `ContactNotProcessed` — contact could not be moved (e.g. access denied, invalid ID) |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Route parameter / body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactIds
                        detail: At least one contact ID is required.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User does not have access to this list
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have access to this list.
                code: contactsList.forbidden
        '404':
          description: Contact list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactsList.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contact-lists/{id}/add-contacts:
    post:
      tags:
        - Contact Lists
      operationId: AddContactsToContactList
      summary: Add contacts to a contact list
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to add contacts to this list while leaving the other lists they already belong to in place. To make this list their only list, use the move-contacts endpoint instead. Contacts are processed one by one and successful additions are kept even when others fail; the response returns only the contact ids that were not processed, each with its error details.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact list ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contactIds
              properties:
                contactIds:
                  type: array
                  items:
                    type: integer
                  description: Array of contact IDs to add
      responses:
        '200':
          description: |-
            Add operation completed. Response is a dictionary keyed by contact ID.
            Only failed items appear; missing IDs were added successfully.

            Possible per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 8 | `ContactNotProcessed` — contact could not be added (e.g. access denied, invalid ID) |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Route parameter / body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactIds
                        detail: At least one contact ID is required.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User does not have access to this list
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have access to this list.
                code: contactsList.forbidden
        '404':
          description: Contact list not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: List with ID 42 not found.
                code: contactsList.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/{id}/lists:
    get:
      tags:
        - Contact Lists
      operationId: GetContactListsForContact
      summary: Get contact's lists
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to see which contact lists a contact belongs to, including each list's name and whether it is shared with your team.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
      responses:
        '200':
          description: Contact lists for contact retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Contact List Reference
                  description: Lightweight contact list reference
                  additionalProperties: false
                  properties: &ref_401
                    id:
                      type: integer
                    name:
                      type: string
        '400':
          description: |-
            Route parameter validation failure (e.g. `id` not a positive integer),
            or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this contact
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewProspect] are denied for userId 123.
                code: contact.forbidden
        '404':
          description: Contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact with ID 42 not found.
                code: contact.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/custom-fields:
    get:
      tags:
        - Custom Fields
      operationId: GetCustomFields
      summary: List all custom fields
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a list of all custom fields in your account
      responses:
        '200':
          description: List of custom fields retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Custom Field
                  description: A user-defined field for storing additional data on contacts.
                  properties: &ref_94
                    id:
                      type: integer
                      readOnly: true
                      description: Custom field ID
                    title:
                      type: string
                      description: Custom field name
                    fieldType:
                      type: string
                      description: Custom field type
                      enum:
                        - text
                        - number
                    metadata:
                      type: string
                      nullable: true
                      description: Optional metadata for the field (e.g., dropdown options)
                    orgWide:
                      type: boolean
                      description: Whether the field is shared across the organization
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view custom fields
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewCustomField] are denied for userId 123
                code: customField.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Custom Fields
      operationId: CreateCustomField
      summary: Create a custom field
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Creates a new custom field
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: &ref_402
                - title
                - fieldType
              properties: &ref_403
                title:
                  type: string
                  description: Custom field name
                  maxLength: 90
                fieldType:
                  type: string
                  description: Custom field type
                  enum:
                    - text
                    - number
                metadata:
                  type: string
                  nullable: true
                  description: Optional metadata for the field (e.g., dropdown options)
                orgWide:
                  type: boolean
                  default: false
                  description: Whether the field should be shared across the organization
      responses:
        '201':
          description: Custom field created successfully
          content:
            application/json:
              schema:
                type: object
                title: Custom Field
                description: A user-defined field for storing additional data on contacts.
                properties: *ref_94
        '400':
          description: |-
            Validation failure on the request body, or a business rule rejection
            (e.g. invalid metadata for the chosen field type).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /title
                        detail: '''Title'' must not be empty.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Metadata is required for dropdown custom fields.
                    code: customField.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create custom fields
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageCustomField] are denied for userId 123
                code: customField.forbidden
        '409':
          description: Duplicate field name or per-team custom field limit exceeded
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              examples:
                duplicate_name:
                  summary: Custom field with the same name already exists
                  value:
                    title: Conflict
                    status: 409
                    detail: A custom field with this name already exists
                    code: customField.duplicateName
                limit_exceeded:
                  summary: Per-team custom field limit reached
                  value:
                    title: Conflict
                    status: 409
                    detail: Custom field limit reached for this team
                    code: customField.limitExceeded
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/custom-fields/{id}:
    get:
      tags:
        - Custom Fields
      operationId: GetCustomFieldById
      summary: Get a custom field
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a single custom field by ID
      parameters:
        - name: id
          in: path
          required: true
          description: Custom field ID
          schema:
            type: integer
      responses:
        '200':
          description: Custom field details retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Custom Field
                description: A user-defined field for storing additional data on contacts.
                properties: *ref_94
        '400':
          description: Invalid id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view custom fields
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewCustomField] are denied for userId 123
                code: customField.forbidden
        '404':
          description: Custom field not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Custom field with ID 42 not found
                code: customField.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Custom Fields
      operationId: UpdateCustomField
      summary: Update a custom field
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Updates an existing custom field
      parameters:
        - name: id
          in: path
          required: true
          description: Custom field ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: &ref_404
                - title
                - fieldType
              properties: &ref_405
                title:
                  type: string
                  description: Custom field name
                  maxLength: 90
                fieldType:
                  type: string
                  description: Custom field type
                  enum:
                    - text
                    - number
                metadata:
                  type: string
                  nullable: true
                  description: Optional metadata for the field (e.g., dropdown options)
      responses:
        '200':
          description: Custom field updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Custom Field
                description: A user-defined field for storing additional data on contacts.
                properties: *ref_94
        '400':
          description: |-
            Validation failure on the route param or request body, or a business
            rule rejection (e.g. invalid metadata for the chosen field type).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /title
                        detail: '''Title'' must not be empty.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Metadata is required for dropdown custom fields.
                    code: customField.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify custom fields
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageCustomField] are denied for userId 123
                code: customField.forbidden
        '404':
          description: Custom field not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Custom field with ID 42 not found
                code: customField.notFound
        '409':
          description: Duplicate field name
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A custom field with this name already exists
                code: customField.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Custom Fields
      operationId: DeleteCustomField
      summary: Delete a custom field
      x-required-scope: contacts:write
      description: |-
        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Deletes an existing custom field
      parameters:
        - name: id
          in: path
          required: true
          description: Custom field ID
          schema:
            type: integer
      responses:
        '204':
          description: Custom field deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete custom fields
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageCustomField] are denied for userId 123
                code: customField.forbidden
        '404':
          description: Custom field not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Custom field with ID 42 not found
                code: customField.notFound
        '409':
          description: Field has values and cannot be deleted
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Custom field has values and cannot be deleted
                code: customField.hasValues
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/{id}/send-direct-email:
    post:
      tags:
        - Direct Outreach
      operationId: SendDirectEmail
      summary: Send a direct email to a contact
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Sends a one-off email directly to a contact outside of any sequence
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - subject
                - body
              properties:
                emailAccountId:
                  type: integer
                  format: int64
                  nullable: true
                  description: Email account ID to send from. If not provided, uses the default account.
                subject:
                  type: string
                  description: Email subject line
                body:
                  type: string
                  description: Email body (HTML)
      responses:
        '200':
          description: Email sent successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - new
                      - sent
                    description: Sending status
                  messageId:
                    type: string
                    nullable: true
                    description: Message ID of the sent email
        '400':
          description: |-
            Validation failure on the route parameter or request body, or a
            business rule rejection (e.g. email account missing, contact in
            blacklist).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /subject
                        detail: '''subject'' must not be empty.'
                business_email_account_not_found:
                  summary: Email account missing or inaccessible
                  value:
                    title: Bad Request
                    status: 400
                    detail: Email account is not found or access is denied.
                    code: contact.emailAccountNotFound
                business_contact_in_blacklist:
                  summary: Contact is on the blacklist
                  value:
                    title: Bad Request
                    status: 400
                    detail: Contact email is on the blacklist.
                    code: contact.contactInBlackList
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to send email
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [SendEmail] are denied for userId 123.
                code: contact.forbidden
        '404':
          description: Contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact with ID 42 not found.
                code: contact.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/contacts/{id}/send-direct-linkedin-connect:
    post:
      tags:
        - Direct Outreach
      operationId: SendDirectLinkedInConnect
      summary: Send a LinkedIn connection request to a contact
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Sends a direct LinkedIn connection request to the contact outside of any sequence.
        The contact must have a LinkedIn profile URL set. The caller must own an active LinkedIn account (`linkedInAccountId`).
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - linkedInAccountId
              properties:
                linkedInAccountId:
                  type: integer
                  description: ID of the LinkedIn account to send from. Must be greater than 0.
                message:
                  type: string
                  nullable: true
                  description: Optional personalized note to include with the connection request.
      responses:
        '200':
          description: Connection request sent successfully.
          content:
            application/json:
              schema:
                type: object
                title: Send Direct LinkedIn Response
                description: Response returned after a direct LinkedIn action is dispatched.
                required: &ref_95
                  - actionType
                  - linkedInActivityId
                  - sentAtUtc
                properties: &ref_96
                  actionType:
                    description: The type of LinkedIn action performed.
                    type: string
                    title: Direct LinkedIn Action Type
                    enum: &ref_406
                      - connect
                      - inMail
                      - message
                      - voice
                      - aiVoice
                  linkedInActivityId:
                    type: integer
                    description: ID of the LinkedIn activity record created for this action.
                  sentAtUtc:
                    type: string
                    format: date-time
                    description: UTC timestamp when the action was dispatched.
              example:
                actionType: connect
                linkedInActivityId: 1042
                sentAtUtc: '2026-05-15T10:30:00Z'
        '400':
          description: |-
            Validation failure on the route parameter or request body, or a business rule rejection.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.invitesNotesLimit` | Connection note character limit exceeded |
            | `directLinkedIn.missingVariables` | Message template contains unresolved variables |
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Request body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /linkedInAccountId
                        detail: '''linkedInAccountId'' must be greater than ''0''.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: LinkedIn direct actions feature is disabled for this account.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: LinkedIn direct actions feature is not enabled for this account.
                code: directLinkedIn.featureDisabled
        '404':
          description: Contact, LinkedIn profile, or LinkedIn account not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              examples:
                contact_not_found:
                  summary: Contact not found
                  value:
                    title: Not Found
                    status: 404
                    detail: Contact with ID 42 not found.
                    code: directLinkedIn.contactNotFound
                no_linkedin_profile:
                  summary: Contact has no LinkedIn profile URL
                  value:
                    title: Not Found
                    status: 404
                    detail: This contact does not have a LinkedIn profile URL set.
                    code: directLinkedIn.noLinkedInProfile
                linkedin_account_not_found:
                  summary: LinkedIn account not found
                  value:
                    title: Not Found
                    status: 404
                    detail: LinkedIn account not found or not accessible.
                    code: directLinkedIn.linkedInAccountNotFound
        '409':
          description: |-
            Conflict — the LinkedIn account state or connection status prevents the action.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.linkedInAccountInactive` | Specified LinkedIn account is inactive |
            | `directLinkedIn.invalidCookie` | LinkedIn account session cookie is invalid |
            | `directLinkedIn.alreadyConnected` | Already connected with this contact on LinkedIn |
            | `directLinkedIn.notConnected` | Not connected to this contact on LinkedIn |
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              examples:
                already_connected:
                  summary: Already connected with this contact
                  value:
                    title: Conflict
                    status: 409
                    detail: You are already connected with this contact on LinkedIn.
                    code: directLinkedIn.alreadyConnected
                linkedin_account_inactive:
                  summary: LinkedIn account is inactive
                  value:
                    title: Conflict
                    status: 409
                    detail: The specified LinkedIn account is inactive.
                    code: directLinkedIn.linkedInAccountInactive
        '429':
          description: |-
            Rate limit reached.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.dailyLimitReached` | Daily connection request limit reached |
            | `directLinkedIn.weeklyLimitReached` | Weekly connection request limit reached |
          headers:
            Retry-After:
              description: Seconds to wait before retrying
              schema:
                type: integer
                minimum: 1
          content:
            application/problem+json:
              schema:
                allOf:
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
              examples:
                daily_limit_reached:
                  summary: Daily limit reached
                  value:
                    title: Too Many Requests
                    status: 429
                    detail: The daily LinkedIn connection request limit has been reached.
                    code: directLinkedIn.dailyLimitReached
                weekly_limit_reached:
                  summary: Weekly limit reached
                  value:
                    title: Too Many Requests
                    status: 429
                    detail: The weekly LinkedIn connection request limit has been reached.
                    code: directLinkedIn.weeklyLimitReached
  /v3/contacts/{id}/send-direct-linkedin-inmail:
    post:
      tags:
        - Direct Outreach
      operationId: SendDirectLinkedInInMail
      summary: Send a LinkedIn InMail to a contact
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Sends a direct LinkedIn InMail message to the contact outside of any sequence.
        Requires a Sales Navigator account with available InMail credits.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - linkedInAccountId
                - subject
                - body
              properties:
                linkedInAccountId:
                  type: integer
                  description: ID of the LinkedIn account to send from. Must be greater than 0.
                subject:
                  type: string
                  maxLength: 200
                  description: InMail subject line.
                body:
                  type: string
                  maxLength: 1900
                  description: InMail body text.
      responses:
        '200':
          description: InMail sent successfully.
          content:
            application/json:
              schema:
                type: object
                title: Send Direct LinkedIn Response
                description: Response returned after a direct LinkedIn action is dispatched.
                required: *ref_95
                properties: *ref_96
              example:
                actionType: inMail
                linkedInActivityId: 1043
                sentAtUtc: '2026-05-15T10:31:00Z'
        '400':
          description: |-
            Validation failure on the route parameter or request body, or a business rule rejection.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.salesNavRequired` | Sales Navigator subscription required |
            | `directLinkedIn.salesNavDisconnected` | Sales Navigator is disconnected |
            | `directLinkedIn.noInMailCredits` | No InMail credits remaining |
            | `directLinkedIn.messageTooLong` | Message body exceeds the allowed length |
            | `directLinkedIn.missingVariables` | Message template contains unresolved variables |
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Request body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /subject
                        detail: '''subject'' must not be empty.'
                no_inmail_credits:
                  summary: No InMail credits remaining
                  value:
                    title: Bad Request
                    status: 400
                    detail: No InMail credits remaining on this LinkedIn account.
                    code: directLinkedIn.noInMailCredits
                sales_nav_required:
                  summary: Sales Navigator required
                  value:
                    title: Bad Request
                    status: 400
                    detail: A Sales Navigator subscription is required to send InMail.
                    code: directLinkedIn.salesNavRequired
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: LinkedIn direct actions feature is disabled for this account.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: LinkedIn direct actions feature is not enabled for this account.
                code: directLinkedIn.featureDisabled
        '404':
          description: Contact, LinkedIn profile, or LinkedIn account not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              examples:
                contact_not_found:
                  summary: Contact not found
                  value:
                    title: Not Found
                    status: 404
                    detail: Contact with ID 42 not found.
                    code: directLinkedIn.contactNotFound
                no_linkedin_profile:
                  summary: Contact has no LinkedIn profile URL
                  value:
                    title: Not Found
                    status: 404
                    detail: This contact does not have a LinkedIn profile URL set.
                    code: directLinkedIn.noLinkedInProfile
                linkedin_account_not_found:
                  summary: LinkedIn account not found
                  value:
                    title: Not Found
                    status: 404
                    detail: LinkedIn account not found or not accessible.
                    code: directLinkedIn.linkedInAccountNotFound
        '409':
          description: |-
            Conflict — the LinkedIn account state prevents the action.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.linkedInAccountInactive` | Specified LinkedIn account is inactive |
            | `directLinkedIn.invalidCookie` | LinkedIn account session cookie is invalid |
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: The specified LinkedIn account is inactive.
                code: directLinkedIn.linkedInAccountInactive
        '429':
          description: |-
            Rate limit reached.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.dailyLimitReached` | Daily InMail limit reached |
            | `directLinkedIn.weeklyLimitReached` | Weekly InMail limit reached |
          headers:
            Retry-After:
              description: Seconds to wait before retrying
              schema:
                type: integer
                minimum: 1
          content:
            application/problem+json:
              schema:
                allOf:
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
              examples:
                daily_limit_reached:
                  summary: Daily limit reached
                  value:
                    title: Too Many Requests
                    status: 429
                    detail: The daily LinkedIn InMail limit has been reached.
                    code: directLinkedIn.dailyLimitReached
                weekly_limit_reached:
                  summary: Weekly limit reached
                  value:
                    title: Too Many Requests
                    status: 429
                    detail: The weekly LinkedIn InMail limit has been reached.
                    code: directLinkedIn.weeklyLimitReached
  /v3/contacts/{id}/send-direct-linkedin-message:
    post:
      tags:
        - Direct Outreach
      operationId: SendDirectLinkedInMessage
      summary: Send a LinkedIn message to a contact
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Sends a direct LinkedIn message to the contact outside of any sequence.
        The caller must already be connected with the contact on LinkedIn.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - linkedInAccountId
                - message
              properties:
                linkedInAccountId:
                  type: integer
                  description: ID of the LinkedIn account to send from. Must be greater than 0.
                message:
                  type: string
                  maxLength: 8000
                  description: Message body text.
      responses:
        '200':
          description: Message sent successfully.
          content:
            application/json:
              schema:
                type: object
                title: Send Direct LinkedIn Response
                description: Response returned after a direct LinkedIn action is dispatched.
                required: *ref_95
                properties: *ref_96
              example:
                actionType: message
                linkedInActivityId: 1044
                sentAtUtc: '2026-05-15T10:32:00Z'
        '400':
          description: |-
            Validation failure on the route parameter or request body, or a business rule rejection.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.messageTooLong` | Message body exceeds the allowed length |
            | `directLinkedIn.missingVariables` | Message template contains unresolved variables |
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /message
                    detail: '''message'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: LinkedIn direct actions feature is disabled for this account.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: LinkedIn direct actions feature is not enabled for this account.
                code: directLinkedIn.featureDisabled
        '404':
          description: Contact, LinkedIn profile, or LinkedIn account not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              examples:
                contact_not_found:
                  summary: Contact not found
                  value:
                    title: Not Found
                    status: 404
                    detail: Contact with ID 42 not found.
                    code: directLinkedIn.contactNotFound
                no_linkedin_profile:
                  summary: Contact has no LinkedIn profile URL
                  value:
                    title: Not Found
                    status: 404
                    detail: This contact does not have a LinkedIn profile URL set.
                    code: directLinkedIn.noLinkedInProfile
                linkedin_account_not_found:
                  summary: LinkedIn account not found
                  value:
                    title: Not Found
                    status: 404
                    detail: LinkedIn account not found or not accessible.
                    code: directLinkedIn.linkedInAccountNotFound
        '409':
          description: |-
            Conflict — the LinkedIn account state or connection status prevents the action.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.linkedInAccountInactive` | Specified LinkedIn account is inactive |
            | `directLinkedIn.invalidCookie` | LinkedIn account session cookie is invalid |
            | `directLinkedIn.notConnected` | Not connected with this contact on LinkedIn |
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              examples:
                not_connected:
                  summary: Not connected with this contact
                  value:
                    title: Conflict
                    status: 409
                    detail: You are not connected with this contact on LinkedIn.
                    code: directLinkedIn.notConnected
                linkedin_account_inactive:
                  summary: LinkedIn account is inactive
                  value:
                    title: Conflict
                    status: 409
                    detail: The specified LinkedIn account is inactive.
                    code: directLinkedIn.linkedInAccountInactive
        '429':
          description: |-
            Rate limit reached.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.dailyLimitReached` | Daily message limit reached |
            | `directLinkedIn.weeklyLimitReached` | Weekly message limit reached |
          headers:
            Retry-After:
              description: Seconds to wait before retrying
              schema:
                type: integer
                minimum: 1
          content:
            application/problem+json:
              schema:
                allOf:
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
              examples:
                daily_limit_reached:
                  summary: Daily limit reached
                  value:
                    title: Too Many Requests
                    status: 429
                    detail: The daily LinkedIn message limit has been reached.
                    code: directLinkedIn.dailyLimitReached
                weekly_limit_reached:
                  summary: Weekly limit reached
                  value:
                    title: Too Many Requests
                    status: 429
                    detail: The weekly LinkedIn message limit has been reached.
                    code: directLinkedIn.weeklyLimitReached
  /v3/contacts/{id}/send-direct-linkedin-voice:
    post:
      tags:
        - Direct Outreach
      operationId: SendDirectLinkedInVoice
      summary: Send a LinkedIn voice message to a contact
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Sends a pre-recorded voice message to the contact via LinkedIn outside of any sequence.
        The caller must already be connected with the contact on LinkedIn.
        Upload audio files via `POST /v3/attachments/voice` to obtain a `voiceAttachmentId`.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - linkedInAccountId
                - voiceAttachmentId
              properties:
                linkedInAccountId:
                  type: integer
                  description: ID of the LinkedIn account to send from. Must be greater than 0.
                voiceAttachmentId:
                  type: integer
                  description: ID of the uploaded voice attachment. Must be greater than 0.
      responses:
        '200':
          description: Voice message sent successfully.
          content:
            application/json:
              schema:
                type: object
                title: Send Direct LinkedIn Response
                description: Response returned after a direct LinkedIn action is dispatched.
                required: *ref_95
                properties: *ref_96
              example:
                actionType: voice
                linkedInActivityId: 1045
                sentAtUtc: '2026-05-15T10:33:00Z'
        '400':
          description: |-
            Validation failure on the route parameter or request body, or a business rule rejection.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.voiceProfileMissing` | Voice profile not configured on this LinkedIn account |
            | `directLinkedIn.voiceTooLong` | Voice attachment exceeds the allowed duration |
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Request body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /voiceAttachmentId
                        detail: '''voiceAttachmentId'' must be greater than ''0''.'
                voice_profile_missing:
                  summary: Voice profile not configured
                  value:
                    title: Bad Request
                    status: 400
                    detail: No voice profile is configured on this LinkedIn account.
                    code: directLinkedIn.voiceProfileMissing
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: LinkedIn direct actions feature is disabled for this account.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: LinkedIn direct actions feature is not enabled for this account.
                code: directLinkedIn.featureDisabled
        '404':
          description: Contact, LinkedIn profile, LinkedIn account, or voice attachment not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              examples:
                contact_not_found:
                  summary: Contact not found
                  value:
                    title: Not Found
                    status: 404
                    detail: Contact with ID 42 not found.
                    code: directLinkedIn.contactNotFound
                no_linkedin_profile:
                  summary: Contact has no LinkedIn profile URL
                  value:
                    title: Not Found
                    status: 404
                    detail: This contact does not have a LinkedIn profile URL set.
                    code: directLinkedIn.noLinkedInProfile
                linkedin_account_not_found:
                  summary: LinkedIn account not found
                  value:
                    title: Not Found
                    status: 404
                    detail: LinkedIn account not found or not accessible.
                    code: directLinkedIn.linkedInAccountNotFound
                voice_attachment_not_found:
                  summary: Voice attachment not found
                  value:
                    title: Not Found
                    status: 404
                    detail: Voice attachment not found.
                    code: directLinkedIn.voiceAttachmentNotFound
        '409':
          description: |-
            Conflict — the LinkedIn account state or connection status prevents the action.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.linkedInAccountInactive` | Specified LinkedIn account is inactive |
            | `directLinkedIn.invalidCookie` | LinkedIn account session cookie is invalid |
            | `directLinkedIn.notConnected` | Not connected with this contact on LinkedIn |
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              examples:
                not_connected:
                  summary: Not connected with this contact
                  value:
                    title: Conflict
                    status: 409
                    detail: You are not connected with this contact on LinkedIn.
                    code: directLinkedIn.notConnected
                linkedin_account_inactive:
                  summary: LinkedIn account is inactive
                  value:
                    title: Conflict
                    status: 409
                    detail: The specified LinkedIn account is inactive.
                    code: directLinkedIn.linkedInAccountInactive
        '429':
          description: |-
            Rate limit reached.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.dailyLimitReached` | Daily voice message limit reached |
            | `directLinkedIn.weeklyLimitReached` | Weekly voice message limit reached |
          headers:
            Retry-After:
              description: Seconds to wait before retrying
              schema:
                type: integer
                minimum: 1
          content:
            application/problem+json:
              schema:
                allOf:
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
              examples:
                daily_limit_reached:
                  summary: Daily limit reached
                  value:
                    title: Too Many Requests
                    status: 429
                    detail: The daily LinkedIn voice message limit has been reached.
                    code: directLinkedIn.dailyLimitReached
                weekly_limit_reached:
                  summary: Weekly limit reached
                  value:
                    title: Too Many Requests
                    status: 429
                    detail: The weekly LinkedIn voice message limit has been reached.
                    code: directLinkedIn.weeklyLimitReached
  /v3/contacts/{id}/send-direct-linkedin-ai-voice:
    post:
      tags:
        - Direct Outreach
      operationId: SendDirectLinkedInAiVoice
      summary: Send an AI-generated LinkedIn voice message to a contact
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Generates and sends an AI voice message to the contact via LinkedIn outside of any sequence.
        The caller must already be connected with the contact on LinkedIn.
        The voice is synthesized from the provided script using the account's text-to-speech settings.
      parameters:
        - name: id
          in: path
          required: true
          description: Contact ID
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - linkedInAccountId
                - script
              properties:
                linkedInAccountId:
                  type: integer
                  description: ID of the LinkedIn account to send from. Must be greater than 0.
                script:
                  type: string
                  maxLength: 1000
                  description: Text script to synthesize into an AI voice message.
      responses:
        '200':
          description: AI voice message sent successfully.
          content:
            application/json:
              schema:
                type: object
                title: Send Direct LinkedIn Response
                description: Response returned after a direct LinkedIn action is dispatched.
                required: *ref_95
                properties: *ref_96
              example:
                actionType: aiVoice
                linkedInActivityId: 1046
                sentAtUtc: '2026-05-15T10:34:00Z'
        '400':
          description: |-
            Validation failure on the route parameter or request body, or a business rule rejection.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.voiceTooLong` | Synthesized voice exceeds the allowed duration |
            | `directLinkedIn.missingVariables` | Script contains unresolved template variables |
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Request body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /script
                        detail: '''script'' must not be empty.'
                voice_too_long:
                  summary: Synthesized voice too long
                  value:
                    title: Bad Request
                    status: 400
                    detail: The synthesized voice message exceeds the allowed duration.
                    code: directLinkedIn.voiceTooLong
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: LinkedIn direct actions feature is disabled for this account.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: LinkedIn direct actions feature is not enabled for this account.
                code: directLinkedIn.featureDisabled
        '404':
          description: Contact, LinkedIn profile, or LinkedIn account not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              examples:
                contact_not_found:
                  summary: Contact not found
                  value:
                    title: Not Found
                    status: 404
                    detail: Contact with ID 42 not found.
                    code: directLinkedIn.contactNotFound
                no_linkedin_profile:
                  summary: Contact has no LinkedIn profile URL
                  value:
                    title: Not Found
                    status: 404
                    detail: This contact does not have a LinkedIn profile URL set.
                    code: directLinkedIn.noLinkedInProfile
                linkedin_account_not_found:
                  summary: LinkedIn account not found
                  value:
                    title: Not Found
                    status: 404
                    detail: LinkedIn account not found or not accessible.
                    code: directLinkedIn.linkedInAccountNotFound
        '409':
          description: |-
            Conflict — the LinkedIn account state or connection status prevents the action.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.linkedInAccountInactive` | Specified LinkedIn account is inactive |
            | `directLinkedIn.invalidCookie` | LinkedIn account session cookie is invalid |
            | `directLinkedIn.notConnected` | Not connected with this contact on LinkedIn |
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              examples:
                not_connected:
                  summary: Not connected with this contact
                  value:
                    title: Conflict
                    status: 409
                    detail: You are not connected with this contact on LinkedIn.
                    code: directLinkedIn.notConnected
                linkedin_account_inactive:
                  summary: LinkedIn account is inactive
                  value:
                    title: Conflict
                    status: 409
                    detail: The specified LinkedIn account is inactive.
                    code: directLinkedIn.linkedInAccountInactive
        '429':
          description: |-
            Rate limit reached.

            | `code` | Meaning |
            |---|---|
            | `directLinkedIn.dailyLimitReached` | Daily AI voice message limit reached |
            | `directLinkedIn.weeklyLimitReached` | Weekly AI voice message limit reached |
          headers:
            Retry-After:
              description: Seconds to wait before retrying
              schema:
                type: integer
                minimum: 1
          content:
            application/problem+json:
              schema:
                allOf:
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
              examples:
                daily_limit_reached:
                  summary: Daily limit reached
                  value:
                    title: Too Many Requests
                    status: 429
                    detail: The daily LinkedIn AI voice message limit has been reached.
                    code: directLinkedIn.dailyLimitReached
                weekly_limit_reached:
                  summary: Weekly limit reached
                  value:
                    title: Too Many Requests
                    status: 429
                    detail: The weekly LinkedIn AI voice message limit has been reached.
                    code: directLinkedIn.weeklyLimitReached
  /v3/email-accounts:
    get:
      tags:
        - Email Accounts
      summary: List email accounts
      x-required-scope: channels:read
      description: |-
        <small>_Requires the `channels:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to browse the email accounts you can send from. By default it returns every account visible to you, which in Public or Organization mode includes your teammates' accounts; pass my=true to see only your own. Results are returned as a page controlled by the top and skip query parameters; omit both to get the first page. To narrow the results by status, provider, domain, owner, or tag, use the filter endpoint instead.
      operationId: ListEmailAccounts
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: my
          in: query
          required: false
          description: |-
            When false (default), returns all email accounts visible to the authenticated user:
            - In Public or Organization mode: all team members' accounts.
            - In Private mode: only the team owner sees all accounts; regular members see only their own.
            When true, returns only the authenticated user's own email accounts regardless of team mode.
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: Paginated list of email accounts
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: EmailAccountListItem
                      description: Summary representation of an email account returned in list endpoints.
                      properties: &ref_101
                        id:
                          type: integer
                          format: int64
                          description: Unique identifier for the email account
                          readOnly: true
                        ownerUserId:
                          type: integer
                          description: ID of the user who owns this email account
                          readOnly: true
                        email:
                          type: string
                          format: email
                          description: The email address
                        senderName:
                          type: string
                          description: The name displayed as sender in recipient inboxes
                        emailAccountType:
                          type: string
                          description: |-
                            Provider type of the email account.
                            Values: custom, gmail, outlook, exchange, exchangeOnPremise
                          enum:
                            - custom
                            - gmail
                            - outlook
                            - exchange
                            - exchangeOnPremise
                          readOnly: true
                        isDefault:
                          type: boolean
                          description: Whether this is the user's default email account
                        dailyLimit:
                          type: integer
                          description: Maximum number of emails that can be sent per day
                        connectionStatus:
                          type: string
                          description: |-
                            Current connection status of the email account.
                            Values: unknown, connected, disconnected
                          enum:
                            - unknown
                            - connected
                            - disconnected
                          readOnly: true
                        tags:
                          type: array
                          items:
                            type: string
                          description: Tag names associated with this email account
                      example: &ref_102
                        id: 12345
                        ownerUserId: 42
                        email: john.doe@company.com
                        senderName: John Doe
                        emailAccountType: gmail
                        isDefault: true
                        dailyLimit: 500
                        connectionStatus: connected
                        tags:
                          - Marketing
                          - Outbound
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
              examples:
                with_results:
                  summary: Email accounts found
                  value:
                    items:
                      - id: 12345
                        ownerUserId: 42
                        email: john.doe@company.com
                        senderName: John Doe
                        emailAccountType: gmail
                        isDefault: true
                        dailyLimit: 500
                        connectionStatus: connected
                        tags:
                          - Marketing
                    hasMore: true
                empty_results:
                  summary: No email accounts
                  value:
                    items: []
                    hasMore: false
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Invalid requested page view
                code: emailAccount.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view email accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Email Accounts
      summary: Create an email account
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to connect a custom SMTP/IMAP mailbox to Reply. Gmail and Office 365 accounts cannot be created this way — start their OAuth flow with the matching connect endpoint instead. Supply the sending and receiving credentials along with any signature, safety, and ramp-up settings; the account is created under your ownership and returned with its assigned id. Validate credentials before committing to them with the SMTP and IMAP test endpoints.
      operationId: CreateEmailAccount
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: EmailAccountCreateRequest
              description: Request body for creating a new custom email account (SMTP/IMAP).
              properties: &ref_407
                connection:
                  type: object
                  title: EmailAccountConnectionSection
                  description: SMTP and IMAP connection settings for a custom email account. Only applicable to Custom provider type.
                  properties: &ref_105
                    email:
                      type: string
                      format: email
                      description: The email address
                    senderName:
                      type: string
                      description: The name displayed as sender in recipient inboxes
                    smtpHost:
                      type: string
                      description: Hostname or IP address of the SMTP server used for sending emails
                    smtpPort:
                      type: integer
                      minimum: 1
                      maximum: 65535
                      description: Port number for the SMTP server (typically 465 for SSL/TLS)
                    smtpPassword:
                      type: string
                      description: Password for SMTP authentication
                    smtpSsl:
                      type: boolean
                      default: true
                      description: Whether SSL/TLS is used for the SMTP connection
                    imapHost:
                      type: string
                      description: Hostname or IP address of the IMAP server used for receiving emails
                    imapPort:
                      type: integer
                      minimum: 1
                      maximum: 65535
                      description: Port number for the IMAP server (typically 993 for SSL/TLS)
                    imapPassword:
                      type: string
                      description: Password for IMAP authentication
                    imapSsl:
                      type: boolean
                      default: true
                      description: Whether SSL/TLS is used for the IMAP connection
                  required: &ref_106
                    - email
                    - smtpHost
                    - smtpPort
                    - smtpPassword
                    - imapHost
                    - imapPort
                    - imapPassword
                safety:
                  type: object
                  title: EmailAccountSafetySection
                  description: Sending safety and throttling configuration.
                  properties: &ref_97
                    dailyLimit:
                      type: integer
                      description: Maximum number of emails that can be sent per day
                    isEmailsThrottlingEnabled:
                      type: boolean
                      nullable: true
                      description: Whether email throttling is enabled
                    emailsPerInterval:
                      type: integer
                      format: int16
                      nullable: true
                      description: Number of emails allowed per throttling interval
                    emailsThrottlingSecondsInterval:
                      type: integer
                      format: int16
                      nullable: true
                      description: Length of the throttling interval in seconds
                    isSendingDelayEnabled:
                      type: boolean
                      nullable: true
                      description: Whether a random delay between emails is enabled
                    maxSendingDelaySeconds:
                      type: integer
                      nullable: true
                      description: Maximum delay in seconds between sent emails
                    minSendingDelaySeconds:
                      type: integer
                      nullable: true
                      description: Minimum delay in seconds between sent emails
                signature:
                  type: object
                  title: EmailAccountSignatureSection
                  description: Email signature configuration.
                  properties: &ref_98
                    signature:
                      type: string
                      nullable: true
                      description: HTML or plain-text signature appended to outgoing emails
                optOut:
                  type: object
                  title: EmailAccountOptOutSection
                  description: Opt-out / unsubscribe link configuration.
                  properties: &ref_99
                    message:
                      type: string
                      nullable: true
                      description: Opt-out message text
                    emailFooter:
                      type: string
                      nullable: true
                      description: Footer text appended to emails
                    isOptOutLinkEnabled:
                      type: boolean
                      description: Whether the opt-out link is included in emails
                    optOutTextBlock:
                      type: string
                      nullable: true
                      description: Custom opt-out text block content
                rampUp:
                  type: object
                  title: EmailAccountRampUpSection
                  description: Sending volume ramp-up configuration for warming up email accounts.
                  properties: &ref_100
                    enabled:
                      type: boolean
                      description: Whether sending ramp-up is enabled
                    startValue:
                      type: integer
                      description: Initial number of emails per day when ramp-up starts
                    incrementValue:
                      type: integer
                      description: Daily increase in email volume during ramp-up
                tags:
                  type: array
                  items:
                    type: string
                  description: Tag names to assign to the new email account
              required: &ref_408
                - connection
              example: &ref_409
                connection:
                  email: sales@company.com
                  senderName: Sales Team
                  smtpHost: smtp.company.com
                  smtpPort: 465
                  smtpPassword: secret123
                  smtpSsl: true
                  imapHost: imap.company.com
                  imapPort: 993
                  imapPassword: secret123
                  imapSsl: true
                safety:
                  dailyLimit: 500
                signature:
                  signature: |-
                    Best regards,
                    Sales Team
                optOut:
                  isOptOutLinkEnabled: true
                  optOutTextBlock: Unsubscribe here
                rampUp:
                  enabled: false
                  startValue: 10
                  incrementValue: 5
                tags:
                  - Outbound
      responses:
        '201':
          description: Email account created successfully
          content:
            application/json:
              schema:
                type: object
                title: EmailAccountDetail
                description: Full detailed representation of an email account, including all configuration sections.
                properties: &ref_103
                  id:
                    type: integer
                    format: int64
                    description: Unique identifier for the email account
                    readOnly: true
                  ownerUserId:
                    type: integer
                    description: ID of the user who owns this email account
                    readOnly: true
                  emailAccountType:
                    type: string
                    description: |-
                      Provider type of the email account.
                      Values: custom, gmail, outlook, exchange, exchangeOnPremise
                    enum:
                      - custom
                      - gmail
                      - outlook
                      - exchange
                      - exchangeOnPremise
                    readOnly: true
                  isDefault:
                    type: boolean
                    description: Whether this is the user's default email account
                    readOnly: true
                  isInUse:
                    type: boolean
                    description: Whether this email account is currently used in any active sequence
                    readOnly: true
                  connectionStatus:
                    type: string
                    description: |-
                      Current connection status of the email account.
                      Values: unknown, connected, disconnected
                    enum:
                      - unknown
                      - connected
                      - disconnected
                    readOnly: true
                  sendingConnectivityError:
                    type: string
                    nullable: true
                    description: Error details if SMTP sending connectivity has failed
                    readOnly: true
                  receivingConnectivityError:
                    type: string
                    nullable: true
                    description: Error details if IMAP receiving connectivity has failed
                    readOnly: true
                  sendingLockedByProvider:
                    type: boolean
                    description: Whether the email provider has locked outbound sending
                    readOnly: true
                  updatedAt:
                    type: string
                    format: date-time
                    description: Timestamp of the last update to this email account
                    readOnly: true
                  connection:
                    type: object
                    title: EmailAccountConnectionResponseSection
                    description: Connection settings returned in responses (passwords excluded).
                    properties: &ref_410
                      email:
                        type: string
                        format: email
                        description: The email address
                      senderName:
                        type: string
                        description: The name displayed as sender in recipient inboxes
                      smtpHost:
                        type: string
                        description: Hostname or IP address of the SMTP server
                      smtpPort:
                        type: integer
                        description: Port number for the SMTP server
                      smtpSsl:
                        type: boolean
                        description: Whether SSL/TLS is used for the SMTP connection
                      imapHost:
                        type: string
                        description: Hostname or IP address of the IMAP server
                      imapPort:
                        type: integer
                        description: Port number for the IMAP server
                      imapSsl:
                        type: boolean
                        description: Whether SSL/TLS is used for the IMAP connection
                  safety:
                    type: object
                    title: EmailAccountSafetySection
                    description: Sending safety and throttling configuration.
                    properties: *ref_97
                  signature:
                    type: object
                    title: EmailAccountSignatureSection
                    description: Email signature configuration.
                    properties: *ref_98
                  optOut:
                    type: object
                    title: EmailAccountOptOutSection
                    description: Opt-out / unsubscribe link configuration.
                    properties: *ref_99
                  rampUp:
                    type: object
                    title: EmailAccountRampUpSection
                    description: Sending volume ramp-up configuration for warming up email accounts.
                    properties: *ref_100
                  tags:
                    type: array
                    items:
                      type: string
                    description: Tag names associated with this email account
                example: &ref_104
                  id: 12345
                  ownerUserId: 42
                  emailAccountType: custom
                  isDefault: false
                  isInUse: true
                  connectionStatus: connected
                  sendingConnectivityError: null
                  receivingConnectivityError: null
                  sendingLockedByProvider: false
                  updatedAt: '2026-03-15T10:30:00Z'
                  connection:
                    email: john.doe@company.com
                    senderName: John Doe
                    smtpHost: smtp.company.com
                    smtpPort: 465
                    smtpSsl: true
                    imapHost: imap.company.com
                    imapPort: 993
                    imapSsl: true
                  safety:
                    dailyLimit: 500
                    isEmailsThrottlingEnabled: true
                    emailsPerInterval: 5
                    emailsThrottlingSecondsInterval: 60
                    isSendingDelayEnabled: true
                    maxSendingDelaySeconds: 120
                    minSendingDelaySeconds: 30
                  signature:
                    signature: |-
                      Best regards,
                      John Doe
                  optOut:
                    message: Unsubscribe
                    emailFooter: ''
                    isOptOutLinkEnabled: true
                    optOutTextBlock: Click here to unsubscribe
                  rampUp:
                    enabled: false
                    startValue: 10
                    incrementValue: 5
                  tags:
                    - Marketing
        '400':
          description: |-
            Validation failure on the request body, or a business rule rejection
            (e.g. invalid input on a domain field).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /email
                        detail: '''email'' is required.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Failed to create email account
                    code: emailAccount.internalError
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create email accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '409':
          description: Email account limit reached for the plan
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: You have reached the email account limit
                code: emailAccount.limitReached
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/filter:
    post:
      tags:
        - Email Accounts
      summary: Filter email accounts
      x-required-scope: channels:read
      description: |-
        <small>_Requires the `channels:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when a plain listing is too broad and you need email accounts matching specific criteria — status, provider type, exact email, domains, owners, or tags. Every filter field is optional, and an empty body matches the same set as the plain listing. Results are paged with the top and skip query parameters. When nothing matches, the response is an empty items array with hasMore false.
      operationId: FilterEmailAccounts
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: EmailAccountFilterRequest
              description: |-
                Filter criteria for searching email accounts.
                All provided filters are combined with AND logic — an account must match every specified filter to be included.
                Omitted (null) filters are ignored.
              properties: &ref_113
                status:
                  type: string
                  nullable: true
                  description: |-
                    Filter by connection status (case-insensitive, exact match).
                    Allowed values: connected, disconnected, unknown
                  enum:
                    - connected
                    - disconnected
                    - unknown
                emailAccountType:
                  type: string
                  nullable: true
                  description: |-
                    Filter by email account provider type (case-insensitive, exact match).
                    Allowed values: Custom, Gmail, Outlook, Exchange, ExchangeOnPremise
                email:
                  type: string
                  nullable: true
                  description: Filter by email address (exact match, case-insensitive)
                domains:
                  type: array
                  nullable: true
                  items:
                    type: string
                  description: |-
                    Filter by email domains (suffix match on the email address).
                    Multiple domains are combined with OR logic — matches any of the provided domains.
                ownerUserIds:
                  type: array
                  nullable: true
                  items:
                    type: integer
                  description: Filter by owner user IDs (matches any of the provided IDs)
                tags:
                  type: array
                  nullable: true
                  items:
                    type: string
                  description: Filter by tag names (case-insensitive, matches any of the provided tags)
              example: &ref_114
                status: connected
                emailAccountType: Gmail
                domains:
                  - company.com
                tags:
                  - Marketing
      responses:
        '200':
          description: Paginated list of matching email accounts
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: EmailAccountListItem
                      description: Summary representation of an email account returned in list endpoints.
                      properties: *ref_101
                      example: *ref_102
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
              examples:
                with_results:
                  summary: Matching accounts found
                  value:
                    items:
                      - id: 12345
                        ownerUserId: 42
                        email: john.doe@company.com
                        senderName: John Doe
                        emailAccountType: gmail
                        isDefault: true
                        dailyLimit: 500
                        connectionStatus: connected
                        tags:
                          - Marketing
                    hasMore: false
                empty_results:
                  summary: No matching accounts
                  value:
                    items: []
                    hasMore: false
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Invalid requested page view
                code: emailAccount.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view email accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/{id}:
    get:
      tags:
        - Email Accounts
      summary: Get an email account
      x-required-scope: channels:read
      description: |-
        <small>_Requires the `channels:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the full record of a single email account by its id — its connection, safety, signature, opt-out, and ramp-up sections, its tags, its current connection status with any connectivity errors, and whether it is the default account or in use by a sequence. The listing endpoints return a lighter summary of the same accounts.
      operationId: GetEmailAccount
      parameters:
        - name: id
          in: path
          required: true
          description: Email Account ID
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: Email account details
          content:
            application/json:
              schema:
                type: object
                title: EmailAccountDetail
                description: Full detailed representation of an email account, including all configuration sections.
                properties: *ref_103
                example: *ref_104
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this email account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '404':
          description: Email account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account with ID 42 not found
                code: emailAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    patch:
      tags:
        - Email Accounts
      summary: Update an email account
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to change specific settings on an existing email account without resending the whole record. Send at least one of the connection, safety, signature, optOut, rampUp, and tags sections; only the sections and fields you include are updated, and anything omitted is left unchanged. The connection section carries the SMTP/IMAP credentials, so it applies to custom mailboxes rather than OAuth-connected Gmail and Office 365 accounts. A safety daily limit above the ceiling allowed by your workspace plan is rejected.
      operationId: UpdateEmailAccount
      parameters:
        - name: id
          in: path
          required: true
          description: Email Account ID
          schema:
            type: integer
            format: int64
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: EmailAccountUpdateRequest
              description: |-
                Request body for partially updating an email account (PATCH).
                Only provide the sections and fields you want to change.
                Omitted sections and fields are left unchanged.
              properties: &ref_411
                connection:
                  type: object
                  title: EmailAccountConnectionSection
                  description: SMTP and IMAP connection settings for a custom email account. Only applicable to Custom provider type.
                  properties: *ref_105
                  required: *ref_106
                safety:
                  type: object
                  title: EmailAccountSafetySection
                  description: Sending safety and throttling configuration.
                  properties: *ref_97
                signature:
                  type: object
                  title: EmailAccountSignatureSection
                  description: Email signature configuration.
                  properties: *ref_98
                optOut:
                  type: object
                  title: EmailAccountOptOutSection
                  description: Opt-out / unsubscribe link configuration.
                  properties: *ref_99
                rampUp:
                  type: object
                  title: EmailAccountRampUpSection
                  description: Sending volume ramp-up configuration for warming up email accounts.
                  properties: *ref_100
                tags:
                  type: array
                  items:
                    type: string
                  description: Tag names to assign (replaces existing tags)
              example: &ref_412
                safety:
                  dailyLimit: 750
                signature:
                  signature: Updated signature
      responses:
        '200':
          description: Email account updated successfully
          content:
            application/json:
              schema:
                type: object
                title: EmailAccountDetail
                description: Full detailed representation of an email account, including all configuration sections.
                properties: *ref_103
                example: *ref_104
        '400':
          description: |-
            Validation failure on the request body or route parameter, or a business
            rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /email
                        detail: '''email'' must be a valid email address.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to update this email account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '404':
          description: Email account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account with ID 42 not found
                code: emailAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Email Accounts
      summary: Delete an email account
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to disconnect a single email account and remove it from Reply by its id. To remove several accounts in one call, use the bulk-delete endpoint instead.
      operationId: DeleteEmailAccount
      parameters:
        - name: id
          in: path
          required: true
          description: Email Account ID
          schema:
            type: integer
            format: int64
      responses:
        '204':
          description: Email account deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete this email account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '404':
          description: Email account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account with ID 42 not found
                code: emailAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/{id}/set-default:
    post:
      tags:
        - Email Accounts
      summary: Set default email account
      x-required-scope: channels:operate
      description: |-
        <small>_Requires the `channels:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to choose which of your email accounts Reply pre-selects for sending. Exactly one account is your default at a time, so setting a new one clears the flag on the previous account.
      operationId: SetDefaultEmailAccount
      parameters:
        - name: id
          in: path
          required: true
          description: Email Account ID to set as default
          schema:
            type: integer
            format: int64
      responses:
        '204':
          description: Default email account set successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to set default email account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '404':
          description: Email account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account with ID 42 not found
                code: emailAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/{id}/resume-sending:
    post:
      tags:
        - Email Accounts
      summary: Resume sending
      x-required-scope: channels:operate
      description: |-
        <small>_Requires the `channels:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when an email account has stopped sending because its provider locked or throttled it, and you have resolved the underlying problem. Clearing the lock lets the account pick its sequences back up. Check sendingLockedByProvider on the account record to see whether it is currently locked.
      operationId: ResumeSending
      parameters:
        - name: id
          in: path
          required: true
          description: Email Account ID
          schema:
            type: integer
            format: int64
      responses:
        '204':
          description: Sending resumed successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to resume sending
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '404':
          description: Email account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account with ID 42 not found
                code: emailAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/bulk-delete:
    post:
      tags:
        - Email Accounts
      summary: Bulk delete email accounts
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to disconnect several email accounts in one call. Accounts are processed one by one and successful deletions are kept even when others fail; the response returns only the account ids that were not deleted, each with its error details.
      operationId: BulkDeleteEmailAccounts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - ids
              properties:
                ids:
                  type: array
                  items:
                    type: integer
                    format: int64
                  description: Array of email account IDs to delete
              example:
                ids:
                  - 123
                  - 456
                  - 789
      responses:
        '200':
          description: |-
            Bulk operation completed. Response is a dictionary keyed by account ID.
            Only failed items appear in the dictionary; missing IDs were deleted successfully.
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /ids
                        detail: At least one ID must be provided.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: At least one ID must be provided
                    code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete email accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/connect/gmail:
    get:
      tags:
        - Email Accounts
      summary: Connect Gmail account via OAuth
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint to start connecting a Gmail mailbox. It responds with a 302 redirect to Google's consent screen, so follow the redirect in a browser rather than calling it from a backend client. The email account is created in Reply once the user finishes granting access — no create call is needed. If a connection attempt is already in progress for your account, the request is rejected.
      operationId: ConnectGmailAccount
      responses:
        '302':
          description: Redirect to Google OAuth consent page
        '400':
          description: OAuth connection already in progress
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Failed to get Gmail OAuth URL, already in progress connection
                code: emailAccount.internalError
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to connect Gmail accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/connect/office-365:
    get:
      tags:
        - Email Accounts
      summary: Connect Office 365 account via OAuth
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint to start connecting an Office 365 or Outlook mailbox. It responds with a 302 redirect to Microsoft's consent screen, so follow the redirect in a browser rather than calling it from a backend client. The email account is created in Reply once the user finishes granting access — no create call is needed. If a connection attempt is already in progress for your account, the request is rejected.
      operationId: ConnectOffice365Account
      responses:
        '302':
          description: Redirect to Microsoft OAuth consent page
        '400':
          description: OAuth connection already in progress
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Failed to get Exchange OAuth URL, already in progress connection
                code: emailAccount.internalError
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to connect Office 365 accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/test/smtp:
    post:
      tags:
        - Email Accounts
      summary: Test SMTP connectivity
      x-required-scope: channels:operate
      description: |-
        <small>_Requires the `channels:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint to check SMTP sending credentials before you commit to them. Nothing is created or changed — the response reports whether the connection succeeded and, when it did not, the error the server returned. A failed test still comes back as 200 with success false.
      operationId: TestSmtpConnectivity
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: ConnectivityTestRequest
              description: Request body for testing SMTP or IMAP connectivity.
              properties: &ref_107
                host:
                  type: string
                  description: Hostname or IP address of the mail server
                port:
                  type: integer
                  minimum: 1
                  maximum: 65535
                  description: Port number of the mail server
                enableSsl:
                  type: boolean
                  default: true
                  description: Whether to use SSL/TLS for the connection
                userName:
                  type: string
                  description: Username for authentication
                password:
                  type: string
                  description: Password for authentication
              required: &ref_108
                - host
                - port
                - userName
                - password
              example: &ref_109
                host: smtp.company.com
                port: 465
                enableSsl: true
                userName: user@company.com
                password: secret123
      responses:
        '200':
          description: Test result
          content:
            application/json:
              schema:
                type: object
                title: ConnectivityTestResponse
                description: Result of a mail server connectivity test.
                properties: &ref_110
                  success:
                    type: boolean
                    description: Whether the connection test was successful
                  error:
                    type: string
                    nullable: true
                    description: Error message if the test failed, null if successful
                required: &ref_111
                  - success
                example: &ref_112
                  success: true
                  error: null
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /host
                        detail: '''host'' is required.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to test connectivity
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/test/imap:
    post:
      tags:
        - Email Accounts
      summary: Test IMAP connectivity
      x-required-scope: channels:operate
      description: |-
        <small>_Requires the `channels:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint to check IMAP receiving credentials before you commit to them. Nothing is created or changed — the response reports whether the connection succeeded and, when it did not, the error the server returned. A failed test still comes back as 200 with success false.
      operationId: TestImapConnectivity
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: ConnectivityTestRequest
              description: Request body for testing SMTP or IMAP connectivity.
              properties: *ref_107
              required: *ref_108
              example: *ref_109
      responses:
        '200':
          description: Test result
          content:
            application/json:
              schema:
                type: object
                title: ConnectivityTestResponse
                description: Result of a mail server connectivity test.
                properties: *ref_110
                required: *ref_111
                example: *ref_112
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /host
                        detail: '''host'' is required.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to test connectivity
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/{id}/stats:
    get:
      tags:
        - Email Accounts
      summary: Get email account stats
      x-required-scope: channels:read
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `channels:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to know how much sending capacity a single email account has left — how many emails it has sent today, its configured daily limit, and its all-time sent total. To pull the same figures for many accounts at once, use the stats filter endpoint instead.
      operationId: GetEmailAccountStats
      parameters:
        - name: id
          in: path
          required: true
          description: Email Account ID
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: Email account stats
          content:
            application/json:
              schema:
                type: object
                required: &ref_115
                  - id
                  - emailsSentToday
                  - totalEmailsSent
                  - dailySendingLimit
                properties: &ref_116
                  id:
                    type: integer
                    format: int64
                    description: Email account ID
                  emailsSentToday:
                    type: integer
                    description: Number of emails sent today from this account
                  totalEmailsSent:
                    type: integer
                    description: Total number of emails sent from this account
                  dailySendingLimit:
                    type: integer
                    description: Maximum number of emails that can be sent per day
                example: &ref_117
                  id: 12345
                  emailsSentToday: 42
                  totalEmailsSent: 1580
                  dailySendingLimit: 500
        '400':
          description: Invalid email account ID
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Invalid request
                code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view email account stats
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '404':
          description: Email account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account with ID 42 not found
                code: emailAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/stats:
    post:
      tags:
        - Email Accounts
      summary: Filter email account stats
      x-required-scope: channels:read
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `channels:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need sending statistics for a set of email accounts rather than one — for example to spot mailboxes close to their daily limit. It takes the same filter as the account filter endpoint and returns a page of per-account figures controlled by the top and skip query parameters.
      operationId: FilterEmailAccountStats
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: EmailAccountFilterRequest
              description: |-
                Filter criteria for searching email accounts.
                All provided filters are combined with AND logic — an account must match every specified filter to be included.
                Omitted (null) filters are ignored.
              properties: *ref_113
              example: *ref_114
      responses:
        '200':
          description: Paginated list of email account stats
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      required: *ref_115
                      properties: *ref_116
                      example: *ref_117
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
              examples:
                with_results:
                  summary: Stats found
                  value:
                    items:
                      - id: 12345
                        emailsSentToday: 42
                        totalEmailsSent: 1580
                        dailySendingLimit: 500
                    hasMore: true
                empty_results:
                  summary: No matching accounts
                  value:
                    items: []
                    hasMore: false
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Invalid requested page view
                code: emailAccount.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view email account stats
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/tags:
    get:
      tags:
        - Email Accounts
      summary: List email account tags
      x-required-scope: channels:read
      description: |-
        <small>_Requires the `channels:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the email account tags available to you, each with its id, name, and color. Tags are referenced by name when you add or remove them on an account and when you filter accounts by tag; the id is what the tag update endpoint takes.
      operationId: ListEmailAccountTags
      responses:
        '200':
          description: List of tags
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: EmailAccountTag
                  description: An email account tag used for organizing and filtering accounts.
                  properties: &ref_413
                    id:
                      type: integer
                      description: Unique identifier for the tag
                      readOnly: true
                    name:
                      type: string
                      description: Tag display name
                    colorId:
                      type: integer
                      format: int16
                      description: Color identifier for the tag
                  example: &ref_414
                    id: 1
                    name: Marketing
                    colorId: 3
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view tags
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/tags/{tagId}:
    put:
      tags:
        - Email Accounts
      summary: Update a tag
      x-required-scope: channels:operate
      description: |-
        <small>_Requires the `channels:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to rename a tag or change its color. The change applies everywhere the tag is used, so every email account carrying it picks up the new name straight away.
      operationId: UpdateEmailAccountTag
      parameters:
        - name: tagId
          in: path
          required: true
          description: Tag ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: New tag name
                colorId:
                  type: integer
                  format: int16
                  description: New color identifier
              example:
                name: Sales
                colorId: 5
      responses:
        '204':
          description: Tag updated successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: tagId
                        detail: The 'tagId' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to update tags
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '404':
          description: Tag not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Tag with ID 5 not found
                code: emailAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-accounts/{id}/tags:
    post:
      tags:
        - Email Accounts
      summary: Add tags to an email account
      x-required-scope: channels:operate
      description: |-
        <small>_Requires the `channels:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to label an email account so you can group or filter by it later. Tags are supplied by name, and any name that does not exist yet is created for you — there is no separate create-tag call. Tags already on the account are left as they are.
      operationId: AddTagsToEmailAccount
      parameters:
        - name: id
          in: path
          required: true
          description: Email Account ID
          schema:
            type: integer
            format: int64
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                tags:
                  type: array
                  items:
                    type: string
                  description: Tag names to add
              example:
                tags:
                  - Marketing
                  - Outbound
      responses:
        '204':
          description: Tags added successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage email account tags
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '404':
          description: Email account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account with ID 42 not found
                code: emailAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Email Accounts
      summary: Remove tags from an email account
      x-required-scope: channels:operate
      description: |-
        <small>_Requires the `channels:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to take one or more tags off an email account. Tags are supplied by name and only the link to this account is removed — the tag itself stays available and keeps its other accounts.
      operationId: RemoveTagsFromEmailAccount
      parameters:
        - name: id
          in: path
          required: true
          description: Email Account ID
          schema:
            type: integer
            format: int64
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                tags:
                  type: array
                  items:
                    type: string
                  description: Tag names to remove
              example:
                tags:
                  - Outbound
      responses:
        '204':
          description: Tags removed successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: emailAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to manage email account tags
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailAccount] are denied for userId 123.
                code: emailAccount.forbidden
        '404':
          description: Email account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account with ID 42 not found
                code: emailAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-templates:
    get:
      tags:
        - Email Templates
      summary: List email templates
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of email templates for the authenticated user.
      operationId: ListEmailTemplates
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: name
          in: query
          required: false
          description: Filter templates by name (partial match)
          schema:
            type: string
        - name: folder_id
          in: query
          required: false
          description: Filter templates by folder ID
          schema:
            type: integer
        - name: folder_type
          in: query
          required: false
          description: Filter templates by folder type (e.g., "personal", "shared")
          schema:
            type: string
        - name: is_default
          in: query
          required: false
          description: Filter templates by default status
          schema:
            type: boolean
      responses:
        '200':
          description: Paginated list of email templates
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: EmailTemplateBase
                      description: Summary representation of an email template returned in list endpoints.
                      properties: &ref_415
                        id:
                          type: integer
                          description: Unique identifier for the email template
                          readOnly: true
                        name:
                          type: string
                          description: Name of the email template
                        subject:
                          type: string
                          nullable: true
                          description: Email subject line
                        body:
                          type: string
                          description: HTML body of the email template
                        folderId:
                          type: integer
                          nullable: true
                          description: ID of the folder containing this template
                        folderType:
                          type: string
                          nullable: true
                          description: Type of the folder (e.g., "personal", "shared")
                        attachments:
                          type: array
                          items:
                            type: object
                            title: EmailTemplateAttachment
                            description: Attachment associated with an email template.
                            properties: &ref_118
                              id:
                                type: integer
                                description: Unique identifier for the attachment
                                readOnly: true
                              fileName:
                                type: string
                                description: Original file name of the attachment
                              url:
                                type: string
                                description: URL to download the attachment
                              size:
                                type: integer
                                description: File size in bytes
                            example: &ref_119
                              id: 42
                              fileName: proposal.pdf
                              url: https://storage.example.com/attachments/proposal.pdf
                              size: 102400
                          description: List of attachments associated with the template
                      example: &ref_416
                        id: 101
                        name: Follow-up template
                        subject: Quick follow-up
                        body: <p>Hi {{firstName}},</p>
                        folderId: 5
                        folderType: personal
                        attachments: []
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page
        '400':
          description: Invalid pagination or filter parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: emailTemplate.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view email templates
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewEmailTemplate] are denied for userId 123.
                code: emailTemplate.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Email Templates
      summary: Create an email template
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates a new email template.
      operationId: CreateEmailTemplate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: EmailTemplateCreateRequest
              description: Request body for creating a new email template.
              properties: &ref_417
                name:
                  type: string
                  description: Name of the email template
                  maxLength: 255
                subject:
                  type: string
                  nullable: true
                  description: Email subject line
                body:
                  type: string
                  description: HTML body of the email template
                folderId:
                  type: integer
                  nullable: true
                  description: ID of the folder to place the template in
                folderType:
                  type: string
                  description: Type of the folder
                  enum:
                    - personal
                    - team
                attachmentIds:
                  type: array
                  items:
                    type: integer
                  maxItems: 3
                  description: List of previously uploaded attachment IDs to associate with the template
              required: &ref_418
                - name
                - body
                - folderType
              example: &ref_419
                name: Welcome email
                subject: Welcome to our service
                body: <p>Hello {{firstName}},</p><p>Welcome aboard!</p>
                folderId: 5
                folderType: personal
                attachmentIds:
                  - 42
                  - 43
      responses:
        '201':
          description: Email template created successfully
          content:
            application/json:
              schema:
                type: object
                title: EmailTemplate
                description: Full representation of an email template including timestamps.
                properties: &ref_120
                  id:
                    type: integer
                    description: Unique identifier for the email template
                    readOnly: true
                  name:
                    type: string
                    description: Name of the email template
                  subject:
                    type: string
                    nullable: true
                    description: Email subject line
                  body:
                    type: string
                    description: HTML body of the email template
                  folderId:
                    type: integer
                    nullable: true
                    description: ID of the folder containing this template
                  folderType:
                    type: string
                    nullable: true
                    description: Type of the folder (e.g., "personal", "shared")
                  attachments:
                    type: array
                    items:
                      type: object
                      title: EmailTemplateAttachment
                      description: Attachment associated with an email template.
                      properties: *ref_118
                      example: *ref_119
                    description: List of attachments associated with the template
                  createdAt:
                    type: string
                    format: date-time
                    description: Timestamp when the template was created
                    readOnly: true
                  updatedAt:
                    type: string
                    format: date-time
                    description: Timestamp when the template was last updated
                    readOnly: true
                example: &ref_121
                  id: 101
                  name: Follow-up template
                  subject: Quick follow-up
                  body: <p>Hi {{firstName}},</p>
                  folderId: 5
                  folderType: personal
                  attachments: []
                  createdAt: '2026-01-15T10:30:00Z'
                  updatedAt: '2026-02-20T14:00:00Z'
        '400':
          description: |-
            Validation failure on the request body, or a business rule rejection
            (e.g. too many attachments).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: '''name'' is required.'
                business_too_many_attachments:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Too many attachments
                    code: emailTemplate.tooManyAttachments
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create email templates
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailTemplate] are denied for userId 123.
                code: emailTemplate.forbidden
        '404':
          description: Referenced folder or attachment not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Folder not found
                code: emailTemplate.folderNotFound
        '409':
          description: An email template with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A template with this name already exists
                code: emailTemplate.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-templates/{id}:
    get:
      tags:
        - Email Templates
      summary: Get an email template
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns a single email template by ID.
      operationId: GetEmailTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: Email template ID
          schema:
            type: integer
      responses:
        '200':
          description: Email template details
          content:
            application/json:
              schema:
                type: object
                title: EmailTemplate
                description: Full representation of an email template including timestamps.
                properties: *ref_120
                example: *ref_121
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_filter:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid filter
                    code: emailTemplate.invalidFilter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this email template
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewEmailTemplate] are denied for userId 123.
                code: emailTemplate.forbidden
        '404':
          description: Email template not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email template with ID 42 not found
                code: emailTemplate.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Email Templates
      summary: Update an email template
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Updates an existing email template.
      operationId: UpdateEmailTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: Email template ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: EmailTemplateUpdateRequest
              description: Request body for updating an existing email template.
              properties: &ref_420
                name:
                  type: string
                  description: Name of the email template
                  maxLength: 255
                subject:
                  type: string
                  nullable: true
                  description: Email subject line
                body:
                  type: string
                  description: HTML body of the email template
                attachmentIds:
                  type: array
                  items:
                    type: integer
                  maxItems: 3
                  description: List of attachment IDs to associate with the template (replaces existing attachments)
              required: &ref_421
                - name
                - body
              example: &ref_422
                name: Updated welcome email
                subject: Welcome!
                body: <p>Hi {{firstName}},</p><p>Updated content.</p>
                attachmentIds:
                  - 42
      responses:
        '200':
          description: Email template updated successfully
          content:
            application/json:
              schema:
                type: object
                title: EmailTemplate
                description: Full representation of an email template including timestamps.
                properties: *ref_120
                example: *ref_121
        '400':
          description: |-
            Validation failure on the request body or route parameter, or a business
            rule rejection (e.g. too many attachments).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body or route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: '''name'' is required.'
                business_too_many_attachments:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Too many attachments
                    code: emailTemplate.tooManyAttachments
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to update this email template
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailTemplate] are denied for userId 123.
                code: emailTemplate.forbidden
        '404':
          description: Email template not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email template with ID 42 not found
                code: emailTemplate.notFound
        '409':
          description: An email template with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A template with this name already exists
                code: emailTemplate.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Email Templates
      summary: Delete an email template
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes an email template by ID.
      operationId: DeleteEmailTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: Email template ID
          schema:
            type: integer
      responses:
        '204':
          description: Email template deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_filter:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid filter
                    code: emailTemplate.invalidFilter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete this email template
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailTemplate] are denied for userId 123.
                code: emailTemplate.forbidden
        '404':
          description: Email template not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email template with ID 42 not found
                code: emailTemplate.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-templates/{id}/clone:
    post:
      tags:
        - Email Templates
      summary: Clone an email template
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates a copy of an existing email template.
      operationId: CloneEmailTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: Email template ID to clone
          schema:
            type: integer
      responses:
        '201':
          description: Email template cloned successfully
          content:
            application/json:
              schema:
                type: object
                title: EmailTemplate
                description: Full representation of an email template including timestamps.
                properties: *ref_120
                example: *ref_121
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_filter:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid filter
                    code: emailTemplate.invalidFilter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to clone email templates
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailTemplate] are denied for userId 123.
                code: emailTemplate.forbidden
        '404':
          description: Email template not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email template with ID 42 not found
                code: emailTemplate.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-templates/{id}/move:
    post:
      tags:
        - Email Templates
      summary: Move an email template
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Moves an email template to a different folder.
      operationId: MoveEmailTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: Email template ID to move
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: MoveEmailTemplateRequest
              description: Request body for moving an email template to a different folder.
              properties: &ref_423
                folderId:
                  type: integer
                  minimum: 1
                  description: ID of the target folder
                folderType:
                  type: string
                  description: Type of the target folder
                  enum:
                    - personal
                    - team
              required: &ref_424
                - folderId
                - folderType
              example: &ref_425
                folderId: 10
                folderType: team
      responses:
        '200':
          description: Email template moved successfully
          content:
            application/json:
              schema:
                type: object
                title: EmailTemplate
                description: Full representation of an email template including timestamps.
                properties: *ref_120
                example: *ref_121
        '400':
          description: |-
            Validation failure on the request body or route parameter, or a business
            rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body or route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /folderType
                        detail: '''folderType'' is required.'
                business_invalid_filter:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid filter
                    code: emailTemplate.invalidFilter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to move email templates
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailTemplate] are denied for userId 123.
                code: emailTemplate.forbidden
        '404':
          description: Email template or target folder not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Folder not found
                code: emailTemplate.folderNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-templates/{id}/render:
    post:
      tags:
        - Email Templates
      summary: Render an email template
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Renders an email template by substituting variables with actual contact data.
      operationId: RenderEmailTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: Email template ID to render
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: RenderEmailTemplateRequest
              description: Request body for rendering an email template with variable substitution.
              properties: &ref_426
                contactId:
                  type: integer
                  minimum: 1
                  description: ID of the contact whose data is used for variable substitution
                sequenceId:
                  type: integer
                  nullable: true
                  description: Optional sequence ID for sequence-specific variables
                emailAccountId:
                  type: integer
                  format: int64
                  nullable: true
                  description: Optional email account ID for sender-specific variables
              required: &ref_427
                - contactId
              example: &ref_428
                contactId: 500
                sequenceId: 12
                emailAccountId: 100
      responses:
        '200':
          description: Rendered template result
          content:
            application/json:
              schema:
                type: object
                title: RenderTemplateResult
                description: Result of rendering an email template with variable substitution.
                properties: &ref_431
                  subject:
                    type: string
                    nullable: true
                    description: Rendered email subject with variables replaced
                  body:
                    type: string
                    nullable: true
                    description: Rendered email body with variables replaced
                  isSuccess:
                    type: boolean
                    description: Whether the rendering completed successfully
                  errors:
                    type: array
                    items:
                      type: object
                      title: RenderError
                      description: An error encountered during template rendering.
                      properties: &ref_429
                        code:
                          type: integer
                          description: Error code identifying the type of rendering error
                        message:
                          type: string
                          description: Human-readable error message
                        variable:
                          type: string
                          nullable: true
                          description: Name of the unresolved variable (only present for code 13 — unresolved variable errors)
                      example: &ref_430
                        code: 13
                        message: One or more values for variables are missing or incorrect. Please check that variables in the email correspond to contact fields, including custom fields
                        variable: companyName
                    description: List of rendering errors (e.g., unresolved variables)
                example: &ref_432
                  subject: Hi John, quick follow-up
                  body: <p>Hi John,</p><p>Following up on our conversation.</p>
                  isSuccess: true
                  errors: []
        '400':
          description: |-
            Validation failure on the request body or route parameter, or a business
            rule rejection (e.g. template render failed).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body or route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactId
                        detail: '''contactId'' must be a positive.'
                business_render_failed:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Failed to render the template
                    code: emailTemplate.renderFailed
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to render email templates
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewEmailTemplate] are denied for userId 123.
                code: emailTemplate.forbidden
        '404':
          description: Email template or contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact not found
                code: emailTemplate.contactNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-templates/{id}/send-test:
    post:
      tags:
        - Email Templates
      summary: Send a test email
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Sends a test email using the specified template.
      operationId: SendTestEmailTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: Email template ID to send
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: SendTestEmailRequest
              description: Request body for sending a test email using a template.
              properties: &ref_433
                email:
                  type: string
                  format: email
                  description: Email address to send the test email to
                emailAccountId:
                  type: integer
                  format: int64
                  minimum: 1
                  description: ID of the email account to send the test email from
              required: &ref_434
                - email
                - emailAccountId
              example: &ref_435
                email: test@example.com
                emailAccountId: 100
      responses:
        '200':
          description: Test email sent successfully
        '400':
          description: |-
            Validation failure on the request body or route parameter, or a business
            rule rejection (e.g. test email send failed).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body or route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /email
                        detail: '''email'' must be a valid email address.'
                business_send_test_failed:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Failed to send test email
                    code: emailTemplate.sendTestFailed
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to send test emails
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [SendEmail] are denied for userId 123.
                code: emailTemplate.forbidden
        '404':
          description: Email template, email account, or contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account not found
                code: emailTemplate.emailAccountNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-templates/variables:
    get:
      tags:
        - Email Templates
      summary: Get template variables
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns all available template variables grouped by category (prospect, team, advanced).
      operationId: GetEmailTemplateVariables
      responses:
        '200':
          description: Available template variables
          content:
            application/json:
              schema:
                type: object
                title: EmailTemplateVariables
                description: Available template variables grouped by category.
                properties: &ref_436
                  prospect:
                    type: object
                    additionalProperties:
                      type: array
                      items:
                        type: object
                        title: VariableInfo
                        description: Information about a single template variable.
                        properties: &ref_122
                          key:
                            type: string
                            description: Variable key to use in templates (e.g., "{{firstName}}")
                          description:
                            type: string
                            description: Human-readable description of the variable
                        example: &ref_123
                          key: '{{firstName}}'
                          description: Contact's first name
                    description: Prospect-related template variables grouped by subcategory
                  team:
                    type: object
                    additionalProperties:
                      type: array
                      items:
                        type: object
                        title: VariableInfo
                        description: Information about a single template variable.
                        properties: *ref_122
                        example: *ref_123
                    description: Team-related template variables grouped by subcategory
                  advanced:
                    type: object
                    additionalProperties:
                      type: array
                      items:
                        type: object
                        title: VariableInfo
                        description: Information about a single template variable.
                        properties: *ref_122
                        example: *ref_123
                    description: Advanced template variables grouped by subcategory
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view template variables
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewEmailTemplate] are denied for userId 123.
                code: emailTemplate.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-template-folders:
    get:
      tags:
        - Email Templates
      summary: List email template folders
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns all email template folders for the authenticated user.
      operationId: ListEmailTemplateFolders
      responses:
        '200':
          description: List of email template folders
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: EmailTemplateFolder
                  description: An email template folder for organizing templates.
                  properties: &ref_124
                    id:
                      type: integer
                      description: Unique identifier for the folder
                      readOnly: true
                    name:
                      type: string
                      description: Name of the folder
                    folderType:
                      type: string
                      description: Type of the folder (e.g., "personal", "shared")
                    isDefault:
                      type: boolean
                      description: Whether this is a default folder
                  example: &ref_125
                    id: 5
                    name: Marketing templates
                    folderType: personal
                    isDefault: false
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view template folders
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewEmailTemplate] are denied for userId 123.
                code: emailTemplateFolder.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Email Templates
      summary: Create an email template folder
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates a new email template folder.
      operationId: CreateEmailTemplateFolder
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: EmailTemplateFolderCreateRequest
              description: Request body for creating a new email template folder.
              properties: &ref_437
                name:
                  type: string
                  description: Name of the folder
                  maxLength: 128
                folderType:
                  type: string
                  description: Type of the folder
                  enum:
                    - personal
                    - team
              required: &ref_438
                - name
                - folderType
              example: &ref_439
                name: Sales templates
                folderType: personal
      responses:
        '201':
          description: Email template folder created successfully
          content:
            application/json:
              schema:
                type: object
                title: EmailTemplateFolder
                description: An email template folder for organizing templates.
                properties: *ref_124
                example: *ref_125
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: '''name'' is required.'
                business_is_default:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Cannot modify the default folder
                    code: emailTemplateFolder.isDefault
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create template folders
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailTemplate] are denied for userId 123.
                code: emailTemplateFolder.forbidden
        '409':
          description: A folder with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A folder with this name already exists
                code: emailTemplateFolder.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-template-folders/{id}:
    get:
      tags:
        - Email Templates
      summary: Get an email template folder
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns a single email template folder by ID.
      operationId: GetEmailTemplateFolder
      parameters:
        - name: id
          in: path
          required: true
          description: Email template folder ID
          schema:
            type: integer
        - name: folder_type
          in: query
          required: true
          description: Type of the folder (e.g., "personal", "shared")
          schema:
            type: string
      responses:
        '200':
          description: Email template folder details
          content:
            application/json:
              schema:
                type: object
                title: EmailTemplateFolder
                description: An email template folder for organizing templates.
                properties: *ref_124
                example: *ref_125
        '400':
          description: Route/query-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: folder_type
                        detail: Query parameter 'folder_type' is required.
                business_is_default:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Cannot modify the default folder
                    code: emailTemplateFolder.isDefault
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this folder
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewEmailTemplate] are denied for userId 123.
                code: emailTemplateFolder.forbidden
        '404':
          description: Email template folder not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Folder with ID 5 not found
                code: emailTemplateFolder.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Email Templates
      summary: Update an email template folder
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Updates an existing email template folder.
      operationId: UpdateEmailTemplateFolder
      parameters:
        - name: id
          in: path
          required: true
          description: Email template folder ID
          schema:
            type: integer
        - name: folder_type
          in: query
          required: true
          description: Type of the folder (e.g., "personal", "shared")
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: EmailTemplateFolderUpdateRequest
              description: Request body for updating an email template folder.
              properties: &ref_440
                name:
                  type: string
                  description: New name for the folder
                  maxLength: 128
              required: &ref_441
                - name
              example: &ref_442
                name: Renamed folder
      responses:
        '200':
          description: Email template folder updated successfully
          content:
            application/json:
              schema:
                type: object
                title: EmailTemplateFolder
                description: An email template folder for organizing templates.
                properties: *ref_124
                example: *ref_125
        '400':
          description: |-
            Validation failure on the request body, route or query parameter, or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body or parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: '''name'' is required.'
                business_is_default:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Cannot modify the default folder
                    code: emailTemplateFolder.isDefault
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to update this folder
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailTemplate] are denied for userId 123.
                code: emailTemplateFolder.forbidden
        '404':
          description: Email template folder not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Folder with ID 5 not found
                code: emailTemplateFolder.notFound
        '409':
          description: A folder with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A folder with this name already exists
                code: emailTemplateFolder.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Email Templates
      summary: Delete an email template folder
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes an email template folder by ID.
      operationId: DeleteEmailTemplateFolder
      parameters:
        - name: id
          in: path
          required: true
          description: Email template folder ID
          schema:
            type: integer
        - name: folder_type
          in: query
          required: true
          description: Type of the folder (e.g., "personal", "shared")
          schema:
            type: string
      responses:
        '204':
          description: Email template folder deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route/query-parameter validation failure, or a business rule rejection
            (e.g. attempting to delete the default folder).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: folder_type
                        detail: Query parameter 'folder_type' is required.
                business_is_default:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Cannot delete the default folder
                    code: emailTemplateFolder.isDefault
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete this folder
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailTemplate] are denied for userId 123.
                code: emailTemplateFolder.forbidden
        '404':
          description: Email template folder not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Folder with ID 5 not found
                code: emailTemplateFolder.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-template-folders/{id}/share:
    post:
      tags:
        - Email Templates
      summary: Share an email template folder
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Shares a personal email template folder with the team.
      operationId: ShareEmailTemplateFolder
      parameters:
        - name: id
          in: path
          required: true
          description: Email template folder ID to share
          schema:
            type: integer
      responses:
        '200':
          description: Email template folder shared successfully
          content:
            application/json:
              schema:
                type: object
                title: EmailTemplateFolder
                description: An email template folder for organizing templates.
                properties: *ref_124
                example: *ref_125
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_is_default:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Cannot share the default folder
                    code: emailTemplateFolder.isDefault
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to share folders
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailTemplate] are denied for userId 123.
                code: emailTemplateFolder.forbidden
        '404':
          description: Email template folder not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Folder with ID 5 not found
                code: emailTemplateFolder.notFound
        '409':
          description: Folder is already shared
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Folder is already shared
                code: emailTemplateFolder.alreadyShared
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-template-attachments:
    post:
      tags:
        - Email Templates
      summary: Upload a template attachment
      description: Uploads a file to be used as an email template attachment. Returns the attachment metadata including the ID to use when creating or updating templates.
      operationId: UploadEmailTemplateAttachment
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
                  description: The file to upload
              required:
                - file
      responses:
        '201':
          description: Attachment uploaded successfully
          content:
            application/json:
              schema:
                type: object
                title: EmailTemplateAttachment
                description: Attachment associated with an email template.
                properties: *ref_118
                example: *ref_119
        '400':
          description: File is missing or empty
          content:
            application/problem+json:
              schema:
                type: object
                title: Problem Details
                description: |-
                  Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                  that don't carry domain context: 401 Unauthorized (auth middleware),
                  429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                  415 (framework middleware).

                  Business and validation responses extend this envelope and add additional
                  fields — see `business-problem.model.yaml` (adds `code` slug) and
                  `validation-problem.model.yaml` (adds `errors[]` array).
                properties: *ref_1
              example:
                title: Invalid request parameter
                status: 400
                detail: File is required.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to upload attachments
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageEmailTemplate] are denied for userId 123.
                code: emailTemplateAttachment.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-validations/estimate:
    post:
      tags:
        - Email Validations
      operationId: EstimateEmailValidation
      summary: Estimate email validation
      x-required-scope: contacts:read
      description: |-
        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Synchronous probe — given a list of contact IDs, returns counts, credit sufficiency, and any blockers that would prevent scheduling. Useful for showing pre-flight feedback in the UI before triggering `/schedule`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Email Validation Request
              description: Request body shared by both `/estimate` and `/schedule`. Specifies the contacts to validate and an optional partial-credit acceptance flag.
              required: &ref_126
                - contactIds
              properties: &ref_127
                contactIds:
                  type: array
                  description: Contact IDs to validate. Must be non-empty, contain at most 10000 items, and every value must be a positive integer.
                  items:
                    type: integer
                    minimum: 1
                  minItems: 1
                  maxItems: 10000
                acceptPartial:
                  type: boolean
                  nullable: true
                  description: When `true`, the schedule call proceeds with `min(eligibleCount, creditsAvailable)` contacts even if available credits are below the eligible count. When `false` (default), insufficient credits become a `NotEnoughCredits` blocker on `/estimate` and a `400` on `/schedule`.
      responses:
        '200':
          description: Estimate computed successfully
          content:
            application/json:
              schema:
                type: object
                title: Email Validation Estimate
                description: Synchronous probe result returned by `/v3/email-validations/estimate`. Reports counts, credit sufficiency, and a list of blockers that prevent scheduling.
                properties: &ref_444
                  requestedCount:
                    type: integer
                    description: Total number of contact IDs in the request body
                    readOnly: true
                  eligibleCount:
                    type: integer
                    description: Number of contacts the user can actually validate (filtered by team scope and validation-status)
                    readOnly: true
                  creditsAvailable:
                    type: integer
                    description: Email-validation credits currently available to the team
                    readOnly: true
                  creditsRequired:
                    type: integer
                    description: Credits that would be charged if the eligible contacts are scheduled in full
                    readOnly: true
                  creditsSufficient:
                    type: boolean
                    description: Whether `creditsAvailable >= creditsRequired`
                    readOnly: true
                  canSchedule:
                    type: boolean
                    description: Whether the request can be scheduled — equivalent to `blockers.length == 0`
                    readOnly: true
                  blockers:
                    type: array
                    description: Reasons why scheduling is currently blocked. Empty when `canSchedule` is `true`.
                    items:
                      type: integer
                      title: Email Validation Blocker
                      description: |-
                        Blocker codes returned by `/v3/email-validations/estimate` in the `blockers` array. The presence of any blocker (with `acceptPartial = false`) means the request cannot be scheduled.

                        | Value | Name | Meaning |
                        |---|---|---|
                        | 1 | `FeatureDisabled` | Email validation feature is disabled for the team |
                        | 2 | `AddonNotPresent` | Required addon is not on the subscription |
                        | 3 | `AlreadyRunning` | Another email-validation job is already running for this user |
                        | 4 | `OutOfCredits` | User has no email-validation credits available |
                        | 5 | `NotEnoughCredits` | Available credits are below the eligible-contact count (and `acceptPartial = false`) |
                        | 6 | `NoEligibleContacts` | No accessible contacts in `RequiresValidation` state were found in the request |
                      enum: &ref_443
                        - 1
                        - 2
                        - 3
                        - 4
                        - 5
                        - 6
                    readOnly: true
        '400':
          description: |-
            Validation failure on the request body, or a service-level
            rejection (e.g. an empty or oversized contact-id list).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactIds
                        detail: At least one contact id is required.
                business_invalid_input:
                  summary: Service-level invalid input
                  value:
                    title: Bad Request
                    status: 400
                    detail: Contact id list is invalid.
                    code: emailValidation.unknown
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/email-validations/schedule:
    post:
      tags:
        - Email Validations
      operationId: ScheduleEmailValidation
      summary: Schedule email validation
      x-required-scope: contacts:operate
      description: |-
        <small>_Requires the `contacts:operate` scope (or a broader one that includes it)._</small>

        Schedules an asynchronous email-validation job for the supplied contact IDs. Returns `202 Accepted` with a `Location` header pointing at `/v3/background-jobs/{jobId}` — poll that endpoint for status and the eventual result.

        The eligibility filter (team scope + `RequiresValidation` status) and the credits cap applied here mirror the `/estimate` semantics. Set `acceptPartial = true` to schedule whatever credits allow when the team's balance is below the eligible count.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Email Validation Request
              description: Request body shared by both `/estimate` and `/schedule`. Specifies the contacts to validate and an optional partial-credit acceptance flag.
              required: *ref_126
              properties: *ref_127
      responses:
        '202':
          description: Job scheduled successfully
          headers:
            Location:
              schema:
                type: string
              description: Path of the corresponding background job, relative to the API root (`v3/background-jobs/{jobId}`)
          content:
            application/json:
              schema:
                type: object
                title: Email Validation Schedule
                description: Acknowledgement returned by `/v3/email-validations/schedule`. The `jobId` corresponds to a background job — poll `/v3/background-jobs/{jobId}` for status and result.
                properties: &ref_445
                  jobId:
                    type: string
                    format: uuid
                    description: Background-job identifier — use with `/v3/background-jobs/{jobId}` to poll status
                    readOnly: true
                  scheduledCount:
                    type: integer
                    description: Number of contacts scheduled for validation (capped by available credits when `acceptPartial = true`)
                    readOnly: true
                  creditsReserved:
                    type: integer
                    description: Credits held against the team's quota for this job. Released for any contacts whose validation does not succeed.
                    readOnly: true
        '400':
          description: |-
            Validation failure on the request body, or a business rule
            rejection (no eligible contacts, insufficient credits with
            `acceptPartial = false`, etc.).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactIds
                        detail: At least one contact id is required.
                business_not_enough_credits:
                  summary: Insufficient credits for the eligible contacts
                  value:
                    title: Bad Request
                    status: 400
                    detail: User does not have enough credits to validate all eligible contacts.
                    code: emailValidation.unknown
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Email validation is forbidden — feature disabled, missing addon, or the request includes contacts the user does not have scope to validate.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: User is not allowed to validate emails for these contacts.
                code: emailValidation.forbidden
        '409':
          description: Another email-validation job is already running for this user
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Another email-validation job is already running for this user.
                code: emailValidation.alreadyRunning
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
        '503':
          description: Background-jobs service is temporarily unavailable
          content:
            application/problem+json:
              schema:
                allOf: *ref_74
              example:
                title: Service Unavailable
                status: 503
                detail: Background-jobs service is temporarily unavailable.
                code: emailValidation.lroUnavailable
  /v3/holiday-calendars:
    get:
      tags:
        - Holiday Calendars
      summary: List holiday calendars
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns all holiday calendars available to the authenticated user, including predefined and custom calendars.
      operationId: ListHolidayCalendars
      responses:
        '200':
          description: List of holiday calendars
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: HolidayCalendarBase
                  description: Summary representation of a holiday calendar returned in list endpoints.
                  properties: &ref_446
                    id:
                      type: integer
                      description: Unique identifier for the holiday calendar
                      readOnly: true
                    name:
                      type: string
                      description: Name of the holiday calendar
                    calendarType:
                      type: string
                      description: Type of calendar (e.g., "predefined", "custom")
                    countryCode:
                      type: string
                      description: ISO 3166-1 alpha-2 country code
                  example: &ref_447
                    id: 3
                    name: US Holidays
                    calendarType: predefined
                    countryCode: US
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view holiday calendars
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewScheduler] are denied for userId 123
                code: holidayCalendar.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Holiday Calendars
      summary: Create a holiday calendar
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates a new custom holiday calendar.
      operationId: CreateHolidayCalendar
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: HolidayCalendarCreateRequest
              description: Request body for creating a new custom holiday calendar.
              properties: &ref_448
                name:
                  type: string
                  description: Name of the holiday calendar
                repeatEveryYear:
                  type: boolean
                  description: Whether the holidays should repeat annually
                holidays:
                  type: array
                  items:
                    type: object
                    title: HolidayInput
                    description: A holiday entry for creating or updating a calendar.
                    properties: &ref_130
                      startDate:
                        type: string
                        format: date
                        description: Start date of the holiday
                      endDate:
                        type: string
                        format: date
                        description: End date of the holiday
                      name:
                        type: string
                        description: Name of the holiday
                    required: &ref_131
                      - startDate
                      - endDate
                      - name
                    example: &ref_132
                      startDate: '2026-12-25'
                      endDate: '2026-12-25'
                      name: Christmas Day
                  description: List of holidays to include in the calendar
              required: &ref_449
                - name
              example: &ref_450
                name: Company Holidays 2026
                repeatEveryYear: false
                holidays:
                  - startDate: '2026-07-04'
                    endDate: '2026-07-04'
                    name: Independence Day
                  - startDate: '2026-12-24'
                    endDate: '2026-12-26'
                    name: Christmas Break
      responses:
        '201':
          description: Holiday calendar created successfully
          content:
            application/json:
              schema:
                type: object
                title: HolidayCalendar
                description: Full representation of a holiday calendar including individual holidays.
                properties: &ref_128
                  id:
                    type: integer
                    description: Unique identifier for the holiday calendar
                    readOnly: true
                  name:
                    type: string
                    description: Name of the holiday calendar
                  calendarType:
                    type: string
                    description: Type of calendar (e.g., "predefined", "custom")
                  countryCode:
                    type: string
                    description: ISO 3166-1 alpha-2 country code
                  repeatEveryYear:
                    type: boolean
                    description: Whether the holidays repeat annually
                  holidays:
                    type: array
                    items:
                      type: object
                      title: Holiday
                      description: A single holiday entry within a calendar.
                      properties: &ref_451
                        id:
                          type: integer
                          format: int64
                          description: Unique identifier for the holiday
                          readOnly: true
                        startDate:
                          type: string
                          format: date
                          description: Start date of the holiday
                        endDate:
                          type: string
                          format: date
                          description: End date of the holiday
                        name:
                          type: string
                          description: Name of the holiday
                      example: &ref_452
                        id: 100
                        startDate: '2026-12-25'
                        endDate: '2026-12-25'
                        name: Christmas Day
                    description: List of holidays in this calendar
                example: &ref_129
                  id: 3
                  name: US Holidays
                  calendarType: custom
                  countryCode: US
                  repeatEveryYear: true
                  holidays:
                    - id: 100
                      startDate: '2026-12-25'
                      endDate: '2026-12-25'
                      name: Christmas Day
        '400':
          description: Validation error
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /name
                    detail: '''Name'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create holiday calendars
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageScheduler] are denied for userId 123
                code: holidayCalendar.forbidden
        '409':
          description: A holiday calendar with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A calendar with the name 'US Holidays' already exists
                code: holidayCalendar.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/holiday-calendars/{id}:
    get:
      tags:
        - Holiday Calendars
      summary: Get a holiday calendar
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns a single holiday calendar by ID, including its holidays.
      operationId: GetHolidayCalendar
      parameters:
        - name: id
          in: path
          required: true
          description: Holiday calendar ID
          schema:
            type: integer
      responses:
        '200':
          description: Holiday calendar details
          content:
            application/json:
              schema:
                type: object
                title: HolidayCalendar
                description: Full representation of a holiday calendar including individual holidays.
                properties: *ref_128
                example: *ref_129
        '400':
          description: Invalid id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view holiday calendars
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewScheduler] are denied for userId 123
                code: holidayCalendar.forbidden
        '404':
          description: Holiday calendar not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Holiday calendar with ID 5 not found
                code: holidayCalendar.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Holiday Calendars
      summary: Update a holiday calendar
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Updates an existing custom holiday calendar. Only custom calendars can be updated.
      operationId: UpdateHolidayCalendar
      parameters:
        - name: id
          in: path
          required: true
          description: Holiday calendar ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: HolidayCalendarUpdateRequest
              description: Request body for updating an existing custom holiday calendar.
              properties: &ref_453
                name:
                  type: string
                  description: Name of the holiday calendar
                repeatEveryYear:
                  type: boolean
                  description: Whether the holidays should repeat annually
                holidays:
                  type: array
                  items:
                    type: object
                    title: HolidayInput
                    description: A holiday entry for creating or updating a calendar.
                    properties: *ref_130
                    required: *ref_131
                    example: *ref_132
                  description: List of holidays (replaces all existing holidays)
              required: &ref_454
                - name
              example: &ref_455
                name: Company Holidays 2026 (Updated)
                repeatEveryYear: true
                holidays:
                  - startDate: '2026-07-04'
                    endDate: '2026-07-04'
                    name: Independence Day
      responses:
        '200':
          description: Holiday calendar updated successfully
          content:
            application/json:
              schema:
                type: object
                title: HolidayCalendar
                description: Full representation of a holiday calendar including individual holidays.
                properties: *ref_128
                example: *ref_129
        '400':
          description: Invalid id parameter or request body validation error
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /name
                    detail: '''Name'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Cannot modify predefined (non-custom) calendars, or user lacks scope
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                not_custom:
                  summary: Calendar is predefined and cannot be modified
                  value:
                    title: Forbidden
                    status: 403
                    detail: Cannot modify holiday calendar with ID 5
                    code: holidayCalendar.notCustomCalendar
                forbidden_scope:
                  summary: User lacks the required feature scope
                  value:
                    title: Forbidden
                    status: 403
                    detail: Feature scopes [ManageScheduler] are denied for userId 123
                    code: holidayCalendar.forbidden
        '404':
          description: Holiday calendar not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Holiday calendar with ID 5 not found
                code: holidayCalendar.notFound
        '409':
          description: A holiday calendar with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A calendar with the name 'US Holidays' already exists
                code: holidayCalendar.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Holiday Calendars
      summary: Delete a holiday calendar
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes a custom holiday calendar. Only custom calendars can be deleted.
      operationId: DeleteHolidayCalendar
      parameters:
        - name: id
          in: path
          required: true
          description: Holiday calendar ID
          schema:
            type: integer
      responses:
        '204':
          description: Holiday calendar deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Cannot delete predefined (non-custom) calendars, or user lacks scope
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                not_custom:
                  summary: Calendar is predefined and cannot be deleted
                  value:
                    title: Forbidden
                    status: 403
                    detail: Cannot delete holiday calendar with ID 5
                    code: holidayCalendar.notCustomCalendar
                forbidden_scope:
                  summary: User lacks the required feature scope
                  value:
                    title: Forbidden
                    status: 403
                    detail: Feature scopes [ManageScheduler] are denied for userId 123
                    code: holidayCalendar.forbidden
        '404':
          description: Holiday calendar not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Holiday calendar with ID 5 not found
                code: holidayCalendar.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/holiday-calendars/{id}/export-csv:
    get:
      tags:
        - Holiday Calendars
      summary: Export a holiday calendar as CSV
      x-required-scope: sequences:read
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by early August 2026.
        </Warning>

        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Exports the holidays of a calendar as a CSV file. The response filename matches the calendar name.
      operationId: ExportHolidayCalendarCsv
      parameters:
        - name: id
          in: path
          required: true
          description: Holiday calendar ID
          schema:
            type: integer
      responses:
        '200':
          description: CSV file containing the calendar's holidays
          content:
            text/csv:
              schema:
                type: string
                format: binary
          headers:
            Content-Disposition:
              description: Attachment filename, e.g. `attachment; filename="US Holidays.csv"`
              schema:
                type: string
        '400':
          description: Invalid id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Holiday calendar not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Holiday calendar with ID 5 not found
                code: holidayCalendar.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads:
    get:
      tags:
        - Inbox
      operationId: ListInboxThreads
      summary: List inbox threads
      x-required-scope: inbox:read
      description: |-
        <small>_Requires the `inbox:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to browse your inbox — the email and LinkedIn conversations with your contacts, most recently active first. Results are returned as a page controlled by the top and skip query parameters; omit both to get the first page. To narrow the list by channel, sequence, category, date range, or free text, use the filter endpoint instead.
      parameters:
        - in: query
          name: top
          schema:
            type: integer
            minimum: 1
            maximum: 1000
          description: Maximum items to return. Defaults to the server-side default page size when omitted.
        - in: query
          name: skip
          schema:
            type: integer
            minimum: 0
          description: Items to skip from the start of the result set.
      responses:
        '200':
          description: Inbox threads page
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - hasMore
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Inbox Thread List Item
                      description: Lightweight thread shape returned from list and filter endpoints — omits the message body history in favour of a `bodyPreview`.
                      required: &ref_139
                        - id
                        - channel
                        - isRead
                        - lastActivityDate
                        - isLastMessagePlanned
                        - contact
                        - hasMeetingIntent
                        - status
                      properties: &ref_140
                        id:
                          type: integer
                        channel:
                          type: string
                          enum:
                            - unknown
                            - email
                            - linkedIn
                        isRead:
                          type: boolean
                        subject:
                          type: string
                          nullable: true
                          description: Subject of the last message in the thread (email only).
                        bodyPreview:
                          type: string
                          nullable: true
                          description: Truncated body of the last message in the thread.
                        lastActivityDate:
                          type: string
                          format: date-time
                        isLastMessagePlanned:
                          type: boolean
                          description: True when the last message in the thread is a scheduled outbound message that has not yet been sent.
                        contact:
                          type: object
                          title: Inbox Thread Contact
                          description: |-
                            Contact party on the other end of an inbox thread.

                            Two shapes are possible, distinguished by the `isDeleted` flag:

                            - **Live contact** (`isDeleted: false`) — `id` and `ownerId` reference the live contact record; `fullName`, `email`, `linkedInProfileUrl`, `phone`, `companyName`, `title` come from the live record (any may still be `null` if the corresponding field is unset on the contact, e.g. `email` is `null` for a LinkedIn-only contact).
                            - **Deleted contact** (`isDeleted: true`) — the underlying contact record has been removed, so `id` and `ownerId` are `null`. The remaining identifying fields (`fullName`, `email`, `linkedInProfileUrl`, `phone`, `companyName`, `title`) are populated from the snapshot stored on the thread when it was created — typically enough for the user to recognise *who* the thread was with even though the contact no longer exists in their workspace.
                          required: &ref_141
                            - isDeleted
                          properties: &ref_142
                            id:
                              type: integer
                              nullable: true
                              description: Contact id. `null` when the contact has been deleted.
                            ownerId:
                              type: integer
                              nullable: true
                              description: User id of the contact's owner. `null` when the contact has been deleted.
                            fullName:
                              type: string
                              nullable: true
                              description: Display name. May still be populated from the thread snapshot when the contact has been deleted.
                            email:
                              type: string
                              nullable: true
                              description: Contact email address. `null` for LinkedIn-only contacts.
                            linkedInProfileUrl:
                              type: string
                              nullable: true
                              description: LinkedIn profile URL. `null` for email-only contacts.
                            phone:
                              type: string
                              nullable: true
                            companyName:
                              type: string
                              nullable: true
                            title:
                              type: string
                              nullable: true
                            isDeleted:
                              type: boolean
                              description: '`true` when the underlying contact record has been deleted from the workspace. In that case `id` and `ownerId` are `null` and the remaining identifying fields reflect the snapshot stored on the thread when the message arrived; `false` when the contact is still present and `id` / `ownerId` reference the live record.'
                        sequence:
                          type: object
                          allOf:
                            - type: object
                              title: Inbox Thread Sequence
                              description: Minimal sequence reference attached to an inbox thread.
                              required: *ref_133
                              properties: *ref_134
                          nullable: true
                        category:
                          type: object
                          allOf:
                            - type: object
                              title: Inbox Thread Category Reference
                              description: Minimal category reference embedded in thread responses.
                              required: *ref_135
                              properties: *ref_136
                          nullable: true
                        hasMeetingIntent:
                          type: boolean
                        status:
                          type: object
                          title: Inbox Thread Status
                          description: Aggregated thread state, derived from the latest message.
                          required: *ref_137
                          properties: *ref_138
                  hasMore:
                    type: boolean
              examples:
                mixed_threads:
                  summary: A page with email + LinkedIn threads, including one whose contact was deleted
                  value:
                    items:
                      - id: 58217
                        channel: email
                        isRead: false
                        subject: 'Re: Pricing for Q3 rollout'
                        bodyPreview: Thanks — does Tuesday at 10am work for a quick call?
                        lastActivityDate: '2026-05-07T14:32:11Z'
                        isLastMessagePlanned: false
                        contact:
                          id: 9821
                          ownerId: 42
                          fullName: Daria Kovalenko
                          email: daria.kovalenko@northwind.example
                          linkedInProfileUrl: https://www.linkedin.com/in/daria-kovalenko
                          phone: '+380501234567'
                          companyName: Northwind Logistics
                          title: VP of Operations
                          isDeleted: false
                        sequence:
                          id: 314
                          name: Q3 Outbound — Logistics ICP
                        category:
                          id: 7
                          name: Hot Leads
                        hasMeetingIntent: true
                        status:
                          state: ok
                      - id: 58198
                        channel: linkedIn
                        isRead: true
                        subject: null
                        bodyPreview: Sounds good, sending over the deck.
                        lastActivityDate: '2026-05-07T09:14:02Z'
                        isLastMessagePlanned: false
                        contact:
                          id: null
                          ownerId: null
                          fullName: Marcus Lee
                          email: null
                          linkedInProfileUrl: https://www.linkedin.com/in/marcus-lee-rev
                          phone: null
                          companyName: Helix Robotics
                          title: Head of Revenue
                          isDeleted: true
                        hasMeetingIntent: false
                        status:
                          state: ok
                      - id: 58104
                        channel: email
                        isRead: true
                        subject: Out of office
                        bodyPreview: I'm out until May 14 with limited email access…
                        lastActivityDate: '2026-05-06T18:02:55Z'
                        isLastMessagePlanned: false
                        contact:
                          id: 9744
                          ownerId: 42
                          fullName: Anya Petrov
                          email: anya.petrov@vector-bio.example
                          linkedInProfileUrl: null
                          phone: null
                          companyName: Vector Bio
                          title: Director of Demand Gen
                          isDeleted: false
                        sequence:
                          id: 287
                          name: Bio ICP — Demand Gen
                        hasMeetingIntent: false
                        status:
                          state: ok
                    hasMore: true
                empty:
                  summary: No threads
                  value:
                    items: []
                    hasMore: false
        '400':
          description: Invalid pagination parameters.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Invalid pagination parameters.
                code: inboxThread.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads/filter:
    post:
      tags:
        - Inbox
      operationId: FilterInboxThreads
      summary: Filter inbox threads
      x-required-scope: inbox:read
      description: |-
        <small>_Requires the `inbox:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the inbox threads matching specific criteria — a search term, channel, owner, sequence, email or LinkedIn account, contact, category, date range, source, or only those flagged with meeting intent. Every filter field is optional, and an empty body matches the same set as the plain thread listing. Results are paged with the top and skip query parameters.
      parameters:
        - in: query
          name: top
          schema:
            type: integer
            minimum: 1
            maximum: 1000
        - in: query
          name: skip
          schema:
            type: integer
            minimum: 0
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Inbox Thread Filter Request
              description: Filter criteria for `POST /v3/inbox/threads/filter`. All fields are optional — omit a field to skip that filter.
              properties: &ref_456
                search:
                  type: string
                  nullable: true
                  description: Free-text search across subject, body preview, and contact identifiers.
                ownerUserId:
                  type: integer
                  nullable: true
                  minimum: 1
                  description: Restrict to threads owned by the given user. The target must be a member of the caller's team; otherwise the request fails with 400 `inboxThread.invalidInput`.
                sequenceIds:
                  type: array
                  nullable: true
                  items:
                    type: integer
                    minimum: 1
                emailAccountIds:
                  type: array
                  nullable: true
                  items:
                    type: integer
                    format: int64
                    minimum: 1
                linkedInAccountIds:
                  type: array
                  nullable: true
                  items:
                    type: integer
                    minimum: 1
                contactIds:
                  type: array
                  nullable: true
                  items:
                    type: integer
                    minimum: 1
                channels:
                  type: array
                  nullable: true
                  items:
                    type: string
                    enum:
                      - email
                      - linkedIn
                  description: Restrict to threads on the given channels. `unknown` is rejected by validation.
                categoryIds:
                  type: array
                  nullable: true
                  items:
                    type: integer
                    minimum: 1
                onlyWithMeetingIntent:
                  type: boolean
                  nullable: true
                source:
                  type: string
                  nullable: true
                  enum:
                    - inbox
                    - sent
                    - unread
                    - aiDraft
                  description: |-
                    Predefined source bucket:
                    - `inbox` — all threads with at least one inbound message.
                    - `sent` — threads where the latest activity is outbound.
                    - `unread` — only unread threads.
                    - `aiDraft` — threads with a pending AI-drafted reply.
                from:
                  type: string
                  format: date-time
                  nullable: true
                to:
                  type: string
                  format: date-time
                  nullable: true
                  description: Upper bound on `lastActivityDate`. Must be strictly after `from` when both are supplied.
            example:
              channels:
                - email
              onlyWithMeetingIntent: true
              from: '2026-04-01T00:00:00Z'
              to: '2026-04-30T23:59:59Z'
      responses:
        '200':
          description: Filtered threads page
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - hasMore
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Inbox Thread List Item
                      description: Lightweight thread shape returned from list and filter endpoints — omits the message body history in favour of a `bodyPreview`.
                      required: *ref_139
                      properties: *ref_140
                  hasMore:
                    type: boolean
              example:
                items:
                  - id: 58217
                    channel: email
                    isRead: false
                    subject: 'Re: Pricing for Q3 rollout'
                    bodyPreview: Thanks — does Tuesday at 10am work for a quick call?
                    lastActivityDate: '2026-04-29T14:32:11Z'
                    isLastMessagePlanned: false
                    contact:
                      id: 9821
                      ownerId: 42
                      fullName: Daria Kovalenko
                      email: daria.kovalenko@northwind.example
                      linkedInProfileUrl: https://www.linkedin.com/in/daria-kovalenko
                      phone: '+380501234567'
                      companyName: Northwind Logistics
                      title: VP of Operations
                      isDeleted: false
                    sequence:
                      id: 314
                      name: Q3 Outbound — Logistics ICP
                    category:
                      id: 7
                      name: Hot Leads
                    hasMeetingIntent: true
                    status:
                      state: ok
                hasMore: false
        '400':
          description: Body validation failure, or a business-rule rejection (e.g. invalid pagination, invalid input).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /to
                        detail: '''to'' must be after ''from''.'
                business_invalid_pagination:
                  summary: Invalid pagination
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid pagination parameters.
                    code: inboxThread.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads/{id}:
    get:
      tags:
        - Inbox
      operationId: GetInboxThread
      summary: Get inbox thread
      x-required-scope: inbox:read
      description: |-
        <small>_Requires the `inbox:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need one conversation in full — its thread details together with the message history in the order it happened. When you only need the messages and want to page through a long exchange, use the messages endpoint instead.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Inbox thread
          content:
            application/json:
              schema:
                type: object
                title: Inbox Thread
                description: Full inbox thread with the contact, channel-specific account ids, sequence, category, meeting-intent flag, and the ordered list of messages.
                required: &ref_463
                  - id
                  - channel
                  - contact
                  - messages
                properties: &ref_464
                  id:
                    type: integer
                  channel:
                    type: string
                    enum:
                      - unknown
                      - email
                      - linkedIn
                  isRead:
                    type: boolean
                    description: Whether the thread is marked as read by the current user.
                  contact:
                    type: object
                    title: Inbox Thread Contact
                    description: |-
                      Contact party on the other end of an inbox thread.

                      Two shapes are possible, distinguished by the `isDeleted` flag:

                      - **Live contact** (`isDeleted: false`) — `id` and `ownerId` reference the live contact record; `fullName`, `email`, `linkedInProfileUrl`, `phone`, `companyName`, `title` come from the live record (any may still be `null` if the corresponding field is unset on the contact, e.g. `email` is `null` for a LinkedIn-only contact).
                      - **Deleted contact** (`isDeleted: true`) — the underlying contact record has been removed, so `id` and `ownerId` are `null`. The remaining identifying fields (`fullName`, `email`, `linkedInProfileUrl`, `phone`, `companyName`, `title`) are populated from the snapshot stored on the thread when it was created — typically enough for the user to recognise *who* the thread was with even though the contact no longer exists in their workspace.
                    required: *ref_141
                    properties: *ref_142
                  emailAccountId:
                    type: integer
                    format: int64
                    nullable: true
                    description: Email account that owns this thread. `null` for non-email threads.
                  linkedInAccountId:
                    type: integer
                    nullable: true
                    description: LinkedIn account that owns this thread. `null` for non-LinkedIn threads.
                  sequence:
                    type: object
                    allOf:
                      - type: object
                        title: Inbox Thread Sequence
                        description: Minimal sequence reference attached to an inbox thread.
                        required: *ref_133
                        properties: *ref_134
                    nullable: true
                  messages:
                    type: array
                    items:
                      title: Inbox Thread Message
                      description: Polymorphic message variant within an inbox thread, discriminated by `channel`. Email messages carry recipient and subject metadata; LinkedIn messages carry only the shared base fields.
                      discriminator: &ref_148
                        propertyName: channel
                        mapping:
                          email: '#/components/schemas/email.type-2'
                          linkedIn: '#/components/schemas/linkedin.type-2'
                      oneOf: &ref_149
                        - type: object
                          title: Inbox Email Message
                          description: Email message within an inbox thread.
                          required: &ref_457
                            - channel
                          properties: &ref_458
                            channel:
                              type: string
                              enum:
                                - email
                              description: Discriminator — always `email` for this variant.
                            messageId:
                              type: string
                              nullable: true
                              description: Unique identifier of the message within the thread. Use this value as `replyToMessageId` when sending a reply to a specific message.
                            date:
                              type: string
                              format: date-time
                            body:
                              type: string
                              nullable: true
                              description: Message body. May contain HTML.
                            fromName:
                              type: string
                              nullable: true
                            isOutbound:
                              type: boolean
                              description: True when the message was sent from this account; false when received.
                            status:
                              type: object
                              allOf:
                                - type: object
                                  title: Inbox Thread Message Status
                                  description: Per-message status. Populated for outbound messages that surfaced a delivery error; absent (`null`) on healthy inbound or successfully delivered outbound messages.
                                  properties: &ref_143
                                    state:
                                      type: string
                                      enum:
                                        - ok
                                        - needsAttention
                                      description: Message state, parallel to the thread state.
                                    code:
                                      type: string
                                      nullable: true
                                      enum:
                                        - linkedInAccountNotEnabled
                                        - linkedInInvalidCookie
                                        - linkedInSendingLimitExceeded
                                        - linkedInMessageSendingDisabled
                                        - linkedInSalesNavigatorSubscriptionMissing
                                        - linkedInMessageTooLong
                                        - linkedInRenderFailed
                                        - linkedInUnknown
                                        - linkedInProfileNotConnected
                                      description: Specific delivery error that put the message into `needsAttention`. `null` for healthy messages.
                                    occurredAt:
                                      type: string
                                      format: date-time
                                      nullable: true
                                      description: Timestamp of the most recent status transition.
                              nullable: true
                            aiSentType:
                              type: string
                              nullable: true
                              enum:
                                - aiGenerated
                                - aiGeneratedEdited
                                - autoSent
                              description: For a sent message, identifies that it was generated by AI. `null` when the message was not AI-generated.
                            subject:
                              type: string
                              nullable: true
                            fromAddress:
                              type: string
                              nullable: true
                            to:
                              type: array
                              nullable: true
                              items:
                                type: string
                            cc:
                              type: array
                              nullable: true
                              items:
                                type: string
                            bcc:
                              type: array
                              nullable: true
                              items:
                                type: string
                        - type: object
                          title: Inbox LinkedIn Message
                          description: LinkedIn message within an inbox thread.
                          required: &ref_459
                            - channel
                          properties: &ref_460
                            channel:
                              type: string
                              enum:
                                - linkedIn
                              description: Discriminator — always `linkedIn` for this variant.
                            messageId:
                              type: string
                              nullable: true
                              description: Unique identifier of the message within the thread.
                            date:
                              type: string
                              format: date-time
                            body:
                              type: string
                              nullable: true
                            fromName:
                              type: string
                              nullable: true
                            isOutbound:
                              type: boolean
                            status:
                              type: object
                              allOf:
                                - type: object
                                  title: Inbox Thread Message Status
                                  description: Per-message status. Populated for outbound messages that surfaced a delivery error; absent (`null`) on healthy inbound or successfully delivered outbound messages.
                                  properties: *ref_143
                              nullable: true
                            aiSentType:
                              type: string
                              nullable: true
                              enum:
                                - aiGenerated
                                - aiGeneratedEdited
                                - autoSent
                              description: For a sent message, identifies that it was generated by AI. `null` when the message was not AI-generated.
                  aiDraft:
                    type: object
                    allOf:
                      - type: object
                        title: Inbox Thread AI Draft
                        description: The thread's pending AI-drafted reply, awaiting review. A thread has at most one active AI draft.
                        required: &ref_461
                          - message
                        properties: &ref_462
                          message:
                            type: string
                            description: The AI-generated draft reply body. May contain HTML.
                          cc:
                            type: array
                            items:
                              type: string
                            description: Draft CC recipients. Empty when the draft has none.
                          bcc:
                            type: array
                            items:
                              type: string
                            description: Draft BCC recipients. Empty when the draft has none.
                          attachments:
                            type: array
                            items:
                              type: object
                              title: Attachment
                              description: Uploaded file attachment usable across email templates, sequence steps, and direct emails.
                              required: *ref_144
                              properties: *ref_145
                            description: Files attached to the draft. Empty when the draft has none.
                    nullable: true
                    description: The thread's single pending AI-drafted reply, if one is awaiting review. `null` when the thread has no active AI draft.
                  category:
                    type: object
                    allOf:
                      - type: object
                        title: Inbox Thread Category Reference
                        description: Minimal category reference embedded in thread responses.
                        required: *ref_135
                        properties: *ref_136
                    nullable: true
                  hasMeetingIntent:
                    type: boolean
                    description: Whether the thread has been flagged as carrying meeting intent (manually or via AI detection).
              examples:
                live_contact_email_thread:
                  summary: Email thread with a live contact and a short reply chain
                  value:
                    id: 58217
                    channel: email
                    isRead: false
                    contact:
                      id: 9821
                      ownerId: 42
                      fullName: Daria Kovalenko
                      email: daria.kovalenko@northwind.example
                      linkedInProfileUrl: https://www.linkedin.com/in/daria-kovalenko
                      phone: '+380501234567'
                      companyName: Northwind Logistics
                      title: VP of Operations
                      isDeleted: false
                    emailAccountId: 18044
                    linkedInAccountId: null
                    sequence:
                      id: 314
                      name: Q3 Outbound — Logistics ICP
                    messages:
                      - channel: email
                        messageId: <abc123@reply.example>
                        date: '2026-05-06T08:01:42Z'
                        body: <p>Hi Daria — quick check-in on the Q3 rollout pricing we discussed last week. Are you free Tuesday at 10am for a 20-min call?</p>
                        fromName: Alex Johnson
                        isOutbound: true
                        subject: Pricing for Q3 rollout
                        fromAddress: alex.johnson@reply.example
                        to:
                          - daria.kovalenko@northwind.example
                        cc: null
                        bcc: null
                      - channel: email
                        messageId: <def456@northwind.example>
                        date: '2026-05-07T14:32:11Z'
                        body: <p>Thanks — does Tuesday at 10am work for a quick call?</p><p>Daria</p>
                        fromName: Daria Kovalenko
                        isOutbound: false
                        subject: 'Re: Pricing for Q3 rollout'
                        fromAddress: daria.kovalenko@northwind.example
                        to:
                          - alex.johnson@reply.example
                        cc: null
                        bcc: null
                    aiDraft:
                      message: <p>Hi Daria — Tuesday at 10am works for me. I'll send a calendar invite shortly.</p>
                      cc: []
                      bcc: []
                      attachments: []
                    category:
                      id: 7
                      name: Hot Leads
                    hasMeetingIntent: true
                deleted_contact_linkedin_thread:
                  summary: LinkedIn thread whose contact was deleted from the workspace. `contact.id` and `contact.ownerId` are `null`, but `fullName`, `linkedInProfileUrl`, `companyName`, and `title` remain populated from the thread snapshot — enough to recognise the conversation history.
                  value:
                    id: 58198
                    channel: linkedIn
                    isRead: true
                    contact:
                      id: null
                      ownerId: null
                      fullName: Marcus Lee
                      email: null
                      linkedInProfileUrl: https://www.linkedin.com/in/marcus-lee-rev
                      phone: null
                      companyName: Helix Robotics
                      title: Head of Revenue
                      isDeleted: true
                    emailAccountId: null
                    linkedInAccountId: 2218
                    messages:
                      - channel: linkedIn
                        messageId: null
                        date: '2026-05-06T16:48:09Z'
                        body: Hey Marcus — saw your team is hiring AEs in EMEA. Worth a quick chat next week?
                        fromName: Alex Johnson
                        isOutbound: true
                      - channel: linkedIn
                        messageId: null
                        date: '2026-05-07T09:14:02Z'
                        body: Sounds good, sending over the deck.
                        fromName: Marcus Lee
                        isOutbound: false
                    hasMeetingIntent: false
                linkedin_thread_with_send_failure:
                  summary: LinkedIn thread where the most recent outbound message hit a delivery error — the message-level `status` carries the specific failure code. The thread will surface as `needsAttention` in the list endpoint.
                  value:
                    id: 58155
                    channel: linkedIn
                    isRead: false
                    contact:
                      id: 9802
                      ownerId: 42
                      fullName: Priya Subramaniam
                      email: null
                      linkedInProfileUrl: https://www.linkedin.com/in/priya-subramaniam
                      phone: null
                      companyName: Lattice Analytics
                      title: Director of Sales Ops
                      isDeleted: false
                    emailAccountId: null
                    linkedInAccountId: 2218
                    messages:
                      - channel: linkedIn
                        messageId: null
                        date: '2026-05-05T11:22:00Z'
                        body: Thanks for connecting — would you be open to a 15 min chat about how teams use Lattice for pipeline reporting?
                        fromName: Priya Subramaniam
                        isOutbound: false
                      - channel: linkedIn
                        messageId: null
                        date: '2026-05-06T07:04:51Z'
                        body: Hi Priya — sure, would Thursday afternoon work?
                        fromName: Alex Johnson
                        isOutbound: true
                        status:
                          state: needsAttention
                          code: linkedInInvalidCookie
                          occurredAt: '2026-05-06T07:04:53Z'
                    hasMeetingIntent: true
        '400':
          description: Invalid id parameter or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxThread.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '404':
          description: Thread not found or not visible to the current user.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Inbox thread not found.
                code: inboxThread.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Inbox
      operationId: DeleteInboxThread
      summary: Delete inbox thread
      x-required-scope: inbox:operate
      description: |-
        <small>_Requires the `inbox:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to permanently remove a single conversation from the inbox, together with its messages. To remove several conversations in one call, use the bulk-delete endpoint instead.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minimum: 1
      responses:
        '204':
          description: Thread deleted
          content:
            application/json:
              schema:
                type: object
        '400':
          description: Invalid id parameter or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxThread.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '404':
          description: Thread not found or not visible to the current user.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Inbox thread not found.
                code: inboxThread.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads/bulk-delete:
    post:
      tags:
        - Inbox
      operationId: BulkDeleteInboxThreads
      summary: Bulk-delete inbox threads
      x-required-scope: inbox:operate
      description: |-
        <small>_Requires the `inbox:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to permanently remove several inbox conversations in one call. Threads are processed one by one and successful deletions are kept even when others fail; the response returns only the thread ids that were not deleted, each with its error details, so an empty object means everything succeeded. A per-item error is notFound when the thread does not exist, or forbidden when you are not allowed to delete it.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Inbox Thread Bulk Request
              description: Identifier list for non-atomic bulk thread operations.
              required: &ref_146
                - threadIds
              properties: &ref_147
                threadIds:
                  type: array
                  minItems: 1
                  items:
                    type: integer
                    minimum: 1
      responses:
        '200':
          description: Per-item results. Threads not present in the dictionary succeeded.
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
              example:
                '5821':
                  error: notFound
                  errorDetails: Inbox thread not found.
        '400':
          description: Body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /threadIds
                        detail: '''threadIds'' must not be empty.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxThread.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads/mark-as-read:
    post:
      tags:
        - Inbox
      operationId: MarkInboxThreadsAsRead
      summary: Mark threads as read
      x-required-scope: inbox:operate
      description: |-
        <small>_Requires the `inbox:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to clear the unread state on one or more conversations — for example after your own app has shown them to the user. Threads that are already read are unaffected. Threads are processed one by one; the response returns only the thread ids that were not updated, each with its error details, so an empty object means everything succeeded. A per-item error is notFound when the thread does not exist, or forbidden when you are not allowed to access it.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Inbox Thread Bulk Request
              description: Identifier list for non-atomic bulk thread operations.
              required: *ref_146
              properties: *ref_147
            example:
              threadIds:
                - 58217
                - 58198
                - 58104
      responses:
        '200':
          description: Per-item results. Threads not present in the dictionary succeeded.
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
              examples:
                all_succeeded:
                  summary: Every supplied thread was marked as read
                  value: {}
                one_failure:
                  summary: Two threads succeeded; one was not found
                  value:
                    '58104':
                      error: notFound
                      errorDetails: Inbox thread not found.
        '400':
          description: Body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /threadIds
                        detail: '''threadIds'' must not be empty.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxThread.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads/mark-as-unread:
    post:
      tags:
        - Inbox
      operationId: MarkInboxThreadsAsUnread
      summary: Mark threads as unread
      x-required-scope: inbox:operate
      description: |-
        <small>_Requires the `inbox:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to flag one or more conversations as needing attention again by restoring their unread state. Threads are processed one by one; the response returns only the thread ids that were not updated, each with its error details, so an empty object means everything succeeded. A per-item error is notFound when the thread does not exist, or forbidden when you are not allowed to access it.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Inbox Thread Bulk Request
              description: Identifier list for non-atomic bulk thread operations.
              required: *ref_146
              properties: *ref_147
            example:
              threadIds:
                - 58217
                - 58198
      responses:
        '200':
          description: Per-item results. Threads not present in the dictionary succeeded.
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
              example: {}
        '400':
          description: Body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /threadIds
                        detail: '''threadIds'' must not be empty.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxThread.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads/{id}/messages:
    get:
      tags:
        - Inbox
      operationId: ListInboxThreadMessages
      summary: List messages in an inbox thread
      x-required-scope: inbox:read
      description: |-
        <small>_Requires the `inbox:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to page through the messages of one conversation, oldest first. Messages vary by channel: email messages carry recipient and subject metadata, LinkedIn messages carry only the shared fields. Results are paged with the top and skip query parameters.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minimum: 1
        - in: query
          name: top
          schema:
            type: integer
            minimum: 1
            maximum: 1000
          description: Maximum items to return. Defaults to the server-side default page size when omitted.
        - in: query
          name: skip
          schema:
            type: integer
            minimum: 0
          description: Items to skip from the start of the result set.
      responses:
        '200':
          description: Thread messages page
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - hasMore
                properties:
                  items:
                    type: array
                    items:
                      title: Inbox Thread Message
                      description: Polymorphic message variant within an inbox thread, discriminated by `channel`. Email messages carry recipient and subject metadata; LinkedIn messages carry only the shared base fields.
                      discriminator: *ref_148
                      oneOf: *ref_149
                  hasMore:
                    type: boolean
              examples:
                email_thread:
                  summary: Two-message email exchange
                  value:
                    items:
                      - channel: email
                        messageId: <abc123@reply.example>
                        date: '2026-05-06T08:01:42Z'
                        body: <p>Hi Daria — quick check-in on the Q3 rollout pricing we discussed last week. Are you free Tuesday at 10am for a 20-min call?</p>
                        fromName: Alex Johnson
                        isOutbound: true
                        subject: Pricing for Q3 rollout
                        fromAddress: alex.johnson@reply.example
                        to:
                          - daria.kovalenko@northwind.example
                        cc: null
                        bcc: null
                      - channel: email
                        messageId: <def456@northwind.example>
                        date: '2026-05-07T14:32:11Z'
                        body: <p>Thanks — does Tuesday at 10am work for a quick call?</p><p>Daria</p>
                        fromName: Daria Kovalenko
                        isOutbound: false
                        subject: 'Re: Pricing for Q3 rollout'
                        fromAddress: daria.kovalenko@northwind.example
                        to:
                          - alex.johnson@reply.example
                        cc: null
                        bcc: null
                    hasMore: false
                linkedin_thread_with_send_failure:
                  summary: LinkedIn thread where the latest outbound message hit a delivery error — the message-level `status` carries the failure code.
                  value:
                    items:
                      - channel: linkedIn
                        messageId: null
                        date: '2026-05-05T11:22:00Z'
                        body: Thanks for connecting — would you be open to a 15 min chat about how teams use Lattice for pipeline reporting?
                        fromName: Priya Subramaniam
                        isOutbound: false
                      - channel: linkedIn
                        messageId: null
                        date: '2026-05-06T07:04:51Z'
                        body: Hi Priya — sure, would Thursday afternoon work?
                        fromName: Alex Johnson
                        isOutbound: true
                        status:
                          state: needsAttention
                          code: linkedInInvalidCookie
                          occurredAt: '2026-05-06T07:04:53Z'
                    hasMore: false
        '400':
          description: Route validation failure, or a business-rule rejection (e.g. invalid pagination, invalid input).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_invalid_pagination:
                  summary: Invalid pagination
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid pagination parameters.
                    code: inboxThread.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '404':
          description: Thread not found or not visible to the current user.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Inbox thread not found.
                code: inboxThread.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Inbox
      operationId: SendInboxThreadMessage
      summary: Send a reply within a thread
      x-required-scope: inbox:operate
      description: |-
        <small>_Requires the `inbox:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to reply to a contact inside an existing conversation. The channel discriminator in the request body must match the thread's own channel — a mismatch is rejected with code inboxThread.channelMismatch. An email reply may also carry cc and bcc recipients, apply your signature, and target a specific message in the chain, while a LinkedIn reply takes just the message text. Attach files by passing the ids returned when you uploaded them. The sent message is returned.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              title: Inbox Thread Send-Message Request
              description: Polymorphic outbound message body, discriminated by `channel`. The supplied channel must match the thread's channel; mismatches are rejected with errorCode 8 (ChannelMismatch).
              discriminator: &ref_469
                propertyName: channel
                mapping:
                  email: '#/components/schemas/email.type-3'
                  linkedIn: '#/components/schemas/linkedin.type-3'
              oneOf: &ref_470
                - type: object
                  title: Inbox Email Message Request
                  description: Outbound email reply within an inbox thread.
                  required: &ref_465
                    - channel
                    - message
                  properties: &ref_466
                    channel:
                      type: string
                      enum:
                        - email
                    message:
                      type: string
                      description: Message body. May contain HTML.
                    attachmentIds:
                      type: array
                      nullable: true
                      items:
                        type: integer
                        minimum: 1
                    cc:
                      type: array
                      nullable: true
                      items:
                        type: string
                        format: email
                    bcc:
                      type: array
                      nullable: true
                      items:
                        type: string
                        format: email
                    applySignature:
                      type: boolean
                      nullable: true
                      description: When true, the sender's email-account signature is appended to the message body.
                    replyToMessageId:
                      type: string
                      nullable: true
                      description: MessageId of a specific message in the thread to reply to. When omitted, the reply targets the last message in the thread.
                - type: object
                  title: Inbox LinkedIn Message Request
                  description: Outbound LinkedIn reply within an inbox thread.
                  required: &ref_467
                    - channel
                    - message
                  properties: &ref_468
                    channel:
                      type: string
                      enum:
                        - linkedIn
                    message:
                      type: string
                    attachmentIds:
                      type: array
                      nullable: true
                      items:
                        type: integer
                        minimum: 1
            example:
              channel: email
              message: Thanks — does Tuesday at 10am work?
              cc:
                - cc@example.com
              applySignature: true
              replyToMessageId: <abc123@reply.example>
      responses:
        '200':
          description: The newly created outbound message.
          content:
            application/json:
              schema:
                title: Inbox Thread Message
                description: Polymorphic message variant within an inbox thread, discriminated by `channel`. Email messages carry recipient and subject metadata; LinkedIn messages carry only the shared base fields.
                discriminator: *ref_148
                oneOf: *ref_149
              examples:
                email_reply:
                  summary: Outbound email reply
                  value:
                    channel: email
                    messageId: <ghi789@reply.example>
                    date: '2026-05-08T08:14:33Z'
                    body: <p>Thanks — does Tuesday at 10am work?</p>
                    fromName: Alex Johnson
                    isOutbound: true
                    subject: 'Re: Pricing for Q3 rollout'
                    fromAddress: alex.johnson@reply.example
                    to:
                      - daria.kovalenko@northwind.example
                    cc:
                      - cc@example.com
                    bcc: null
                linkedin_reply:
                  summary: Outbound LinkedIn reply
                  value:
                    channel: linkedIn
                    messageId: null
                    date: '2026-05-08T08:14:33Z'
                    body: Sounds good — Tuesday 10am works.
                    fromName: Alex Johnson
                    isOutbound: true
        '400':
          description: Body validation failure, or a business-rule rejection (channel mismatch, attachment not found, referenced sequence not found, contact opted out, invalid input).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /message
                        detail: '''message'' must not be empty.'
                channel_mismatch:
                  summary: Request channel does not match the thread's channel
                  value:
                    title: Bad Request
                    status: 400
                    detail: Channel mismatch — request channel does not match the thread's channel.
                    code: inboxThread.channelMismatch
                attachment_not_found:
                  summary: Referenced attachment does not exist
                  value:
                    title: Bad Request
                    status: 400
                    detail: Attachment not found.
                    code: inboxThread.attachmentNotFound
                sequence_not_found:
                  summary: Referenced sequence does not exist
                  value:
                    title: Bad Request
                    status: 400
                    detail: Sequence not found.
                    code: inboxThread.sequenceNotFound
                contact_opted_out:
                  summary: Contact has opted out and cannot be messaged
                  value:
                    title: Bad Request
                    status: 400
                    detail: Contact has opted out.
                    code: inboxThread.contactOptedOut
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '404':
          description: Thread not found or not visible to the current user.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Inbox thread not found.
                code: inboxThread.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
        '502':
          description: The provider rejected delivery (LinkedIn cookie invalid, send limit exceeded, message too long, etc.). The thread enters `needsAttention` state.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: Failed to deliver the message.
                code: inboxThread.threadSendFailed
  /v3/inbox/threads/{id}/category:
    put:
      tags:
        - Inbox
      operationId: SetInboxThreadCategory
      summary: Assign or clear a thread's category
      x-required-scope: inbox:operate
      description: |-
        <small>_Requires the `inbox:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to file a single conversation under an inbox category, or to take it out of the one it is in by sending categoryId as null. A thread sits in at most one category, so setting a new one replaces the previous. Repeating the same call changes nothing. To move many threads at once, use the category thread-links endpoints instead.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Inbox Thread Set-Category Request
              description: Assign or clear a category on a thread.
              properties: &ref_471
                categoryId:
                  type: integer
                  nullable: true
                  minimum: 1
                  description: Target category id, or `null` to clear the assignment.
            example:
              categoryId: 42
      responses:
        '204':
          description: Category set
          content:
            application/json:
              schema:
                type: object
        '400':
          description: Route/body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /categoryId
                        detail: '''categoryId'' must be a positive value. Send null to clear the category.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxThread.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '404':
          description: Thread or category not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Inbox thread not found.
                code: inboxThread.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads/{id}/meeting-intent:
    put:
      tags:
        - Inbox
      operationId: SetInboxThreadMeetingIntent
      summary: Toggle thread meeting-intent
      x-required-scope: inbox:operate
      description: |-
        <small>_Requires the `inbox:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to mark a conversation as one where the contact wants to book a meeting, or to clear that mark. Send hasMeetingIntent true to set it and false to remove it. The thread filter can then return only the threads carrying this flag.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Inbox Thread Set-Meeting-Intent Request
              description: Toggle the meeting-intent flag on a thread.
              required: &ref_472
                - hasMeetingIntent
              properties: &ref_473
                hasMeetingIntent:
                  type: boolean
                  description: True to flag the thread as carrying meeting intent; false to clear it.
            example:
              hasMeetingIntent: true
      responses:
        '204':
          description: Meeting-intent flag updated
          content:
            application/json:
              schema:
                type: object
        '400':
          description: Route/body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /hasMeetingIntent
                        detail: '''hasMeetingIntent'' is required.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxThread.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxThread.forbidden
        '404':
          description: Thread not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Inbox thread not found.
                code: inboxThread.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads/{id}/ai-draft/generate:
    post:
      tags:
        - Inbox
      summary: Generate an AI draft reply
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        Generates an AI-suggested reply for an inbox thread. The same endpoint backs both the initial generate and the "Regenerate" action in the message editor — each call produces a fresh draft. To send the draft (with or without edits), use the existing `POST /v3/inbox/threads/{id}/messages` endpoint.
      operationId: GenerateInboxAiDraft
      parameters:
        - name: id
          in: path
          required: true
          description: Thread id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: AI draft generated
          content:
            application/json:
              schema:
                type: object
                description: Coming soon — full response shape is still being finalized.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Thread not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
  /v3/inbox/threads/{id}/ai-draft/feedback:
    post:
      tags:
        - Inbox
      summary: Submit feedback on a generated AI draft
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        Records a thumbs-up / thumbs-down on the AI-generated draft, with optional dislike reasons and a freeform comment. Used as a training signal.

        Requires the AI SDR feature on the caller's team.
      operationId: SubmitInboxAiDraftFeedback
      parameters:
        - name: id
          in: path
          required: true
          description: Thread id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - vote
              properties:
                vote:
                  type: string
                  enum:
                    - like
                    - dislike
                dislikeReasons:
                  type: array
                  description: Categorized reasons when `vote` is `dislike`. The exact enum is still being finalized — coming soon.
                  items:
                    type: string
                comment:
                  type: string
                  description: Freeform comment from the user
      responses:
        '204':
          description: Feedback recorded
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: AI SDR feature is not available for the caller's team
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
        '404':
          description: Thread not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
  /v3/inbox/threads/categories:
    get:
      tags:
        - Inbox
      operationId: ListInboxCategories
      summary: List inbox categories
      x-required-scope: inbox:read
      description: |-
        <small>_Requires the `inbox:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the inbox categories you can file conversations under, including the reserved ones Reply provides out of the box. Each entry carries its name, color, whether it is reserved, and how many unread threads it currently holds. Pass ownerUserId to see the categories of a specific teammate instead of your own.
      parameters:
        - name: ownerUserId
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
          description: Restrict to categories visible to the given user. The target must be a member of the caller's team; otherwise the request fails with 400 `inboxCategory.invalidInput`.
      responses:
        '200':
          description: Inbox categories
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Inbox Category
                  description: Inbox thread category. Reserved categories are owned by the system and cannot be modified or deleted.
                  required: &ref_150
                    - id
                    - name
                    - color
                    - isReserved
                    - unreadThreadsCount
                  properties: &ref_151
                    id:
                      type: integer
                    name:
                      type: string
                      maxLength: 64
                    color:
                      type: string
                      enum:
                        - gray
                        - green
                        - blue
                        - red
                        - yellow
                        - purple
                        - orange
                        - lightBlue
                        - olive
                    isReserved:
                      type: boolean
                      description: True for system-reserved categories (e.g., the default category). Reserved categories cannot be renamed, recoloured, or deleted.
                    unreadThreadsCount:
                      type: integer
                      description: Number of unread threads currently assigned to this category.
              example:
                - id: 1
                  name: Meeting
                  color: green
                  isReserved: true
                  unreadThreadsCount: 3
                - id: 7
                  name: Hot Leads
                  color: red
                  isReserved: false
                  unreadThreadsCount: 12
                - id: 8
                  name: Needs Follow-up
                  color: yellow
                  isReserved: false
                  unreadThreadsCount: 5
        '400':
          description: |-
            Query parameter validation failure, or a business-rule rejection
            (the supplied `ownerUserId` is not a member of the caller's team).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Query parameter validation
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: /ownerUserId
                        detail: '''ownerUserId'' must be a positive integer.'
                owner_not_team_member:
                  summary: Owner not in caller's team
                  value:
                    title: Bad Request
                    status: 400
                    detail: The specified owner is not a member of your team.
                    code: inboxCategory.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxCategory.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Inbox
      operationId: CreateInboxCategory
      summary: Create inbox category
      x-required-scope: inbox:write
      description: |-
        <small>_Requires the `inbox:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need a category of your own to sort inbox conversations under. Provide a name — unique within your team, ignoring case — and optionally a color; the created category is returned with its assigned id.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Inbox Category Creation Request
              required: &ref_474
                - name
                - color
              properties: &ref_475
                name:
                  type: string
                  minLength: 1
                  maxLength: 64
                color:
                  type: string
                  enum:
                    - gray
                    - green
                    - blue
                    - red
                    - yellow
                    - purple
                    - orange
                    - lightBlue
                    - olive
            example:
              name: Hot Leads
              color: red
      responses:
        '201':
          description: Category created
          content:
            application/json:
              schema:
                type: object
                title: Inbox Category
                description: Inbox thread category. Reserved categories are owned by the system and cannot be modified or deleted.
                required: *ref_150
                properties: *ref_151
              example:
                id: 9
                name: Hot Leads
                color: red
                isReserved: false
                unreadThreadsCount: 0
        '400':
          description: Body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: '''name'' must not be empty.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxCategory.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxCategory.forbidden
        '409':
          description: A category with this name already exists.
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A category with this name already exists.
                code: inboxCategory.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads/categories/{id}:
    get:
      tags:
        - Inbox
      operationId: GetInboxCategory
      summary: Get inbox category
      x-required-scope: inbox:read
      description: |-
        <small>_Requires the `inbox:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need a single inbox category by its id — its name, color, whether it is one of Reply's reserved categories, and its current unread thread count.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Inbox category
          content:
            application/json:
              schema:
                type: object
                title: Inbox Category
                description: Inbox thread category. Reserved categories are owned by the system and cannot be modified or deleted.
                required: *ref_150
                properties: *ref_151
              example:
                id: 7
                name: Hot Leads
                color: red
                isReserved: false
                unreadThreadsCount: 12
        '400':
          description: Route parameter validation failure.
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: '''id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxCategory.forbidden
        '404':
          description: Category not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Inbox category not found.
                code: inboxCategory.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Inbox
      operationId: UpdateInboxCategory
      summary: Update inbox category
      x-required-scope: inbox:write
      description: |-
        <small>_Requires the `inbox:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to rename a category or change its color. Both name and color are replaced by what you send, so include the values you want to keep. The new name must be unique within your team. Reply's reserved categories cannot be edited — those are rejected with 403 and code inboxCategory.cannotModifyDefault.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Inbox Category Update Request
              description: Full replacement of the category's name and color. Reserved categories reject this operation with 403.
              required: &ref_476
                - name
                - color
              properties: &ref_477
                name:
                  type: string
                  minLength: 1
                  maxLength: 64
                color:
                  type: string
                  enum:
                    - gray
                    - green
                    - blue
                    - red
                    - yellow
                    - purple
                    - orange
                    - lightBlue
                    - olive
            example:
              name: Warm Leads
              color: yellow
      responses:
        '200':
          description: Category updated
          content:
            application/json:
              schema:
                type: object
                title: Inbox Category
                description: Inbox thread category. Reserved categories are owned by the system and cannot be modified or deleted.
                required: *ref_150
                properties: *ref_151
              example:
                id: 9
                name: Warm Leads
                color: yellow
                isReserved: false
                unreadThreadsCount: 4
        '400':
          description: Route/body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: '''name'' must not be empty.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxCategory.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is unavailable, or the category is system-reserved and cannot be modified.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                feature_forbidden:
                  summary: Inbox feature is not available for this user or team
                  value:
                    title: Forbidden
                    status: 403
                    detail: Inbox feature is not available for this user.
                    code: inboxCategory.forbidden
                cannot_modify_default:
                  summary: Reserved (system) category cannot be modified
                  value:
                    title: Forbidden
                    status: 403
                    detail: Reserved categories cannot be modified.
                    code: inboxCategory.cannotModifyDefault
        '404':
          description: Category not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Inbox category not found.
                code: inboxCategory.notFound
        '409':
          description: Another category already uses the supplied name.
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A category with this name already exists.
                code: inboxCategory.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Inbox
      operationId: DeleteInboxCategory
      summary: Delete inbox category
      x-required-scope: inbox:write
      description: |-
        <small>_Requires the `inbox:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you no longer need one of your own categories. Any conversations filed under it are unlinked and stay in the inbox — only the category is removed. Reply's reserved categories cannot be deleted — those are rejected with 403 and code inboxCategory.cannotModifyDefault.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minimum: 1
      responses:
        '204':
          description: Category deleted
          content:
            application/json:
              schema:
                type: object
        '400':
          description: Route validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxCategory.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is unavailable, or the category is system-reserved and cannot be deleted.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                feature_forbidden:
                  summary: Inbox feature is not available for this user or team
                  value:
                    title: Forbidden
                    status: 403
                    detail: Inbox feature is not available for this user.
                    code: inboxCategory.forbidden
                cannot_modify_default:
                  summary: Reserved (system) category cannot be deleted
                  value:
                    title: Forbidden
                    status: 403
                    detail: Reserved categories cannot be deleted.
                    code: inboxCategory.cannotModifyDefault
        '404':
          description: Category not found.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Inbox category not found.
                code: inboxCategory.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads/categories/{id}/thread-links/bulk:
    post:
      tags:
        - Inbox
      operationId: AssignThreadsToInboxCategory
      summary: Assign threads to a category
      x-required-scope: inbox:operate
      description: |-
        <small>_Requires the `inbox:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to file several conversations under this category at once. A thread sits in at most one category, so any earlier category on a supplied thread is replaced. Threads are processed one by one and successful links are kept even when others fail; the response returns only the thread ids that were not linked, each with its error details. A per-item error is notFound when the thread or the category does not exist, invalidInput when the thread id is not usable, or forbidden when you are not allowed to file that thread.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Inbox Thread Bulk Request
              description: Identifier list for non-atomic bulk thread operations.
              required: *ref_146
              properties: *ref_147
            example:
              threadIds:
                - 58217
                - 58198
                - 58104
      responses:
        '200':
          description: Per-item results. Threads not present in the dictionary succeeded.
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
              examples:
                all_succeeded:
                  summary: Every supplied thread was assigned
                  value: {}
                partial_failure:
                  summary: One thread was not found, the others succeeded
                  value:
                    '58104':
                      error: notFound
                      errorDetails: Inbox thread not found.
        '400':
          description: Route/body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /threadIds
                        detail: '''threadIds'' must not be empty.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxCategory.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxCategory.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/inbox/threads/categories/{id}/thread-links/bulk-delete:
    post:
      tags:
        - Inbox
      operationId: UnassignThreadsFromInboxCategory
      summary: Unassign threads from a category
      x-required-scope: inbox:operate
      description: |-
        <small>_Requires the `inbox:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to take several conversations out of this category. A supplied thread filed under a different category is left alone. The conversations themselves are not deleted. Threads are processed one by one; the response returns only the thread ids that were not unlinked, each with its error details. A per-item error is notFound when the thread or the category does not exist, invalidInput when the thread id is not usable, or forbidden when you are not allowed to modify that thread.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Inbox Thread Bulk Request
              description: Identifier list for non-atomic bulk thread operations.
              required: *ref_146
              properties: *ref_147
            example:
              threadIds:
                - 58217
                - 58198
      responses:
        '200':
          description: Per-item results. Threads not present in the dictionary succeeded.
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
              example: {}
        '400':
          description: Route/body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /threadIds
                        detail: '''threadIds'' must not be empty.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: inboxCategory.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Inbox feature is not available for this user or team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Inbox feature is not available for this user.
                code: inboxCategory.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/linkedin-accounts:
    get:
      tags:
        - LinkedIn Accounts
      summary: List LinkedIn accounts
      x-required-scope: channels:read
      description: |-
        <small>_Requires the `channels:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the LinkedIn accounts connected to your Reply account, with their connection state and automation limits. The full set is returned in one call — there is no paging. Accounts that have been invited but not yet connected are not included here; list those with the pending endpoint.
      operationId: ListLinkedInAccounts
      responses:
        '200':
          description: List of LinkedIn accounts
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: LinkedInAccount
                  description: Full representation of a LinkedIn account.
                  properties: &ref_154
                    id:
                      type: integer
                      description: Unique identifier for the LinkedIn account
                      readOnly: true
                    name:
                      type: string
                      description: Display name of the LinkedIn account
                    status:
                      type: string
                      description: Current status of the account
                      enum:
                        - disabled
                        - enabled
                        - dailyLimitReached
                        - cookieInvalid
                    profileUrl:
                      type: string
                      nullable: true
                      description: URL to the LinkedIn profile
                    photoUrl:
                      type: string
                      nullable: true
                      description: URL to the profile photo
                    ownerUserId:
                      type: integer
                      description: ID of the user who owns this account
                      readOnly: true
                    accountType:
                      type: string
                      nullable: true
                      description: Type of LinkedIn account
                      enum:
                        - public
                        - salesNavigator
                        - premium
                    authType:
                      type: string
                      description: Authentication method used
                      enum:
                        - cookie
                        - credentials
                    cookieStatus:
                      type: string
                      description: Status of the LinkedIn authentication cookie
                      enum:
                        - notValid
                        - valid
                        - neverValidated
                    usage:
                      nullable: true
                      type: object
                      title: LinkedInAccountUsage
                      description: Daily usage statistics for a LinkedIn account.
                      properties: &ref_478
                        connectionRequests:
                          type: integer
                          description: Number of connection requests sent today
                        messages:
                          type: integer
                          description: Number of messages sent today
                        salesNavigatorConnectionRequests:
                          type: integer
                          description: Number of Sales Navigator connection requests sent today
                        inMails:
                          type: integer
                          description: Number of InMails sent today
                        viewProfiles:
                          type: integer
                          description: Number of profiles viewed today
                        likeRecentPosts:
                          type: integer
                          description: Number of recent posts liked today
                        detects:
                          type: integer
                          description: Number of profile detections today
                        revokeConnections:
                          type: integer
                          description: Number of connections revoked today
                        endorseSkills:
                          type: integer
                          description: Number of skills endorsed today
                        followProfile:
                          type: integer
                          description: Number of profiles followed today
                      example: &ref_479
                        connectionRequests: 10
                        messages: 25
                        salesNavigatorConnectionRequests: 5
                        inMails: 3
                        viewProfiles: 50
                        likeRecentPosts: 15
                        detects: 30
                        revokeConnections: 2
                        endorseSkills: 5
                        followProfile: 8
                    limits:
                      nullable: true
                      type: object
                      title: LinkedInAccountLimits
                      description: Daily limits configuration for a LinkedIn account.
                      properties: &ref_156
                        limitsMode:
                          type: string
                          description: Limits mode
                          enum:
                            - Fixed
                            - Ranged
                        rangeMin:
                          description: Minimum values for ranged limits mode
                          type: object
                          title: LinkedInAccountLimitsValues
                          properties: &ref_152
                            dailyDetectCount:
                              type: integer
                              description: Daily limit for profile detections
                            dailySendConnectionRequestCount:
                              type: integer
                              description: Daily limit for sending connection requests
                            dailySendMessageCount:
                              type: integer
                              description: Daily limit for sending messages
                            dailySendSalesNavigatorConnectionRequestCount:
                              type: integer
                              description: Daily limit for Sales Navigator connection requests
                            dailyInMailCount:
                              type: integer
                              description: Daily limit for InMails
                            dailyViewProfileCount:
                              type: integer
                              description: Daily limit for viewing profiles
                            dailyLikeRecentPostsCount:
                              type: integer
                              description: Daily limit for liking recent posts
                            dailyRevokeConnectionCount:
                              type: integer
                              description: Daily limit for revoking connections
                            dailyEndorsedSkillsCount:
                              type: integer
                              description: Daily limit for endorsing skills
                            dailyFollowedProfilesCount:
                              type: integer
                              description: Daily limit for following profiles
                            dailyCommentRecentPostCount:
                              type: integer
                              description: Daily limit for commenting on recent posts
                          example: &ref_153
                            dailyDetectCount: 100
                            dailySendConnectionRequestCount: 20
                            dailySendMessageCount: 50
                            dailySendSalesNavigatorConnectionRequestCount: 10
                            dailyInMailCount: 10
                            dailyViewProfileCount: 80
                            dailyLikeRecentPostsCount: 30
                            dailyRevokeConnectionCount: 10
                            dailyEndorsedSkillsCount: 10
                            dailyFollowedProfilesCount: 20
                            dailyCommentRecentPostCount: 10
                        rangeMax:
                          description: Maximum values for ranged limits mode
                          type: object
                          title: LinkedInAccountLimitsValues
                          properties: *ref_152
                          example: *ref_153
                        fixedMax:
                          description: Fixed maximum values for fixed limits mode
                          type: object
                          title: LinkedInAccountLimitsValues
                          properties: *ref_152
                          example: *ref_153
                      required: &ref_157
                        - limitsMode
                      example: &ref_158
                        limitsMode: Fixed
                        fixedMax:
                          dailyDetectCount: 100
                          dailySendConnectionRequestCount: 20
                          dailySendMessageCount: 50
                          dailySendSalesNavigatorConnectionRequestCount: 10
                          dailyInMailCount: 10
                          dailyViewProfileCount: 80
                          dailyLikeRecentPostsCount: 30
                          dailyRevokeConnectionCount: 10
                          dailyEndorsedSkillsCount: 10
                          dailyFollowedProfilesCount: 20
                    userLimitValues:
                      nullable: true
                      type: object
                      title: LinkedInAccountLimitsValues
                      description: Individual daily limit values for LinkedIn automation actions.
                      properties: *ref_152
                      example: *ref_153
                    revokeSettings:
                      nullable: true
                      type: object
                      title: LinkedInAccountRevokeSettings
                      description: Connection revocation settings for a LinkedIn account.
                      properties: &ref_480
                        enabled:
                          type: boolean
                          description: Whether automatic connection revocation is enabled
                        periodDays:
                          type: integer
                          description: Number of days after which connections are revoked
                      required: &ref_481
                        - enabled
                        - periodDays
                      example: &ref_482
                        enabled: true
                        periodDays: 30
                    voiceProfile:
                      nullable: true
                      type: object
                      title: LinkedInAccountVoiceProfile
                      description: Voice profile associated with a LinkedIn account.
                      properties: &ref_483
                        voiceProfileId:
                          type: integer
                          nullable: true
                          description: ID of the voice profile
                        voiceProfileName:
                          type: string
                          description: Name of the voice profile
                        isDefault:
                          type: boolean
                          description: Whether this is the default voice profile
                      example: &ref_484
                        voiceProfileId: 5
                        voiceProfileName: Professional tone
                        isDefault: true
                  example: &ref_155
                    id: 10
                    name: John Doe
                    status: enabled
                    profileUrl: https://www.linkedin.com/in/johndoe
                    photoUrl: https://media.licdn.com/photo.jpg
                    ownerUserId: 42
                    accountType: premium
                    authType: cookie
                    cookieStatus: valid
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view LinkedIn accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewLinkedInAccount] are denied for userId 123.
                code: linkedInAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/linkedin-accounts/{id}:
    get:
      tags:
        - LinkedIn Accounts
      summary: Get a LinkedIn account
      x-required-scope: channels:read
      description: |-
        <small>_Requires the `channels:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the full record of a single connected LinkedIn account by its id — profile details, account and cookie status, current usage against its daily automation limits, and its auto-revoke settings.
      operationId: GetLinkedInAccount
      parameters:
        - name: id
          in: path
          required: true
          description: LinkedIn account ID
          schema:
            type: integer
      responses:
        '200':
          description: LinkedIn account details
          content:
            application/json:
              schema:
                type: object
                title: LinkedInAccount
                description: Full representation of a LinkedIn account.
                properties: *ref_154
                example: *ref_155
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: linkedInAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this LinkedIn account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewLinkedInAccount] are denied for userId 123.
                code: linkedInAccount.forbidden
        '404':
          description: LinkedIn account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: LinkedIn account not found
                code: linkedInAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - LinkedIn Accounts
      summary: Delete a LinkedIn account
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to disconnect a LinkedIn account and remove it from Reply. An account that is still in use by one or more sequences is rejected; pass force=true to delete it anyway. To remove several accounts in one call, use the bulk-delete endpoint instead.
      operationId: DeleteLinkedInAccount
      parameters:
        - name: id
          in: path
          required: true
          description: LinkedIn account ID
          schema:
            type: integer
        - name: force
          in: query
          required: false
          description: Whether to force delete even if the account is in use by sequences
          schema:
            type: boolean
      responses:
        '204':
          description: LinkedIn account deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: linkedInAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Cannot delete because voice profile count exceeds remaining LinkedIn accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Cannot delete this LinkedIn account because you have more voice profiles than remaining LinkedIn accounts
                code: linkedInAccount.voiceProfileConflict
        '404':
          description: LinkedIn account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: LinkedIn account not found
                code: linkedInAccount.notFound
        '409':
          description: Account is in use by sequences (use force=true to override)
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: LinkedIn account is currently in use by one or more sequences
                code: linkedInAccount.accountInUse
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/linkedin-accounts/bulk-delete:
    post:
      tags:
        - LinkedIn Accounts
      summary: Bulk delete LinkedIn accounts
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to disconnect several LinkedIn accounts in one call — up to 100 ids per request. Set force to true to also delete accounts that are still in use by sequences. Accounts are processed one by one and successful deletions are kept even when others fail; the response returns only the account ids that were not deleted, each with its error details.
      operationId: BulkDeleteLinkedInAccounts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: BulkDeleteLinkedInAccountsRequest
              description: Request body for bulk deleting LinkedIn accounts.
              properties: &ref_485
                ids:
                  type: array
                  items:
                    type: integer
                  description: List of LinkedIn account IDs to delete
                force:
                  type: boolean
                  description: Whether to force delete accounts that are in use by sequences
              required: &ref_486
                - ids
              example: &ref_487
                ids:
                  - 10
                  - 11
                  - 12
                force: false
      responses:
        '200':
          description: |-
            Bulk delete results. Only failed items appear in the response dictionary.

            Possible per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 2 | `NotFound` — account does not exist |
            | 3 | `AccountInUse` — account is in use by sequences (omit `force=true` triggers this) |
            | 7 | `InternalError` — unexpected failure |
            | 8 | `VoiceProfileConflict` — more voice profiles than remaining LinkedIn accounts |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /ids
                        detail: At least one ID must be provided.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: linkedInAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete LinkedIn accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageLinkedInAccount] are denied for userId 123.
                code: linkedInAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/linkedin-accounts/{id}/toggle-status:
    post:
      tags:
        - LinkedIn Accounts
      summary: Toggle LinkedIn account status
      x-required-scope: channels:operate
      description: |-
        <small>_Requires the `channels:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to pause or resume LinkedIn automation on a single account. The call flips the account between enabled and disabled — there is no separate enable or disable endpoint — and returns the resulting status. An account whose LinkedIn cookie is no longer valid cannot be toggled; reconnect it first.
      operationId: ToggleLinkedInAccountStatus
      parameters:
        - name: id
          in: path
          required: true
          description: LinkedIn account ID
          schema:
            type: integer
      responses:
        '200':
          description: Account status toggled successfully
          content:
            application/json:
              schema:
                type: object
                title: LinkedInAccountToggleStatus
                description: Response after toggling a LinkedIn account status.
                properties: &ref_488
                  status:
                    type: string
                    description: New status of the account after toggling
                    enum:
                      - disabled
                      - enabled
                      - dailyLimitReached
                      - cookieInvalid
                required: &ref_489
                  - status
                example: &ref_490
                  status: enabled
        '400':
          description: |-
            Route-parameter validation failure, or a business rule rejection
            (e.g. LinkedIn cookie is invalid).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_cookie_invalid:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Cannot toggle status while cookie is invalid
                    code: linkedInAccount.cookieInvalid
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this LinkedIn account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageLinkedInAccount] are denied for userId 123.
                code: linkedInAccount.forbidden
        '404':
          description: LinkedIn account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: LinkedIn account not found
                code: linkedInAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/linkedin-accounts/{id}/limits:
    put:
      tags:
        - LinkedIn Accounts
      summary: Update LinkedIn account limits
      x-required-scope: channels:operate
      description: |-
        <small>_Requires the `channels:operate` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to cap how much LinkedIn automation an account performs per day — connection requests, messages, InMails, profile views, and the other per-action daily counters. Set limitsMode to Fixed and fill fixedMax to use one hard ceiling per action, or set it to Ranged and fill rangeMin and rangeMax to have Reply pick a daily value inside that range. The whole limits object is replaced, so send every value you want to keep.
      operationId: UpdateLinkedInAccountLimits
      parameters:
        - name: id
          in: path
          required: true
          description: LinkedIn account ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: LinkedInAccountLimits
              description: Daily limits configuration for a LinkedIn account.
              properties: *ref_156
              required: *ref_157
              example: *ref_158
      responses:
        '204':
          description: Limits updated successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: linkedInAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this LinkedIn account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageLinkedInAccount] are denied for userId 123.
                code: linkedInAccount.forbidden
        '404':
          description: LinkedIn account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: LinkedIn account not found
                code: linkedInAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/linkedin-accounts/{id}/revoke-settings:
    put:
      tags:
        - LinkedIn Accounts
      summary: Update LinkedIn account revoke settings
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need the account to withdraw its own LinkedIn connection requests that go unanswered. Set enabled to true and periodDays to the number of days a request may stay pending before it is withdrawn, or set enabled to false to stop withdrawing them.
      operationId: UpdateLinkedInAccountRevokeSettings
      parameters:
        - name: id
          in: path
          required: true
          description: LinkedIn account ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: LinkedInAccountRevokeSettingsUpdateRequest
              description: Request body for updating revocation settings on a LinkedIn account.
              properties: &ref_491
                enabled:
                  type: boolean
                  description: Whether automatic connection revocation is enabled
                periodDays:
                  type: integer
                  description: Number of days after which connections are revoked
              required: &ref_492
                - enabled
                - periodDays
              example: &ref_493
                enabled: true
                periodDays: 30
      responses:
        '204':
          description: Revoke settings updated successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Validation failure on the request body or route parameter, or a business
            rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body or route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: linkedInAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this LinkedIn account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageLinkedInAccount] are denied for userId 123.
                code: linkedInAccount.forbidden
        '404':
          description: LinkedIn account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: LinkedIn account not found
                code: linkedInAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/linkedin-accounts/connection-link:
    post:
      tags:
        - LinkedIn Accounts
      summary: Create a connection link
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to invite a named LinkedIn account to be connected. Give the account a name up front and the response returns a connection link to hand to whoever owns the profile, plus the id of the pending account created for it. The account appears under the pending endpoint until the link is completed, after which it becomes a regular LinkedIn account. To issue a link without naming the account first, use the connect endpoint instead.
      operationId: CreateLinkedInConnectionLink
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: CreateConnectionLinkRequest
              description: Request body for creating a new LinkedIn connection link.
              properties: &ref_494
                name:
                  type: string
                  description: Display name for the LinkedIn account being connected
              required: &ref_495
                - name
              example: &ref_496
                name: John Doe LinkedIn
      responses:
        '201':
          description: Connection link created successfully
          content:
            application/json:
              schema:
                type: object
                title: ConnectionLinkWithPending
                description: A connection link with the associated pending account ID.
                properties: &ref_497
                  connectionLink:
                    type: string
                    description: URL to use for connecting the LinkedIn account
                  pendingAccountId:
                    type: integer
                    description: ID of the pending LinkedIn account created for this connection attempt
                example: &ref_498
                  connectionLink: https://app.reply.io/connect/linkedin?token=abc123
                  pendingAccountId: 50
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /name
                        detail: '''name'' is required.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Failed to create connection link
                    code: linkedInAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create LinkedIn accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageLinkedInAccount] are denied for userId 123.
                code: linkedInAccount.forbidden
        '409':
          description: LinkedIn account limit reached or payment required
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Maximum number of LinkedIn accounts reached
                code: linkedInAccount.limitReached
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/linkedin-accounts/connect:
    post:
      tags:
        - LinkedIn Accounts
      summary: Create a direct connection link
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need a connection link without deciding the account name up front — the name is captured while the link is being completed. No pending account is created until then. To name the account in advance and track it as pending, use the connection-link endpoint instead.
      operationId: CreateDirectLinkedInConnectionLink
      responses:
        '200':
          description: Direct connection link created successfully
          content:
            application/json:
              schema:
                type: object
                title: ConnectionLink
                description: A link for connecting a LinkedIn account via browser extension.
                properties: &ref_159
                  connectionLink:
                    type: string
                    description: URL to use for connecting the LinkedIn account
                example: &ref_160
                  connectionLink: https://app.reply.io/connect/linkedin?token=abc123
        '400':
          description: Failed to create direct connection link
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Failed to create connection link
                code: linkedInAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create LinkedIn accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageLinkedInAccount] are denied for userId 123.
                code: linkedInAccount.forbidden
        '409':
          description: LinkedIn account limit reached or payment required
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Maximum number of LinkedIn accounts reached
                code: linkedInAccount.limitReached
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/linkedin-accounts/{id}/reconnect:
    post:
      tags:
        - LinkedIn Accounts
      summary: Reconnect a LinkedIn account
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when an already-connected LinkedIn account has stopped working because its session expired — its cookie status is no longer valid. The response returns a fresh connection link for that same account; once it is completed the account resumes with its existing name, limits, and sequence assignments.
      operationId: ReconnectLinkedInAccount
      parameters:
        - name: id
          in: path
          required: true
          description: LinkedIn account ID to reconnect
          schema:
            type: integer
      responses:
        '200':
          description: Reconnection link created successfully
          content:
            application/json:
              schema:
                type: object
                title: ConnectionLink
                description: A link for connecting a LinkedIn account via browser extension.
                properties: *ref_159
                example: *ref_160
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: linkedInAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this LinkedIn account
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageLinkedInAccount] are denied for userId 123.
                code: linkedInAccount.forbidden
        '404':
          description: LinkedIn account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: LinkedIn account not found
                code: linkedInAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/linkedin-accounts/pending:
    get:
      tags:
        - LinkedIn Accounts
      summary: List pending LinkedIn accounts
      x-required-scope: channels:read
      description: |-
        <small>_Requires the `channels:read` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to track LinkedIn accounts that were invited through a connection link but have not completed the connection yet. Each entry carries the name it was invited under, its connection link, when that link expires, and whether it has already expired.
      operationId: ListPendingLinkedInAccounts
      responses:
        '200':
          description: List of pending LinkedIn accounts
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: PendingLinkedInAccount
                  description: A LinkedIn account that is pending connection.
                  properties: &ref_499
                    id:
                      type: integer
                      description: Unique identifier for the pending account
                      readOnly: true
                    name:
                      type: string
                      description: Display name of the pending account
                    connectionLink:
                      type: string
                      description: URL to use for completing the connection
                    expiresAtUtc:
                      type: string
                      format: date-time
                      description: UTC timestamp when the connection link expires
                    isExpired:
                      type: boolean
                      description: Whether the connection link has expired
                  example: &ref_500
                    id: 50
                    name: John Doe LinkedIn
                    connectionLink: https://app.reply.io/connect/linkedin?token=abc123
                    expiresAtUtc: '2026-04-01T12:00:00Z'
                    isExpired: false
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view pending LinkedIn accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewLinkedInAccount] are denied for userId 123.
                code: linkedInAccount.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/linkedin-accounts/pending/{id}:
    delete:
      tags:
        - LinkedIn Accounts
      summary: Delete a pending LinkedIn account
      x-required-scope: channels:write
      description: |-
        <small>_Requires the `channels:write` scope (or a broader one that includes it)._</small>

        Use this endpoint when you need to cancel an outstanding LinkedIn connection invitation — for example because its link expired or was sent to the wrong person. This removes the pending entry only; connected accounts are removed with the delete endpoint instead.
      operationId: DeletePendingLinkedInAccount
      parameters:
        - name: id
          in: path
          required: true
          description: Pending LinkedIn account ID
          schema:
            type: integer
      responses:
        '204':
          description: Pending account deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Route-parameter validation failure, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more parameters did not match the expected format.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid request
                    code: linkedInAccount.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete pending LinkedIn accounts
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageLinkedInAccount] are denied for userId 123.
                code: linkedInAccount.forbidden
        '404':
          description: Pending LinkedIn account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Pending LinkedIn account not found
                code: linkedInAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/live-data/searches/preview:
    post:
      tags:
        - Live Data
      summary: Preview a Live Data search
      x-required-scope: contacts:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Starts a Live Data preview for the given filters and returns a background job to poll. The job is tracked by `GET /v3/background-jobs/{id}`; on completion its `jsonDataResult` carries `{ contactsCount, companiesCount, sampleContacts }`, where `sampleContacts` is a capped sample of matching contacts. A preview adds no prospects and consumes no credits.
      operationId: PreviewLiveDataSearch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Live Data preview request
              description: Filters to preview before running a full Live Data search.
              required: &ref_501
                - filters
              properties: &ref_502
                filters:
                  type: object
                  title: Live Data filters
                  description: |-
                    Account- and contact-level filter configuration for a Live Data search.

                    Most collections are capped at 25 items. `accountKeywords` and `contactKeywords` are always present and non-null in responses even when empty (`{ "values": [], "type": "or" }`).
                  properties: &ref_167
                    accountListIds:
                      type: array
                      maxItems: 25
                      description: Saved account-list ids the search is scoped to
                      items:
                        type: object
                        title: Integer filter value
                        description: A single integer value used in an autopilot filter, with include/exclude polarity.
                        required: *ref_161
                        properties: *ref_162
                    industries:
                      type: array
                      maxItems: 25
                      description: Industry filters
                      items:
                        type: object
                        title: Filter value
                        description: A single string value used in an autopilot filter, with include/exclude polarity.
                        required: *ref_41
                        properties: *ref_42
                    companyLocations:
                      type: array
                      maxItems: 25
                      description: Company location filters
                      items:
                        type: object
                        title: Filter value
                        description: A single string value used in an autopilot filter, with include/exclude polarity.
                        required: *ref_41
                        properties: *ref_42
                    companySizes:
                      type: array
                      maxItems: 25
                      description: Company size bands to include
                      items:
                        type: string
                        title: Company size
                        description: Headcount band used when filtering companies for autopilot search.
                        enum: *ref_163
                    headcountGrowth:
                      allOf:
                        - type: object
                          title: Headcount growth range
                          description: |-
                            Min/max range applied to the company's total headcount growth (percent). Either bound may be omitted.

                            When both are provided, `min` must be less than or equal to `max`.
                          properties: *ref_164
                      nullable: true
                      description: Overall company headcount growth range
                    departmentHeadcountGrowth:
                      allOf:
                        - type: object
                          title: Department headcount growth range
                          description: |-
                            Min/max range applied to a specific department's headcount growth (percent). Either bound may be omitted.

                            When both are provided, `min` must be less than or equal to `max`.
                          required: *ref_165
                          properties: *ref_166
                      nullable: true
                      description: Per-department headcount growth range
                    minRevenue:
                      allOf:
                        - type: string
                          title: Company revenue tier
                          description: Annual revenue tier used when filtering companies for autopilot search.
                          enum: *ref_43
                      nullable: true
                      description: Minimum company revenue tier
                    maxRevenue:
                      allOf:
                        - type: string
                          title: Company revenue tier
                          description: Annual revenue tier used when filtering companies for autopilot search.
                          enum: *ref_43
                      nullable: true
                      description: Maximum company revenue tier. When both `minRevenue` and `maxRevenue` are provided, `minRevenue` must be less than or equal to `maxRevenue`.
                    accountKeywords:
                      allOf:
                        - type: object
                          title: Keyword filter
                          description: |-
                            Boolean keyword filter applied to account or contact searches.

                            In responses this field is always present and non-null even when no keywords are configured (`{ "values": [], "type": "or" }`).
                          properties: *ref_44
                      description: Free-text keyword filter applied at the account level. Always present and non-null in responses.
                    isHiringOnLinkedIn:
                      type: boolean
                      description: When `true`, restrict to companies currently hiring on LinkedIn. `false` (the default) applies no filter — it is treated the same as omitting the field.
                    contactLocations:
                      type: array
                      maxItems: 25
                      description: Contact location filters
                      items:
                        type: object
                        title: Filter value
                        description: A single string value used in an autopilot filter, with include/exclude polarity.
                        required: *ref_41
                        properties: *ref_42
                    jobTitles:
                      type: array
                      maxItems: 25
                      description: Contact job-title filters
                      items:
                        type: object
                        title: Filter value
                        description: A single string value used in an autopilot filter, with include/exclude polarity.
                        required: *ref_41
                        properties: *ref_42
                    departments:
                      type: array
                      maxItems: 25
                      description: Contact department filters
                      items:
                        type: object
                        title: Filter value
                        description: A single string value used in an autopilot filter, with include/exclude polarity.
                        required: *ref_41
                        properties: *ref_42
                    seniorities:
                      type: array
                      maxItems: 25
                      description: Seniority slugs to include
                      items:
                        type: string
                        minLength: 1
                        maxLength: 200
                    contactKeywords:
                      allOf:
                        - type: object
                          title: Keyword filter
                          description: |-
                            Boolean keyword filter applied to account or contact searches.

                            In responses this field is always present and non-null even when no keywords are configured (`{ "values": [], "type": "or" }`).
                          properties: *ref_44
                      description: Free-text keyword filter applied at the contact level. Always present and non-null in responses.
                maxPeoplePerCompany:
                  type: integer
                  minimum: 1
                  default: 1
                  description: Maximum contacts to consider per company. Optional; defaults to 1 when omitted.
      responses:
        '202':
          description: Preview accepted; poll the returned job for progress and results
          content:
            application/json:
              schema:
                type: object
                required:
                  - jobId
                properties:
                  jobId:
                    type: string
                    format: uuid
                    description: Background job id; poll `GET /v3/background-jobs/{id}`.
        '400':
          description: Invalid filters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Filters are invalid.
                code: liveDataSearch.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '409':
          description: A Live Data search is already in progress for the team
          content:
            application/problem+json:
              schema:
                allOf: *ref_6
                title: Business Problem
                description: |-
                  Domain error response carrying a stable, namespaced error slug.
                  Emitted for most 4xx responses (business 400, 403, 404, 409, …) and
                  for 503 when a downstream dependency is unavailable.
              example:
                title: Conflict
                status: 409
                detail: A live data search is already in progress.
                code: liveDataSearch.searchInProgress
        '502':
          description: Upstream service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: 'Upstream service failure: ...'
                code: liveDataSearch.upstreamFailure
  /v3/live-data/searches:
    get:
      tags:
        - Live Data
      summary: List Live Data searches
      x-required-scope: contacts:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of past Live Data searches for the caller's team, most recent first. Each item includes status and progress for polling.
      operationId: ListLiveDataSearches
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
      responses:
        '200':
          description: Paginated list of searches
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Live Data search
                      description: Summary of a Live Data search.
                      required: &ref_168
                        - id
                        - status
                        - startedAt
                      properties: &ref_169
                        id:
                          type: integer
                          description: Search id
                        status:
                          type: string
                          title: Live Data search status
                          description: |-
                            Lifecycle status of a Live Data search.
                            - `inProgress` — actively searching and adding contacts.
                            - `finished` — completed; the requested number of contacts was added.
                            - `noMoreContacts` — completed; the audience was exhausted before the requested count was reached.
                            - `manuallyPaused` — paused by the user.
                            - `pausedDueToInsufficientCredits` — paused because the team ran out of credits.
                          enum: &ref_503
                            - inProgress
                            - finished
                            - noMoreContacts
                            - manuallyPaused
                            - pausedDueToInsufficientCredits
                        startedAt:
                          type: string
                          format: date-time
                          description: When the search started (UTC)
                        contactsFound:
                          type: integer
                          description: Number of contacts found and added so far
                        usedCredits:
                          type: integer
                          description: Total credits spent by the search (contacts + emails + phones)
                        userId:
                          type: integer
                          description: Id of the user who started the search
                        sequenceId:
                          type: integer
                          nullable: true
                          description: Sequence the found contacts are added to, when configured
                        sequenceName:
                          type: string
                          nullable: true
                          description: Name of the target sequence, when configured
                        lists:
                          type: array
                          description: Prospect lists the found contacts are added to
                          items:
                            type: object
                            required:
                              - id
                              - name
                            properties:
                              id:
                                type: integer
                              name:
                                type: string
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: liveDataSearch.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
    post:
      tags:
        - Live Data
      summary: Start a Live Data search
      x-required-scope: contacts:write
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `contacts:write` scope (or a broader one that includes it)._</small>

        Starts a Live Data search that finds contacts matching the filters and adds them as prospects (optionally moving them into a sequence and/or lists). Consumes credits from the Reply credit pool per resulting contact. Returns the created search's id; track its progress via `GET /v3/live-data/searches/{id}`.
      operationId: StartLiveDataSearch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Start Live Data search request
              description: Configuration for a Live Data search that adds found contacts as prospects.
              required: &ref_504
                - filters
                - contactsCountToAdd
              properties: &ref_505
                filters:
                  type: object
                  title: Live Data filters
                  description: |-
                    Account- and contact-level filter configuration for a Live Data search.

                    Most collections are capped at 25 items. `accountKeywords` and `contactKeywords` are always present and non-null in responses even when empty (`{ "values": [], "type": "or" }`).
                  properties: *ref_167
                contactsCountToAdd:
                  type: integer
                  minimum: 1
                  description: Number of contacts to find and add
                addContactsWithoutEmails:
                  type: boolean
                  description: When `true`, contacts without an email address are still added
                maxPeoplePerCompany:
                  type: integer
                  minimum: 1
                  default: 1
                  description: Maximum contacts to add per company. Optional; defaults to 1 when omitted.
                sequenceId:
                  type: integer
                  nullable: true
                  description: Sequence to move the found contacts into
                listIds:
                  type: array
                  description: Prospect lists to add the found contacts to
                  items:
                    type: integer
                referenceUrl:
                  type: string
                  nullable: true
                  description: Optional reference URL used to seed the search
                searchContactPhones:
                  type: boolean
                  description: When `true`, enrich phone numbers during the search
      responses:
        '200':
          description: Search started
          content:
            application/json:
              schema:
                type: object
                required:
                  - searchId
                properties:
                  searchId:
                    type: integer
                    description: Id of the created search; poll `GET /v3/live-data/searches/{id}`.
        '400':
          description: Invalid filters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Filters are invalid.
                code: liveDataSearch.invalidParameter
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: You do not have permission to add prospects
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to add prospects.
                code: liveDataSearch.forbidden
        '409':
          description: A Live Data search is already in progress for the team
          content:
            application/problem+json:
              schema:
                allOf: *ref_6
                title: Business Problem
                description: |-
                  Domain error response carrying a stable, namespaced error slug.
                  Emitted for most 4xx responses (business 400, 403, 404, 409, …) and
                  for 503 when a downstream dependency is unavailable.
              example:
                title: Conflict
                status: 409
                detail: A live data search is already in progress.
                code: liveDataSearch.searchInProgress
        '422':
          description: The filters matched no contacts, so no search could be started
          content:
            application/problem+json:
              schema:
                allOf: *ref_6
                title: Business Problem
                description: |-
                  Domain error response carrying a stable, namespaced error slug.
                  Emitted for most 4xx responses (business 400, 403, 404, 409, …) and
                  for 503 when a downstream dependency is unavailable.
              example:
                title: Unprocessable Entity
                status: 422
                detail: No matching contacts were found for the given filters.
                code: liveDataSearch.noMatchingContacts
        '502':
          description: Upstream service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: 'Upstream service failure: ...'
                code: liveDataSearch.upstreamFailure
  /v3/live-data/searches/{id}:
    get:
      tags:
        - Live Data
      summary: Get a Live Data search
      x-required-scope: contacts:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Returns a single Live Data search by id, including its status, progress, and the filters it was run with.
      operationId: GetLiveDataSearch
      parameters:
        - name: id
          in: path
          required: true
          description: Search id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Search found
          content:
            application/json:
              schema:
                title: Live Data search details
                description: A single Live Data search, including the filters it was run with.
                allOf: &ref_506
                  - type: object
                    title: Live Data search
                    description: Summary of a Live Data search.
                    required: *ref_168
                    properties: *ref_169
                  - type: object
                    properties:
                      filters:
                        type: object
                        title: Live Data filters
                        description: |-
                          Account- and contact-level filter configuration for a Live Data search.

                          Most collections are capped at 25 items. `accountKeywords` and `contactKeywords` are always present and non-null in responses even when empty (`{ "values": [], "type": "or" }`).
                        properties: *ref_167
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Search not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
  /v3/live-data/filter-values/industries:
    get:
      tags:
        - Live Data
      summary: Industries typeahead
      x-required-scope: contacts:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Typeahead values for the `industries` filter on the Live Data / Autopilot sidebar.
      operationId: ListLiveDataIndustryFilterValues
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match
          schema:
            type: string
      responses:
        '200':
          description: Page of industry values
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: string
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: liveDataFilterValues.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '502':
          description: Upstream service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: 'Upstream service failure: ...'
                code: liveDataFilterValues.upstreamFailure
  /v3/live-data/filter-values/departments:
    get:
      tags:
        - Live Data
      summary: Departments typeahead
      x-required-scope: contacts:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Typeahead values for the `departments` filter on the Live Data / Autopilot sidebar.
      operationId: ListLiveDataDepartmentFilterValues
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match
          schema:
            type: string
      responses:
        '200':
          description: Page of department values
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: string
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: liveDataFilterValues.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '502':
          description: Upstream service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: 'Upstream service failure: ...'
                code: liveDataFilterValues.upstreamFailure
  /v3/live-data/filter-values/seniorities:
    get:
      tags:
        - Live Data
      summary: Seniorities typeahead
      x-required-scope: contacts:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Typeahead values for the `seniorities` filter on the Live Data / Autopilot sidebar.
      operationId: ListLiveDataSeniorityFilterValues
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match
          schema:
            type: string
      responses:
        '200':
          description: Page of seniority values
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: string
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: liveDataFilterValues.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '502':
          description: Upstream service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: 'Upstream service failure: ...'
                code: liveDataFilterValues.upstreamFailure
  /v3/live-data/filter-values/locations:
    get:
      tags:
        - Live Data
      summary: Locations typeahead
      x-required-scope: contacts:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Typeahead values for the `locations` filter on the Live Data / Autopilot sidebar. The response mixes countries, regions, and cities (no separate `/countries` endpoint).
      operationId: ListLiveDataLocationFilterValues
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match
          schema:
            type: string
      responses:
        '200':
          description: Page of location values
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: string
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: liveDataFilterValues.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '502':
          description: Upstream service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: 'Upstream service failure: ...'
                code: liveDataFilterValues.upstreamFailure
  /v3/live-data/filter-values/job-titles:
    get:
      tags:
        - Live Data
      summary: Job titles typeahead
      x-required-scope: contacts:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `contacts:read` scope (or a broader one that includes it)._</small>

        Typeahead values for the `jobTitles` filter on the Live Data / Autopilot sidebar.
      operationId: ListLiveDataJobTitleFilterValues
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 100, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: search
          in: query
          required: false
          description: Case-insensitive substring match
          schema:
            type: string
      responses:
        '200':
          description: Page of job title values
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: string
                  hasMore:
                    type: boolean
        '400':
          description: Invalid pagination parameters
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000
                code: liveDataFilterValues.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '502':
          description: Upstream service failure
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Gateway
                status: 502
                detail: 'Upstream service failure: ...'
                code: liveDataFilterValues.upstreamFailure
  /v3/reporting/emails/overview:
    post:
      tags:
        - Reports
      summary: Get email reporting overview
      x-required-scope: reporting:read
      description: |-
        <small>_Requires the `reporting:read` scope (or a broader one that includes it)._</small>

        Returns email delivery and engagement metrics with optional trend comparison.

        Provides aggregated statistics including delivery rates, opens, replies, bounces, and clicks.
        Optionally compare against a previous period by providing the `compareTo` field.
      operationId: GetEmailsOverview
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Email Reporting Overview Request
              description: Request body for email overview reporting with optional comparison period
              required: &ref_507
                - filters
              properties: &ref_508
                filters:
                  allOf: &ref_172
                    - type: object
                      title: Reporting Filters
                      description: Base filters shared across all reporting endpoints
                      properties: &ref_170
                        from:
                          type: string
                          format: date-time
                          description: Start date of the reporting period
                          example: '2026-01-01T00:00:00Z'
                        to:
                          type: string
                          format: date-time
                          description: End date of the reporting period
                          example: '2026-03-01T00:00:00Z'
                        dateRangePreset:
                          type: string
                          description: Predefined date range shortcut. Defaults to lastWeek when neither dateRangePreset nor from/to are provided. Use allTime to retrieve the full historical report. Cannot be combined with from/to.
                          enum:
                            - lastWeek
                            - lastMonth
                            - lastYear
                            - allTime
                          default: lastWeek
                        teamIds:
                          type: array
                          items:
                            type: integer
                          description: Filter by team IDs
                        userIds:
                          type: array
                          items:
                            type: integer
                          description: Filter by user IDs
                        contactListIds:
                          type: array
                          items:
                            type: integer
                          description: Filter by contact list IDs
                        emailValidationStatuses:
                          type: array
                          items:
                            type: string
                            enum:
                              - requiresValidation
                              - valid
                              - notValid
                              - risky
                              - validationFailed
                              - catchAll
                          description: Filter by email validation status
                        companies:
                          type: array
                          items:
                            type: string
                          description: Filter by company names
                        companySizes:
                          type: array
                          items:
                            type: string
                            enum:
                              - empty
                              - selfEmployed
                              - ten
                              - fifty
                              - twoHundred
                              - fiveHundred
                              - oneThousand
                              - fiveThousand
                              - tenThousand
                              - overTenThousand
                          description: Filter by company size ranges
                        industries:
                          type: array
                          items:
                            type: string
                          description: Filter by industry names
                        cities:
                          type: array
                          items:
                            type: string
                          description: Filter by city names
                        states:
                          type: array
                          items:
                            type: string
                          description: Filter by state/region names
                        countries:
                          type: array
                          items:
                            type: string
                          description: Filter by country names
                        titles:
                          type: array
                          items:
                            type: string
                          description: Filter by job titles
                        sequenceIds:
                          type: array
                          items:
                            type: integer
                          description: Filter by sequence IDs
                        includeOutOfSequence:
                          type: boolean
                          description: Include activity outside of sequences
                          default: false
                        emailProviders:
                          type: array
                          items:
                            type: string
                            enum:
                              - none
                              - other
                              - gSuite
                              - office
                              - zoho
                              - mimecast
                              - proofpoint
                              - yandex
                              - ovh
                              - goDaddy
                              - ionos
                              - gandi
                              - hostinger
                              - oneAndOne
                              - amazon
                              - unknown
                              - barracuda
                              - spamexperts
                              - hotmail
                              - liveCom
                              - yahoo
                              - bloomberg
                              - gmail
                              - outlook
                              - ciscoSecureEmail
                              - titanMail
                              - protonmail
                              - namecheap
                              - appleMail
                              - linkedin
                          description: Filter by email provider type
                    - type: object
                      title: Email Reporting Filters
                      description: Filters specific to email reporting endpoints
                      properties:
                        emailAccountIds:
                          type: array
                          items:
                            type: integer
                            format: int64
                          description: Filter by email account IDs
                        emailSendingSources:
                          type: array
                          items:
                            type: string
                            enum:
                              - sequenceProcessing
                              - manualEmail
                          description: Filter by email sending source
                        bounceTypes:
                          type: array
                          items:
                            type: string
                            enum:
                              - unknown
                              - soft
                              - hard
                              - gmailApiLimitWarning
                              - office365LimitWarning
                              - mailboxFull
                              - authenticationFailure
                              - spamRejection
                              - policyViolation
                          description: Filter by bounce type
                        sentiments:
                          type: array
                          items:
                            type: string
                            enum:
                              - unknown
                              - interested
                              - notInterested
                              - doNotContact
                              - notNow
                              - forwarded
                              - meeting
                          description: Filter by reply sentiment category
                compareTo:
                  type: object
                  description: Optional comparison period to calculate trends against
                  properties:
                    from:
                      type: string
                      format: date-time
                      description: Start date of the comparison period
                      example: '2025-12-01T00:00:00Z'
                    to:
                      type: string
                      format: date-time
                      description: End date of the comparison period
                      example: '2025-12-31T00:00:00Z'
      responses:
        '200':
          description: Email overview with trends retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Emails Overview Response
                description: Email delivery and engagement metrics
                properties: &ref_509
                  contacted:
                    type: integer
                    description: Number of people contacted
                  delivered:
                    type: integer
                    description: Number of emails delivered
                  opened:
                    type: integer
                    description: Number of emails opened
                  replied:
                    type: integer
                    description: Number of emails replied to
                  interested:
                    type: integer
                    description: Number of replies marked as interested
                  notReached:
                    type: integer
                    description: Number of contacts not reached
                  optedOut:
                    type: integer
                    description: Number of opt-outs
                  outOfOffice:
                    type: integer
                    description: Number of out-of-office replies
                  bounced:
                    type: integer
                    description: Number of bounced emails
                  autoReplied:
                    type: integer
                    description: Number of auto-replies received
                  meetingsBooked:
                    type: integer
                    description: Number of meetings booked from emails
                  accounts:
                    type: integer
                    nullable: true
                    description: Total number of email accounts used
                  deliveredPercentage:
                    type: number
                    format: double
                    description: Delivery rate as a percentage (0–100)
                  openedPercentage:
                    type: number
                    format: double
                    description: Open rate as a percentage (0–100)
                  repliedPercentage:
                    type: number
                    format: double
                    description: Reply rate as a percentage (0–100)
                  interestedPercentage:
                    type: number
                    format: double
                    description: Interested rate as a percentage (0–100)
                  notReachedPercentage:
                    type: number
                    format: double
                    description: Not-reached rate as a percentage (0–100)
                  optedOutPercentage:
                    type: number
                    format: double
                    description: Opt-out rate as a percentage (0–100)
                  outOfOfficePercentage:
                    type: number
                    format: double
                    description: Out-of-office rate as a percentage (0–100)
                  bouncedPercentage:
                    type: number
                    format: double
                    description: Bounce rate as a percentage (0–100)
                  autoRepliedPercentage:
                    type: number
                    format: double
                    description: Auto-reply rate as a percentage (0–100)
                  meetingsBookedPercentage:
                    type: number
                    format: double
                    description: Meetings booked rate as a percentage (0–100)
        '400':
          description: Request-body validation failure (FluentValidator).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /filters/from
                    detail: '''from'' must be a valid ISO 8601 date.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view reports.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: reports.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/reporting/calls/overview:
    post:
      tags:
        - Reports
      summary: Get calls reporting overview
      x-required-scope: reporting:read
      description: |-
        <small>_Requires the `reporting:read` scope (or a broader one that includes it)._</small>

        Returns aggregated call statistics with per-member breakdown.

        Includes total calls, average duration, positive/answered counts, and inbound missing calls.
      operationId: GetCallsOverview
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filters
              properties:
                filters:
                  allOf: &ref_173
                    - type: object
                      title: Reporting Filters
                      description: Base filters shared across all reporting endpoints
                      properties: *ref_170
                    - type: object
                      title: Calls Reporting Filters
                      description: Filters specific to call reporting endpoints
                      properties:
                        callResolutions:
                          type: array
                          items:
                            type: string
                            enum:
                              - positive
                              - toCall
                              - negative
                          description: Filter by call resolution outcome
                        callDispositions:
                          type: array
                          items:
                            type: string
                            enum:
                              - answered
                              - loggedManually
                              - noAnswer
                              - busy
                              - fail
                          description: Filter by call disposition
                        callTypes:
                          type: array
                          items:
                            type: string
                            enum:
                              - outbound
                              - inbound
                          description: Filter by call direction
      responses:
        '200':
          description: Calls overview retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Calls Overview Response
                description: Aggregated call statistics with per-member breakdown
                properties: &ref_510
                  callsCount:
                    type: integer
                    description: Total number of calls
                  averageDuration:
                    type: integer
                    description: Average call duration in seconds
                  positiveCallsCount:
                    type: integer
                    description: Number of calls with positive resolution
                  positiveCallsPercentage:
                    type: number
                    format: double
                    description: Percentage of calls with positive resolution
                  answeredCallsCount:
                    type: integer
                    description: Number of answered calls
                  callsToContactCount:
                    type: number
                    format: double
                    description: Average calls per contact
                  inboundMissingCallsCount:
                    type: integer
                    description: Number of missed inbound calls
                  memberStatistics:
                    type: array
                    description: Per-member call statistics breakdown
                    items:
                      type: object
                      properties:
                        userId:
                          type: integer
                        callsCount:
                          type: integer
                        totalDuration:
                          type: integer
                          description: Total call duration in seconds
                        averageDuration:
                          type: integer
                          description: Average call duration in seconds
                        positiveCallsCount:
                          type: integer
                        positiveCallsPercentage:
                          type: number
                          format: double
                        answeredCallsCount:
                          type: integer
                        inboundMissingCallsCount:
                          type: integer
        '400':
          description: Request-body validation failure (FluentValidator).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /filters
                    detail: '''filters'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view reports.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: reports.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/reporting/tasks/overview:
    post:
      tags:
        - Reports
      summary: Get tasks reporting overview
      x-required-scope: reporting:read
      description: |-
        <small>_Requires the `reporting:read` scope (or a broader one that includes it)._</small>

        Returns aggregated task statistics broken down by type (call, email, LinkedIn, meetings, SMS, to-do, WhatsApp), with per-member breakdown.
      operationId: GetTasksOverview
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filters
              properties:
                filters:
                  allOf: &ref_174
                    - type: object
                      title: Reporting Filters
                      description: Base filters shared across all reporting endpoints
                      properties: *ref_170
                    - type: object
                      title: Tasks Reporting Filters
                      description: Filters specific to task reporting endpoints
                      properties:
                        taskStatuses:
                          type: array
                          items:
                            type: string
                            enum:
                              - created
                              - completed
                          description: Filter by task status
                        taskTypes:
                          type: array
                          items:
                            type: string
                            enum:
                              - toDo
                              - call
                              - meeting
                              - linkedIn
                              - manualEmail
                              - sms
                              - whatsApp
                          description: Filter by task type
      responses:
        '200':
          description: Tasks overview retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Tasks Overview Response
                description: Aggregated task statistics broken down by type, with per-member breakdown
                properties: &ref_511
                  totalTasks:
                    type: integer
                    description: Total number of tasks
                  callTasks:
                    type: object
                    title: Task Info
                    description: Count and percentage for a specific task type
                    properties: &ref_171
                      count:
                        type: integer
                        description: Number of tasks of this type
                      percentage:
                        type: number
                        format: double
                        description: Percentage this type represents of total tasks
                  emailTasks:
                    type: object
                    title: Task Info
                    description: Count and percentage for a specific task type
                    properties: *ref_171
                  linkedInTasks:
                    type: object
                    title: Task Info
                    description: Count and percentage for a specific task type
                    properties: *ref_171
                  meetingsBooked:
                    type: object
                    title: Task Info
                    description: Count and percentage for a specific task type
                    properties: *ref_171
                  smsTasks:
                    type: object
                    title: Task Info
                    description: Count and percentage for a specific task type
                    properties: *ref_171
                  toDoTasks:
                    type: object
                    title: Task Info
                    description: Count and percentage for a specific task type
                    properties: *ref_171
                  whatsAppTasks:
                    type: object
                    title: Task Info
                    description: Count and percentage for a specific task type
                    properties: *ref_171
                  memberStatistics:
                    type: array
                    description: Per-member task statistics breakdown
                    items:
                      type: object
                      properties:
                        userId:
                          type: integer
                        totalTasks:
                          type: integer
                        callTasks:
                          type: integer
                        emailTasks:
                          type: integer
                        linkedInTasks:
                          type: integer
                        meetingsBooked:
                          type: integer
                        smsTasks:
                          type: integer
                        toDoTasks:
                          type: integer
                        whatsAppTasks:
                          type: integer
        '400':
          description: Request-body validation failure (FluentValidator).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /filters
                    detail: '''filters'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view reports.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: reports.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/reporting/linkedin/overview:
    post:
      tags:
        - Reports
      summary: Get LinkedIn reporting overview
      x-required-scope: reporting:read
      description: |-
        <small>_Requires the `reporting:read` scope (or a broader one that includes it)._</small>

        Returns LinkedIn engagement metrics overview including connection requests, messages, InMails, and profile views.
      operationId: GetLinkedInOverview
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filters
              properties:
                filters:
                  allOf: &ref_175
                    - type: object
                      title: Reporting Filters
                      description: Base filters shared across all reporting endpoints
                      properties: *ref_170
                    - type: object
                      title: LinkedIn Reporting Filters
                      description: Filters specific to LinkedIn reporting endpoints
                      properties:
                        linkedInAccountIds:
                          type: array
                          items:
                            type: integer
                          description: Filter by LinkedIn account IDs
      responses:
        '200':
          description: LinkedIn overview retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: LinkedIn Overview Response
                description: LinkedIn engagement metrics overview
                properties: &ref_512
                  connectionsSent:
                    type: integer
                    description: Number of connection requests sent
                  connectionsAccepted:
                    type: integer
                    description: Number of connection requests accepted
                  connectionsAcceptedPercentage:
                    type: number
                    format: double
                    description: Connection acceptance rate as a percentage (0–100)
                  messagesSent:
                    type: integer
                    description: Number of LinkedIn messages sent
                  replied:
                    type: integer
                    description: Number of message replies received
                  repliedPercentage:
                    type: number
                    format: double
                    description: Message reply rate as a percentage (0–100)
                  inMailsSent:
                    type: integer
                    description: Number of InMails sent
                  inMailsReplied:
                    type: integer
                    description: Number of InMail replies received
                  inMailsRepliedPercentage:
                    type: number
                    format: double
                    description: InMail reply rate as a percentage (0–100)
                  connectionNotesSent:
                    type: integer
                    description: Number of connection notes sent
                  connectionNotesReplied:
                    type: integer
                    description: Number of connection note replies received
                  connectionNotesRepliedPercentage:
                    type: number
                    format: double
                    description: Connection notes reply rate as a percentage (0–100)
                  profileViews:
                    type: integer
                    description: Number of profile views
                  likes:
                    type: integer
                    description: Number of likes
                  follows:
                    type: integer
                    description: Number of follows
                  endorses:
                    type: integer
                    description: Number of endorsements
                  regularMessagesSent:
                    type: integer
                    description: Number of regular messages sent
                  regularMessagesReplied:
                    type: integer
                    description: Number of regular message replies received
                  regularMessagesRepliedPercentage:
                    type: number
                    format: double
                    description: Regular messages reply rate as a percentage (0–100)
        '400':
          description: Request-body validation failure (FluentValidator).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /filters
                    detail: '''filters'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view reports.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: reports.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/reporting/team-performance/overview:
    post:
      tags:
        - Reports
      summary: Get team performance overview
      x-required-scope: reporting:read
      description: |-
        <small>_Requires the `reporting:read` scope (or a broader one that includes it)._</small>

        Returns team performance metrics including meetings booked, contacts engaged, conversion rates, touches per contact, and response times, with per-member breakdown.
      operationId: GetTeamPerformanceOverview
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filters
              properties:
                filters:
                  allOf: &ref_176
                    - type: object
                      title: Reporting Filters
                      description: Base filters shared across all reporting endpoints
                      properties: *ref_170
                    - type: object
                      title: Team Performance Reporting Filters
                      description: Filters specific to team performance reporting endpoints
                      properties:
                        emailAccountIds:
                          type: array
                          items:
                            type: integer
                            format: int64
                          description: Filter by email account IDs
      responses:
        '200':
          description: Team performance overview retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Team Performance Overview Response
                description: Team performance metrics including meetings, contacts, and engagement rates
                properties: &ref_513
                  meetings:
                    type: integer
                    description: Total number of meetings booked
                  contacted:
                    type: integer
                    description: Total number of contacts engaged
                  meetingConversionPercentage:
                    type: number
                    format: double
                    description: Meeting conversion rate as a percentage (0–100)
                  touchesPerContact:
                    type: number
                    format: double
                    description: Average total touches per contact
                  autoTouchesPerContact:
                    type: number
                    format: double
                    description: Average automated touches per contact
                  manualTouchesPerContact:
                    type: number
                    format: double
                    description: Average manual touches per contact
                  averageResponseTimePerContact:
                    type: integer
                    description: Average response time per contact in seconds
                  memberStatistics:
                    type: array
                    description: Per-member performance breakdown
                    items:
                      type: object
                      properties:
                        userId:
                          type: integer
                        meetings:
                          type: integer
                        contacted:
                          type: integer
                        conversionPercentage:
                          type: number
                          format: double
                        touches:
                          type: number
                          format: double
                        autoTouches:
                          type: number
                          format: double
                        manualTouches:
                          type: number
                          format: double
                        responseTime:
                          type: integer
                          description: Response time in seconds
                        responseRate:
                          type: string
                          enum:
                            - slow
                            - fast
                            - average
                          description: Categorized response rate
        '400':
          description: Request-body validation failure (FluentValidator).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /filters
                    detail: '''filters'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view reports.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: reports.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/reporting/channel-efficiency/overview:
    post:
      tags:
        - Reports
      summary: Get channel efficiency overview
      x-required-scope: reporting:read
      description: |-
        <small>_Requires the `reporting:read` scope (or a broader one that includes it)._</small>

        Returns cross-channel efficiency statistics comparing performance across email, calls, LinkedIn, and other channels.
      operationId: GetChannelEfficiencyOverview
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filters
              properties:
                filters:
                  type: object
                  title: Reporting Filters
                  description: Base filters shared across all reporting endpoints
                  properties: *ref_170
      responses:
        '200':
          description: Channel efficiency overview retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Channel Efficiency Overview Response
                description: Cross-channel efficiency statistics
                properties: &ref_514
                  totalPeopleContacted:
                    type: integer
                    description: Total number of people contacted across all channels
                  totalTouches:
                    type: integer
                    description: Total number of touches across all channels
                  replies:
                    type: integer
                    description: Total number of replies received
                  repliesPercentage:
                    type: number
                    format: decimal
                    description: Reply rate as a percentage
                  meetingsBooked:
                    type: integer
                    description: Total number of meetings booked
                  meetingsBookedPercentage:
                    type: number
                    format: decimal
                    description: Meetings booked rate as a percentage
        '400':
          description: Request-body validation failure (FluentValidator).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /filters
                    detail: '''filters'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view reports.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: reports.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/reporting/emails:
    post:
      tags:
        - Reports
      summary: List email activity
      x-required-scope: reporting:read
      description: |-
        <small>_Requires the `reporting:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of individual email activity records matching the specified filters.

        Use `top` and `skip` query parameters for pagination.
      operationId: GetEmailsList
      parameters:
        - name: top
          in: query
          required: false
          description: Number of records to return (page size)
          schema:
            type: integer
            minimum: 1
        - name: skip
          in: query
          required: false
          description: Number of records to skip
          schema:
            type: integer
            minimum: 0
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filters
              properties:
                filters:
                  allOf: *ref_172
      responses:
        '200':
          description: Email list retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Email List Item
                      description: Individual email activity record in a reporting list
                      properties: &ref_515
                        contactId:
                          type: integer
                          description: ID of the contact
                        firstName:
                          type: string
                          description: Contact's first name
                        lastName:
                          type: string
                          description: Contact's last name
                        email:
                          type: string
                          format: email
                          description: Contact's email address
                        company:
                          type: string
                          description: Contact's company name
                        emailAccountId:
                          type: integer
                          format: int64
                          description: ID of the email account used for sending
                        emailAccountEmail:
                          type: string
                          format: email
                          description: Email address of the sending account
                        sequenceId:
                          type: integer
                          description: ID of the sequence
                        sequenceName:
                          type: string
                          description: Name of the sequence
                        sequenceStepNumber:
                          type: integer
                          description: Step number within the sequence
                        sequenceStepDisplayName:
                          type: string
                          description: Display name of the sequence step
                        deliveryDate:
                          type: string
                          format: date-time
                          description: Date when the email was delivered
                        isDelivered:
                          type: boolean
                        isOpened:
                          type: boolean
                        isReplied:
                          type: boolean
                        isInterested:
                          type: boolean
                        isBounced:
                          type: boolean
                        isClicked:
                          type: boolean
                        isOptedOut:
                          type: boolean
                  hasMore:
                    type: boolean
                    description: Indicates if there are more items to fetch
        '400':
          description: |-
            Invalid pagination parameters, or request-body validation failure
            (FluentValidator).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
              examples:
                invalid_pagination:
                  summary: Pagination out of range
                  value:
                    title: Bad Request
                    status: 400
                    detail: Parameter 'top' must be between 1 and 1000.
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /filters
                        detail: '''filters'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view reports.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: reports.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/reporting/calls:
    post:
      tags:
        - Reports
      summary: List call activity
      x-required-scope: reporting:read
      description: |-
        <small>_Requires the `reporting:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of individual call records matching the specified filters.

        Call recording URLs are included only if the user has permission to listen to call records.
      operationId: GetCallsList
      parameters:
        - name: top
          in: query
          required: false
          description: Number of records to return (page size)
          schema:
            type: integer
            minimum: 1
        - name: skip
          in: query
          required: false
          description: Number of records to skip
          schema:
            type: integer
            minimum: 0
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filters
              properties:
                filters:
                  allOf: *ref_173
      responses:
        '200':
          description: Calls list retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Call List Item
                      description: Individual call activity record in a reporting list
                      properties: &ref_516
                        id:
                          type: string
                          description: Unique call identifier
                        userId:
                          type: integer
                          description: ID of the user who made/received the call
                        userFullName:
                          type: string
                          description: Full name of the user
                        contactId:
                          type: integer
                          description: ID of the contact
                        contactFullName:
                          type: string
                          description: Full name of the contact
                        contactPhoneNumber:
                          type: string
                          description: Phone number of the contact
                        startDate:
                          type: string
                          format: date-time
                          description: Call start date and time
                        durationSeconds:
                          type: integer
                          description: Call duration in seconds
                        resolution:
                          type: string
                          enum:
                            - positive
                            - toCall
                            - negative
                          description: Call resolution outcome
                        disposition:
                          type: string
                          enum:
                            - answered
                            - loggedManually
                            - noAnswer
                            - busy
                            - fail
                          description: Call disposition
                        type:
                          type: string
                          enum:
                            - outbound
                            - inbound
                          description: Call direction
                        callRecordUrl:
                          type: string
                          description: URL to the call recording (if available and permitted)
                        customResolution:
                          type: string
                          description: Custom resolution text
                  hasMore:
                    type: boolean
                    description: Indicates if there are more items to fetch
        '400':
          description: |-
            Invalid pagination parameters, or request-body validation failure
            (FluentValidator).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
              examples:
                invalid_pagination:
                  summary: Pagination out of range
                  value:
                    title: Bad Request
                    status: 400
                    detail: Parameter 'top' must be between 1 and 1000.
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /filters
                        detail: '''filters'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view reports.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: reports.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/reporting/tasks:
    post:
      tags:
        - Reports
      summary: List task activity
      x-required-scope: reporting:read
      description: |-
        <small>_Requires the `reporting:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of individual task records matching the specified filters.
      operationId: GetTasksList
      parameters:
        - name: top
          in: query
          required: false
          description: Number of records to return (page size)
          schema:
            type: integer
            minimum: 1
        - name: skip
          in: query
          required: false
          description: Number of records to skip
          schema:
            type: integer
            minimum: 0
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filters
              properties:
                filters:
                  allOf: *ref_174
      responses:
        '200':
          description: Tasks list retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Task List Item
                      description: Individual task record in a reporting list
                      properties: &ref_517
                        id:
                          type: string
                          description: Unique task identifier
                        userId:
                          type: integer
                          description: ID of the user assigned to the task
                        taskType:
                          type: string
                          enum:
                            - toDo
                            - call
                            - meeting
                            - linkedIn
                            - manualEmail
                            - sms
                            - whatsApp
                          description: Type of task
                        linkedInTaskType:
                          type: string
                          enum:
                            - message
                            - connect
                            - inMail
                            - viewProfile
                          description: LinkedIn-specific task type (only present for LinkedIn tasks)
                        description:
                          type: string
                          description: Task description
                        contactFullName:
                          type: string
                          description: Full name of the associated contact
                        taskStatus:
                          type: string
                          enum:
                            - created
                            - completed
                          description: Current task status
                        dueDate:
                          type: string
                          format: date-time
                          description: Task due date
                  hasMore:
                    type: boolean
                    description: Indicates if there are more items to fetch
        '400':
          description: |-
            Invalid pagination parameters, or request-body validation failure
            (FluentValidator).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
              examples:
                invalid_pagination:
                  summary: Pagination out of range
                  value:
                    title: Bad Request
                    status: 400
                    detail: Parameter 'top' must be between 1 and 1000.
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /filters
                        detail: '''filters'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view reports.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: reports.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/reporting/linkedin:
    post:
      tags:
        - Reports
      summary: List LinkedIn activity
      x-required-scope: reporting:read
      description: |-
        <small>_Requires the `reporting:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of individual LinkedIn action records matching the specified filters.
      operationId: GetLinkedInList
      parameters:
        - name: top
          in: query
          required: false
          description: Number of records to return (page size)
          schema:
            type: integer
            minimum: 1
        - name: skip
          in: query
          required: false
          description: Number of records to skip
          schema:
            type: integer
            minimum: 0
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filters
              properties:
                filters:
                  allOf: *ref_175
      responses:
        '200':
          description: LinkedIn actions list retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: LinkedIn Action Item
                      description: Individual LinkedIn action record in a reporting list
                      properties: &ref_518
                        contactId:
                          type: integer
                          description: ID of the contact (may be null for unmatched actions)
                        contactFirstName:
                          type: string
                          description: Contact's first name
                        contactLastName:
                          type: string
                          description: Contact's last name
                        contactEmail:
                          type: string
                          format: email
                          description: Contact's email address
                        contactLinkedInUrl:
                          type: string
                          description: Contact's LinkedIn profile URL
                        senderLinkedInAccountName:
                          type: string
                          description: Name of the LinkedIn account that performed the action
                        sequenceName:
                          type: string
                          description: Name of the sequence
                        sequenceStepNumber:
                          type: integer
                          description: Step number within the sequence
                        sequenceStepDisplayName:
                          type: string
                          description: Display name of the sequence step
                        actionDate:
                          type: string
                          format: date-time
                          description: Date the action was performed
                        actionType:
                          type: string
                          enum:
                            - unknown
                            - acceptedAutoConnection
                            - sentAutoConnection
                            - sentManualConnection
                            - repliedAutoConnectionNote
                            - sentAutoConnectionNote
                            - repliedAutoMessage
                            - sentAutoMessage
                            - sentManualMessage
                            - repliedAutoInMail
                            - sentAutoInMail
                            - sentManualInMail
                            - autoProfileView
                            - manualProfileView
                            - like
                            - followProfile
                            - endorseSkills
                          description: Type of LinkedIn action performed
                  hasMore:
                    type: boolean
                    description: Indicates if there are more items to fetch
        '400':
          description: |-
            Invalid pagination parameters, or request-body validation failure
            (FluentValidator).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
              examples:
                invalid_pagination:
                  summary: Pagination out of range
                  value:
                    title: Bad Request
                    status: 400
                    detail: Parameter 'top' must be between 1 and 1000.
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /filters
                        detail: '''filters'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view reports.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: reports.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/reporting/team-performance/meetings:
    post:
      tags:
        - Reports
      summary: List meetings
      x-required-scope: reporting:read
      description: |-
        <small>_Requires the `reporting:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of meetings booked through team performance, matching the specified filters.
      operationId: GetMeetingsList
      parameters:
        - name: top
          in: query
          required: false
          description: Number of records to return (page size)
          schema:
            type: integer
            minimum: 1
        - name: skip
          in: query
          required: false
          description: Number of records to skip
          schema:
            type: integer
            minimum: 0
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filters
              properties:
                filters:
                  allOf: *ref_176
      responses:
        '200':
          description: Meetings list retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: Meeting List Item
                      description: Individual meeting record in a team performance reporting list
                      properties: &ref_519
                        userId:
                          type: integer
                          description: ID of the user who booked the meeting
                        source:
                          type: string
                          enum:
                            - unspecified
                            - automatedEmail
                            - manualEmail
                            - automatedSms
                            - manualSms
                            - call
                            - whatsApp
                            - linkedIn
                          description: Channel through which the meeting was booked
                        contactFullName:
                          type: string
                          description: Full name of the contact
                        sequenceName:
                          type: string
                          description: Name of the sequence that generated the meeting
                        bookedAt:
                          type: string
                          format: date-time
                          description: Date and time the meeting was booked
                  hasMore:
                    type: boolean
                    description: Indicates if there are more items to fetch
        '400':
          description: |-
            Invalid pagination parameters, or request-body validation failure
            (FluentValidator).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - type: object
                    title: Problem Details
                    description: |-
                      Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
                      that don't carry domain context: 401 Unauthorized (auth middleware),
                      429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
                      415 (framework middleware).

                      Business and validation responses extend this envelope and add additional
                      fields — see `business-problem.model.yaml` (adds `code` slug) and
                      `validation-problem.model.yaml` (adds `errors[]` array).
                    properties: *ref_1
              examples:
                invalid_pagination:
                  summary: Pagination out of range
                  value:
                    title: Bad Request
                    status: 400
                    detail: Parameter 'top' must be between 1 and 1000.
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /filters
                        detail: '''filters'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view reports.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: reports.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/schedules:
    get:
      tags:
        - Schedules
      summary: List schedules
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns all schedules for the authenticated user.
      operationId: ListSchedules
      responses:
        '200':
          description: List of schedules
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Schedule
                  description: Full representation of a schedule with timing configuration.
                  properties: &ref_183
                    id:
                      type: integer
                      description: Unique identifier for the schedule
                      readOnly: true
                    name:
                      type: string
                      description: Name of the schedule
                    timezoneId:
                      type: string
                      description: IANA timezone identifier (e.g., "America/New_York")
                    excludeHolidays:
                      type: boolean
                      description: Whether to skip sending on holidays from linked calendars
                    useProspectTimezone:
                      type: boolean
                      description: Whether to use the prospect's timezone instead of the schedule timezone
                    useFollowUpSchedule:
                      type: boolean
                      description: Whether a separate follow-up schedule is enabled
                    mainTimings:
                      type: array
                      items:
                        type: object
                        title: ScheduleTiming
                        description: Timing configuration for a single day of the week.
                        properties: &ref_180
                          weekDay:
                            type: string
                            description: Day of the week
                            enum:
                              - Monday
                              - Tuesday
                              - Wednesday
                              - Thursday
                              - Friday
                              - Saturday
                              - Sunday
                          isActive:
                            type: boolean
                            description: Whether sending is enabled on this day
                          timeRanges:
                            type: array
                            items:
                              type: object
                              title: ScheduleTimingTimeRange
                              description: A time range within a day.
                              properties: &ref_520
                                fromTime:
                                  type: object
                                  title: ScheduleTime
                                  description: A time of day represented as hour and minute.
                                  properties: &ref_177
                                    hour:
                                      type: integer
                                      minimum: 0
                                      maximum: 23
                                      description: Hour of the day (0-23)
                                    minute:
                                      type: integer
                                      minimum: 0
                                      maximum: 59
                                      description: Minute of the hour (0-59)
                                  required: &ref_178
                                    - hour
                                    - minute
                                  example: &ref_179
                                    hour: 9
                                    minute: 30
                                toTime:
                                  type: object
                                  title: ScheduleTime
                                  description: A time of day represented as hour and minute.
                                  properties: *ref_177
                                  required: *ref_178
                                  example: *ref_179
                              required: &ref_521
                                - fromTime
                                - toTime
                              example: &ref_522
                                fromTime:
                                  hour: 9
                                  minute: 0
                                toTime:
                                  hour: 17
                                  minute: 0
                            description: Active time ranges for this day
                        required: &ref_181
                          - weekDay
                          - isActive
                        example: &ref_182
                          weekDay: Monday
                          isActive: true
                          timeRanges:
                            - fromTime:
                                hour: 9
                                minute: 0
                              toTime:
                                hour: 17
                                minute: 0
                      description: Primary schedule timings for each day of the week
                    followUpTimings:
                      type: array
                      items:
                        type: object
                        title: ScheduleTiming
                        description: Timing configuration for a single day of the week.
                        properties: *ref_180
                        required: *ref_181
                        example: *ref_182
                      description: Follow-up schedule timings (used when useFollowUpSchedule is true)
                    isDefault:
                      type: boolean
                      description: Whether this is the default schedule
                      readOnly: true
                    status:
                      type: string
                      description: Current status of the schedule
                      readOnly: true
                  example: &ref_184
                    id: 1
                    name: Business hours
                    timezoneId: America/New_York
                    excludeHolidays: true
                    useProspectTimezone: false
                    useFollowUpSchedule: false
                    mainTimings:
                      - weekDay: Monday
                        isActive: true
                        timeRanges:
                          - fromTime:
                              hour: 9
                              minute: 0
                            toTime:
                              hour: 17
                              minute: 0
                    followUpTimings: []
                    isDefault: true
                    status: active
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view schedules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewScheduler] are denied for userId 123
                code: schedule.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Schedules
      summary: Create a schedule
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates a new schedule with timing configuration.
      operationId: CreateSchedule
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: ScheduleCreateRequest
              description: Request body for creating a new schedule.
              properties: &ref_523
                name:
                  type: string
                  description: Name of the schedule
                timezoneId:
                  type: string
                  description: IANA timezone identifier (e.g., "America/New_York")
                excludeHolidays:
                  type: boolean
                  description: Whether to skip sending on holidays from linked calendars
                useProspectTimezone:
                  type: boolean
                  description: Whether to use the prospect's timezone instead of the schedule timezone
                useFollowUpSchedule:
                  type: boolean
                  description: Whether a separate follow-up schedule is enabled
                mainTimings:
                  type: array
                  items:
                    type: object
                    title: ScheduleTiming
                    description: Timing configuration for a single day of the week.
                    properties: *ref_180
                    required: *ref_181
                    example: *ref_182
                  description: Primary schedule timings for each day of the week
                followUpTimings:
                  type: array
                  items:
                    type: object
                    title: ScheduleTiming
                    description: Timing configuration for a single day of the week.
                    properties: *ref_180
                    required: *ref_181
                    example: *ref_182
                  description: Follow-up schedule timings (used when useFollowUpSchedule is true)
              required: &ref_524
                - name
                - timezoneId
              example: &ref_525
                name: Evening outreach
                timezoneId: Europe/London
                excludeHolidays: false
                useProspectTimezone: true
                useFollowUpSchedule: false
                mainTimings:
                  - weekDay: Monday
                    isActive: true
                    timeRanges:
                      - fromTime:
                          hour: 18
                          minute: 0
                        toTime:
                          hour: 21
                          minute: 0
                followUpTimings: []
      responses:
        '201':
          description: Schedule created successfully
          content:
            application/json:
              schema:
                type: object
                title: Schedule
                description: Full representation of a schedule with timing configuration.
                properties: *ref_183
                example: *ref_184
        '400':
          description: Validation error
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /name
                    detail: '''Name'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create schedules
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageScheduler] are denied for userId 123
                code: schedule.forbidden
        '409':
          description: A schedule with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Scheduler with name 'My Schedule' already exists
                code: schedule.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/schedules/{id}:
    get:
      tags:
        - Schedules
      summary: Get a schedule
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns a single schedule by ID.
      operationId: GetSchedule
      parameters:
        - name: id
          in: path
          required: true
          description: Schedule ID
          schema:
            type: integer
      responses:
        '200':
          description: Schedule details
          content:
            application/json:
              schema:
                type: object
                title: Schedule
                description: Full representation of a schedule with timing configuration.
                properties: *ref_183
                example: *ref_184
        '400':
          description: Invalid id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this schedule
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewScheduler] are denied for userId 123
                code: schedule.forbidden
        '404':
          description: Schedule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Scheduler with ID 42 not found
                code: schedule.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Schedules
      summary: Update a schedule
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Updates an existing schedule.
      operationId: UpdateSchedule
      parameters:
        - name: id
          in: path
          required: true
          description: Schedule ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: ScheduleUpdateRequest
              description: Request body for updating an existing schedule.
              properties: &ref_526
                name:
                  type: string
                  description: Name of the schedule
                timezoneId:
                  type: string
                  description: IANA timezone identifier (e.g., "America/New_York")
                excludeHolidays:
                  type: boolean
                  description: Whether to skip sending on holidays from linked calendars
                useProspectTimezone:
                  type: boolean
                  description: Whether to use the prospect's timezone instead of the schedule timezone
                useFollowUpSchedule:
                  type: boolean
                  description: Whether a separate follow-up schedule is enabled
                mainTimings:
                  type: array
                  items:
                    type: object
                    title: ScheduleTiming
                    description: Timing configuration for a single day of the week.
                    properties: *ref_180
                    required: *ref_181
                    example: *ref_182
                  description: Primary schedule timings for each day of the week
                followUpTimings:
                  type: array
                  items:
                    type: object
                    title: ScheduleTiming
                    description: Timing configuration for a single day of the week.
                    properties: *ref_180
                    required: *ref_181
                    example: *ref_182
                  description: Follow-up schedule timings (used when useFollowUpSchedule is true)
              required: &ref_527
                - name
                - timezoneId
              example: &ref_528
                name: Updated business hours
                timezoneId: America/Chicago
                excludeHolidays: true
                useProspectTimezone: false
                useFollowUpSchedule: true
                mainTimings:
                  - weekDay: Monday
                    isActive: true
                    timeRanges:
                      - fromTime:
                          hour: 9
                          minute: 0
                        toTime:
                          hour: 12
                          minute: 0
                followUpTimings:
                  - weekDay: Monday
                    isActive: true
                    timeRanges:
                      - fromTime:
                          hour: 14
                          minute: 0
                        toTime:
                          hour: 17
                          minute: 0
      responses:
        '200':
          description: Schedule updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Schedule
                description: Full representation of a schedule with timing configuration.
                properties: *ref_183
                example: *ref_184
        '400':
          description: Invalid id parameter or request body validation error
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /name
                    detail: '''Name'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to update this schedule
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageScheduler] are denied for userId 123
                code: schedule.forbidden
        '404':
          description: Schedule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Scheduler with ID 42 not found
                code: schedule.notFound
        '409':
          description: A schedule with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Scheduler with name 'My Schedule' already exists
                code: schedule.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Schedules
      summary: Delete a schedule
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes a schedule by ID. Cannot delete the default schedule or a schedule in use.
      operationId: DeleteSchedule
      parameters:
        - name: id
          in: path
          required: true
          description: Schedule ID
          schema:
            type: integer
      responses:
        '204':
          description: Schedule deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Schedule cannot be deleted (in use / default), or user lacks scope
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                delete_rejected:
                  summary: Schedule is in use or is the default
                  value:
                    title: Forbidden
                    status: 403
                    detail: Scheduler with ID 42 cannot be deleted because it is in use
                    code: schedule.deleteRejected
                forbidden_scope:
                  summary: User lacks the required feature scope
                  value:
                    title: Forbidden
                    status: 403
                    detail: Feature scopes [ManageScheduler] are denied for userId 123
                    code: schedule.forbidden
        '404':
          description: Schedule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Scheduler with ID 42 not found
                code: schedule.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/schedules/{id}/set-default:
    post:
      tags:
        - Schedules
      summary: Set default schedule
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Sets the specified schedule as the default.
      operationId: SetDefaultSchedule
      parameters:
        - name: id
          in: path
          required: true
          description: Schedule ID to set as default
          schema:
            type: integer
      responses:
        '204':
          description: Default schedule updated successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to set default schedule
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageScheduler] are denied for userId 123
                code: schedule.forbidden
        '404':
          description: Schedule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Scheduler with ID 42 not found
                code: schedule.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/schedules/{id}/holiday-calendars:
    get:
      tags:
        - Schedules
      summary: List linked holiday calendars
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns all holiday calendars linked to the specified schedule.
      operationId: ListScheduleHolidayCalendars
      parameters:
        - name: id
          in: path
          required: true
          description: Schedule ID
          schema:
            type: integer
      responses:
        '200':
          description: List of linked holiday calendars
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: HolidayCalendarShort
                  description: Brief representation of a holiday calendar linked to a schedule.
                  properties: &ref_529
                    id:
                      type: integer
                      description: Unique identifier for the holiday calendar
                      readOnly: true
                    name:
                      type: string
                      description: Name of the holiday calendar
                    calendarType:
                      type: string
                      description: Type of calendar (e.g., "predefined", "custom")
                    countryCode:
                      type: string
                      description: ISO 3166-1 alpha-2 country code
                  example: &ref_530
                    id: 3
                    name: US Holidays
                    calendarType: predefined
                    countryCode: US
        '400':
          description: Invalid id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this schedule
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewScheduler] are denied for userId 123
                code: scheduleHolidayCalendarLink.forbidden
        '404':
          description: Schedule not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Scheduler with ID 42 not found
                code: scheduleHolidayCalendarLink.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/schedules/{id}/holiday-calendar-links:
    post:
      tags:
        - Schedules
      summary: Link a holiday calendar to a schedule
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Links a holiday calendar to the specified schedule.
      operationId: LinkHolidayCalendarToSchedule
      parameters:
        - name: id
          in: path
          required: true
          description: Schedule ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: ScheduleHolidayCalendarLinkRequest
              description: Request body for linking a holiday calendar to a schedule.
              properties: &ref_531
                calendarId:
                  type: integer
                  description: ID of the holiday calendar to link
              required: &ref_532
                - calendarId
              example: &ref_533
                calendarId: 3
      responses:
        '201':
          description: Holiday calendar linked successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid id parameter or request body validation error
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /calendarId
                    detail: '''CalendarId'' must be greater than 0.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this schedule
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageScheduler] are denied for userId 123
                code: scheduleHolidayCalendarLink.forbidden
        '404':
          description: Schedule or holiday calendar not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              examples:
                schedule_not_found:
                  summary: Schedule with this ID does not exist
                  value:
                    title: Not Found
                    status: 404
                    detail: Scheduler with ID 42 not found
                    code: scheduleHolidayCalendarLink.notFound
                calendar_not_found:
                  summary: Holiday calendar with this ID does not exist
                  value:
                    title: Not Found
                    status: 404
                    detail: Holiday calendar with ID 5 not found
                    code: scheduleHolidayCalendarLink.holidayCalendarNotFound
        '409':
          description: Calendar is already linked to this schedule
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Calendar with ID 5 is already linked to scheduler with ID 42
                code: scheduleHolidayCalendarLink.alreadyLinked
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/schedules/{id}/holiday-calendar-links/{calendarId}:
    delete:
      tags:
        - Schedules
      summary: Unlink a holiday calendar from a schedule
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Removes the link between a holiday calendar and the specified schedule.
      operationId: UnlinkHolidayCalendarFromSchedule
      parameters:
        - name: id
          in: path
          required: true
          description: Schedule ID
          schema:
            type: integer
        - name: calendarId
          in: path
          required: true
          description: Holiday calendar ID to unlink
          schema:
            type: integer
      responses:
        '204':
          description: Holiday calendar unlinked successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid id or calendarId parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this schedule
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageScheduler] are denied for userId 123
                code: scheduleHolidayCalendarLink.forbidden
        '404':
          description: Schedule, calendar, or link not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Calendar with ID 5 is not linked to scheduler with ID 42
                code: scheduleHolidayCalendarLink.linkNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences:
    get:
      tags:
        - Sequences
      summary: List all sequences
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of all sequences in your account.
        Results are ordered by creation date, newest first, unless overridden with `sortBy` / `sortDirection`.
      operationId: GetSequences
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000)
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: status
          in: query
          required: false
          description: Filter sequences by status
          schema:
            type: string
            enum:
              - active
              - paused
              - new
        - name: ownerUserId
          in: query
          required: false
          description: Filter sequences by owner user ID
          schema:
            type: integer
        - name: folderId
          in: query
          required: false
          description: Filter sequences by folder ID
          schema:
            type: string
            format: uuid
        - name: isArchived
          in: query
          required: false
          description: Filter sequences by archive status. When `true`, returns only archived sequences. When `false`, returns only non-archived sequences. When omitted, returns all sequences regardless of archive status.
          schema:
            type: boolean
        - name: name
          in: query
          required: false
          description: Search sequences by name (case-insensitive, partial match)
          schema:
            type: string
        - name: createdAfter
          in: query
          required: false
          description: Return only sequences created after this timestamp (ISO-8601).
          schema:
            type: string
            format: date-time
        - name: sortBy
          in: query
          required: false
          description: Field to sort results by. When omitted, results are ordered by creation date.
          schema:
            type: string
            enum:
              - created
              - name
              - status
        - name: sortDirection
          in: query
          required: false
          description: Sort direction. Requires `sortBy` to be set; supplying `sortDirection` alone is rejected with 400. When omitted, `created` sorts descending (newest first) while `name` and `status` sort ascending.
          schema:
            type: string
            enum:
              - asc
              - desc
      responses:
        '200':
          description: List of sequences retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Sequence List Model
                description: Response model for listing sequences with pagination
                properties: &ref_200
                  items:
                    type: array
                    description: Array of sequence items
                    items:
                      type: object
                      properties: *ref_185
                      example: *ref_186
                  hasMore:
                    type: boolean
                    description: Indicates if there are more items to fetch
                example: &ref_201
                  items:
                    - id: 12345
                      ownerUserId: 42
                      name: Sales Outreach
                      status: active
                      created: '2024-03-08T10:00:00+00:00'
                      isArchived: false
                      health: healthy
                    - id: 12346
                      ownerUserId: 42
                      name: Follow-up Campaign
                      status: paused
                      created: '2024-03-07T14:30:00+00:00'
                      isArchived: false
                      health: degraded
                  hasMore: true
        '400':
          description: Invalid pagination parameters, invalid sort parameters, or other business rejection
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              examples:
                invalid_pagination:
                  summary: Invalid pagination parameters
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid requested page view.
                    code: sequence.invalidPagination
                invalid_sort:
                  summary: Invalid sort parameters
                  value:
                    title: Bad Request
                    status: 400
                    detail: 'Invalid sortBy value ''foo''. Allowed values: created, name, status.'
                    code: sequence.invalidSort
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to view sequences
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to view sequences.
                code: sequence.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Sequences
      summary: Create a sequence
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates a new email sequence
      operationId: CreateSequence
      requestBody:
        required: true
        content:
          application/json:
            schema:
              title: Sequence Create
              description: Create a new sequence
              type: object
              required: &ref_534
                - name
              properties: &ref_535
                name:
                  type: string
                  description: Name of the sequence
                scheduleId:
                  type: integer
                  minimum: 1
                  description: ID of the schedule to use
                settings:
                  type: object
                  title: Sequence Settings
                  description: Settings configuration for a sequence
                  required: *ref_45
                  properties: *ref_46
                emailAccounts:
                  type: array
                  items:
                    type: integer
                    format: int64
                    minimum: 1
                  description: Array of email account IDs
                linkedInAccounts:
                  type: array
                  items:
                    type: integer
                    minimum: 1
                  description: Array of LinkedIn account IDs
                steps:
                  type: array
                  description: Array of sequence steps. Select a step type to see its configuration.
                  items:
                    title: Sequence Step
                    discriminator: *ref_187
                    oneOf: *ref_188
              example: &ref_536
                name: Sales Outreach 2024
                scheduleId: 1
                emailAccounts:
                  - 101
                  - 102
                linkedInAccounts:
                  - 42
                settings:
                  emailsCountPerDay: 50
                  daysToFinishProspect: 14
                  emailSendingDelaySeconds: 30
                  dailyThrottling: 200
                  useDailyThrottling: true
                  disableOpensTracking: false
                  repliesHandlingType: markAsFinished
                  enableLinksTracking: true
                steps:
                  - type: email
                    delayInMinutes: 0
                    executionMode: automatic
                    variants:
                      - subject: Quick question about {{companyName}}
                        message: <p>Hi {{firstName}},</p><p>I noticed you are leading initiatives at {{companyName}} and wanted to reach out.</p><p>Best regards</p>
                  - type: linkedIn
                    actionType: message
                    delayInMinutes: 1440
                    executionMode: automatic
                    variants:
                      - message: Hi {{firstName}}, would love to connect!
                        isEnabled: true
      responses:
        '201':
          description: Sequence created successfully
          content:
            application/json:
              schema:
                title: Sequence
                description: Full representation of a sequence, including its schedule and the email and LinkedIn accounts used to send from it.
                allOf: *ref_189
                example: *ref_190
        '400':
          description: Validation failure on the request body (e.g. invalid step or empty subject)
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /steps/0/subject
                    detail: First email should have subject.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to create a sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to create sequence.
                code: sequence.forbidden
        '404':
          description: Referenced email account, scheduler, template, or LinkedIn account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Some of the email accounts are not found.
                code: sequence.emailAccountNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/count:
    get:
      tags:
        - Sequences
      summary: Count sequences
      x-required-scope: sequences:read
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns the total number of sequences matching the given filters. Accepts the same filter parameters as `GET /v3/sequences` (except pagination and sorting).
      operationId: CountSequences
      parameters:
        - name: status
          in: query
          required: false
          description: Filter sequences by status
          schema:
            type: string
            enum:
              - active
              - paused
              - new
        - name: ownerUserId
          in: query
          required: false
          description: Filter sequences by owner user ID
          schema:
            type: integer
        - name: folderId
          in: query
          required: false
          description: Filter sequences by folder ID
          schema:
            type: string
            format: uuid
        - name: isArchived
          in: query
          required: false
          description: Filter sequences by archive status. When `true`, counts only archived sequences. When `false`, counts only non-archived sequences. When omitted, counts all sequences.
          schema:
            type: boolean
        - name: name
          in: query
          required: false
          description: Filter sequences by name (case-insensitive, partial match)
          schema:
            type: string
        - name: createdAfter
          in: query
          required: false
          description: Count only sequences created after this timestamp (ISO-8601).
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Count retrieved successfully
          content:
            application/json:
              schema:
                type: object
                required: *ref_191
                properties: *ref_192
        '400':
          description: Business rule rejection
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Invalid filter parameters.
                code: sequence.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to view sequences
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to view sequences.
                code: sequence.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}:
    get:
      tags:
        - Sequences
      summary: Get a sequence
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns sequence details by Id
      operationId: GetSequenceById
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Sequence details retrieved successfully
          content:
            application/json:
              schema:
                title: Sequence
                description: Full representation of a sequence, including its schedule and the email and LinkedIn accounts used to send from it.
                allOf: *ref_189
                example: *ref_190
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_invalid_step:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid step configuration.
                    code: sequence.invalidStep
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to view this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to view this sequence.
                code: sequence.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence with ID 42 is not found.
                code: sequence.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    patch:
      tags:
        - Sequences
      summary: Update a sequence
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Updates an existing sequence
      operationId: UpdateSequence
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Sequence Update Model
              description: |-
                Model for updating an existing sequence.
                All fields are optional — only include the fields you want to change (PATCH semantics).
              properties: &ref_537
                name:
                  type: string
                  description: Name of the sequence
                scheduleId:
                  type: integer
                  minimum: 1
                  description: ID of the schedule to use
                settings:
                  type: object
                  title: Sequence Settings
                  description: Settings configuration for a sequence
                  required: *ref_45
                  properties: *ref_46
                emailAccounts:
                  type: array
                  items:
                    type: integer
                    format: int64
                    minimum: 1
                  description: Array of email account IDs
                linkedInAccounts:
                  type: array
                  items:
                    type: integer
                    minimum: 1
                  description: Array of LinkedIn account IDs
      responses:
        '200':
          description: Sequence updated successfully
          content:
            application/json:
              schema:
                title: Sequence
                description: Full representation of a sequence, including its schedule and the email and LinkedIn accounts used to send from it.
                allOf: *ref_189
                example: *ref_190
        '400':
          description: Validation failure on the route parameter or request body
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: One or more validation errors occurred.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to view/update this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to view this sequence.
                code: sequence.forbidden
        '404':
          description: Sequence or referenced resource (scheduler, email account, template, LinkedIn account) not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence with ID 42 is not found.
                code: sequence.notFound
        '409':
          description: Sequence is archived and cannot be updated
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Cannot update sequence with ID 42 because it is archived.
                code: sequence.archived
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Sequences
      summary: Delete a sequence
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes an existing sequence
      operationId: DeleteSequence
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
      responses:
        '204':
          description: Sequence deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection (including `sequence.notFound` — runtime
            maps a missing sequence here despite the controller's declared
            types omitting 404).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_not_found:
                  summary: Sequence not found (mapped to 400 via fallback)
                  value:
                    title: Bad Request
                    status: 400
                    detail: Sequence with ID 42 is not found.
                    code: sequence.notFound
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to delete this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to delete this sequence.
                code: sequence.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/start:
    post:
      tags:
        - Sequences
      summary: Start a sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Activates a new or paused sequence. Returns the updated sequence.

        This operation is **idempotent**: calling Start on an already active sequence returns `200` with the current sequence state. No error is raised.
      operationId: StartSequence
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Sequence is now active. Returned both when the sequence was just started and when it was already active (idempotent).
          content:
            application/json:
              schema:
                title: Sequence
                description: Full representation of a sequence, including its schedule and the email and LinkedIn accounts used to send from it.
                allOf: *ref_189
                example: *ref_190
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection (e.g. sequence has no contacts or no email
            accounts).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_no_contacts:
                  summary: Sequence has no contacts
                  value:
                    title: Bad Request
                    status: 400
                    detail: Sequence has no contacts.
                    code: sequenceAction.noContacts
                business_no_email_accounts:
                  summary: Sequence has no email accounts
                  value:
                    title: Bad Request
                    status: 400
                    detail: Sequence has no email accounts.
                    code: sequenceAction.noEmailAccounts
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to start this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to start this sequence.
                code: sequenceAction.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence with ID 42 not found.
                code: sequenceAction.notFound
        '409':
          description: Sequence is in an incompatible state (archived)
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Sequence is archived and cannot be started.
                code: sequenceAction.archived
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/pause:
    post:
      tags:
        - Sequences
      summary: Pause a sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Pauses an active sequence. Returns the updated sequence.

        This operation is **idempotent**: calling Pause on an already paused sequence returns `200` with the current sequence state. No error is raised.
      operationId: PauseSequence
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Sequence is now paused. Returned both when the sequence was just paused and when it was already paused (idempotent).
          content:
            application/json:
              schema:
                title: Sequence
                description: Full representation of a sequence, including its schedule and the email and LinkedIn accounts used to send from it.
                allOf: *ref_189
                example: *ref_190
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_team_member_not_found:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Team member is not found.
                    code: sequenceAction.teamMemberNotFound
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to pause this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to pause this sequence.
                code: sequenceAction.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence with ID 42 not found.
                code: sequenceAction.notFound
        '409':
          description: Sequence is in an incompatible state (archived)
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Sequence is archived and cannot be paused.
                code: sequenceAction.archived
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/archive:
    post:
      tags:
        - Sequences
      summary: Archive a sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Archives a sequence. Returns the updated sequence.
      operationId: ArchiveSequence
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Sequence archived successfully
          content:
            application/json:
              schema:
                title: Sequence
                description: Full representation of a sequence, including its schedule and the email and LinkedIn accounts used to send from it.
                allOf: *ref_189
                example: *ref_190
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_team_member_not_found:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Team member is not found.
                    code: sequenceAction.teamMemberNotFound
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to archive this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to archive this sequence.
                code: sequenceAction.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence with ID 42 not found.
                code: sequenceAction.notFound
        '409':
          description: Sequence is already archived or in an incompatible state
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Sequence is already archived.
                code: sequenceAction.archived
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/unarchive:
    post:
      tags:
        - Sequences
      summary: Unarchive a sequence
      x-required-scope: sequences:operate
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Restores an archived sequence to its previous state. Returns the updated sequence.
      operationId: UnarchiveSequence
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Sequence unarchived successfully
          content:
            application/json:
              schema:
                title: Sequence
                description: Full representation of a sequence, including its schedule and the email and LinkedIn accounts used to send from it.
                allOf: *ref_189
                example: *ref_190
        '400':
          description: Route-parameter validation failure (e.g. non-positive `id`).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to unarchive this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to unarchive sequence.
                code: sequenceAction.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence with ID 42 is not found.
                code: sequenceAction.notFound
        '409':
          description: Sequence is not archived
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Sequence is not archived.
                code: sequenceAction.notArchived
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/owner:
    put:
      tags:
        - Sequences
      operationId: UpdateSequenceOwner
      summary: Change sequence owner
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Changes the owner of a single sequence to a different team member
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - userId
              properties:
                userId:
                  type: integer
                  description: Target user ID to assign as owner
      responses:
        '200':
          description: Sequence owner updated successfully
          content:
            application/json:
              schema:
                title: Sequence
                description: Full representation of a sequence, including its schedule and the email and LinkedIn accounts used to send from it.
                allOf: *ref_189
                example: *ref_190
        '400':
          description: |-
            Validation failure on the request body, or a business rule rejection
            (target user not a team member, owner limit exceeded).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /userId
                        detail: '''userId'' must be greater than 0.'
                business_team_member_not_found:
                  summary: Target user is not a team member
                  value:
                    title: Bad Request
                    status: 400
                    detail: Target user is not a member of the team.
                    code: sequenceAction.teamMemberNotFound
                business_owner_limit_exceeded:
                  summary: Target user has reached their sequence ownership limit
                  value:
                    title: Bad Request
                    status: 400
                    detail: Target user has reached their sequence ownership limit.
                    code: sequenceAction.ownerLimitExceeded
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to change sequence owner
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to change sequence owner.
                code: sequenceAction.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence with ID 42 not found.
                code: sequenceAction.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/start:
    post:
      tags:
        - Sequences
      operationId: BulkStartSequences
      summary: Bulk start sequences
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Starts multiple sequences at once. Non-atomic — some may succeed while others fail.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - ids
              properties:
                ids:
                  type: array
                  items:
                    type: integer
                  description: List of sequence IDs to start
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by sequence ID. Empty object `{}` means all succeeded.

            Per-item failures use the `SequenceActionError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `notFound` | Sequence does not exist |
            | `forbidden` | Caller lacks permission for this sequence |
            | `archived` | Sequence is archived |
            | `noContacts` | Sequence has no contacts |
            | `noEmailAccounts` | Sequence has no email accounts |
            | `salesAgentNotAllowed` | Operation not permitted on a sales-agent sequence |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /ids
                        detail: '''ids'' must contain between 1 and 100 items.'
                business_team_member_not_found:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Team member is not found.
                    code: sequenceAction.teamMemberNotFound
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to start sequences
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to start sequences.
                code: sequenceAction.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/pause:
    post:
      tags:
        - Sequences
      operationId: BulkPauseSequences
      summary: Bulk pause sequences
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Pauses multiple sequences at once. Non-atomic — some may succeed while others fail.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - ids
              properties:
                ids:
                  type: array
                  items:
                    type: integer
                  description: List of sequence IDs to pause
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by sequence ID. Empty object `{}` means all succeeded.

            Per-item failures use the `SequenceActionError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `notFound` | Sequence does not exist |
            | `forbidden` | Caller lacks permission for this sequence |
            | `archived` | Sequence is archived |
            | `salesAgentNotAllowed` | Operation not permitted on a sales-agent sequence |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /ids
                        detail: '''ids'' must contain between 1 and 100 items.'
                business_team_member_not_found:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Team member is not found.
                    code: sequenceAction.teamMemberNotFound
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to pause sequences
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to pause sequences.
                code: sequenceAction.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/archive:
    post:
      tags:
        - Sequences
      operationId: BulkArchiveSequences
      summary: Bulk archive sequences
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Archives multiple sequences at once. Non-atomic — some may succeed while others fail.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - ids
              properties:
                ids:
                  type: array
                  items:
                    type: integer
                  description: List of sequence IDs to archive
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by sequence ID. Empty object `{}` means all succeeded.

            Per-item failures use the `SequenceActionError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `notFound` | Sequence does not exist |
            | `forbidden` | Caller lacks permission for this sequence |
            | `archived` | Sequence is already archived |
            | `salesAgentNotAllowed` | Operation not permitted on a sales-agent sequence |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /ids
                        detail: '''ids'' must contain between 1 and 100 items.'
                business_team_member_not_found:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Team member is not found.
                    code: sequenceAction.teamMemberNotFound
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to archive sequences
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to archive sequences.
                code: sequenceAction.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/unarchive:
    post:
      tags:
        - Sequences
      summary: Bulk unarchive sequences
      x-required-scope: sequences:write
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Unarchives multiple sequences at once. Non-atomic — some may succeed while others fail.
      operationId: BulkUnarchiveSequences
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - ids
              properties:
                ids:
                  type: array
                  items:
                    type: integer
                  description: List of sequence IDs to unarchive
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by sequence ID. Empty object `{}` means all succeeded.

            Per-item failures use the `SequenceActionError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `notArchived` | Sequence is not archived or not found |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /ids
                        detail: '''ids'' must contain between 1 and 100 items.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to unarchive sequences
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to unarchive sequences.
                code: sequenceAction.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/bulk-delete:
    post:
      tags:
        - Sequences
      operationId: BulkDeleteSequences
      summary: Bulk delete sequences
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes multiple sequences at once. Non-atomic — some may succeed while others fail.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - ids
              properties:
                ids:
                  type: array
                  items:
                    type: integer
                  description: List of sequence IDs to delete
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by sequence ID. Empty object `{}` means all succeeded.

            Per-item failures use the `SequenceActionError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `notFound` | Sequence does not exist |
            | `forbidden` | Caller lacks permission for this sequence |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Validation failure on the request body, or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /ids
                        detail: '''ids'' must contain between 1 and 100 items.'
                business_team_member_not_found:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Team member is not found.
                    code: sequenceAction.teamMemberNotFound
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete sequences
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to delete sequences.
                code: sequenceAction.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/batch/owner:
    post:
      tags:
        - Sequences
      operationId: BulkChangeSequenceOwner
      summary: Bulk change sequence owner
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Changes the owner of multiple sequences at once. Non-atomic — some may succeed while others fail.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - ids
                - userId
              properties:
                ids:
                  type: array
                  items:
                    type: integer
                  description: List of sequence IDs to reassign
                userId:
                  type: integer
                  description: Target user ID to assign as owner
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by sequence ID. Empty object `{}` means all succeeded.

            Per-item failures use the `SequenceActionError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `notFound` | Sequence does not exist |
            | `forbidden` | Caller lacks permission for this sequence |
            | `ownerLimitExceeded` | Target user has reached their sequence ownership limit |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: |-
            Validation failure on the request body, or a business rule rejection
            (target user not a team member, owner limit exceeded).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /userId
                        detail: '''userId'' must be greater than 0.'
                business_team_member_not_found:
                  summary: Target user is not a team member
                  value:
                    title: Bad Request
                    status: 400
                    detail: Target user is not a member of the team.
                    code: sequenceAction.teamMemberNotFound
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to change sequence owners
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to change sequence owner.
                code: sequenceAction.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/save-as-template:
    post:
      tags:
        - Sequences
      summary: Save a sequence as a template
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates a new sequence template from an existing sequence
      operationId: SaveSequenceAsTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
                  description: Name for the new template
                description:
                  type: string
                  nullable: true
                  description: Description for the template
                scope:
                  type: string
                  nullable: true
                  description: Scope of the template (e.g., team, organization)
      responses:
        '201':
          description: Sequence template created successfully
          content:
            application/json:
              schema:
                type: object
                title: Sequence Template
                description: A sequence template
                properties: &ref_236
                  id:
                    type: string
                    format: uuid
                    description: Unique identifier for the template
                  name:
                    type: string
                    description: Name of the template
                  description:
                    type: string
                    nullable: true
                    description: Description of the template
                  stepTypes:
                    type: array
                    items:
                      type: string
                    description: Types of steps in the template (e.g. Email, LinkedIn, Call, Task)
                  isConditional:
                    type: boolean
                    description: Whether the template contains conditional steps
                example: &ref_237
                  id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                  name: Cold Outreach
                  description: A template for cold outreach sequences
                  stepTypes:
                    - Email
                    - LinkedIn
                  isConditional: false
        '400':
          description: Validation failure on the route parameter or request body
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: One or more validation errors occurred.
                errors:
                  - pointer: /name
                    detail: '''name'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Organization templates are not available for this account, or caller lacks permission
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Organization templates are not available for your account.
                code: sequenceTemplate.orgTemplatesDisabled
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence with ID 42 not found.
                code: sequenceTemplate.sequenceNotFound
        '409':
          description: A template with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Template with name 'My template' already exists.
                code: sequenceTemplate.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/create-from-template:
    post:
      tags:
        - Sequences
      summary: Create a sequence from a template
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates a new sequence based on an existing sequence template
      operationId: CreateSequenceFromTemplate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - templateId
              properties:
                templateId:
                  type: string
                  format: uuid
                  description: Template Id to create the sequence from
                sequenceFolderId:
                  type: string
                  format: uuid
                  nullable: true
                  description: Optional folder Id to place the new sequence in
      responses:
        '201':
          description: Sequence created from template successfully
          content:
            application/json:
              schema:
                title: Sequence
                description: Full representation of a sequence, including its schedule and the email and LinkedIn accounts used to send from it.
                allOf: *ref_189
                example: *ref_190
        '400':
          description: Validation failure on the request body
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /templateId
                    detail: '''templateId'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to view the newly created sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to view this sequence.
                code: sequence.forbidden
        '404':
          description: Template not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence template with ID 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d not found.
                code: sequenceTemplate.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/stats:
    post:
      tags:
        - Sequences
      summary: Get sequence stats
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns aggregated email and LinkedIn engagement stats for a single sequence.
      operationId: GetSequenceStats
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence ID
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties: &ref_539
                filters:
                  type: object
                  description: Date range filters for sequence stats
                  properties: &ref_538
                    from:
                      type: string
                      format: date-time
                      description: Start date of the reporting period
                    to:
                      type: string
                      format: date-time
                      description: End date of the reporting period
                    dateRangePreset:
                      type: string
                      enum:
                        - lastWeek
                        - lastMonth
                        - lastYear
                        - allTime
                      description: Predefined date range. Cannot be combined with from/to. Defaults to `lastWeek` if no dates provided.
      responses:
        '200':
          description: Sequence stats retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Sequence Stats Response
                description: Aggregated email and LinkedIn stats for a single sequence
                properties: &ref_540
                  emailOverview:
                    type: object
                    title: Sequence Email Overview
                    description: Email engagement metrics for a sequence
                    properties: &ref_193
                      contacted:
                        type: integer
                        description: Number of people contacted
                      delivered:
                        type: integer
                        description: Number of emails delivered
                      opened:
                        type: integer
                        description: Number of emails opened
                      replied:
                        type: integer
                        description: Number of emails replied to
                      interested:
                        type: integer
                        description: Number of replies marked as interested
                      notReached:
                        type: integer
                        description: Number of contacts not reached
                      optedOut:
                        type: integer
                        description: Number of opt-outs
                      outOfOffice:
                        type: integer
                        description: Number of out-of-office replies
                      bounced:
                        type: integer
                        description: Number of bounced emails
                      autoReplied:
                        type: integer
                        description: Number of auto-replies received
                      meetingsBooked:
                        type: integer
                        description: Number of meetings booked
                      deliveredPercentage:
                        type: number
                        format: double
                        description: Delivery rate as a percentage (0–100)
                      openedPercentage:
                        type: number
                        format: double
                        description: Open rate as a percentage (0–100)
                      repliedPercentage:
                        type: number
                        format: double
                        description: Reply rate as a percentage (0–100)
                      interestedPercentage:
                        type: number
                        format: double
                        description: Interested rate as a percentage (0–100)
                      notReachedPercentage:
                        type: number
                        format: double
                        description: Not-reached rate as a percentage (0–100)
                      optedOutPercentage:
                        type: number
                        format: double
                        description: Opt-out rate as a percentage (0–100)
                      outOfOfficePercentage:
                        type: number
                        format: double
                        description: Out-of-office rate as a percentage (0–100)
                      bouncedPercentage:
                        type: number
                        format: double
                        description: Bounce rate as a percentage (0–100)
                      autoRepliedPercentage:
                        type: number
                        format: double
                        description: Auto-reply rate as a percentage (0–100)
                      meetingsBookedPercentage:
                        type: number
                        format: double
                        description: Meetings booked rate as a percentage (0–100)
                  linkedInOverview:
                    type: object
                    title: Sequence LinkedIn Overview
                    description: LinkedIn engagement metrics for a sequence
                    properties: &ref_194
                      connectionsSent:
                        type: integer
                        description: Number of connection requests sent
                      connectionsAccepted:
                        type: integer
                        description: Number of connection requests accepted
                      connectionsAcceptedPercentage:
                        type: number
                        format: double
                        description: Connection acceptance rate as a percentage (0–100)
                      messagesSent:
                        type: integer
                        description: Number of LinkedIn messages sent
                      replied:
                        type: integer
                        description: Number of message replies received
                      repliedPercentage:
                        type: number
                        format: double
                        description: Message reply rate as a percentage (0–100)
                      inMailsSent:
                        type: integer
                        description: Number of InMails sent
                      inMailsReplied:
                        type: integer
                        description: Number of InMail replies received
                      inMailsRepliedPercentage:
                        type: number
                        format: double
                        description: InMail reply rate as a percentage (0–100)
                      connectionNotesSent:
                        type: integer
                        description: Number of connection notes sent
                      connectionNotesReplied:
                        type: integer
                        description: Number of connection note replies received
                      connectionNotesRepliedPercentage:
                        type: number
                        format: double
                        description: Connection notes reply rate as a percentage (0–100)
                      profileViews:
                        type: integer
                        description: Number of profile views
                      likes:
                        type: integer
                        description: Number of likes
                      follows:
                        type: integer
                        description: Number of follows
                      endorses:
                        type: integer
                        description: Number of endorsements
                      regularMessagesSent:
                        type: integer
                        description: Number of regular messages sent
                      regularMessagesReplied:
                        type: integer
                        description: Number of regular message replies received
                      regularMessagesRepliedPercentage:
                        type: number
                        format: double
                        description: Regular messages reply rate as a percentage (0–100)
        '400':
          description: Invalid `id` parameter, or request-body validation failure (FluentValidator).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              examples:
                invalid_id:
                  summary: Route-parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /filters/from
                        detail: '''from'' must be a valid ISO 8601 date.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view sequence stats.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: sequenceStats.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/stats:
    post:
      tags:
        - Sequences
      summary: Get stats for all sequences
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns email and LinkedIn engagement stats per sequence.

        **Date range restrictions:**
        - `dateRangePreset` must be `lastWeek` or `lastMonth`. `lastYear` and `allTime` are rejected.
        - When using `from`/`to`, the span must not exceed 31 days.
        - `from` must be within the last 31 days from the current date.
        - Defaults to `lastWeek` if no date filters are provided.
      operationId: GetSequenceStatsList
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties: &ref_542
                filters:
                  type: object
                  description: |-
                    Date range filters for sequence stats list.

                    **Restrictions:** Date range is limited to one month maximum.
                    - `dateRangePreset` must be `lastWeek` or `lastMonth`. `lastYear` and `allTime` are rejected.
                    - When using `from`/`to`, the span must not exceed 31 days.
                    - `from` must be within the last 31 days from the current date.
                  properties: &ref_541
                    from:
                      type: string
                      format: date-time
                      description: Start date. Must be within the last 31 days.
                    to:
                      type: string
                      format: date-time
                      description: End date. Range from `from` must not exceed 31 days.
                    dateRangePreset:
                      type: string
                      enum:
                        - lastWeek
                        - lastMonth
                      description: |-
                        Predefined date range. Cannot be combined with from/to. Defaults to `lastWeek` if no dates provided.
                        Only `lastWeek` and `lastMonth` are allowed on this endpoint.
                    userIds:
                      type: array
                      items:
                        type: integer
                      description: Filter by user IDs
      responses:
        '200':
          description: Sequence stats list retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Sequence Stats List Item Response
                  description: Email and LinkedIn stats for a single sequence in the list
                  properties: &ref_543
                    sequenceId:
                      type: integer
                      description: Sequence ID
                    name:
                      type: string
                      description: Sequence name
                    status:
                      type: string
                      enum:
                        - new
                        - active
                        - paused
                        - archived
                      description: Current sequence status
                    emailOverview:
                      type: object
                      title: Sequence Email Overview
                      description: Email engagement metrics for a sequence
                      properties: *ref_193
                    linkedInOverview:
                      type: object
                      title: Sequence LinkedIn Overview
                      description: LinkedIn engagement metrics for a sequence
                      properties: *ref_194
        '400':
          description: |-
            Request-body validation failure (FluentValidator) — including date-range
            restriction violations.
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /filters
                    detail: Date range must not exceed 31 days.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view sequence stats.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewReports] are denied for userId 123.
                code: sequenceStats.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/contacts:
    get:
      tags:
        - Sequence Contacts
      operationId: GetSequenceContacts
      summary: List contacts in sequence
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Retrieve all contacts enrolled in the sequence. Defaults to most-recently-added first; use `sort_by` and `sort_direction` to override.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Sequence ID
        - name: top
          in: query
          schema:
            type: integer
          description: Maximum number of items to return (default 25, max 1000)
        - name: skip
          in: query
          schema:
            type: integer
          description: Number of items to skip
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - addingDate
              - email
              - firstName
              - lastName
              - company
              - statusInSequence
          description: Field name to sort results by. Each value matches the corresponding response field. When omitted, results are ordered most-recently-added first.
        - name: sort_direction
          in: query
          required: false
          schema:
            type: string
            enum:
              - asc
              - desc
          description: Sort direction (asc or desc). Defaults to `desc` when `sort_by` is provided.
      responses:
        '200':
          description: List of contacts in sequence
          content:
            application/json:
              schema:
                type: object
                title: Sequence Contacts List
                description: Response model for listing contacts in a sequence with pagination
                properties: &ref_544
                  items:
                    type: array
                    description: Array of sequence contact items
                    items:
                      type: object
                      title: Sequence Contact
                      description: A contact enrolled in a sequence with sequence-specific metadata
                      properties: &ref_195
                        contactId:
                          type: integer
                          description: Contact ID
                        sequenceId:
                          type: integer
                          description: Sequence ID
                        email:
                          type: string
                          nullable: true
                          description: Contact email address
                        firstName:
                          type: string
                          nullable: true
                          description: Contact first name
                        lastName:
                          type: string
                          nullable: true
                          description: Contact last name
                        company:
                          type: string
                          nullable: true
                          description: Contact company name
                        title:
                          type: string
                          nullable: true
                          description: Contact job title
                        statusInSequence:
                          type: string
                          enum:
                            - active
                            - paused
                            - finished
                            - inactive
                            - outOfOffice
                          description: Contact's status in this sequence. The writable subset (`active`, `paused`, `finished`, `outOfOffice`) can be set via `POST /v3/sequences/{id}/contacts/set-status-in-sequence`. `inactive` is set by the system when the contact is missing data needed to continue (e.g. no email when the next step is an email step).
                        isOptedOut:
                          type: boolean
                          description: Whether the contact has opted out (contact-level flag, not sequence-scoped)
                        callStatus:
                          allOf:
                            - type: string
                              title: Contact Call Status
                              description: Contact-level call status. Set via `PATCH /v3/contacts/{id}` (`callStatus` field). Pass `none` to clear.
                              enum: *ref_77
                          description: Contact-level call status (`none` / `toCall` / `called`).
                        meetingStatus:
                          allOf:
                            - type: string
                              title: Contact Meeting Status
                              description: Contact-level meeting status. Set via `PATCH /v3/contacts/{id}` (`meetingStatus` field). Pass `none` to clear.
                              enum: *ref_78
                          description: Contact-level meeting status (`none` / `meetingBooked`).
                        emailDisposition:
                          type: object
                          nullable: true
                          description: |-
                            Reply/bounce status for the most recent email sent to this contact in this sequence.

                            `null` when no email has been sent to this contact yet in this sequence.
                            Otherwise an object with `isReplied` and `isBounced` flags. `false`/`false` here means an email was sent
                            but no reply or bounce was registered — distinct from the `null` "never sent" state.
                          required:
                            - isReplied
                            - isBounced
                          properties:
                            isReplied:
                              type: boolean
                              description: Whether the contact has replied to any email in this sequence
                            isBounced:
                              type: boolean
                              description: Whether any email sent to this contact in this sequence has bounced
                        currentStep:
                          type: object
                          description: |-
                            Current sequence step the contact is on. Always present in the response.
                            When the contact has no in-progress step (e.g. finished or paused at the end of the sequence), `stepId` is `null` and `displayName` is `"Finished"`.
                          required:
                            - stepId
                            - displayName
                          properties:
                            stepId:
                              type: integer
                              nullable: true
                              description: Identifier of the current step. `null` when the contact has no active step.
                            displayName:
                              type: string
                              nullable: true
                              description: Display label of the current step (e.g. `"1"`, `"2A"`, or `"Finished"`).
                        addingDate:
                          type: string
                          format: date-time
                          description: Date the contact was added to the sequence
                        emailAccountId:
                          type: integer
                          format: int64
                          nullable: true
                          description: |-
                            Identifier of the email account this contact is assigned to send from in this sequence.
                            `null` when no email account is assigned (e.g. the sequence has no email steps the contact has reached, or the assignment hasn't been resolved yet).
                        linkedInAccountId:
                          type: integer
                          format: int64
                          nullable: true
                          description: |-
                            Identifier of the LinkedIn account this contact is assigned to send from in this sequence.
                            `null` when no LinkedIn account is assigned (e.g. the sequence has no LinkedIn steps the contact has reached).
                      example: &ref_196
                        contactId: 12345
                        sequenceId: 100
                        email: john.doe@company.com
                        firstName: John
                        lastName: Doe
                        company: Tech Solutions Inc
                        title: Senior Product Manager
                        statusInSequence: active
                        isOptedOut: false
                        callStatus: none
                        meetingStatus: none
                        emailDisposition:
                          isReplied: false
                          isBounced: false
                        currentStep:
                          stepId: 5421
                          displayName: '2'
                        addingDate: '2024-03-08T10:00:00+00:00'
                        emailAccountId: 101
                        linkedInAccountId: null
                  hasMore:
                    type: boolean
                    readOnly: true
                    description: Indicates if there are more items to fetch
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection (e.g. invalid pagination or invalid sort parameters).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceContact.invalidInput
                business_invalid_sort:
                  summary: Invalid sort parameters
                  value:
                    title: Bad Request
                    status: 400
                    detail: 'Invalid sort_by value ''foo''. Allowed values: addingDate, email, firstName, lastName, company, statusInSequence'
                    code: sequenceContact.invalidSort
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewSequence] are denied for userId 123.
                code: sequenceContact.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence 42 not found.
                code: sequenceContact.sequenceNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/contacts/count:
    get:
      tags:
        - Sequence Contacts
      operationId: CountSequenceContacts
      summary: Count contacts in sequence
      x-required-scope: sequences:read
      description: |-
        <Warning>
          **Coming soon.** This endpoint will be available by late August 2026.
        </Warning>

        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns the total number of contacts enrolled in the sequence.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Sequence ID
      responses:
        '200':
          description: Count retrieved successfully
          content:
            application/json:
              schema:
                type: object
                required: *ref_191
                properties: *ref_192
        '400':
          description: Route-parameter validation failure (e.g. non-positive `id`)
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Invalid input.
                code: sequenceContact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to view this sequence.
                code: sequenceContact.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence 42 not found.
                code: sequenceContact.sequenceNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/contacts/{contact_id}:
    get:
      tags:
        - Sequence Contacts
      operationId: GetSequenceContactById
      summary: Get a contact in a sequence
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns details of a specific contact enrolled in the sequence.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Sequence ID
        - name: contact_id
          in: path
          required: true
          schema:
            type: integer
          description: Contact ID
      responses:
        '200':
          description: Contact details retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Sequence Contact
                description: A contact enrolled in a sequence with sequence-specific metadata
                properties: *ref_195
                example: *ref_196
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id` or
            `contact_id`) or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: contact_id
                        detail: The field contact_id must be between 1 and 2147483647.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceContact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewSequence] are denied for userId 123.
                code: sequenceContact.forbidden
        '404':
          description: Sequence or contact not found, or contact not in sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact 7 is not in sequence 42.
                code: sequenceContact.notInSequence
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/contacts/state:
    get:
      tags:
        - Sequence Contacts
      operationId: GetSequenceContactsState
      summary: List contacts in sequence with extended state
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Retrieve contacts enrolled in the sequence with optional additional columns such as current step, last step completed at, and status.

        The response always includes the base fields: `contactId`, `email`, `firstName`, `lastName`, `title`, `addedAt`. Additional fields (`currentStep`, `lastStepCompletedAt`, `status`) are **only** included when explicitly requested via the `additionalColumns` query parameter. Omitting `additionalColumns` returns only the base fields.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Sequence ID
        - name: top
          in: query
          schema:
            type: integer
          description: Maximum number of items to return (default 25, max 100)
        - name: skip
          in: query
          schema:
            type: integer
          description: Number of items to skip
        - name: additionalColumns
          in: query
          schema:
            type: string
          description: |-
            Comma-separated list of additional columns to include in the response. When omitted, only base fields are returned.

            | Column | Description |
            |---|---|
            | `CurrentStep` | Current sequence step info (stepId, displayStepNumber, stepNumber) |
            | `LastStepCompletedAt` | Timestamp of the last completed step |
            | `Status` | Engagement status with delivery/open/click/reply/bounce flags |

            Example: `additionalColumns=CurrentStep,Status`
      responses:
        '200':
          description: List of contacts with extended state data
          content:
            application/json:
              schema:
                type: object
                title: Sequence Contacts List with Extended State
                description: Response model for listing contacts in a sequence with pagination, including extended state columns
                properties: &ref_548
                  items:
                    type: array
                    description: Array of sequence contact items
                    items:
                      type: object
                      description: |-
                        Contact with optional extended state columns. The base fields (`contactId`, `email`, `firstName`, `lastName`, `title`, `addedAt`) are always returned.
                        The fields `currentStep`, `lastStepCompletedAt`, and `status` are **only** included when explicitly requested via the `additionalColumns` query parameter.
                      required: &ref_545
                        - contactId
                        - email
                        - firstName
                        - lastName
                        - title
                        - addedAt
                      properties: &ref_546
                        contactId:
                          type: integer
                          readOnly: true
                          description: Unique identifier of the contact
                        email:
                          type: string
                          format: email
                          description: Primary email address
                        firstName:
                          type: string
                          description: First name
                        lastName:
                          type: string
                          description: Last name
                        title:
                          type: string
                          description: Job title
                        addedAt:
                          type: string
                          format: date-time
                          readOnly: true
                          description: Timestamp when the contact was added to the sequence
                        currentStep:
                          type: object
                          readOnly: true
                          description: Current step in the sequence. **Only returned when `additionalColumns` includes `CurrentStep`.**
                          properties:
                            stepId:
                              type: integer
                              nullable: true
                              description: Identifier of the current step (`null` when the contact has finished the sequence)
                            displayStepNumber:
                              type: string
                              description: Display label of the current step (e.g. "1", "2A"), "Finished" when the contact has completed the sequence, or "Unknown" when the contact's current step is no longer part of the sequence.
                            stepNumber:
                              type: integer
                              description: Numeric position of the current step
                        lastStepCompletedAt:
                          type: string
                          nullable: true
                          format: date-time
                          readOnly: true
                          description: Timestamp of the last completed step. **Only returned when `additionalColumns` includes `LastStepCompletedAt`.**
                        status:
                          type: object
                          readOnly: true
                          description: Contact engagement status in the sequence. **Only returned when `additionalColumns` includes `Status`.**
                          properties:
                            status:
                              type: string
                              description: Current status of the contact in the sequence (e.g. Active, Paused, Finished)
                            replied:
                              type: boolean
                              description: Indicates if the contact has replied
                            delivered:
                              type: boolean
                              description: Indicates if the last email was delivered
                            bounced:
                              type: boolean
                              description: Indicates if the last email bounced
                            opened:
                              type: boolean
                              description: Indicates if the last email was opened
                            clicked:
                              type: boolean
                              description: Indicates if any link in the last email was clicked
                      example: &ref_547
                        contactId: 150467348
                        email: john.doe@example.com
                        firstName: John
                        lastName: Doe
                        title: Important Client
                        addedAt: '2025-10-29T10:00:00.00'
                        currentStep:
                          stepId: 11111111
                          displayStepNumber: '1'
                          stepNumber: 1
                        lastStepCompletedAt: null
                        status:
                          status: Active
                          replied: false
                          delivered: false
                          bounced: false
                          opened: false
                          clicked: false
                  hasMore:
                    type: boolean
                    readOnly: true
                    description: Indicates if there are more items to fetch
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id`) or a
            business rule rejection (e.g. invalid `additionalColumns` value).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: id
                        detail: The field id must be between 1 and 2147483647.
                business_invalid_input:
                  summary: Invalid additionalColumns value
                  value:
                    title: Bad Request
                    status: 400
                    detail: 'Invalid additionalColumns value ''foo''. Allowed values: CurrentStep, LastStepCompletedAt, Status'
                    code: sequenceContact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewSequence] are denied for userId 123.
                code: sequenceContact.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence 42 not found.
                code: sequenceContact.sequenceNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/contact-links/{contact_id}:
    delete:
      tags:
        - Sequence Contacts
      operationId: RemoveContactFromSequence
      summary: Remove contact from sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Remove a contact from the sequence
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Sequence ID
        - name: contact_id
          in: path
          required: true
          schema:
            type: integer
          description: Contact ID
      responses:
        '204':
          description: Contact removed from sequence. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route-parameter validation failure (e.g. non-positive `id` or
            `contact_id`) or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: One or more validation errors occurred.
                    errors:
                      - pointer: contact_id
                        detail: The field contact_id must be between 1 and 2147483647.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceContact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceContact.forbidden
        '404':
          description: Sequence or contact not found, or contact not in sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact 7 is not in sequence 42.
                code: sequenceContact.notInSequence
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/contact-links/bulk:
    post:
      tags:
        - Sequence Contacts
      operationId: BulkAddContactsToSequence
      summary: Bulk add contacts to sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Add multiple contacts to the sequence at once
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Sequence ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contactIds
              properties:
                contactIds:
                  type: array
                  items:
                    type: integer
                  description: Array of contact IDs to add
                removeFromExisting:
                  type: boolean
                  default: false
                  description: If true, contacts will be removed from their current sequences before being added to this one
                startStepId:
                  type: integer
                  nullable: true
                  description: Optional step ID to start from
                ignoreStepDelay:
                  type: boolean
                  default: false
                  description: If true, skip the configured delay before the first step and start processing immediately
                startFrom:
                  type: string
                  format: date-time
                  nullable: true
                  description: Optional date when contact processing should begin. If not provided, processing starts immediately.
      responses:
        '200':
          description: |-
            Contacts added to sequence.

            Per-item failures use the `SequenceContactError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `invalidInput` | Generic validation failure for this contact |
            | `contactLimitExceeded` | Plan limit reached |
            | `contactAlreadyInSequence` | Contact is already enrolled |
            | `contactNotFound` | Contact does not exist |
            | `forbidden` | Caller lacks permission for this contact |
          content:
            application/json:
              schema:
                type: object
                properties:
                  added:
                    type: array
                    items:
                      type: integer
                    description: IDs of successfully added contacts
                  notProcessed:
                    type: object
                    additionalProperties:
                      type: object
                      title: NotProcessedItemResult
                      description: |-
                        Per-item error for non-atomic bulk operations.
                        Only failed items are returned in the response dictionary.
                        Items not present in the dictionary succeeded.
                      properties: *ref_68
                    description: Contacts that could not be added, keyed by contact ID
        '400':
          description: |-
            Validation failure on the route parameter or request body, or a
            business rule rejection (e.g. sequence has no steps).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactIds
                        detail: '''contactIds'' must not be empty.'
                business_no_steps:
                  summary: Sequence has no steps
                  value:
                    title: Bad Request
                    status: 400
                    detail: Sequence has no steps to enroll contacts into.
                    code: sequenceContact.noStepsInSequence
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceContact.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence 42 not found.
                code: sequenceContact.sequenceNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/contact-links/bulk-delete:
    post:
      tags:
        - Sequence Contacts
      operationId: BulkRemoveContactsFromSequence
      summary: Bulk remove contacts from sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Remove multiple contacts from the sequence at once
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Sequence ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contactIds
              properties:
                contactIds:
                  type: array
                  items:
                    type: integer
      responses:
        '200':
          description: Contacts removed from sequence
          content:
            application/json:
              schema:
                type: object
                properties:
                  requested:
                    type: integer
                    description: Number of contacts requested for removal
                  removed:
                    type: integer
                    description: Number of contacts actually removed
                  notFound:
                    type: integer
                    description: Number of contacts not found
                  notInSequence:
                    type: integer
                    description: Number of contacts not in the sequence
                  removedIds:
                    type: array
                    items:
                      type: integer
                    description: IDs of contacts that were removed
        '400':
          description: |-
            Validation failure on the route parameter or request body, or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactIds
                        detail: '''contactIds'' must not be empty.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceContact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceContact.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence 42 not found.
                code: sequenceContact.sequenceNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/contacts/set-status-in-sequence:
    post:
      tags:
        - Sequence Contacts
      operationId: SetSequenceContactsStatusInSequence
      summary: Set contacts' status in this sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Sets the in-sequence status (`active` / `paused` / `finished` / `outOfOffice`) for the given contacts, scoped to **this sequence only**.

        To apply across every sequence a contact is in, use `POST /v3/contacts/set-status-in-sequence` instead.

        Replied and Bounced are **not** values of this enum — use `POST /v3/sequences/{id}/contacts/set-replied` or `POST /v3/sequences/{id}/contacts/set-bounced` for those.

        `paused` requires the contact to currently be `active` in this sequence — pausing from any other state is reported per-item as `invalidStatusTransition`. The other targets (`active`, `finished`, `outOfOffice`) accept any current state.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Sequence ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contactIds
                - statusInSequence
              properties:
                contactIds:
                  type: array
                  items:
                    type: integer
                  minItems: 1
                  maxItems: 100
                  description: Contact IDs to update. At least one, at most 100. Each ID must be positive.
                statusInSequence:
                  allOf:
                    - type: string
                      title: In-Sequence Status (writable)
                      description: |-
                        In-sequence status values that can be set via `POST /v3/contacts/set-status-in-sequence` and `POST /v3/sequences/{id}/contacts/set-status-in-sequence`.

                        Replied and Bounced are not values of this enum — they are flipped via the dedicated `set-replied` / `set-bounced` endpoints. OptedOut, Called/ToCall, and MeetingBooked are contact-level (not in-sequence) and are flipped via `PATCH /v3/contacts/{id}` (`isOptedOut`, `callStatus`, `meetingStatus`).
                      enum: *ref_197
                  description: Target in-sequence status to set.
      responses:
        '200':
          description: |-
            Non-atomic result. The response body is a dictionary keyed by contact id listing per-item failures. Empty object `{}` means all contacts were updated successfully.

            Per-item failures use the `SequenceContactError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `invalidInput` | Generic validation failure for this contact |
            | `contactNotFound` | Contact does not exist |
            | `notInSequence` | Contact is not in this sequence |
            | `invalidStatusTransition` | Disallowed transition from the current state |
            | `sequenceArchived` | Sequence is archived |
            | `forbidden` | Caller lacks permission for this contact |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
                description: Dictionary of per-item failures keyed by contact id. Empty object `{}` means all succeeded.
        '400':
          description: |-
            Validation failure on the route parameter or request body (missing/empty
            `contactIds`, non-positive ids, more than 100 ids, or unsupported
            `statusInSequence` value), or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /statusInSequence
                        detail: 'Invalid statusInSequence value ''replied''. Allowed: active, paused, finished, outOfOffice.'
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceContact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceContact.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence 42 not found.
                code: sequenceContact.sequenceNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/contacts/set-replied:
    post:
      tags:
        - Sequence Contacts
      operationId: SetSequenceContactsReplied
      summary: Mark or unmark contacts as replied in this sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Marks the given contacts as replied (`isReplied: true`) or clears the replied flag (`isReplied: false`), scoped to **this sequence only**.

        To apply across every sequence a contact is in, use `POST /v3/contacts/set-replied` instead.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Sequence ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contactIds
                - isReplied
              properties:
                contactIds:
                  type: array
                  items:
                    type: integer
                  minItems: 1
                  maxItems: 100
                  description: Contact IDs to update. At least one, at most 100. Each ID must be positive.
                isReplied:
                  type: boolean
                  description: '`true` marks the contacts as replied; `false` clears the replied flag.'
      responses:
        '200':
          description: |-
            Non-atomic result. The response body is a dictionary keyed by contact id listing per-item failures. Empty object `{}` means all contacts were updated successfully.

            Per-item failures use the `SequenceContactError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `invalidInput` | Generic validation failure for this contact |
            | `contactNotFound` | Contact does not exist |
            | `notInSequence` | Contact is not in this sequence |
            | `forbidden` | Caller lacks permission for this contact |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
                description: Dictionary of per-item failures keyed by contact id. Empty object `{}` means all succeeded.
        '400':
          description: |-
            Validation failure on the route parameter or request body (missing/empty
            `contactIds`, non-positive ids, more than 100 ids, missing `isReplied`),
            or a business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contactIds
                        detail: ContactIds must contain between 1 and 100 positive integers.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceContact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceContact.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence 42 not found.
                code: sequenceContact.sequenceNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/contacts/set-bounced:
    post:
      tags:
        - Sequence Contacts
      operationId: SetSequenceContactsBounced
      summary: Mark or unmark contacts as bounced in this sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Marks the given contacts as bounced (`isBounced: true`) or clears the bounced flag (`isBounced: false`), scoped to **this sequence only**.

        When clearing the flag (`isBounced: false`), `resendEmails` is required: pass `true` to retry the previously bounced step or `false` to leave the schedule untouched. When marking as bounced (`isBounced: true`), `resendEmails` must be omitted.

        To apply across every sequence a contact is in, use `POST /v3/contacts/set-bounced` instead.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Sequence ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contactIds
                - isBounced
              properties:
                contactIds:
                  type: array
                  items:
                    type: integer
                  minItems: 1
                  maxItems: 100
                  description: Contact IDs to update. At least one, at most 100. Each ID must be positive.
                isBounced:
                  type: boolean
                  description: '`true` marks the contacts as bounced; `false` clears the bounced flag.'
                resendEmails:
                  type: boolean
                  nullable: true
                  description: |-
                    Required (non-null) when `isBounced=false`; **must be omitted** when `isBounced=true`.
                    When `true`, the previously bounced step is rescheduled for retry.
      responses:
        '200':
          description: |-
            Non-atomic result. The response body is a dictionary keyed by contact id listing per-item failures. Empty object `{}` means all contacts were updated successfully.

            Per-item failures use the `SequenceContactError` enum. Common per-item slugs:

            | Slug | Meaning |
            | --- | --- |
            | `invalidInput` | Generic validation failure for this contact |
            | `contactNotFound` | Contact does not exist |
            | `notInSequence` | Contact is not in this sequence |
            | `forbidden` | Caller lacks permission for this contact |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
                description: Dictionary of per-item failures keyed by contact id. Empty object `{}` means all succeeded.
        '400':
          description: |-
            Validation failure on the route parameter or request body (missing/empty
            `contactIds`, non-positive ids, more than 100 ids, missing `isBounced`,
            or `resendEmails` violating the `isBounced` pairing rule), or a
            business rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /resendEmails
                        detail: resendEmails is required when isBounced is false.
                business_invalid_input:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceContact.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceContact.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence 42 not found.
                code: sequenceContact.sequenceNotFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{sequence_id}/contacts/{contact_id}/preview:
    get:
      tags:
        - Sequence Contacts
      summary: Get sequence preview for a contact
      x-required-scope: sequences:read
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns the per-contact preview of the messages this sequence will send, including any AI-personalized step templates.
      operationId: GetSequencePreview
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
        - name: contact_id
          in: path
          required: true
          description: Contact id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Preview returned
          content:
            application/json:
              schema:
                type: object
                required:
                  - sequenceId
                  - contactId
                  - contactFullName
                  - steps
                properties:
                  sequenceId:
                    type: integer
                  contactId:
                    type: integer
                  contactFullName:
                    type: string
                  contactEmail:
                    type: string
                    nullable: true
                  contactTitle:
                    type: string
                    nullable: true
                  contactCompany:
                    type: string
                    nullable: true
                  contactLinkedInUrl:
                    type: string
                    nullable: true
                  steps:
                    type: array
                    items:
                      type: object
                      required:
                        - stepId
                        - displayName
                        - personalizationStatus
                        - needsPersonalization
                        - body
                        - isModifiedByUser
                      properties:
                        stepId:
                          type: integer
                        displayName:
                          type: string
                        personalizationStatus:
                          type: string
                          enum:
                            - notPersonalized
                            - inProgress
                            - personalized
                            - failed
                            - awaitingApproval
                        needsPersonalization:
                          type: boolean
                        subject:
                          type: string
                          nullable: true
                        body:
                          type: string
                        isModifiedByUser:
                          type: boolean
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: You do not have permission to view this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to access this sequence.
                code: sequenceContactPreview.forbidden
        '404':
          description: Sequence or contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact 200 was not found in sequence 100.
                code: sequenceContactPreview.notFound
  /v3/sequences/{sequence_id}/contacts/{contact_id}/preview/reset:
    post:
      tags:
        - Sequence Contacts
      summary: Reset manual edits in a sequence preview
      x-required-scope: sequences:operate
      description: |-
        <Info>
          **Beta.** This endpoint is in beta. Behavior, parameters, and response shapes may change without notice.
        </Info>

        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Reverts any manual edits the user has made to the preview for a contact and restores the AI-generated templates.
      operationId: ResetSequencePreview
      parameters:
        - name: sequence_id
          in: path
          required: true
          description: Sequence id
          schema:
            type: integer
            minimum: 1
        - name: contact_id
          in: path
          required: true
          description: Contact id
          schema:
            type: integer
            minimum: 1
      responses:
        '204':
          description: Manual edits cleared
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: You do not have permission to edit this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to access this sequence.
                code: sequenceContactPreview.forbidden
        '404':
          description: Sequence or contact not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Contact 200 was not found in sequence 100.
                code: sequenceContactPreview.notFound
  /v3/sequences/{id}/email-accounts:
    get:
      tags:
        - Sequence Email Accounts
      summary: List email accounts in sequence
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns the list of email accounts currently linked to the specified sequence.
      operationId: GetSequenceEmailAccounts
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence ID
          schema:
            type: integer
      responses:
        '200':
          description: List of email accounts linked to the sequence
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: SequenceEmailAccount
                  description: An email account linked to a sequence for sending outbound emails.
                  properties: &ref_549
                    id:
                      type: integer
                      format: int64
                      description: Email account ID
                    ownerUserId:
                      type: integer
                      description: ID of the user who owns this email account
                    email:
                      type: string
                      format: email
                      description: The email address
                    senderName:
                      type: string
                      nullable: true
                      description: The name displayed as sender in recipient inboxes
                    emailAccountType:
                      type: string
                      description: |-
                        Provider type of the email account.
                        Values: custom, gmail, outlook, exchange, exchangeOnPremise
                      enum:
                        - custom
                        - gmail
                        - outlook
                        - exchange
                        - exchangeOnPremise
                      readOnly: true
                    isDefault:
                      type: boolean
                      description: Whether this is the user's default email account
                    dailyLimit:
                      type: integer
                      description: Maximum number of emails that can be sent per day from this account
                    connectionStatus:
                      type: string
                      description: |-
                        Current connection status of the email account.
                        Values: unknown, connected, disconnected
                      enum:
                        - unknown
                        - connected
                        - disconnected
                      readOnly: true
                  example: &ref_550
                    id: 12345
                    ownerUserId: 42
                    email: sales@company.com
                    senderName: Sales Team
                    emailAccountType: gmail
                    isDefault: false
                    dailyLimit: 500
                    connectionStatus: connected
        '400':
          description: Invalid id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to view this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to view this sequence.
                code: sequenceEmailAccount.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence not found
                code: sequenceEmailAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/email-account-links:
    post:
      tags:
        - Sequence Email Accounts
      summary: Assign email account to sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Links an email account to the sequence so it can be used for sending outbound emails.
      operationId: AssignEmailAccountToSequence
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - emailAccountId
              properties:
                emailAccountId:
                  type: integer
                  format: int64
                  minimum: 1
                  description: ID of the email account to link to the sequence
              example:
                emailAccountId: 12345
      responses:
        '200':
          description: Email account is already linked to the sequence (idempotent)
        '201':
          description: Email account linked to sequence successfully
        '400':
          description: Invalid id parameter or request body validation error
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /emailAccountId
                    detail: '''EmailAccountId'' must be greater than 0.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to modify this sequence.
                code: sequenceEmailAccount.forbidden
        '404':
          description: Sequence or email account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account not found
                code: sequenceEmailAccount.notFound
        '409':
          description: Email account limit reached for this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Email account limit reached for this sequence
                code: sequenceEmailAccount.limitReached
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Sequence Email Accounts
      summary: Set sequence email accounts
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Replaces all email account links for the sequence with the provided list.
        Any previously linked accounts not in the new list will be unlinked.
      operationId: SetSequenceEmailAccounts
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - emailAccountIds
              properties:
                emailAccountIds:
                  type: array
                  items:
                    type: integer
                    format: int64
                    minimum: 1
                  description: IDs of email accounts to link to the sequence (replaces existing links)
              example:
                emailAccountIds:
                  - 12345
                  - 67890
      responses:
        '204':
          description: Sequence email accounts updated successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid id parameter or request body validation error
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /emailAccountIds
                    detail: '''EmailAccountIds'' must not be empty.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to modify this sequence.
                code: sequenceEmailAccount.forbidden
        '404':
          description: Sequence or email account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account not found
                code: sequenceEmailAccount.notFound
        '409':
          description: Email account limit reached for this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Email account limit reached for this sequence
                code: sequenceEmailAccount.limitReached
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/email-account-links/{email_account_id}:
    delete:
      tags:
        - Sequence Email Accounts
      summary: Remove email account from sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Unlinks an email account from the sequence. The email account itself is not deleted.
      operationId: RemoveEmailAccountFromSequence
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence ID
          schema:
            type: integer
        - name: email_account_id
          in: path
          required: true
          description: Email Account ID to unlink
          schema:
            type: integer
            format: int64
      responses:
        '204':
          description: Email account removed from sequence. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid id or email_account_id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to modify this sequence.
                code: sequenceEmailAccount.forbidden
        '404':
          description: Sequence or email account link not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Email account is not linked to this sequence
                code: sequenceEmailAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequence-folders:
    get:
      tags:
        - Sequence Folders
      summary: List all sequence folders
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns a list of all sequence folders for the current user
      operationId: GetSequenceFolders
      responses:
        '200':
          description: List of sequence folders retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Sequence Folder
                  description: A folder for organizing sequences
                  properties: &ref_198
                    id:
                      type: string
                      format: uuid
                      readOnly: true
                      description: Unique identifier for the folder
                    name:
                      type: string
                      description: Name of the folder
                  example: &ref_199
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    name: Sales Outreach
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view sequence folders
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewSequence] are denied for userId 123.
                code: sequenceFolder.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Sequence Folders
      summary: Create a sequence folder
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates a new sequence folder
      operationId: CreateSequenceFolder
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Create Sequence Folder
              description: Request body for creating a sequence folder
              properties: &ref_551
                name:
                  type: string
                  description: Name of the folder
              required: &ref_552
                - name
              example: &ref_553
                name: Sales Outreach
      responses:
        '201':
          description: Sequence folder created successfully
          content:
            application/json:
              schema:
                type: object
                title: Sequence Folder
                description: A folder for organizing sequences
                properties: *ref_198
                example: *ref_199
        '400':
          description: Validation failure on the request body
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /name
                    detail: Field is required.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create sequence folders
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceFolder.forbidden
        '409':
          description: A sequence folder with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A folder with this name already exists.
                code: sequenceFolder.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequence-folders/{id}:
    get:
      tags:
        - Sequence Folders
      summary: Get a sequence folder
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns a sequence folder by Id
      operationId: GetSequenceFolderById
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence folder Id
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Sequence folder retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Sequence Folder
                description: A folder for organizing sequences
                properties: *ref_198
                example: *ref_199
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this folder
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewSequence] are denied for userId 123.
                code: sequenceFolder.forbidden
        '404':
          description: Sequence folder not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence folder not found.
                code: sequenceFolder.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Sequence Folders
      summary: Update a sequence folder
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Updates an existing sequence folder
      operationId: UpdateSequenceFolder
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence folder Id
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Update Sequence Folder
              description: Request body for updating a sequence folder
              properties: &ref_554
                name:
                  type: string
                  description: Name of the folder
              required: &ref_555
                - name
              example: &ref_556
                name: Updated Folder Name
      responses:
        '200':
          description: Sequence folder updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Sequence Folder
                description: A folder for organizing sequences
                properties: *ref_198
                example: *ref_199
        '400':
          description: Validation failure on the request body
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /name
                    detail: Field is required.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this folder
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceFolder.forbidden
        '404':
          description: Sequence folder not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence folder not found.
                code: sequenceFolder.notFound
        '409':
          description: A sequence folder with the given name already exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: A folder with this name already exists.
                code: sequenceFolder.duplicateName
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Sequence Folders
      summary: Delete a sequence folder
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes an existing sequence folder
      operationId: DeleteSequenceFolder
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence folder Id
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Sequence folder deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete this folder
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceFolder.forbidden
        '404':
          description: Sequence folder not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence folder not found.
                code: sequenceFolder.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequence-folders/{id}/sequences:
    get:
      tags:
        - Sequence Folders
      summary: List sequences in a folder
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of sequences in a folder
      operationId: GetFolderSequences
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence folder Id
          schema:
            type: string
            format: uuid
        - name: top
          in: query
          required: false
          description: Maximum number of items to return
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip
          schema:
            type: integer
        - name: sort_by
          in: query
          required: false
          description: Field to sort by
          schema:
            type: string
        - name: sort_direction
          in: query
          required: false
          description: Sort direction (asc or desc)
          schema:
            type: string
            enum:
              - asc
              - desc
      responses:
        '200':
          description: List of sequences in folder retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Sequence List Model
                description: Response model for listing sequences with pagination
                properties: *ref_200
                example: *ref_201
        '400':
          description: Invalid pagination or sort
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000.
                code: sequenceFolderSequenceLink.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view sequences in this folder
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewSequence] are denied for userId 123.
                code: sequenceFolderSequenceLink.forbidden
        '404':
          description: Sequence folder not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence folder not found.
                code: sequenceFolderSequenceLink.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequence-folders/{id}/sequence-links/bulk:
    post:
      tags:
        - Sequence Folders
      summary: Bulk assign sequences to a folder
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Assigns multiple sequences to a folder. Returns a map of sequence IDs that could not be processed with their error details.
      operationId: BulkAssignSequencesToFolder
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence folder Id
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - sequenceIds
              properties:
                sequenceIds:
                  type: array
                  items:
                    type: integer
                  description: List of sequence IDs to assign to the folder
      responses:
        '200':
          description: |-
            Bulk assign result — only failed items are returned, keyed by sequence ID.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 1 | `NotFound` — sequence does not exist |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Validation failure on the request body
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /sequenceIds
                    detail: At least one sequence id is required.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this folder
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceFolderSequenceLink.forbidden
        '404':
          description: Sequence folder not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence folder not found.
                code: sequenceFolderSequenceLink.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequence-folders/{id}/sequence-links/bulk-delete:
    post:
      tags:
        - Sequence Folders
      summary: Bulk unassign sequences from a folder
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Removes multiple sequences from a folder. Returns a map of sequence IDs that could not be processed with their error details.
      operationId: BulkUnassignSequencesFromFolder
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence folder Id
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - sequenceIds
              properties:
                sequenceIds:
                  type: array
                  items:
                    type: integer
                  description: List of sequence IDs to unassign from the folder
      responses:
        '200':
          description: |-
            Bulk unassign result — only failed items are returned, keyed by sequence ID.

            Per-item error codes:

            | error | Meaning |
            |-------|---------|
            | 1 | `NotFound` — sequence is not in this folder |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Validation failure on the request body
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /sequenceIds
                    detail: At least one sequence id is required.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this folder
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceFolderSequenceLink.forbidden
        '404':
          description: Sequence folder not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence folder not found.
                code: sequenceFolderSequenceLink.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/linkedin-accounts:
    get:
      tags:
        - Sequence LinkedIn Accounts
      summary: List LinkedIn accounts for a sequence
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns all LinkedIn accounts available for the sequence
      operationId: GetSequenceLinkedInAccounts
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: List of LinkedIn accounts retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Sequence LinkedIn Account
                  description: A LinkedIn account linked to a sequence
                  properties: *ref_202
                  example: *ref_203
        '400':
          description: Invalid id parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to view this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to view this sequence.
                code: sequenceLinkedInAccount.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence with ID 42 is not found.
                code: sequenceLinkedInAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/linkedin-account-links:
    post:
      tags:
        - Sequence LinkedIn Accounts
      summary: Assign a LinkedIn account to a sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Links a LinkedIn account to the specified sequence
      operationId: AssignLinkedInAccountToSequence
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - linkedInAccountId
              properties:
                linkedInAccountId:
                  type: integer
                  description: LinkedIn account Id to assign
      responses:
        '200':
          description: LinkedIn account is already linked to the sequence (idempotent)
        '201':
          description: LinkedIn account assigned to sequence successfully
        '400':
          description: Invalid id parameter or request body validation error
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /linkedInAccountId
                    detail: '''LinkedInAccountId'' must be greater than 0.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to modify this sequence.
                code: sequenceLinkedInAccount.forbidden
        '404':
          description: Sequence or LinkedIn account not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: LinkedIn account with ID 7 is not found or not accessible
                code: sequenceLinkedInAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/linkedin-account-links/{linkedInAccountId}:
    delete:
      tags:
        - Sequence LinkedIn Accounts
      summary: Remove a LinkedIn account from a sequence
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Unlinks a LinkedIn account from the specified sequence
      operationId: RemoveLinkedInAccountFromSequence
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
            minimum: 1
        - name: linkedInAccountId
          in: path
          required: true
          description: LinkedIn account Id
          schema:
            type: integer
            minimum: 1
      responses:
        '204':
          description: LinkedIn account removed from sequence successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid id or linkedInAccountId parameter
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The field id must be between 1 and 2147483647.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks permission to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to modify this sequence.
                code: sequenceLinkedInAccount.forbidden
        '404':
          description: Sequence or LinkedIn account link not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: LinkedIn account is not linked to this sequence
                code: sequenceLinkedInAccount.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/steps:
    get:
      tags:
        - Sequence Steps
      summary: List all sequence steps
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns a list of all steps in a sequence
      operationId: GetSequenceSteps
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
      responses:
        '200':
          description: List of sequence steps retrieved successfully
          content:
            application/json:
              schema:
                type: array
                description: Array of sequence steps with different types
                items:
                  title: Sequence Step
                  discriminator: *ref_187
                  oneOf: *ref_188
        '400':
          description: Invalid sequence id, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewSequence] are denied for userId 123.
                code: sequenceStep.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Sequence Steps
      summary: Create a sequence step
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates a new step in a sequence. For bulk creation, use the `/steps/bulk` endpoint.

        For email steps, each variant may carry up to **3** `attachmentIds` (upload first via `POST /v3/attachments`); attachments that don't belong to the caller (or the caller's team) are rejected with `403 sequenceStep.forbidden`.
      operationId: CreateSequenceStep
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              title: Sequence Step
              discriminator: *ref_187
              oneOf: *ref_188
      responses:
        '201':
          description: Sequence step created successfully
          content:
            application/json:
              schema:
                title: Sequence Step
                discriminator: *ref_187
                oneOf: *ref_188
        '400':
          description: Body validation failure, or a business-rule rejection (invalid step type, configuration, missing email subject, or more than 3 attachments on a variant).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /parentId
                        detail: '''parentId'' is required when the sequence contains conditional steps.'
                too_many_attachments:
                  summary: A variant carries more than 3 attachment IDs
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /variants/0/attachmentIds
                        detail: Maximum 3 attachments allowed per variant.
                invalid_step:
                  summary: Invalid step type or configuration
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid step configuration.
                    code: sequenceStep.invalidStep
                missing_email_subject:
                  summary: Email step is missing a subject
                  value:
                    title: Bad Request
                    status: 400
                    detail: Email step is missing a subject.
                    code: sequenceStep.missingEmailSubject
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Caller does not have permission to modify this sequence, or one or more of the supplied variant `attachmentIds` are not accessible.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                no_permission:
                  summary: Caller does not have permission to modify this sequence
                  value:
                    title: Forbidden
                    status: 403
                    detail: You do not have permission to modify this sequence.
                    code: sequenceStep.forbidden
                attachment_inaccessible:
                  summary: One or more attachment IDs are not accessible
                  value:
                    title: Forbidden
                    status: 403
                    detail: 'Attachment IDs not found or not accessible: 9001, 9002'
                    code: sequenceStep.forbidden
        '404':
          description: Sequence not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence 42 not found.
                code: sequenceStep.notFound
        '409':
          description: A step in the sequence is locked and blocks the operation
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Step is locked and cannot be modified.
                code: sequenceStep.stepLocked
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/steps/{step_id}:
    get:
      tags:
        - Sequence Steps
      summary: Get a sequence step
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns details of a specific sequence step
      operationId: GetSequenceStepById
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
        - name: step_id
          in: path
          required: true
          description: Step Id
          schema:
            type: integer
      responses:
        '200':
          description: Sequence step details retrieved successfully
          content:
            application/json:
              schema:
                title: Sequence Step
                discriminator: *ref_187
                oneOf: *ref_188
        '400':
          description: Invalid sequence id or step id, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewSequence] are denied for userId 123.
                code: sequenceStep.forbidden
        '404':
          description: Sequence or step not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Step 7 not found on sequence 42.
                code: sequenceStep.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Sequence Steps
      summary: Update a sequence step
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Updates an existing sequence step. Each variant in the request body must include its `id` to identify which variant to update.

        For email steps, each variant may carry up to **3** `attachmentIds` (upload first via `POST /v3/attachments`); attachments that don't belong to the caller (or the caller's team) are rejected with `403 sequenceStep.forbidden`.
      operationId: UpdateSequenceStep
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
        - name: step_id
          in: path
          required: true
          description: Step Id
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              title: Sequence Step (Update)
              description: Polymorphic step schema for update operations. Variant `id` is required to identify which variant to update.
              discriminator: &ref_571
                propertyName: type
                mapping:
                  email: '#/components/schemas/email-update.type'
                  linkedIn: '#/components/schemas/linkedin-update.type'
                  call: '#/components/schemas/call.type'
                  sms: '#/components/schemas/sms.type'
                  whatsApp: '#/components/schemas/whatsapp.type'
                  zapier: '#/components/schemas/zapier.type'
                  task: '#/components/schemas/task.type'
                  condition: '#/components/schemas/condition.type'
              oneOf: &ref_572
                - type: object
                  title: Email (Update)
                  description: Email step with variant configuration for update operations
                  properties: &ref_559
                    id:
                      type: integer
                      nullable: true
                      readOnly: true
                      description: Unique identifier for the step
                    parentId:
                      type: integer
                      nullable: true
                      description: ID of the parent step (for branching)
                    ifConditionPositive:
                      type: boolean
                      nullable: true
                      description: Whether this step is on the positive branch of a condition
                    type:
                      type: string
                      enum:
                        - email
                      description: Step type discriminator
                    delayInMinutes:
                      type: integer
                      minimum: 0
                      description: Delay in minutes before executing this step
                    executionMode:
                      type: string
                      description: Execution mode for the email step
                      enum:
                        - automatic
                        - manual
                    variants:
                      type: array
                      description: Array of email variants (A/B test versions). Each variant must include its `id` for update operations.
                      items:
                        type: object
                        title: Email Variant (Update)
                        description: Individual email variant within an email step for update operations. The `id` field is required to identify which variant to update.
                        properties: &ref_557
                          id:
                            type: integer
                            description: Unique identifier for this email variant. Required for update operations.
                          subject:
                            type: string
                            nullable: true
                            description: Email subject line.
                          message:
                            type: string
                            nullable: true
                            description: Email message content.
                          attachmentIds:
                            type: array
                            nullable: true
                            writeOnly: true
                            maxItems: 3
                            items:
                              type: integer
                            description: |-
                              **Write-only.** IDs of previously uploaded attachments to attach to this variant. Upload files via `POST /v3/attachments` first to obtain attachment IDs.
                              A variant may carry up to 3 attachments. Omit or pass `null` to leave existing attachments unchanged; pass an empty array to clear them.
                              Not returned on read — use `hasAttachments` to detect presence.
                          hasAttachments:
                            type: boolean
                            readOnly: true
                            description: Whether the variant has any attachments. Returned on read; ignored on write.
                        required: &ref_558
                          - id
                  required: &ref_560
                    - type
                    - delayInMinutes
                    - executionMode
                    - variants
                - title: LinkedIn (Update)
                  description: LinkedIn step with action type sub-discriminator for update operations. Uses type "linkedIn" with a second discriminator actionType to select the specific LinkedIn action. Variants require `id` field for update operations.
                  discriminator: &ref_569
                    propertyName: actionType
                    mapping:
                      message: '#/components/schemas/linkedin-message-update.type'
                      connect: '#/components/schemas/linkedin-connect-update.type'
                      inMail: '#/components/schemas/linkedin-inmail-update.type'
                      viewProfile: '#/components/schemas/linkedin-view-profile.type'
                      endorseSkills: '#/components/schemas/linkedin-endorse-skills.type'
                      voiceMessage: '#/components/schemas/linkedin-voice-message.type'
                      likeRecentPosts: '#/components/schemas/linkedin-like-recent-posts.type'
                      followProfile: '#/components/schemas/linkedin-follow-profile.type'
                      commentOnRecentPost: '#/components/schemas/linkedin-comment-on-recent-post.type'
                  oneOf: &ref_570
                    - type: object
                      title: LinkedIn Message (Update)
                      description: LinkedIn message action step for update operations
                      properties: &ref_561
                        id:
                          type: integer
                          nullable: true
                          readOnly: true
                          description: Unique identifier for the step
                        parentId:
                          type: integer
                          nullable: true
                          description: ID of the parent step (for branching)
                        ifConditionPositive:
                          type: boolean
                          nullable: true
                          description: Whether this step is on the positive branch of a condition
                        type:
                          type: string
                          enum:
                            - linkedIn
                          description: Step type discriminator
                        actionType:
                          type: string
                          enum:
                            - message
                          description: LinkedIn action type discriminator
                        delayInMinutes:
                          type: integer
                          minimum: 0
                          description: Delay in minutes before executing this step
                        executionMode:
                          type: string
                          description: Execution mode for the action
                          enum:
                            - automatic
                            - manual
                        variants:
                          type: array
                          description: Array of LinkedIn message variants (A/B test versions). Each variant must include its `id` for update operations.
                          items:
                            type: object
                            title: LinkedIn Variant (Update)
                            description: Individual LinkedIn message/connect variant for update operations. The `id` field is required to identify which variant to update.
                            properties: &ref_204
                              id:
                                type: integer
                                description: Unique identifier for this LinkedIn variant. Required for update operations.
                              message:
                                type: string
                                description: Message content
                              isEnabled:
                                type: boolean
                                description: Indicates whether the variant is enabled
                            required: &ref_205
                              - id
                              - message
                              - isEnabled
                      required: &ref_562
                        - type
                        - actionType
                        - delayInMinutes
                        - executionMode
                        - variants
                    - type: object
                      title: LinkedIn Connect (Update)
                      description: LinkedIn connect action step for update operations
                      properties: &ref_563
                        id:
                          type: integer
                          nullable: true
                          readOnly: true
                          description: Unique identifier for the step
                        parentId:
                          type: integer
                          nullable: true
                          description: ID of the parent step (for branching)
                        ifConditionPositive:
                          type: boolean
                          nullable: true
                          description: Whether this step is on the positive branch of a condition
                        type:
                          type: string
                          enum:
                            - linkedIn
                          description: Step type discriminator
                        actionType:
                          type: string
                          enum:
                            - connect
                          description: LinkedIn action type discriminator
                        delayInMinutes:
                          type: integer
                          minimum: 0
                          description: Delay in minutes before executing this step
                        executionMode:
                          type: string
                          description: Execution mode for the action
                          enum:
                            - automatic
                            - manual
                        variants:
                          type: array
                          description: Array of LinkedIn connect variants (A/B test versions). Message is optional, max 300 characters. Each variant must include its `id` for update operations.
                          items:
                            type: object
                            title: LinkedIn Variant (Update)
                            description: Individual LinkedIn message/connect variant for update operations. The `id` field is required to identify which variant to update.
                            properties: *ref_204
                            required: *ref_205
                      required: &ref_564
                        - type
                        - actionType
                        - delayInMinutes
                        - executionMode
                        - variants
                    - type: object
                      title: LinkedIn InMail (Update)
                      description: LinkedIn InMail action step for update operations
                      properties: &ref_567
                        id:
                          type: integer
                          nullable: true
                          readOnly: true
                          description: Unique identifier for the step
                        parentId:
                          type: integer
                          nullable: true
                          description: ID of the parent step (for branching)
                        ifConditionPositive:
                          type: boolean
                          nullable: true
                          description: Whether this step is on the positive branch of a condition
                        type:
                          type: string
                          enum:
                            - linkedIn
                          description: Step type discriminator
                        actionType:
                          type: string
                          enum:
                            - inMail
                          description: LinkedIn action type discriminator
                        delayInMinutes:
                          type: integer
                          minimum: 0
                          description: Delay in minutes before executing this step
                        executionMode:
                          type: string
                          description: Execution mode for the InMail
                          enum:
                            - automatic
                            - manual
                        variants:
                          type: array
                          description: Array of LinkedIn InMail variants (A/B test versions). Each variant must include its `id` for update operations.
                          items:
                            type: object
                            title: LinkedIn InMail Variant (Update)
                            description: Individual LinkedIn InMail variant for update operations. The `id` field is required to identify which variant to update.
                            properties: &ref_565
                              id:
                                type: integer
                                description: Unique identifier for this LinkedIn InMail variant. Required for update operations.
                              subject:
                                type: string
                                description: InMail subject line
                              message:
                                type: string
                                description: InMail message content
                              isEnabled:
                                type: boolean
                                description: Indicates whether the variant is enabled
                            required: &ref_566
                              - id
                              - subject
                              - message
                              - isEnabled
                      required: &ref_568
                        - type
                        - actionType
                        - delayInMinutes
                        - executionMode
                        - variants
                    - type: object
                      title: LinkedIn View Profile
                      description: LinkedIn view profile action step
                      properties: *ref_206
                      required: *ref_207
                    - type: object
                      title: LinkedIn Endorse Skills
                      description: LinkedIn endorse skills action step
                      properties: *ref_208
                      required: *ref_209
                    - type: object
                      title: LinkedIn Voice Message
                      description: LinkedIn voice message action step
                      properties: *ref_210
                      required: *ref_211
                    - type: object
                      title: LinkedIn Like Recent Posts
                      description: LinkedIn like recent posts action step
                      properties: *ref_212
                      required: *ref_213
                    - type: object
                      title: LinkedIn Follow Profile
                      description: LinkedIn follow profile action step
                      properties: *ref_214
                      required: *ref_215
                    - type: object
                      title: LinkedIn Comment On Recent Post
                      description: |-
                        LinkedIn comment on a recent post action step. The AI writes a comment on the contact's most recent post using the
                        instructions in `aiPromptText`. Use the AI prompt preview endpoints to check what a prompt produces before saving
                        it on a step. How many of these comments an account posts per day is governed by that LinkedIn account's own daily
                        limits, not by this step.
                      properties: *ref_216
                      required: *ref_217
                - type: object
                  title: Call
                  description: Call step with script/notes
                  properties: *ref_218
                  required: *ref_219
                - type: object
                  title: SMS
                  description: SMS step with message content
                  properties: *ref_220
                  required: *ref_221
                - type: object
                  title: WhatsApp
                  description: WhatsApp step with message content
                  properties: *ref_222
                  required: *ref_223
                - type: object
                  title: Zapier
                  description: Zapier integration step
                  properties: *ref_224
                  required: *ref_225
                - type: object
                  title: Task
                  description: Task step for manual actions
                  properties: *ref_226
                  required: *ref_227
                - type: object
                  title: Condition
                  description: Condition step that evaluates rules before proceeding
                  properties: *ref_228
                  required: *ref_229
      responses:
        '200':
          description: Sequence step updated successfully
          content:
            application/json:
              schema:
                title: Sequence Step
                discriminator: *ref_187
                oneOf: *ref_188
        '400':
          description: Route/body validation failure, or a business-rule rejection (including more than 3 attachments on a variant).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /id
                        detail: '''id'' is required.'
                too_many_attachments:
                  summary: A variant carries more than 3 attachment IDs
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /variants/0/attachmentIds
                        detail: Maximum 3 attachments allowed per variant.
                invalid_step:
                  summary: Invalid step type or configuration
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid step configuration.
                    code: sequenceStep.invalidStep
                missing_email_subject:
                  summary: Email step is missing a subject
                  value:
                    title: Bad Request
                    status: 400
                    detail: Email step is missing a subject.
                    code: sequenceStep.missingEmailSubject
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Caller does not have permission to modify this sequence, or one or more of the supplied variant `attachmentIds` are not accessible.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                no_permission:
                  summary: Caller does not have permission to modify this sequence
                  value:
                    title: Forbidden
                    status: 403
                    detail: You do not have permission to modify this sequence.
                    code: sequenceStep.forbidden
                attachment_inaccessible:
                  summary: One or more attachment IDs are not accessible
                  value:
                    title: Forbidden
                    status: 403
                    detail: 'Attachment IDs not found or not accessible: 9001, 9002'
                    code: sequenceStep.forbidden
        '404':
          description: Sequence or step not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Step 7 not found on sequence 42.
                code: sequenceStep.notFound
        '409':
          description: Step is locked and cannot be modified
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              examples:
                step_locked:
                  summary: Step is locked
                  value:
                    title: Conflict
                    status: 409
                    detail: Step is locked and cannot be modified.
                    code: sequenceStep.stepLocked
                step_locked_subject_source:
                  summary: Step is the subject source for downstream steps
                  value:
                    title: Conflict
                    status: 409
                    detail: Step is the subject source for downstream steps and cannot be modified.
                    code: sequenceStep.stepLockedSubjectSource
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Sequence Steps
      summary: Delete a sequence step
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes a sequence step.

        By default only the addressed step is removed (`mode=nodeOnly`), and any children remain attached to the parent. For condition (branch) steps, set `mode` to also remove descendants on one or both branches.
      operationId: DeleteSequenceStep
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
        - name: step_id
          in: path
          required: true
          description: Step Id
          schema:
            type: integer
        - name: mode
          in: query
          required: false
          description: Node selection mode for deletion. Defaults to `nodeOnly`.
          schema:
            type: string
            enum:
              - nodeOnly
              - nodeAndAllChildren
              - nodeAndPositiveChildren
              - nodeAndNegativeChildren
            default: nodeOnly
      responses:
        '204':
          description: Sequence step deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid id parameters, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceStep.forbidden
        '404':
          description: Step not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Step 7 not found on sequence 42.
                code: sequenceStep.notFound
        '409':
          description: Step is locked or has children that prevent deletion
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              examples:
                step_locked:
                  summary: Step is locked
                  value:
                    title: Conflict
                    status: 409
                    detail: Step is locked and cannot be deleted.
                    code: sequenceStep.stepLocked
                step_locked_has_children:
                  summary: Step has children that prevent deletion
                  value:
                    title: Conflict
                    status: 409
                    detail: Step cannot be deleted because it has children.
                    code: sequenceStep.stepLockedHasChildren
                step_locked_subject_source_with_children:
                  summary: Step is the subject source for downstream steps and has children
                  value:
                    title: Conflict
                    status: 409
                    detail: Step is the subject source for downstream steps and has children.
                    code: sequenceStep.stepLockedSubjectSourceWithChildren
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/steps/bulk:
    post:
      tags:
        - Sequence Steps
      summary: Bulk create sequence steps
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates multiple steps in a sequence at once. Returns a list of results for each step. Email-step variants may carry up to **3** `attachmentIds` each; inaccessible attachment IDs surface as a per-item `forbidden` result (upload first via `POST /v3/attachments`).
      operationId: BulkCreateSequenceSteps
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                title: Sequence Step
                discriminator: *ref_187
                oneOf: *ref_188
      responses:
        '200':
          description: |-
            Array of per-item results, one per input step (same order as request).

            Possible per-item error codes:

            | Error code | Meaning |
            |-------|---------|
            | `invalidInput` | Validation failed (e.g. more than 3 attachments on a variant) |
            | `invalidStep` | Step type or configuration is invalid |
            | `forbidden` | One or more attachment IDs are not accessible to the caller |
            | `internalError` | Unexpected server error |
            | `stepLocked` | Step cannot be modified |
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: CreateItemResult
                  description: |-
                    Per-item result for non-atomic bulk create operations.
                    On success, id is set. On failure, error and errorDetails are set.
                    Response array order matches request array order.
                  properties: &ref_235
                    id:
                      type: integer
                      nullable: true
                      readOnly: true
                      description: ID of the created resource, null if creation failed
                    error:
                      type: integer
                      nullable: true
                      readOnly: true
                      description: Error code if creation failed
                    errorDetails:
                      type: string
                      nullable: true
                      readOnly: true
                      description: Human-readable error description if creation failed
        '400':
          description: Invalid sequence id, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Caller does not have permission to modify this sequence. Per-item attachment-accessibility failures surface as `forbidden` entries in the 200 result array, not as a top-level 403.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to modify this sequence.
                code: sequenceStep.forbidden
        '409':
          description: A step in the sequence is locked and blocks bulk creation
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Step is locked and cannot be modified.
                code: sequenceStep.stepLocked
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/steps/bulk-delete:
    post:
      tags:
        - Sequence Steps
      summary: Bulk delete sequence steps
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes multiple steps from a sequence at once. Returns a map of step IDs that could not be processed with their error details.
      operationId: BulkDeleteSequenceSteps
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - ids
              properties:
                ids:
                  type: array
                  items:
                    type: integer
                  description: List of step IDs to delete
      responses:
        '200':
          description: |-
            Dictionary keyed by step ID. Only failed items appear; items not in the dictionary succeeded.

            Possible per-item error codes:

            | Error code | Meaning |
            |-------|---------|
            | `notFound` | Step does not exist or caller lacks permission |
            | `stepLocked` | Step cannot be deleted |
            | `stepLockedHasChildren` | Step has children that prevent deletion |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /ids
                        detail: '''ids'' must not be empty.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceStep.forbidden
        '409':
          description: A step in the sequence is locked and blocks bulk deletion
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Step is locked and cannot be deleted.
                code: sequenceStep.stepLocked
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/steps/{step_id}/enable:
    post:
      tags:
        - Sequence Steps
      summary: Enable step variants
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Enables the specified variants on a sequence step. Variants are toggled independently — failures are reported per `variantId` in the response without aborting the whole call.
      operationId: EnableSequenceStepVariants
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
        - name: step_id
          in: path
          required: true
          description: Step Id
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - variantIds
              properties:
                variantIds:
                  type: array
                  items:
                    type: integer
                  description: List of variant IDs to enable
      responses:
        '200':
          description: |-
            Dictionary keyed by variant ID. Only failed items appear; items not in the dictionary succeeded.

            Possible per-item error codes:

            | Error code | Meaning |
            |-------|---------|
            | `invalidInput` | Variant id is not valid for this step |
            | `unsupportedOperation` | Step type does not support enabling/disabling variants |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Route/body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /variantIds
                        detail: '''variantIds'' must not be empty.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceStep.forbidden
        '404':
          description: Step not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Step 7 not found on sequence 42.
                code: sequenceStep.notFound
        '409':
          description: Step is locked and cannot be modified
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Step is locked and cannot be modified.
                code: sequenceStep.stepLocked
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/steps/{step_id}/disable:
    post:
      tags:
        - Sequence Steps
      summary: Disable step variants
      x-required-scope: sequences:operate
      description: |-
        <small>_Requires the `sequences:operate` scope (or a broader one that includes it)._</small>

        Disables the specified variants on a sequence step. Variants are toggled independently — failures are reported per `variantId` in the response without aborting the whole call.
      operationId: DisableSequenceStepVariants
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
        - name: step_id
          in: path
          required: true
          description: Step Id
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - variantIds
              properties:
                variantIds:
                  type: array
                  items:
                    type: integer
                  description: List of variant IDs to disable
      responses:
        '200':
          description: |-
            Dictionary keyed by variant ID. Only failed items appear; items not in the dictionary succeeded.

            Possible per-item error codes:

            | Error code | Meaning |
            |-------|---------|
            | `invalidInput` | Variant id is not valid for this step |
            | `unsupportedOperation` | Step type does not support enabling/disabling variants |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Route/body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /variantIds
                        detail: '''variantIds'' must not be empty.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceStep.forbidden
        '404':
          description: Step not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Step 7 not found on sequence 42.
                code: sequenceStep.notFound
        '409':
          description: Step is locked and cannot be modified
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Step is locked and cannot be modified.
                code: sequenceStep.stepLocked
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/steps/{step_id}/variants:
    get:
      tags:
        - Sequence Steps
      summary: List step variants
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns all variants for a sequence step
      operationId: GetSequenceStepVariants
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
        - name: step_id
          in: path
          required: true
          description: Step Id
          schema:
            type: integer
      responses:
        '200':
          description: List of variants retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: Step Variant
                  description: A text variant for a sequence step
                  properties: &ref_230
                    id:
                      type: integer
                      readOnly: true
                      description: Unique identifier for the variant
                    subject:
                      type: string
                      nullable: true
                      description: Subject line of the variant
                    message:
                      type: string
                      nullable: true
                      description: Message content of the variant
                    isEnabled:
                      type: boolean
                      description: Whether the variant is enabled
                    hasAttachments:
                      type: boolean
                      description: Whether the variant has any attachments. To retrieve or modify attachments, use `GET /v3/attachments` and the `attachmentIds` field on create/update.
                  example: &ref_231
                    id: 1
                    subject: Follow up on our conversation
                    message: Hi {{firstName}}, I wanted to follow up...
                    isEnabled: true
                    hasAttachments: false
        '400':
          description: Invalid id parameters, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewSequence] are denied for userId 123.
                code: sequenceStep.forbidden
        '404':
          description: Step not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Step 7 not found on sequence 42.
                code: sequenceStep.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Sequence Steps
      summary: Create a step variant
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates a new variant for a sequence step. Supports both text variants (`application/json`) and voice message variants (`multipart/form-data`).

        For email-step text variants, the request may carry up to **3** `attachmentIds` (upload first via `POST /v3/attachments`). Inaccessible attachment IDs are rejected with `403 sequenceStep.forbidden`.
      operationId: CreateSequenceStepVariant
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
        - name: step_id
          in: path
          required: true
          description: Step Id
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Variant Request
              description: Request body for creating or updating a text variant
              properties: &ref_232
                subject:
                  type: string
                  nullable: true
                  description: Subject line of the variant
                message:
                  type: string
                  description: Message content of the variant
                isEnabled:
                  type: boolean
                  default: true
                  description: Whether the variant is enabled
                attachmentIds:
                  type: array
                  nullable: true
                  maxItems: 3
                  items:
                    type: integer
                  description: |-
                    IDs of previously uploaded attachments to attach to this variant. Upload files via `POST /v3/attachments` first to obtain attachment IDs.
                    A variant may carry up to 3 attachments. Omit or pass `null` to leave attachments unchanged on update; pass an empty array to clear existing attachments.
              required: &ref_233
                - message
              example: &ref_234
                subject: Follow up on our conversation
                message: Hi {{firstName}}, I wanted to follow up...
                isEnabled: true
                attachmentIds:
                  - 101
                  - 102
      responses:
        '201':
          description: Variant created successfully
          content:
            application/json:
              schema:
                type: object
                title: Step Variant
                description: A text variant for a sequence step
                properties: *ref_230
                example: *ref_231
        '400':
          description: Route/body validation failure, or a business-rule rejection (including more than 3 attachments).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /body
                        detail: '''body'' must not be empty.'
                too_many_attachments:
                  summary: More than 3 attachment IDs supplied
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /attachmentIds
                        detail: Maximum 3 attachments allowed per variant.
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks the required feature scope to modify this sequence, or one or more of the supplied `attachmentIds` are not accessible to the caller.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                feature_scope_denied:
                  summary: User lacks ManageSequence scope
                  value:
                    title: Forbidden
                    status: 403
                    detail: Feature scopes [ManageSequence] are denied for userId 123.
                    code: sequenceStep.forbidden
                attachment_inaccessible:
                  summary: One or more attachment IDs are not accessible to the caller
                  value:
                    title: Forbidden
                    status: 403
                    detail: 'Attachment IDs not found or not accessible: 9001, 9002'
                    code: sequenceStep.forbidden
        '404':
          description: Step not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Step 7 not found on sequence 42.
                code: sequenceStep.notFound
        '409':
          description: Step is locked and cannot accept new variants
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Step is locked and cannot be modified.
                code: sequenceStep.stepLocked
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/steps/{step_id}/variants/bulk:
    post:
      tags:
        - Sequence Steps
      summary: Bulk create step variants
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Creates multiple text variants for a sequence step at once. For email steps, each variant may carry up to **3** `attachmentIds` (upload first via `POST /v3/attachments`); inaccessible attachment IDs surface as a per-item `forbidden` result.
      operationId: BulkCreateSequenceStepVariants
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
        - name: step_id
          in: path
          required: true
          description: Step Id
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                title: Variant Request
                description: Request body for creating or updating a text variant
                properties: *ref_232
                required: *ref_233
                example: *ref_234
      responses:
        '200':
          description: |-
            Array of per-item results, one per input variant (same order as request).

            Possible per-item error codes:

            | Error code | Meaning |
            |-------|---------|
            | `invalidInput` | Validation failed (e.g. more than 3 attachments) |
            | `invalidStep` | Step type does not support this variant |
            | `forbidden` | One or more attachment IDs are not accessible to the caller |
            | `internalError` | Unexpected server error |
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  title: CreateItemResult
                  description: |-
                    Per-item result for non-atomic bulk create operations.
                    On success, id is set. On failure, error and errorDetails are set.
                    Response array order matches request array order.
                  properties: *ref_235
        '400':
          description: Invalid id parameters, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Caller does not have permission to modify this sequence. Per-item attachment-accessibility failures surface as `forbidden` entries in the 200 result array, not as a top-level 403.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: You do not have permission to modify this sequence.
                code: sequenceStep.forbidden
        '404':
          description: Step not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Step 7 not found on sequence 42.
                code: sequenceStep.notFound
        '409':
          description: Step is locked and blocks bulk variant creation
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Step is locked and cannot be modified.
                code: sequenceStep.stepLocked
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/steps/{step_id}/variants/bulk-delete:
    post:
      tags:
        - Sequence Steps
      summary: Bulk delete step variants
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes multiple variants from a sequence step at once. Returns a map of variant IDs that could not be processed with their error details.
      operationId: BulkDeleteSequenceStepVariants
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
        - name: step_id
          in: path
          required: true
          description: Step Id
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - ids
              properties:
                ids:
                  type: array
                  items:
                    type: integer
                  description: List of variant IDs to delete
      responses:
        '200':
          description: |-
            Dictionary keyed by variant ID. Only failed items appear; items not in the dictionary succeeded.

            Possible per-item error codes:

            | Error code | Meaning |
            |-------|---------|
            | `notFound` | Variant does not exist or caller lacks permission |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: Body validation failure, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /ids
                        detail: '''ids'' must not be empty.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceStep.forbidden
        '409':
          description: Step is locked and blocks bulk variant deletion
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Step is locked and cannot be modified.
                code: sequenceStep.stepLocked
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/{id}/steps/{step_id}/variants/{variant_id}:
    put:
      tags:
        - Sequence Steps
      summary: Update a step variant
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Updates an existing variant for a sequence step. Supports both text variants (`application/json`) and voice message variants (`multipart/form-data`).

        For email-step text variants, the request may carry up to **3** `attachmentIds` (upload first via `POST /v3/attachments`). Inaccessible attachment IDs are rejected with `403 sequenceStep.forbidden`.
      operationId: UpdateSequenceStepVariant
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
        - name: step_id
          in: path
          required: true
          description: Step Id
          schema:
            type: integer
        - name: variant_id
          in: path
          required: true
          description: Variant Id
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Variant Request
              description: Request body for creating or updating a text variant
              properties: *ref_232
              required: *ref_233
              example: *ref_234
      responses:
        '200':
          description: Variant updated successfully
          content:
            application/json:
              schema:
                type: object
                title: Step Variant
                description: A text variant for a sequence step
                properties: *ref_230
                example: *ref_231
        '400':
          description: Route/body validation failure, or a business-rule rejection (including more than 3 attachments).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /body
                        detail: '''body'' must not be empty.'
                too_many_attachments:
                  summary: More than 3 attachment IDs supplied
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /attachmentIds
                        detail: Maximum 3 attachments allowed per variant.
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Caller does not have permission to modify this sequence, or one or more of the supplied `attachmentIds` are not accessible.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                no_permission:
                  summary: Caller does not have permission to modify this sequence
                  value:
                    title: Forbidden
                    status: 403
                    detail: You do not have permission to modify this sequence.
                    code: sequenceStep.forbidden
                attachment_inaccessible:
                  summary: One or more attachment IDs are not accessible
                  value:
                    title: Forbidden
                    status: 403
                    detail: 'Attachment IDs not found or not accessible: 9001, 9002'
                    code: sequenceStep.forbidden
        '404':
          description: Step or variant not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Variant 3 not found on step 7.
                code: sequenceStep.notFound
        '409':
          description: Step is locked and cannot be modified
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Step is locked and cannot be modified.
                code: sequenceStep.stepLocked
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Sequence Steps
      summary: Delete a step variant
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes an existing variant from a sequence step
      operationId: DeleteSequenceStepVariant
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence Id
          schema:
            type: integer
        - name: step_id
          in: path
          required: true
          description: Step Id
          schema:
            type: integer
        - name: variant_id
          in: path
          required: true
          description: Variant Id
          schema:
            type: integer
      responses:
        '204':
          description: Variant deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid id parameters, or a business-rule rejection.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_invalid_input:
                  summary: Business-rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Invalid input.
                    code: sequenceStep.invalidInput
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to modify this sequence
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageSequence] are denied for userId 123.
                code: sequenceStep.forbidden
        '404':
          description: Step or variant not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Variant 3 not found on step 7.
                code: sequenceStep.notFound
        '409':
          description: Step is locked and cannot be modified
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Step is locked and cannot be modified.
                code: sequenceStep.stepLocked
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequences/steps/contact-filter-properties:
    get:
      tags:
        - Sequence Steps
      summary: List contact filter properties
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns all available contact filter properties that can be used in sequence step conditions.
        Each property includes its supported operators and, for enum-like properties, the allowed values.

        This is a static discovery endpoint — the response does not depend on user data or any specific sequence.
      operationId: GetConditionProperties
      responses:
        '200':
          description: Dictionary of property definitions keyed by property name
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: ConditionPropertyResponse
                  description: |-
                    Describes a single contact filter property available for sequence step conditions.
                    Each property defines which operators can be used and, for enum-like properties, the allowed values.
                  required: &ref_573
                    - operators
                  properties: &ref_574
                    operators:
                      type: array
                      items:
                        type: string
                      description: List of operators supported by this property (e.g. "is", "isNot", "contains", "isSet")
                    values:
                      type: array
                      nullable: true
                      items:
                        type: string
                      description: |-
                        Allowed values for enum-like properties. Only present when the property
                        accepts a fixed set of values (e.g. stage, emailValidationStatus).
                        Omitted (null) for free-text, numeric, and set-only properties.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequence-templates:
    get:
      tags:
        - Sequence Templates
      summary: List all sequence templates
      x-required-scope: sequences:read
      description: |-
        <small>_Requires the `sequences:read` scope (or a broader one that includes it)._</small>

        Returns all sequence templates grouped by scope (global, organization, team)
      operationId: GetSequenceTemplates
      responses:
        '200':
          description: Sequence templates retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Sequence Templates List
                description: Response model for listing sequence templates grouped by scope
                properties: &ref_575
                  globalTemplates:
                    type: array
                    description: Global templates available to all users
                    items:
                      type: object
                      title: Sequence Template
                      description: A sequence template
                      properties: *ref_236
                      example: *ref_237
                  organizationTemplates:
                    type: array
                    description: Organization-level templates
                    items:
                      type: object
                      title: Sequence Template
                      description: A sequence template
                      properties: *ref_236
                      example: *ref_237
                  teamTemplates:
                    type: array
                    description: Team-level templates
                    items:
                      type: object
                      title: Sequence Template
                      description: A sequence template
                      properties: *ref_236
                      example: *ref_237
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view sequence templates
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewSequence] are denied for userId 123.
                code: sequenceTemplate.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/sequence-templates/{id}:
    delete:
      tags:
        - Sequence Templates
      summary: Delete a sequence template
      x-required-scope: sequences:write
      description: |-
        <small>_Requires the `sequences:write` scope (or a broader one that includes it)._</small>

        Deletes an existing sequence template.

        - **Global templates** (seeded by the system) cannot be deleted — returns 403.
        - **User-scoped templates** are team-shared: any teammate may delete a template visible to them. Out-of-team or non-existent ids return 404.
        - **Organization templates** require the `DeleteOrgTemplates` feature scope — callers without it get 403.
      operationId: DeleteSequenceTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: Sequence template Id
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Sequence template deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Either the target is a global template (which no one can delete) or the caller lacks `DeleteOrgTemplates` for an organization template.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                global_template:
                  summary: Global (system) template cannot be deleted
                  value:
                    title: Forbidden
                    status: 403
                    detail: Global templates cannot be deleted.
                    code: sequenceTemplate.forbidden
                org_template_scope_missing:
                  summary: Organization template — caller lacks DeleteOrgTemplates scope
                  value:
                    title: Forbidden
                    status: 403
                    detail: You do not have permission to delete organization templates.
                    code: sequenceTemplate.forbidden
        '404':
          description: Sequence template not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Sequence template with ID 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d not found.
                code: sequenceTemplate.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/settings:
    get:
      tags:
        - Settings
      summary: Get settings
      x-required-scope: settings:read
      description: |-
        <small>_Requires the `settings:read` scope (or a broader one that includes it)._</small>

        Returns the full settings object for the authenticated user's team, including account profile, email configuration, LinkedIn, calls, contacts, and beta features.
      operationId: GetSettings
      responses:
        '200':
          description: Settings retrieved successfully
          content:
            application/json:
              schema:
                type: object
                title: Settings
                description: Team and user settings. All properties are nullable — on GET, null means the setting is not configured or not applicable. On PATCH, only properties present in the JSON body are updated.
                properties: &ref_238
                  account:
                    type: object
                    description: User profile settings
                    properties: &ref_576
                      firstName:
                        type: string
                        nullable: true
                        maxLength: 48
                        description: User's first name
                      lastName:
                        type: string
                        nullable: true
                        maxLength: 48
                        description: User's last name
                      company:
                        type: string
                        nullable: true
                        maxLength: 48
                        description: Company name
                      phone:
                        type: string
                        nullable: true
                        description: Phone number
                      title:
                        type: string
                        nullable: true
                        maxLength: 72
                        description: Job title
                      timezone:
                        type: string
                        nullable: true
                        description: IANA timezone identifier (e.g. "America/New_York")
                  emails:
                    type: object
                    description: Email-related settings
                    properties: &ref_580
                      isEmailQualityCheckEnabled:
                        type: boolean
                        nullable: true
                        description: Whether email quality checks are enabled before sending
                      safety:
                        type: object
                        description: Email safety and throttling settings
                        properties: &ref_577
                          firstStepDelay:
                            type: integer
                            nullable: true
                            minimum: 0
                            description: Delay in minutes before sending the first step of a sequence
                          prospectEmailsPerDayLimit:
                            type: integer
                            nullable: true
                            minimum: 1
                            description: Maximum number of emails sent to a single prospect per day
                          nonRepliesHandlingType:
                            type: integer
                            nullable: true
                            minimum: 0
                            maximum: 2
                            description: 'How to handle non-replies: 0 = do nothing, 1 = pause, 2 = mark as finished'
                          inboxNonRepliesHandlingType:
                            type: integer
                            nullable: true
                            minimum: 0
                            maximum: 1
                            description: 'How to handle inbox non-replies: 0 = do nothing, 1 = pause'
                      inbox:
                        type: object
                        description: Email inbox settings
                        properties: &ref_578
                          bccList:
                            type: string
                            nullable: true
                            description: Comma-separated list of BCC email addresses for outgoing emails
                          repliesBccList:
                            type: string
                            nullable: true
                            description: Comma-separated list of BCC email addresses for replies
                          forwardOnlyReplies:
                            type: boolean
                            nullable: true
                            description: Whether to forward only replies (not all incoming emails)
                      outOfOffice:
                        type: object
                        description: Out-of-office detection and handling settings
                        properties: &ref_579
                          isResumeOutOfOfficeContactsEnabled:
                            type: boolean
                            nullable: true
                            description: Whether to automatically resume contacts who return from out-of-office
                          isUseSmartReturnDateEnabled:
                            type: boolean
                            nullable: true
                            description: Whether to use smart return date detection from out-of-office messages
                          defaultDaysToWaitBeforeResumingOutOfOffice:
                            type: integer
                            nullable: true
                            minimum: 1
                            description: Default number of days to wait before resuming a contact after out-of-office
                          maximumDaysThresholdBeforeResumingOutOfOffice:
                            type: integer
                            nullable: true
                            minimum: 1
                            description: Maximum number of days to wait before resuming a contact after out-of-office
                      isOpenTrackingDisabled:
                        type: boolean
                        nullable: true
                        description: Whether open tracking is disabled for emails
                      isAutomaticEmailValidationEnabled:
                        type: boolean
                        nullable: true
                        description: Whether automatic email validation is enabled for new contacts
                      reassignSequenceProspectsWhenEmailAccountAdded:
                        type: boolean
                        nullable: true
                        description: Whether to reassign sequence prospects when a new email account is added
                  linkedIn:
                    type: object
                    description: LinkedIn-related settings
                    properties: &ref_581
                      reassignSequenceProspectsWhenLinkedInAccountAdded:
                        type: boolean
                        nullable: true
                        description: Whether to reassign sequence prospects when a new LinkedIn account is added
                  calls:
                    type: object
                    description: Call-related settings
                    properties: &ref_584
                      isTeamCallsEnabled:
                        type: boolean
                        nullable: true
                        description: Whether team cloud calls are enabled. Only the team owner can change this setting.
                      resolutions:
                        type: array
                        nullable: true
                        description: List of call resolution options
                        items:
                          type: object
                          description: A call resolution option
                          required: &ref_582
                            - name
                          properties: &ref_583
                            id:
                              type: integer
                              nullable: true
                              description: Resolution ID. Null when creating a new resolution.
                            name:
                              type: string
                              maxLength: 128
                              description: Display name of the resolution
                            defaultResolutionValue:
                              type: integer
                              nullable: true
                              minimum: 0
                              maximum: 2
                              description: 'Default resolution value: 0 = interested, 1 = not interested, 2 = not reached. Required when creating a new resolution (id is null).'
                            isDefault:
                              type: boolean
                              description: Whether this is the default resolution
                  contacts:
                    type: object
                    description: Contact-related settings
                    properties: &ref_591
                      handling:
                        type: object
                        description: Contact handling behavior settings
                        properties: &ref_585
                          pauseProspectOrganizationMode:
                            type: boolean
                            nullable: true
                            description: Whether to pause contacts from the same organization when one replies
                          pauseProspectOrganizationValue:
                            type: integer
                            nullable: true
                            minimum: 1
                            maximum: 2
                            description: 'Organization pause scope: 1 = same sequence, 2 = all sequences'
                          pauseProspectInAllCampaignMode:
                            type: boolean
                            nullable: true
                            description: Whether to pause a contact in all sequences when they reply in one
                          pauseProspectInAllCampaignValue:
                            type: integer
                            nullable: true
                            minimum: 1
                            maximum: 2
                            description: 'All-campaign pause scope: 1 = pause, 2 = mark as finished'
                          leaveProspectsInSequenceWhenMovingToAnother:
                            type: boolean
                            nullable: true
                            description: Whether to keep contacts in the original sequence when moving them to another
                          enrichProspectWhenLinkedInUrlIsMissing:
                            type: boolean
                            nullable: true
                            description: Whether to attempt LinkedIn URL enrichment when a contact's LinkedIn URL is missing
                      contactAccounts:
                        type: object
                        description: Contact account (company) settings
                        properties: &ref_586
                          autoPopulate:
                            type: boolean
                            nullable: true
                            description: Whether to automatically populate contact accounts from contact data
                          overwriteFields:
                            type: boolean
                            nullable: true
                            description: Whether to overwrite existing contact account fields with new data
                      contactStages:
                        type: array
                        nullable: true
                        description: Custom contact stage definitions. When updating, all 8 stages must be provided.
                        items:
                          type: object
                          description: A custom contact stage definition
                          required: &ref_587
                            - id
                            - name
                          properties: &ref_588
                            id:
                              type: integer
                              minimum: 1
                              maximum: 8
                              description: Stage ID (1–8)
                            name:
                              type: string
                              maxLength: 21
                              description: Display name of the stage
                            colorId:
                              type: integer
                              nullable: true
                              description: Color identifier for the stage
                            description:
                              type: string
                              nullable: true
                              description: Description of the stage
                      accountStages:
                        type: array
                        nullable: true
                        description: Custom account stage definitions. When updating, all 8 stages must be provided.
                        items:
                          type: object
                          description: A custom account stage definition
                          required: &ref_589
                            - id
                            - name
                          properties: &ref_590
                            id:
                              type: integer
                              minimum: 1
                              maximum: 8
                              description: Stage ID (1–8)
                            name:
                              type: string
                              maxLength: 64
                              description: Display name of the stage
                            colorId:
                              type: integer
                              nullable: true
                              description: Color identifier for the stage
                  beta:
                    type: object
                    description: Beta features settings
                    properties: &ref_592
                      isBetaFeaturesEnabled:
                        type: boolean
                        nullable: true
                        description: Whether beta features are enabled for this team. Only the team owner can change this setting.
        '400':
          description: Failed to get settings (e.g. team in an invalid state)
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Settings cannot be retrieved while the team is suspended.
                code: settings.invalidOperation
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view settings
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewSettings] are denied for userId 123.
                code: settings.forbidden
        '404':
          description: User or team settings not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: User settings not found.
                code: settings.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    patch:
      tags:
        - Settings
      summary: Update settings
      x-required-scope: settings:write
      description: |-
        <small>_Requires the `settings:write` scope (or a broader one that includes it)._</small>

        Performs a sparse update of settings. Only properties present in the request body are updated — omitted properties are left unchanged.

        Nested sections follow the same rule: include only the fields you want to change within each section.

        **Contact stages and account stages** are an exception — when the `contactStages` or `accountStages` array is present, all 8 stages must be provided with unique IDs (1–8).
      operationId: UpdateSettings
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Settings
              description: Team and user settings. All properties are nullable — on GET, null means the setting is not configured or not applicable. On PATCH, only properties present in the JSON body are updated.
              properties: *ref_238
      responses:
        '200':
          description: Settings updated successfully — returns the full settings object after applying changes
          content:
            application/json:
              schema:
                type: object
                title: Settings
                description: Team and user settings. All properties are nullable — on GET, null means the setting is not configured or not applicable. On PATCH, only properties present in the JSON body are updated.
                properties: *ref_238
        '400':
          description: |-
            Validation failure on the request body, or a business rule rejection
            (e.g. a sparse-update rule that requires all 8 contact stages when
            `contactStages` is present).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /contacts/contactStages
                        detail: Exactly 8 contact stages required, got 6.
                business_invalid_op:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Cannot update settings while the team is suspended.
                    code: settings.invalidOperation
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Non-owner user tried to change an owner-only field
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: 'Only the team owner can change: isTeamCallsEnabled, isBetaFeaturesEnabled.'
                code: settings.forbidden
        '404':
          description: User or team settings not found
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: User settings not found.
                code: settings.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/tasks:
    get:
      tags:
        - Tasks
      summary: List all tasks
      x-required-scope: tasks:read
      description: |-
        <small>_Requires the `tasks:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of all tasks visible to the current user.
        For filtered search, use POST /tasks/filter.
      operationId: GetTasks
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000).
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip.
          schema:
            type: integer
      responses:
        '200':
          description: Tasks retrieved successfully.
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: TaskListItemResponse
                      description: Summary task item returned in list and filter responses.
                      properties: &ref_240
                        id:
                          type: integer
                          readOnly: true
                          description: Task ID.
                        taskType:
                          type: string
                          description: |-
                            Task type.
                            Possible values: `toDo`, `call`, `meeting`, `linkedIn`, `manualEmail`, `sms`, `whatsApp`.
                          enum:
                            - toDo
                            - call
                            - meeting
                            - linkedIn
                            - manualEmail
                            - sms
                            - whatsApp
                        status:
                          type: string
                          readOnly: true
                          description: |-
                            Task status.
                            Possible values: `new`, `finished`, `cancelled`, `archived`, `sequenceDetached`.
                          enum:
                            - new
                            - finished
                            - cancelled
                            - archived
                            - sequenceDetached
                        linkedInTaskType:
                          type: string
                          nullable: true
                          description: 'LinkedIn action subtype. Possible values: `message`, `connect`, `inMail`, `viewProfile`.'
                          enum:
                            - message
                            - connect
                            - inMail
                            - viewProfile
                        assignedUserId:
                          type: integer
                          description: ID of the user this task is assigned to.
                        contact:
                          nullable: true
                          allOf:
                            - type: object
                              title: TaskContactSummary
                              description: Minimal contact information embedded in task list responses.
                              properties: &ref_593
                                id:
                                  type: integer
                                  description: Contact (prospect) ID.
                                fullName:
                                  type: string
                                  nullable: true
                                  description: Contact's full name.
                              required: &ref_594
                                - id
                          description: Contact summary. Null if no contact is associated.
                        startAt:
                          type: string
                          format: date-time
                          description: Task start time.
                        dueTo:
                          type: string
                          format: date-time
                          description: Task due time.
                        finishedAt:
                          type: string
                          format: date-time
                          nullable: true
                          readOnly: true
                          description: When the task was completed. Null for active tasks.
                        isScheduled:
                          type: boolean
                          description: Whether the task is scheduled for automatic execution.
                        sequenceId:
                          type: integer
                          nullable: true
                          description: Sequence ID if this task was created by a sequence.
                        sequenceStepId:
                          type: integer
                          nullable: true
                          description: Sequence step ID.
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page.
        '400':
          description: Invalid pagination parameters (e.g. `top` out of range, `skip` negative).
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000.
                code: task.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view tasks
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewTask] are denied for userId 123.
                code: task.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Tasks
      summary: Create a task
      x-required-scope: tasks:write
      description: |-
        <small>_Requires the `tasks:write` scope (or a broader one that includes it)._</small>

        Creates a new task. The template body may contain handlebars variables
        (e.g. `{{firstName}}`) which are resolved when the task is read or executed.
      operationId: CreateTask
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: TaskCreateRequest
              description: Request body for creating a new task.
              properties: &ref_595
                taskType:
                  type: string
                  description: |-
                    Task type. Must be a valid enum value.
                    Possible values: `toDo`, `call`, `meeting`, `linkedIn`, `manualEmail`, `sms`, `whatsApp`.
                  enum:
                    - toDo
                    - call
                    - meeting
                    - linkedIn
                    - manualEmail
                    - sms
                    - whatsApp
                startAt:
                  type: string
                  format: date-time
                  description: Task start time. Must be on or after 2015-01-01.
                dueTo:
                  type: string
                  format: date-time
                  description: Task due time. Must be after startAt.
                contactId:
                  type: integer
                  nullable: true
                  description: Contact (prospect) ID to associate with the task. Required for template variable rendering.
                linkedInTaskType:
                  type: string
                  nullable: true
                  description: |-
                    LinkedIn action subtype. Only applicable for LinkedIn tasks (taskType=linkedIn). Must be a valid enum value when provided.
                    Possible values: `message`, `connect`, `inMail`, `viewProfile`.
                  enum:
                    - message
                    - connect
                    - inMail
                    - viewProfile
                template:
                  description: Task content template. Body is required.
                  type: object
                  title: TaskTemplate
                  properties: &ref_239
                    body:
                      type: string
                      description: Template body text. May contain `{{variable}}` placeholders for sequence tasks.
                    subject:
                      type: string
                      nullable: true
                      description: Email subject or LinkedIn message subject. Null for non-email/LinkedIn task types.
                    attachmentIdList:
                      type: array
                      nullable: true
                      items:
                        type: integer
                      description: Read-only. Attachment IDs for ManualEmail tasks (set by sequence system, not user-editable via API).
              required: &ref_596
                - taskType
                - startAt
                - dueTo
                - template
      responses:
        '201':
          description: Task created successfully.
          content:
            application/json:
              schema:
                type: object
                title: Task
                description: Full task detail returned by GET by ID, Create, and Update endpoints.
                properties: &ref_241
                  id:
                    type: integer
                    readOnly: true
                    description: Task ID.
                  contactId:
                    type: integer
                    nullable: true
                    description: Associated contact (prospect) ID.
                  taskType:
                    type: string
                    description: |-
                      Task type.
                      Possible values: `toDo`, `call`, `meeting`, `linkedIn`, `manualEmail`, `sms`, `whatsApp`.
                    enum:
                      - toDo
                      - call
                      - meeting
                      - linkedIn
                      - manualEmail
                      - sms
                      - whatsApp
                  status:
                    type: string
                    readOnly: true
                    description: |-
                      Task status.
                      Possible values: `new`, `finished`, `cancelled`, `archived`, `sequenceDetached`.
                    enum:
                      - new
                      - finished
                      - cancelled
                      - archived
                      - sequenceDetached
                  linkedInTaskType:
                    type: string
                    nullable: true
                    description: |-
                      LinkedIn action subtype. Only present for LinkedIn tasks.
                      Possible values: `message`, `connect`, `inMail`, `viewProfile`.
                    enum:
                      - message
                      - connect
                      - inMail
                      - viewProfile
                  sequenceId:
                    type: integer
                    nullable: true
                    description: Sequence ID if this task was created by a sequence.
                  sequenceStepId:
                    type: integer
                    nullable: true
                    description: Sequence step ID. Available when the ExtendedFilterInTasks feature is enabled.
                  sequenceStepDisplayName:
                    type: string
                    nullable: true
                    description: Human-readable sequence step name (e.g. "Step 2 - Email").
                  assignedUserId:
                    type: integer
                    description: ID of the user this task is assigned to.
                  creationSource:
                    type: string
                    readOnly: true
                    description: |-
                      How the task was created.
                      Possible values: `user`, `sequence`, `meeting`.
                    enum:
                      - user
                      - sequence
                      - meeting
                  createdAt:
                    type: string
                    format: date-time
                    readOnly: true
                    description: When the task was created.
                  startAt:
                    type: string
                    format: date-time
                    description: Task start time. When `isScheduled` is true, this is the scheduled execution time.
                  dueTo:
                    type: string
                    format: date-time
                    description: Task due time.
                  finishedAt:
                    type: string
                    format: date-time
                    nullable: true
                    readOnly: true
                    description: When the task was completed. Null for active tasks.
                  isFailed:
                    type: boolean
                    readOnly: true
                    description: Whether the task execution failed.
                  isScheduled:
                    type: boolean
                    description: Whether the task is scheduled for automatic execution.
                  template:
                    description: |-
                      Raw task template. For active tasks, may contain `{{variable}}` placeholders.
                      For finished tasks, contains the final content (raw version is no longer available).
                    type: object
                    title: TaskTemplate
                    properties: *ref_239
                  content:
                    nullable: true
                    allOf:
                      - type: object
                        title: TaskContent
                        description: |-
                          Rendered task content with all variables resolved. Returned only when `includeContent=true` is requested on GET by ID.
                          Also used as input for the execute endpoint — the final text to send.
                        properties: &ref_242
                          body:
                            type: string
                            description: Rendered body text with all variables resolved.
                          subject:
                            type: string
                            nullable: true
                            description: Rendered subject for ManualEmail/LinkedIn tasks.
                    description: |-
                      Rendered content with variables resolved. Only populated when `includeContent=true` query parameter is set.
                      Null by default.
                  deliveryInfo:
                    nullable: true
                    allOf:
                      - type: object
                        title: TaskDeliveryInfo
                        description: |-
                          Delivery target information. Only one field is populated depending on task type.
                          For active tasks, sourced from the prospect record. For finished ManualEmail tasks, sourced from the sent email.
                        properties: &ref_597
                          email:
                            type: string
                            nullable: true
                            description: Recipient email address (ManualEmail tasks).
                          phoneNumber:
                            type: string
                            nullable: true
                            description: Recipient phone number (Call and SMS tasks).
                          linkedInUrl:
                            type: string
                            nullable: true
                            description: Prospect's LinkedIn profile URL (LinkedIn tasks).
                    description: |-
                      Delivery target information. Populated for ManualEmail (email), Call/SMS (phone), and LinkedIn (URL) tasks.
                      Null for ToDo, Meeting, and WhatsApp tasks.
        '400':
          description: |-
            Validation failure on the request body (missing required fields, invalid enum value
            for `taskType` or `linkedInTaskType`, or unparseable JSON).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /taskType
                    detail: '''taskType'' is required.'
                  - pointer: /contactId
                    detail: '''contactId'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to create tasks
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageTask] are denied for userId 123.
                code: task.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/tasks/filter:
    post:
      tags:
        - Tasks
      summary: Filter tasks
      x-required-scope: tasks:read
      description: |-
        <small>_Requires the `tasks:read` scope (or a broader one that includes it)._</small>

        Returns a filtered, paginated list of tasks.
        Pagination params (`top`, `skip`) are in query string; filter criteria in request body.
        All filter fields are optional — an empty body `{}` returns all tasks.
        The request body must be a valid JSON object; a missing or unparseable body returns 400.
      operationId: FilterTasks
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (default 25, max 1000).
          schema:
            type: integer
        - name: skip
          in: query
          required: false
          description: Number of items to skip.
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: TaskFilterRequest
              description: |-
                Request body for the POST /tasks/filter endpoint.
                All fields are optional — an empty object `{}` returns all tasks visible to the caller.
              properties: &ref_598
                from:
                  type: string
                  format: date-time
                  nullable: true
                  description: Filter tasks with StartAt >= this value. Defaults to 2000-01-01 if omitted.
                to:
                  type: string
                  format: date-time
                  nullable: true
                  description: Filter tasks with StartAt <= this value. Must be after `from` when both are provided. Defaults to now + 1 year if omitted.
                taskType:
                  type: string
                  nullable: true
                  description: |-
                    Filter by task type. Must be a valid enum value.
                    Possible values: `toDo`, `call`, `meeting`, `linkedIn`, `manualEmail`, `sms`, `whatsApp`.
                  enum:
                    - toDo
                    - call
                    - meeting
                    - linkedIn
                    - manualEmail
                    - sms
                    - whatsApp
                status:
                  type: string
                  nullable: true
                  description: |-
                    Filter by task status. Must be a valid enum value.
                    Possible values: `new`, `finished`, `cancelled`, `archived`, `sequenceDetached`.
                  enum:
                    - new
                    - finished
                    - cancelled
                    - archived
                    - sequenceDetached
                sequenceIds:
                  type: array
                  nullable: true
                  items:
                    type: integer
                  description: Filter tasks belonging to these sequences.
                sequenceStepIds:
                  type: array
                  nullable: true
                  items:
                    type: integer
                  description: Filter tasks belonging to these sequence steps.
                timeZoneIds:
                  type: array
                  nullable: true
                  items:
                    type: string
                  description: Filter by prospect timezone (e.g. "America/New_York").
                contactId:
                  type: integer
                  nullable: true
                  description: Filter tasks for a specific contact.
                assignedUserId:
                  type: integer
                  nullable: true
                  description: |-
                    Filter tasks assigned to a specific user.
                    Only returns results if the caller has permission to view that user's tasks.
                overdue:
                  type: boolean
                  nullable: true
                  description: Filter by overdue status. `true` = overdue only, `false` = not overdue only, `null` = all.
      responses:
        '200':
          description: Filtered tasks retrieved successfully.
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: TaskListItemResponse
                      description: Summary task item returned in list and filter responses.
                      properties: *ref_240
                  hasMore:
                    type: boolean
        '400':
          description: |-
            Validation failure on the request body, query parameters, or pagination
            (e.g. missing/unparseable body, invalid `taskType`/`status` enum values,
            `to` before `from`, `top` out of range, `skip` negative).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: top
                    detail: '''top'' must be between 1 and 1000.'
                  - pointer: /to
                    detail: '''to'' must be greater than or equal to ''from''.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view tasks
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewTask] are denied for userId 123.
                code: task.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/tasks/{id}:
    get:
      tags:
        - Tasks
      summary: Get a task
      x-required-scope: tasks:read
      description: |-
        <small>_Requires the `tasks:read` scope (or a broader one that includes it)._</small>

        Returns full task details by ID.
        Use `includeContent=true` to also get the rendered content (variables resolved).
      operationId: GetTaskById
      parameters:
        - name: id
          in: path
          required: true
          description: Task ID.
          schema:
            type: integer
        - name: includeContent
          in: query
          required: false
          description: |-
            When true, the response includes a `content` field with rendered template
            (handlebars variables resolved with contact data).
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: Task details retrieved successfully.
          content:
            application/json:
              schema:
                type: object
                title: Task
                description: Full task detail returned by GET by ID, Create, and Update endpoints.
                properties: *ref_241
        '400':
          description: Route parameter validation failed, or a domain rule rejected the request.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_unknown:
                  summary: Domain rule rejection (other 400)
                  value:
                    title: Bad Request
                    status: 400
                    detail: Request could not be processed.
                    code: task.unknown
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to view this task
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ViewTask] are denied for userId 123.
                code: task.forbidden
        '404':
          description: Task does not exist, or the caller does not have permission to view it.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Task with ID 42 not found or insufficient permissions.
                code: task.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Tasks
      summary: Update a task
      x-required-scope: tasks:write
      description: |-
        <small>_Requires the `tasks:write` scope (or a broader one that includes it)._</small>

        Full replacement update of a task. Only tasks with status `New` (0) can be updated.
        Sequence task type and contact cannot be changed.
      operationId: UpdateTask
      parameters:
        - name: id
          in: path
          required: true
          description: Task ID.
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: TaskUpdateRequest
              description: Request body for updating a task. Full replacement (PUT), not partial update.
              properties: &ref_599
                taskType:
                  type: string
                  description: 'Task type. Possible values: `toDo`, `call`, `meeting`, `linkedIn`, `manualEmail`, `sms`, `whatsApp`.'
                  enum:
                    - toDo
                    - call
                    - meeting
                    - linkedIn
                    - manualEmail
                    - sms
                    - whatsApp
                startAt:
                  type: string
                  format: date-time
                  description: Task start time. Must be on or after 2015-01-01.
                dueTo:
                  type: string
                  format: date-time
                  description: Task due time. Must be after startAt.
                contactId:
                  type: integer
                  nullable: true
                  description: Contact (prospect) ID. Cannot be changed for sequence-created tasks.
                linkedInTaskType:
                  type: string
                  nullable: true
                  description: |-
                    LinkedIn action subtype. Only for LinkedIn tasks.
                    Possible values: `message`, `connect`, `inMail`, `viewProfile`.
                  enum:
                    - message
                    - connect
                    - inMail
                    - viewProfile
                template:
                  description: Updated task content template. Body is required.
                  type: object
                  title: TaskTemplate
                  properties: *ref_239
              required: &ref_600
                - taskType
                - startAt
                - dueTo
                - template
      responses:
        '200':
          description: Task updated successfully.
          content:
            application/json:
              schema:
                type: object
                title: Task
                description: Full task detail returned by GET by ID, Create, and Update endpoints.
                properties: *ref_241
        '400':
          description: |-
            Validation failure on the request body or route parameter (missing/unparseable body,
            invalid field values, `id` not a positive integer). Domain rule rejections
            (`canOnlyEditNewTasks`, `cannotChangeSequenceTaskType`, `cannotChangeSequenceTaskContact`,
            `invalidDates`, `renderError`) also surface here at 400 via the fallback `task.unknown` code.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /dueTo
                        detail: '''dueTo'' must be after ''startAt''.'
                business_unknown:
                  summary: Domain rule rejection (e.g. task not in `New` status)
                  value:
                    title: Bad Request
                    status: 400
                    detail: Only tasks with 'New' status can be edited.
                    code: task.unknown
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to update this task
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageTask] are denied for userId 123.
                code: task.forbidden
        '404':
          description: Task does not exist, or the caller does not have permission to edit it.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Task with ID 42 not found or insufficient permissions.
                code: task.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Tasks
      summary: Delete a task
      x-required-scope: tasks:write
      description: |-
        <small>_Requires the `tasks:write` scope (or a broader one that includes it)._</small>

        Deletes a single task by ID. Returns 204 on success.
      operationId: DeleteTask
      parameters:
        - name: id
          in: path
          required: true
          description: Task ID.
          schema:
            type: integer
      responses:
        '204':
          description: Task deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: |-
            Route parameter validation failed, or the task is in a state that prevents
            deletion. The conflict variant (`cannotDelete`) surfaces here at 400 via the
            fallback `task.unknown` code rather than 409.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: '''id'' must be a positive integer.'
                business_unknown:
                  summary: Domain rule rejection
                  value:
                    title: Bad Request
                    status: 400
                    detail: Task cannot be deleted in its current state.
                    code: task.unknown
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete this task
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageTask] are denied for userId 123.
                code: task.forbidden
        '404':
          description: Task does not exist, or the caller does not have permission to delete it.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Task with ID 42 not found or insufficient permissions.
                code: task.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/tasks/{id}/assigned-user:
    put:
      tags:
        - Tasks
      summary: Reassign a task
      x-required-scope: tasks:write
      description: |-
        <small>_Requires the `tasks:write` scope (or a broader one that includes it)._</small>

        Changes the assigned user for a single task. The target user must be a member of the caller's team.
      operationId: AssignTask
      parameters:
        - name: id
          in: path
          required: true
          description: Task ID.
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                userId:
                  type: integer
                  description: User ID to assign the task to. Must be a member of the caller's team.
              required:
                - userId
      responses:
        '200':
          description: Task reassigned successfully. Returns the updated task.
          content:
            application/json:
              schema:
                type: object
                title: Task
                description: Full task detail returned by GET by ID, Create, and Update endpoints.
                properties: *ref_241
        '400':
          description: |-
            Validation failure on the request body or route parameter
            (missing/unparseable body, `userId` not a positive integer, `id` not a positive integer).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /userId
                    detail: '''userId'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Target user is not a member of the caller's team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: User 7 is not a member of the caller's team.
                code: task.forbidden
        '404':
          description: Task does not exist, or the caller does not have permission to assign it.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Task with ID 42 not found or insufficient permissions.
                code: task.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/tasks/{id}/complete:
    post:
      tags:
        - Tasks
      summary: Complete a task
      x-required-scope: tasks:operate
      description: |-
        <small>_Requires the `tasks:operate` scope (or a broader one that includes it)._</small>

        Marks a task as completed without execution (no email sent, no SMS sent).
        For tasks that require execution (sending), use the execute endpoint instead.
      operationId: CompleteTask
      parameters:
        - name: id
          in: path
          required: true
          description: Task ID.
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: TaskCompleteRequest
              description: |-
                Request body for completing a task without execution.
                All fields are optional — an empty object `{}` is valid.
              properties: &ref_601
                callResolution:
                  type: integer
                  nullable: true
                  description: |-
                    Call resolution outcome. Only meaningful for Call tasks. Affects sequence branching.
                    `0` = Positive, `1` = ToCall, `2` = Negative.
                finishProspectInSequence:
                  type: boolean
                  default: false
                  description: |-
                    If true, also removes the prospect from the sequence.
                    The finish reason is derived automatically from the task type (Call → Called, others → Manual).
      responses:
        '200':
          description: Task completed successfully. Returns the updated task.
          content:
            application/json:
              schema:
                type: object
                title: Task
                description: Full task detail returned by GET by ID, Create, and Update endpoints.
                properties: *ref_241
        '400':
          description: |-
            Validation failure on the request body or route parameter
            (missing/unparseable body, invalid body fields, `id` not a positive integer).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: '''id'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to complete this task
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageTask] are denied for userId 123.
                code: task.forbidden
        '404':
          description: Task does not exist, or the caller does not have permission to complete it.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Task with ID 42 not found or insufficient permissions.
                code: task.notFound
        '409':
          description: Task is already finished or in an invalid state for completion.
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Task is already finished or in an invalid state for completion.
                code: task.cannotComplete
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/tasks/{id}/execute:
    post:
      tags:
        - Tasks
      summary: Execute and complete a task
      x-required-scope: tasks:operate
      description: |-
        <small>_Requires the `tasks:operate` scope (or a broader one that includes it)._</small>

        Executes the task action (sends email or SMS) and completes it.
        Only ManualEmail (7) and Sms (8) task types support execution.
        Other task types return 400 — use the complete endpoint for those.
      operationId: ExecuteTask
      parameters:
        - name: id
          in: path
          required: true
          description: Task ID.
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: TaskExecuteRequest
              description: |-
                Request body for executing a task (send email/SMS) and completing it.
                Only ManualEmail (7) and Sms (8) task types support execution.
                All fields are optional — an empty object `{}` uses server-rendered template and default email account.
              properties: &ref_602
                content:
                  nullable: true
                  allOf:
                    - type: object
                      title: TaskContent
                      description: |-
                        Rendered task content with all variables resolved. Returned only when `includeContent=true` is requested on GET by ID.
                        Also used as input for the execute endpoint — the final text to send.
                      properties: *ref_242
                  description: Final rendered content to send. If omitted, the server renders the stored template automatically.
                emailAccountId:
                  type: integer
                  format: int64
                  nullable: true
                  description: |-
                    Email account to send from. Only for non-sequence ManualEmail tasks.
                    If omitted, the user's default email account is used.
                    Ignored for sequence tasks (account resolved from sequence configuration).
      responses:
        '200':
          description: Task executed and completed successfully. Returns the updated task.
          content:
            application/json:
              schema:
                type: object
                title: Task
                description: Full task detail returned by GET by ID, Create, and Update endpoints.
                properties: *ref_241
        '400':
          description: |-
            Validation failure on the request body or route parameter
            (missing/unparseable body, task type does not support execution,
            `id` not a positive integer).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: ''
                    detail: Task type does not support execution.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to execute this task
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageTask] are denied for userId 123.
                code: task.forbidden
        '404':
          description: Task does not exist, or the caller does not have permission to execute it.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Task with ID 42 not found or insufficient permissions.
                code: task.notFound
        '409':
          description: |-
            Task cannot be executed because it is already finished, in an invalid state,
            or its template failed to render before execution.
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              examples:
                cannot_complete:
                  summary: Task already finished or in invalid state
                  value:
                    title: Conflict
                    status: 409
                    detail: Task is already finished or in an invalid state.
                    code: task.cannotComplete
                render_error:
                  summary: Template rendering failed
                  value:
                    title: Conflict
                    status: 409
                    detail: Failed to render the task template before execution.
                    code: task.renderError
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/tasks/bulk-delete:
    post:
      tags:
        - Tasks
      summary: Bulk delete tasks
      x-required-scope: tasks:write
      description: |-
        <small>_Requires the `tasks:write` scope (or a broader one that includes it)._</small>

        Deletes multiple tasks by ID. Non-atomic — some may succeed while others fail.
        Items not in the response dictionary succeeded.
      operationId: BulkDeleteTasks
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: TaskBulkDeleteRequest
              description: Request body for bulk deleting tasks.
              properties: &ref_603
                ids:
                  type: array
                  items:
                    type: integer
                  minItems: 1
                  maxItems: 100
                  description: Task IDs to delete (1-100).
              required: &ref_604
                - ids
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by task ID. Empty object `{}` means all succeeded.

            Possible per-item error codes:

            | code | Meaning |
            |------|---------|
            | `notFound` | Task does not exist or caller lacks permission to delete it |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: |-
            Validation failure on the request body (missing/unparseable body,
            `ids` empty or > 100 items, any ID not a positive integer).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /ids
                    detail: '''ids'' must contain between 1 and 100 items.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to delete tasks
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageTask] are denied for userId 123.
                code: task.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/tasks/batch/assign:
    post:
      tags:
        - Tasks
      summary: Batch reassign tasks
      x-required-scope: tasks:write
      description: |-
        <small>_Requires the `tasks:write` scope (or a broader one that includes it)._</small>

        Reassigns multiple tasks to a user. The target user must be a member of the caller's team.
        Non-atomic — some may succeed while others fail.
        Items not in the response dictionary succeeded.
      operationId: BatchAssignTasks
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: TaskBatchAssignRequest
              description: Request body for batch reassigning tasks.
              properties: &ref_605
                ids:
                  type: array
                  items:
                    type: integer
                  minItems: 1
                  maxItems: 100
                  description: Task IDs to reassign (1-100).
                userId:
                  type: integer
                  description: User ID to assign the tasks to. Must be a member of the caller's team.
              required: &ref_606
                - ids
                - userId
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by task ID. Empty object `{}` means all succeeded.

            Possible per-item error codes:

            | code | Meaning |
            |------|---------|
            | `notFound` | Task does not exist or caller lacks permission to assign it |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: |-
            Validation failure on the request body (missing/unparseable body,
            `ids` empty or > 100 items, any ID not a positive integer,
            `userId` not a positive integer).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /userId
                    detail: '''userId'' must be a positive integer.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Target user is not a member of the caller's team.
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: User 7 is not a member of the caller's team.
                code: task.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/tasks/batch/complete:
    post:
      tags:
        - Tasks
      summary: Batch complete tasks
      x-required-scope: tasks:operate
      description: |-
        <small>_Requires the `tasks:operate` scope (or a broader one that includes it)._</small>

        Completes multiple tasks without execution. Non-atomic — some may succeed while others fail.
        Items not in the response dictionary succeeded.
      operationId: BatchCompleteTasks
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: TaskBatchCompleteRequest
              description: Request body for batch completing tasks (without execution).
              properties: &ref_607
                ids:
                  type: array
                  items:
                    type: integer
                  minItems: 1
                  maxItems: 100
                  description: Task IDs to complete (1-100).
              required: &ref_608
                - ids
      responses:
        '200':
          description: |-
            Dictionary of failed items keyed by task ID. Empty object `{}` means all succeeded.

            Possible per-item error codes:

            | code | Meaning |
            |------|---------|
            | `notFound` | Task does not exist or caller lacks permission to complete it |
            | `cannotComplete` | Task is already finished or in an invalid state |
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  title: NotProcessedItemResult
                  description: |-
                    Per-item error for non-atomic bulk operations.
                    Only failed items are returned in the response dictionary.
                    Items not present in the dictionary succeeded.
                  properties: *ref_68
        '400':
          description: |-
            Validation failure on the request body (missing/unparseable body,
            `ids` empty or > 100 items, any ID not a positive integer).
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request body contains validation errors.
                errors:
                  - pointer: /ids
                    detail: '''ids'' must contain between 1 and 100 items.'
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: User lacks required feature scope to complete tasks
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Feature scopes [ManageTask] are denied for userId 123.
                code: task.forbidden
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/whoami:
    get:
      tags:
        - User Account
      summary: Get current user
      x-required-scope: none
      description: |-
        <small>_No scope required — any valid API key can call this endpoint._</small>

        Returns the authenticated user's ID, username, and team ID. Useful for verifying credentials and identifying the current user and their team.
      operationId: Whoami
      responses:
        '200':
          description: Current user info retrieved successfully
          content:
            application/json:
              schema:
                type: object
                required:
                  - userId
                  - username
                  - teamId
                properties:
                  userId:
                    type: integer
                    description: The authenticated user's ID
                  username:
                    type: string
                    description: The authenticated user's username
                  teamId:
                    type: integer
                    description: The ID of the team the authenticated user belongs to
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Authenticated user no longer exists
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: User not found.
                code: whoami.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/whoami/team-users:
    get:
      tags:
        - User Account
      summary: List team users
      x-required-scope: none
      description: |-
        <small>_No scope required — any valid API key can call this endpoint._</small>

        Returns all users in the authenticated user's team (workspace), including each user's team ID, team name, user ID, display name, and email address.
      operationId: WhoamiTeamUsers
      responses:
        '200':
          description: Team users retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required:
                    - teamId
                    - teamName
                    - userId
                    - userName
                    - userEmail
                  properties:
                    teamId:
                      type: integer
                      description: The team (workspace) ID
                    teamName:
                      type: string
                      description: The team (workspace) name
                    userId:
                      type: integer
                      description: The user's ID
                    userName:
                      type: string
                      description: The user's display name
                    userEmail:
                      type: string
                      description: The user's email address
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: Caller lacks permission or their account is not part of an organization
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              examples:
                forbidden:
                  summary: Access denied
                  value:
                    title: Forbidden
                    status: 403
                    detail: Access denied.
                    code: workspace.forbidden
                organizationRequired:
                  summary: Organization membership required
                  value:
                    title: Forbidden
                    status: 403
                    detail: Organization membership is required.
                    code: workspace.organizationRequired
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/webhooks:
    get:
      tags:
        - Webhooks
      summary: List webhook subscriptions
      x-required-scope: webhooks:read
      description: |-
        <small>_Requires the `webhooks:read` scope (or a broader one that includes it)._</small>

        Returns a paginated list of the authenticated user's webhook subscriptions, ordered
        by descending id. Use `top`/`skip` to page through results and inspect `hasMore` to
        detect additional pages.
      operationId: ListWebhooks
      parameters:
        - name: top
          in: query
          required: false
          description: Maximum number of items to return (defaults to the API page size).
          schema:
            type: integer
            minimum: 1
        - name: skip
          in: query
          required: false
          description: Number of items to skip.
          schema:
            type: integer
            minimum: 0
      responses:
        '200':
          description: Paginated list of webhook subscriptions.
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: WebHook
                      description: |-
                        A webhook subscription. The subscription fires a single event type to a configured URL
                        when activity matching the subscription's `scope` occurs.
                      properties: &ref_246
                        id:
                          type: integer
                          readOnly: true
                          description: Unique identifier for the webhook subscription.
                        eventType:
                          type: string
                          description: |-
                            Event type this subscription fires on. One of the values returned by
                            `GET /v3/webhooks/events`.
                          example: email_replied
                        url:
                          type: string
                          format: uri
                          description: Absolute `http`/`https` URL that receives the webhook payload.
                          example: https://example.com/hooks/reply
                        scope:
                          type: string
                          title: WebHookScope
                          description: |-
                            Scope that determines which users' activity triggers the webhook.

                            - `personal` — fires only for activity of the subscription owner.
                            - `team` — fires for activity of any member of the owner's team. Creation requires the current user to be the team owner for private teams; anyone can create for public teams.
                            - `organization` — reserved for future use. The API currently rejects creation/update with this value (`errorCode: 5`).
                          enum: &ref_243
                            - personal
                            - team
                            - organization
                          example: personal
                        enabled:
                          type: boolean
                          description: |-
                            If `false`, the subscription does not fire. Toggle via the dedicated
                            `POST /v3/webhooks/{id}/enable` and `POST /v3/webhooks/{id}/disable`
                            endpoints — the state cannot be changed through `PUT`.
                        createdAt:
                          type: string
                          format: date-time
                          readOnly: true
                          description: ISO-8601 timestamp (UTC) when the subscription was created.
                        payloadConfig:
                          type: object
                          title: WebHookPayloadConfig
                          description: Optional flags that enrich the delivered webhook payload with extra fields from the originating email/contact.
                          properties: &ref_244
                            includeEmailUrl:
                              type: boolean
                              description: Include a link to the tracked email in the delivered payload.
                            includeEmailText:
                              type: boolean
                              description: Include the plain-text body of the email in the delivered payload.
                            includeProspectCustomFields:
                              type: boolean
                              description: Include the contact's custom-field values in the delivered payload.
                          example: &ref_245
                            includeEmailUrl: true
                            includeEmailText: false
                            includeProspectCustomFields: true
                      example: &ref_247
                        id: 1823
                        eventType: email_replied
                        url: https://example.com/hooks/reply
                        scope: personal
                        enabled: true
                        createdAt: '2026-04-17T12:00:00+00:00'
                        payloadConfig:
                          includeEmailUrl: true
                          includeEmailText: false
                          includeProspectCustomFields: true
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page.
        '400':
          description: Invalid pagination parameters.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              example:
                title: Bad Request
                status: 400
                detail: Parameter 'top' must be between 1 and 1000.
                code: webHook.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    post:
      tags:
        - Webhooks
      summary: Create a webhook subscription
      x-required-scope: webhooks:write
      description: |-
        <small>_Requires the `webhooks:write` scope (or a broader one that includes it)._</small>

        Creates a new webhook subscription for the authenticated user.

        `scope` defaults to `personal` when omitted. `team`-scope subscriptions are accepted
        only when policy allows: any member may create them for public teams or organization
        mode; only the team owner may create them for private teams.

        Attempting to create an `organization`-scope subscription is rejected with
        `code: webHook.organizationScopeNotImplemented` — the value is reserved for future use.
      operationId: CreateWebhook
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: WebHookCreationRequest
              description: Request body for creating a webhook subscription.
              properties: &ref_609
                eventType:
                  type: string
                  description: |-
                    Event type this subscription should fire on. Must be one of the values returned by
                    `GET /v3/webhooks/events`.
                  example: email_replied
                url:
                  type: string
                  format: uri
                  maxLength: 1024
                  description: Absolute `http`/`https` URL that will receive the webhook payload.
                  example: https://example.com/hooks/reply
                scope:
                  type: string
                  title: WebHookScope
                  description: |-
                    Scope that determines which users' activity triggers the webhook.

                    - `personal` — fires only for activity of the subscription owner.
                    - `team` — fires for activity of any member of the owner's team. Creation requires the current user to be the team owner for private teams; anyone can create for public teams.
                    - `organization` — reserved for future use. The API currently rejects creation/update with this value (`errorCode: 5`).
                  enum: *ref_243
                  example: personal
                enabled:
                  type: boolean
                  description: |-
                    Create the subscription in an enabled (firing) state. Defaults to `true`. After
                    creation, toggle the state via the dedicated
                    `POST /v3/webhooks/{id}/enable` and `POST /v3/webhooks/{id}/disable` endpoints.
                  default: true
                payloadConfig:
                  type: object
                  title: WebHookPayloadConfig
                  description: Optional flags that enrich the delivered webhook payload with extra fields from the originating email/contact.
                  properties: *ref_244
                  example: *ref_245
              required: &ref_610
                - eventType
                - url
              example: &ref_611
                eventType: email_replied
                url: https://example.com/hooks/reply
                scope: personal
                enabled: true
                payloadConfig:
                  includeEmailUrl: true
                  includeEmailText: false
                  includeProspectCustomFields: true
      responses:
        '201':
          description: Webhook subscription created successfully.
          content:
            application/json:
              schema:
                type: object
                title: WebHook
                description: |-
                  A webhook subscription. The subscription fires a single event type to a configured URL
                  when activity matching the subscription's `scope` occurs.
                properties: *ref_246
                example: *ref_247
        '400':
          description: |-
            Request-body validation failed, or a domain rule rejected the create (unknown
            event, invalid URL, invalid scope value, or organization scope reserved for
            future use).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /url
                        detail: '''url'' must not be empty.'
                invalid_event:
                  summary: Unknown event type
                  value:
                    title: Bad Request
                    status: 400
                    detail: Unknown webhook event 'email_clicked'.
                    code: webHook.invalidEvent
                invalid_url:
                  summary: Malformed URL
                  value:
                    title: Bad Request
                    status: 400
                    detail: Url must be a valid absolute http(s) URL.
                    code: webHook.invalidUrl
                invalid_scope:
                  summary: Invalid scope value
                  value:
                    title: Bad Request
                    status: 400
                    detail: Unknown webhook scope value.
                    code: webHook.invalidScope
                organization_scope_not_implemented:
                  summary: Organization scope reserved
                  value:
                    title: Bad Request
                    status: 400
                    detail: Organization-scope webhooks are not yet implemented.
                    code: webHook.organizationScopeNotImplemented
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: |-
            The caller is not allowed to create a `team`-scope subscription for their team
            (private team, caller is not the owner).
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Team-scope webhook subscriptions are not allowed for your current team configuration.
                code: webHook.teamScopeForbidden
        '409':
          description: The active webhook-subscription limit for the user has been reached.
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Limit of active webhook subscriptions reached (50).
                code: webHook.limitReached
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/webhooks/events:
    get:
      tags:
        - Webhooks
      summary: List supported event types
      x-required-scope: webhooks:read
      description: |-
        <small>_Requires the `webhooks:read` scope (or a broader one that includes it)._</small>

        Returns the catalog of event type names a subscription may listen to. Use any of
        these values in the `eventType` field when creating or updating a subscription.
      operationId: GetWebhookEvents
      responses:
        '200':
          description: Supported event types.
          content:
            application/json:
              schema:
                type: object
                title: WebHookEvents
                description: Catalog of event types that a webhook subscription can subscribe to.
                properties: &ref_612
                  events:
                    type: array
                    readOnly: true
                    items:
                      type: string
                    description: All supported event type names. Use any of these as the `eventType` field when creating or updating a subscription.
                example: &ref_613
                  events:
                    - email_replied
                    - reply_categorized
                    - email_sent
                    - contact_finished
                    - email_opened
                    - contact_opted_out
                    - contact_called
                    - email_link_clicked
                    - email_account_connection_lost
                    - email_bounced
                    - linkedin_connection_request_sent
                    - linkedin_message_sent
                    - linkedin_connection_request_accepted
                    - linkedin_message_replied
                    - linkedin_reply_categorized
                    - email_account_error
                    - email_auto_reply
                    - autopilot_stopped
                    - linkedin_account_alerts
                    - contact_replied
                    - linkedin_comment_posted
                    - linkedin_comment_skipped
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/webhooks/{id}:
    get:
      tags:
        - Webhooks
      summary: Get a webhook subscription
      x-required-scope: webhooks:read
      description: |-
        <small>_Requires the `webhooks:read` scope (or a broader one that includes it)._</small>

        Returns a single webhook subscription owned by the authenticated user.
      operationId: GetWebhookById
      parameters:
        - name: id
          in: path
          required: true
          description: Webhook subscription ID.
          schema:
            type: integer
      responses:
        '200':
          description: Webhook subscription details.
          content:
            application/json:
              schema:
                type: object
                title: WebHook
                description: |-
                  A webhook subscription. The subscription fires a single event type to a configured URL
                  when activity matching the subscription's `scope` occurs.
                properties: *ref_246
                example: *ref_247
        '400':
          description: Invalid `id` parameter.
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Webhook subscription not found or not owned by the caller.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Webhook subscription 1823 not found.
                code: webHook.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    put:
      tags:
        - Webhooks
      summary: Update a webhook subscription
      x-required-scope: webhooks:write
      description: |-
        <small>_Requires the `webhooks:write` scope (or a broader one that includes it)._</small>

        Full replacement of the mutable fields of an existing subscription. `organization`
        scope is rejected with `code: webHook.organizationScopeNotImplemented`.
      operationId: UpdateWebhook
      parameters:
        - name: id
          in: path
          required: true
          description: Webhook subscription ID.
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: WebHookUpdateRequest
              description: |-
                Request body for updating a webhook subscription. `PUT` performs a full replacement
                of the mutable fields — every required field listed below must be provided on every
                call. To toggle the paused state use the dedicated
                `POST /v3/webhooks/{id}/enable` / `POST /v3/webhooks/{id}/disable` endpoints — the
                `enabled` flag is not accepted on update.
              properties: &ref_614
                eventType:
                  type: string
                  description: |-
                    Event type this subscription should fire on. Must be one of the values returned by
                    `GET /v3/webhooks/events`.
                  example: email_replied
                url:
                  type: string
                  format: uri
                  maxLength: 1024
                  description: Absolute `http`/`https` URL that will receive the webhook payload.
                  example: https://example.com/hooks/reply
                scope:
                  type: string
                  title: WebHookScope
                  description: |-
                    Scope that determines which users' activity triggers the webhook.

                    - `personal` — fires only for activity of the subscription owner.
                    - `team` — fires for activity of any member of the owner's team. Creation requires the current user to be the team owner for private teams; anyone can create for public teams.
                    - `organization` — reserved for future use. The API currently rejects creation/update with this value (`errorCode: 5`).
                  enum: *ref_243
                  example: personal
                payloadConfig:
                  type: object
                  title: WebHookPayloadConfig
                  description: Optional flags that enrich the delivered webhook payload with extra fields from the originating email/contact.
                  properties: *ref_244
                  example: *ref_245
              required: &ref_615
                - eventType
                - url
                - scope
              example: &ref_616
                eventType: email_replied
                url: https://example.com/hooks/reply-v2
                scope: personal
                payloadConfig:
                  includeEmailUrl: true
                  includeEmailText: true
                  includeProspectCustomFields: true
      responses:
        '200':
          description: Webhook subscription updated successfully.
          content:
            application/json:
              schema:
                type: object
                title: WebHook
                description: |-
                  A webhook subscription. The subscription fires a single event type to a configured URL
                  when activity matching the subscription's `scope` occurs.
                properties: *ref_246
                example: *ref_247
        '400':
          description: |-
            Invalid `id`, request-body validation failure, or a domain rule rejected the
            update (unknown event, invalid URL, invalid scope value, or organization scope
            reserved for future use).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Body validation failure (FluentValidator)
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request body contains validation errors.
                    errors:
                      - pointer: /url
                        detail: '''url'' must not be empty.'
                invalid_event:
                  summary: Unknown event type
                  value:
                    title: Bad Request
                    status: 400
                    detail: Unknown webhook event 'email_clicked'.
                    code: webHook.invalidEvent
                invalid_url:
                  summary: Malformed URL
                  value:
                    title: Bad Request
                    status: 400
                    detail: Url must be a valid absolute http(s) URL.
                    code: webHook.invalidUrl
                organization_scope_not_implemented:
                  summary: Organization scope reserved
                  value:
                    title: Bad Request
                    status: 400
                    detail: Organization-scope webhooks are not yet implemented.
                    code: webHook.organizationScopeNotImplemented
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '403':
          description: |-
            The caller is not allowed to set the subscription to `team` scope for their
            team (private team, caller is not the owner).
          content:
            application/problem+json:
              schema:
                allOf: *ref_8
              example:
                title: Forbidden
                status: 403
                detail: Team-scope webhook subscriptions are not allowed for your current team configuration.
                code: webHook.teamScopeForbidden
        '404':
          description: Webhook subscription not found or not owned by the caller.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Webhook subscription 1823 not found.
                code: webHook.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
    delete:
      tags:
        - Webhooks
      summary: Delete a webhook subscription
      x-required-scope: webhooks:write
      description: |-
        <small>_Requires the `webhooks:write` scope (or a broader one that includes it)._</small>

        Permanently deletes the subscription and its delivery-log payloads.
      operationId: DeleteWebhook
      parameters:
        - name: id
          in: path
          required: true
          description: Webhook subscription ID.
          schema:
            type: integer
      responses:
        '204':
          description: Webhook subscription deleted successfully. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid `id` parameter.
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Webhook subscription not found or not owned by the caller.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Webhook subscription 1823 not found.
                code: webHook.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/webhooks/{id}/test:
    post:
      tags:
        - Webhooks
      summary: Send a test payload
      x-required-scope: webhooks:operate
      description: |-
        <small>_Requires the `webhooks:operate` scope (or a broader one that includes it)._</small>

        Triggers a synthetic delivery to the subscription's URL so the integrator can
        validate wiring. Only enabled subscriptions can be tested.
      operationId: TestWebhook
      parameters:
        - name: id
          in: path
          required: true
          description: Webhook subscription ID.
          schema:
            type: integer
      responses:
        '204':
          description: Test payload dispatched. The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid `id` parameter.
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Subscription not found, not owned by the caller, or disabled.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Webhook subscription 1823 not found or disabled.
                code: webHook.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
        '502':
          description: |-
            The webhook subscription is valid and the request was dispatched, but the target URL could
            not be reached or rejected the delivery. Causes include connection failures, TLS handshake
            errors, the target returning a 4xx or 5xx, or the request timing out. The subscription is
            left untouched — the integrator should fix the target endpoint and retry the test.
          content:
            application/problem+json:
              schema:
                allOf: *ref_11
              examples:
                target_unreachable:
                  summary: Target URL unreachable (connection / DNS / timeout)
                  value:
                    title: Bad Gateway
                    status: 502
                    detail: 'Could not reach target URL: No such host is known.'
                    code: webHook.deliveryFailed
                target_returned_error:
                  summary: Target URL returned a non-2xx
                  value:
                    title: Bad Gateway
                    status: 502
                    detail: Target URL responded with status 503.
                    code: webHook.deliveryFailed
  /v3/webhooks/{id}/enable:
    post:
      tags:
        - Webhooks
      summary: Enable a webhook subscription
      x-required-scope: webhooks:operate
      description: |-
        <small>_Requires the `webhooks:operate` scope (or a broader one that includes it)._</small>

        Resumes a paused subscription. Idempotent — calling on an already-enabled
        subscription still returns `204`. Use this dedicated endpoint rather than
        `PUT` to toggle the paused state (`PUT` does not accept the `enabled` flag).

        When the active-subscriptions limit has been reached, returns `409 Conflict`
        with `code: webHook.limitReached`.
      operationId: EnableWebhook
      parameters:
        - name: id
          in: path
          required: true
          description: Webhook subscription ID.
          schema:
            type: integer
      responses:
        '204':
          description: Subscription is enabled (or was already enabled). The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid `id` parameter.
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Subscription not found or not owned by the caller.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Webhook subscription 1823 not found.
                code: webHook.notFound
        '409':
          description: Enabling would exceed the active webhook-subscription limit for the user.
          content:
            application/problem+json:
              schema:
                allOf: *ref_12
              example:
                title: Conflict
                status: 409
                detail: Limit of active webhook subscriptions reached (50).
                code: webHook.limitReached
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/webhooks/{id}/disable:
    post:
      tags:
        - Webhooks
      summary: Disable a webhook subscription
      x-required-scope: webhooks:operate
      description: |-
        <small>_Requires the `webhooks:operate` scope (or a broader one that includes it)._</small>

        Pauses a subscription without deleting it — no events fire until re-enabled.
        Idempotent: calling on an already-disabled subscription still returns `204`.
        Use this dedicated endpoint rather than `PUT` to toggle the paused state
        (`PUT` does not accept the `enabled` flag).
      operationId: DisableWebhook
      parameters:
        - name: id
          in: path
          required: true
          description: Webhook subscription ID.
          schema:
            type: integer
      responses:
        '204':
          description: Subscription is disabled (or was already disabled). The response body is empty.
          content:
            application/json:
              schema:
                description: Empty body
        '400':
          description: Invalid `id` parameter.
          content:
            application/problem+json:
              schema:
                allOf: *ref_5
              example:
                title: Validation failed
                status: 400
                detail: The request contains validation errors.
                errors:
                  - pointer: id
                    detail: The 'id' parameter must be a positive integer.
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Subscription not found or not owned by the caller.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Webhook subscription 1823 not found.
                code: webHook.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
  /v3/webhooks/{id}/logs:
    get:
      tags:
        - Webhooks
      summary: Get webhook delivery logs
      x-required-scope: webhooks:read
      description: |-
        <small>_Requires the `webhooks:read` scope (or a broader one that includes it)._</small>

        Returns a paginated **failure log** for a single subscription — only failed
        delivery attempts are recorded here; successful deliveries are not listed. Each
        log entry captures the triggering event id, HTTP status (or `null` when the
        request could not be completed) and the UTC timestamp of the attempt.
      operationId: GetWebhookLogs
      parameters:
        - name: id
          in: path
          required: true
          description: Webhook subscription ID.
          schema:
            type: integer
        - name: top
          in: query
          required: false
          description: Maximum number of log entries to return.
          schema:
            type: integer
            minimum: 1
        - name: skip
          in: query
          required: false
          description: Number of log entries to skip.
          schema:
            type: integer
            minimum: 0
      responses:
        '200':
          description: Paginated delivery-log entries.
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      title: WebHookLog
                      description: One delivery-attempt record for a webhook subscription.
                      properties: &ref_617
                        eventId:
                          type: string
                          format: uuid
                          readOnly: true
                          description: Unique identifier of the event that triggered the delivery.
                        httpStatus:
                          type:
                            - integer
                            - 'null'
                          readOnly: true
                          description: HTTP status code returned by the subscriber endpoint, or `null` if the delivery could not be completed (e.g. network error).
                        date:
                          type: string
                          format: date-time
                          readOnly: true
                          description: ISO-8601 timestamp (UTC) when the delivery attempt was made.
                      example: &ref_618
                        eventId: 9a7d53be-b7d6-4a9d-9f1a-77ab7f4c5f1a
                        httpStatus: 200
                        date: '2026-04-17T12:05:34+00:00'
                  hasMore:
                    type: boolean
                    description: Whether more items are available beyond the current page..
        '400':
          description: Invalid `id` parameter, or invalid pagination parameters.
          content:
            application/problem+json:
              schema:
                oneOf:
                  - allOf: *ref_5
                  - allOf: *ref_11
              examples:
                validation_failed:
                  summary: Route-parameter validation failure
                  value:
                    title: Validation failed
                    status: 400
                    detail: The request contains validation errors.
                    errors:
                      - pointer: id
                        detail: The 'id' parameter must be a positive integer.
                invalid_pagination:
                  summary: Pagination out of range
                  value:
                    title: Bad Request
                    status: 400
                    detail: Parameter 'top' must be between 1 and 1000.
                    code: webHook.invalidPagination
        '401':
          description: Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
          content:
            application/problem+json:
              schema:
                allOf: *ref_7
        '404':
          description: Webhook subscription not found or not owned by the caller.
          content:
            application/problem+json:
              schema:
                allOf: *ref_13
              example:
                title: Not Found
                status: 404
                detail: Webhook subscription 1823 not found.
                code: webHook.notFound
        '429':
          description: Too Many Requests
          headers: *ref_9
          content: *ref_10
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: |-
        Authenticate every request with a Bearer token. Pass your Reply API key in the
        `Authorization` header:

        ```
        Authorization: Bearer <your-api-key>
        ```

        Get your API key from the Reply dashboard: **Settings → API Key**.
  schemas:
    ai-prompt-step-type.enum:
      type: string
      title: AI Prompt Step Type
      description: |-
        The sequence step type an AI prompt is written for. A prompt is only offered for the step type it was created
        with, and that step type cannot be changed afterwards.
      enum: *ref_0
    ai-prompt-scope.enum:
      type: string
      title: AI Prompt Scope
      description: |-
        Who owns an AI prompt and whether you can change it. `library` prompts are curated by Reply and are read-only.
        `personal` prompts are your own and can be updated or deleted.
      enum: *ref_248
    ai-prompt.model:
      type: object
      title: AiPrompt
      description: An AI prompt available for configuring a sequence step.
      properties: *ref_2
      required: *ref_3
      example: *ref_4
    problem-details.model:
      type: object
      title: Problem Details
      description: |-
        Bare RFC 9457 problem-details envelope. Returned by middleware-level errors
        that don't carry domain context: 401 Unauthorized (auth middleware),
        429 Too Many Requests (rate-limit middleware), and route-level 404 / 405 /
        415 (framework middleware).

        Business and validation responses extend this envelope and add additional
        fields — see `business-problem.model.yaml` (adds `code` slug) and
        `validation-problem.model.yaml` (adds `errors[]` array).
      properties: *ref_1
    validation-error.model:
      type: object
      title: Validation Error
      description: A single field-level validation error.
      properties: *ref_249
    validation-problem.model:
      allOf: *ref_250
      title: Validation Problem
      description: |-
        Input-validation error response at 400. Returned when the request body
        fails binding, FluentValidator rules, or when route/query parameter
        attribute validation (`[Range]`, `[Required]`) fails. Route, query, and
        body errors are combined into a single `errors[]` array — clients should
        not assume one error per request.
    bad-request-validation:
      allOf: *ref_5
    unauthorized:
      allOf: *ref_7
    business-problem.model:
      allOf: *ref_6
      title: Business Problem
      description: |-
        Domain error response carrying a stable, namespaced error slug.
        Emitted for most 4xx responses (business 400, 403, 404, 409, …) and
        for 503 when a downstream dependency is unavailable.
    forbidden:
      allOf: *ref_8
    ai-prompt-creation.request:
      type: object
      title: AiPromptCreationRequest
      description: Request body for saving a new personal AI prompt.
      properties: *ref_251
      required: *ref_252
      example: *ref_253
    bad-request-business:
      allOf: *ref_11
    conflict:
      allOf: *ref_12
    ai-prompt-update.request:
      type: object
      title: AiPromptUpdateRequest
      description: |-
        Request body for updating a personal AI prompt. Both fields are required — the prompt is replaced with exactly
        what you send.
      properties: *ref_254
      required: *ref_255
      example: *ref_256
    not-found:
      allOf: *ref_13
    ai-prompt-sample-preview.request:
      type: object
      title: AiPromptSamplePreviewRequest
      description: Request body for previewing a comment prompt against a generic sample post.
      properties: *ref_257
      required: *ref_258
      example: *ref_259
    comment-preview-outcome.enum:
      type: string
      title: Comment Preview Outcome
      description: |-
        What the preview produced. Only `generated` returns a comment; every other value explains why the AI wrote
        nothing, and `commentText` is `null`.

        - `generated` — a comment was written and is in `commentText`.
        - `noRecentPosts` — the latest visible post is older than the `skipIfNoPostsInDays` window.
        - `postsUnavailable` — no posts could be read for the profile. The person may never have posted, or their posts
          may not be visible to the LinkedIn account used for the lookup; the two cases are indistinguishable.
        - `commentingRestricted` — commenting is not permitted on the post.
        - `reshareNoText` — the post is a reshare that adds no commentary of its own.
        - `noPostContent` — the post has no text and no images, so there is nothing to react to.
        - `aiSkip` — the AI declined to comment, typically because the post matches one of the `skipTopics`.
      enum: *ref_260
    ai-prompt-preview.response:
      type: object
      title: AiPromptPreviewResponse
      description: |-
        The result of a comment preview. Read `outcome` first — it tells you whether a comment was produced and, if not,
        why.
      properties: *ref_14
      required: *ref_15
      example: *ref_16
    too-many-requests: &ref_619
      description: Too Many Requests
      headers: *ref_9
      content: *ref_10
    ai-prompt-linkedin-post-preview.request:
      type: object
      title: AiPromptLinkedInPostPreviewRequest
      description: |-
        Request body for previewing a comment prompt against a real person's latest LinkedIn post. One Reply credit is
        spent per call, whatever the outcome.
      properties: *ref_261
      required: *ref_262
      example: *ref_263
    intent-industry-item.model:
      type: object
      title: Intent Signal Industry
      description: A single industry entry from the typeahead list, used in intent-signal configuration.
      properties: *ref_264
      example: *ref_265
    intent-technology-item.model:
      type: object
      title: Intent Signal Technology
      description: A single technology entry from the typeahead list, used in intent-signal configuration.
      properties: *ref_266
      example: *ref_267
    knowledge-base-list-item.model:
      type: object
      title: KnowledgeBaseListItem
      description: Summary representation of a knowledge base returned in list responses.
      properties: *ref_268
      example: *ref_269
    knowledge-base-creation.request:
      type: object
      title: KnowledgeBaseCreationRequest
      description: Request body for creating a new knowledge base.
      required: *ref_270
      properties: *ref_271
      example: *ref_272
    knowledge-base.model:
      type: object
      title: KnowledgeBase
      description: Detailed representation of a knowledge base.
      properties: *ref_17
      example: *ref_18
    knowledge-base-patch.request:
      type: object
      title: KnowledgeBasePatchRequest
      description: Partial update for a knowledge base. Send only the fields you want to change; absent fields retain their current value. At least one field must be present.
      properties: *ref_273
      example: *ref_274
    knowledge-base-link.model:
      type: object
      title: KnowledgeBaseLink
      description: A web link attached to a knowledge base.
      properties: *ref_19
      example: *ref_20
    knowledge-base-link-creation.request:
      type: object
      title: KnowledgeBaseLinkCreationRequest
      description: Request body for adding a web link to a knowledge base.
      required: *ref_275
      properties: *ref_276
      example: *ref_277
    knowledge-base-document.model:
      type: object
      title: KnowledgeBaseDocument
      description: A file document attached to a knowledge base.
      properties: *ref_21
      example: *ref_22
    reply-handler-delivery-mode.enum:
      type: string
      title: Reply handler delivery mode
      description: |-
        How a generated reply is delivered:
        - `draft` — the reply is saved as a draft for manual review before sending.
        - `auto` — the reply is sent automatically without manual review.
        - `stopAndNotify` — the reply is not drafted or auto-sent; instead an alert is raised (optionally to the address in `additionalNotificationEmail`) so a person can handle it. Requires the stop-and-notify feature on the caller's team; otherwise create and update return `403` with code `knowledgeBase.stopAndNotifyNotEnabled`.

        Defaults to `draft` when omitted on create.
      enum: *ref_23
    reply-handler-list-item.model:
      type: object
      title: ReplyHandlerListItem
      description: Summary representation of a reply handler returned in list responses.
      properties: *ref_278
      example: *ref_279
    tone-of-voice.enum:
      type: string
      title: Tone of voice
      description: Tone applied to generated replies and reengagement messages.
      enum: *ref_24
    response-length.enum:
      type: string
      title: Response length
      description: Target length of generated replies and reengagement messages.
      enum: *ref_25
    reply-handler-creation.request:
      type: object
      title: ReplyHandlerCreationRequest
      description: Request body for creating a new reply handler.
      required: *ref_280
      properties: *ref_281
      example: *ref_282
    knowledge-base-media.model:
      type: object
      title: KnowledgeBaseMedia
      description: A media file attached to a reply handler or reengagement card.
      properties: *ref_28
      example: *ref_29
    reply-handler.model:
      type: object
      title: ReplyHandler
      description: Detailed representation of a reply handler.
      properties: *ref_26
      example: *ref_27
    reply-handler-patch.request:
      type: object
      title: ReplyHandlerPatchRequest
      description: Partial update for a reply handler. Send only the fields you want to change; absent fields retain their current value. At least one field must be present. Media is not patched here — manage it via the `/media` sub-resource.
      properties: *ref_283
      example: *ref_284
    reengagement-card-delivery-mode.enum:
      type: string
      title: Reengagement card delivery mode
      description: |-
        How a generated reengagement message is delivered:
        - `draft` — the message is saved as a draft for manual review before sending.
        - `auto` — the message is sent automatically without manual review.

        Defaults to `draft` when omitted on create.
      enum: *ref_30
    reengagement-card-list-item.model:
      type: object
      title: ReengagementCardListItem
      description: Summary representation of a reengagement card returned in list responses.
      properties: *ref_285
      example: *ref_286
    reengagement-card-creation.request:
      type: object
      title: ReengagementCardCreationRequest
      description: Request body for creating a new reengagement card.
      required: *ref_287
      properties: *ref_288
      example: *ref_289
    reengagement-card.model:
      type: object
      title: ReengagementCard
      description: Detailed representation of a reengagement card.
      properties: *ref_31
      example: *ref_32
    reengagement-card-patch.request:
      type: object
      title: ReengagementCardPatchRequest
      description: Partial update for a reengagement card. Send only the fields you want to change; absent fields retain their current value. At least one field must be present. Media is not patched here — manage it via the `/media` sub-resource.
      properties: *ref_290
      example: *ref_291
    offer-list-item.model:
      type: object
      title: OfferListItem
      description: Summary representation of an offer returned in list responses.
      properties: *ref_292
      example: *ref_293
    offer-creation.request:
      type: object
      title: OfferCreationRequest
      description: Request body for creating a new offer.
      required: *ref_294
      properties: *ref_295
      example: *ref_296
    offer.model:
      type: object
      title: Offer
      description: Detailed representation of an offer — the bundle of company-context inputs the AI SDR uses to personalize outreach. Returned by get/create/update responses.
      properties: *ref_33
      example: *ref_34
    offer-patch.request:
      type: object
      title: OfferPatchRequest
      description: |-
        Partial update for an offer. Send only the fields you want to change; absent fields retain their current value. At least one field must be present.

        All array fields, if present, fully replace the current value (no item-level merge).
      properties: *ref_297
      example: *ref_298
    playbook-type.enum:
      type: string
      title: Playbook scope
      description: |-
        Identifies the visibility scope of a playbook.

        - `global` — Reply-curated, read-only across all teams.
        - `organization` — visible to every team in the caller's organization.
        - `team` — visible to the caller's team only.

        `global` playbooks are never created or modified via the API; only `organization` and `team` are accepted on create.
      enum: *ref_35
    playbook-list-item.model:
      type: object
      title: PlaybookListItem
      description: Summary representation of a playbook returned in list responses.
      properties: *ref_299
      example: *ref_300
    playbook-creation.request:
      type: object
      title: PlaybookCreationRequest
      description: Request body for creating a new playbook.
      required: *ref_301
      properties: *ref_302
      example: *ref_303
    playbook-style-file.model:
      type: object
      title: PlaybookStyleFile
      description: A single style file attached to a playbook. Style files are reference documents (PDFs, text excerpts, etc.) that inform tone and voice when the playbook is applied.
      properties: *ref_38
      example: *ref_39
    playbook.model:
      type: object
      title: Playbook
      description: Detailed representation of a playbook, returned by get/create/update responses.
      properties: *ref_36
      example: *ref_37
    playbook-patch.request:
      type: object
      title: PlaybookPatchRequest
      description: |-
        Partial update for a playbook. Send only the fields you want to change; absent fields retain their current value. At least one of `name`, `description`, or `body` must be present.

        `type` is immutable after creation and cannot be patched.
      properties: *ref_304
      example: *ref_305
    settings.component:
      type: object
      title: Sequence Settings
      description: Settings configuration for a sequence
      required: *ref_45
      properties: *ref_46
    generation-inputs.component:
      type: object
      title: Offer generation inputs
      description: |-
        Inline offer-context inputs used when the sequence is created without referencing a saved offer. Mirrors the shape of an offer.

        On create, exactly one of `offerId` or `offerGenerationInputs` must be provided.
      properties: *ref_49
    sales-agent-language.enum:
      type: string
      title: Sales agent language
      description: Language used by the AI SDR when generating outreach messages.
      enum: *ref_50
    sales-agent-tone-of-voice.enum:
      type: string
      title: Sales agent tone of voice
      description: Tone of voice used by the AI SDR when generating outreach messages.
      enum: *ref_51
    sales-agent-message-length.enum:
      type: string
      title: Personalized message length
      description: Target length for AI-generated personalized messages.
      enum: *ref_52
    sales-agent-gender.enum:
      type: string
      title: Sales agent gender
      description: Gender used by the AI SDR persona when generating outreach messages.
      enum: *ref_53
    tone-of-voice-settings.component:
      type: object
      title: Tone of voice settings (request)
      description: Tone-of-voice configuration on create/patch. All fields are optional on create — omitted fields fall back to defaults (English (US), Confident tone, Medium length, Man).
      properties: *ref_61
    sales-agent-step-type.enum:
      type: string
      title: Generated step type
      description: Channel of a step the AI SDR is allowed to generate when building the sequence.
      enum: *ref_54
    structure-setup.component:
      type: object
      title: Sequence structure setup
      description: Shape of the sequence steps the AI SDR should generate on create.
      required: *ref_306
      properties: *ref_307
    sales-agent-content-provider.enum:
      type: string
      title: AI content provider
      description: LLM provider that generates the outreach content for the AI SDR sequence.
      enum: *ref_55
    contact-default-field.enum:
      type: string
      title: Contact default field
      description: Built-in contact field selectable for AI SDR personalization.
      enum: *ref_308
    personalization-points.component:
      type: object
      title: Personalization points
      description: Which research signals the AI SDR is allowed to weave into personalized messages. Every leaf is optional; absent flags are treated as "no preference / keep the current value".
      properties: *ref_56
    data-filter-type.enum:
      type: string
      title: Filter polarity
      description: Whether matching values are included in or excluded from the autopilot search.
      enum: *ref_40
    filter-int-value.component:
      type: object
      title: Integer filter value
      description: A single integer value used in an autopilot filter, with include/exclude polarity.
      required: *ref_161
      properties: *ref_162
    filter-value.component:
      type: object
      title: Filter value
      description: A single string value used in an autopilot filter, with include/exclude polarity.
      required: *ref_41
      properties: *ref_42
    data-search-company-size.enum:
      type: string
      title: Company size
      description: Headcount band used when filtering companies for autopilot search.
      enum: *ref_163
    headcount-growth.component:
      type: object
      title: Headcount growth range
      description: |-
        Min/max range applied to the company's total headcount growth (percent). Either bound may be omitted.

        When both are provided, `min` must be less than or equal to `max`.
      properties: *ref_164
    department-headcount-growth.component:
      type: object
      title: Department headcount growth range
      description: |-
        Min/max range applied to a specific department's headcount growth (percent). Either bound may be omitted.

        When both are provided, `min` must be less than or equal to `max`.
      required: *ref_165
      properties: *ref_166
    sales-agent-company-revenue.enum:
      type: string
      title: Company revenue tier
      description: Annual revenue tier used when filtering companies for autopilot search.
      enum: *ref_43
    keyword-filter-type.enum:
      type: string
      title: Keyword combination
      description: Boolean combinator applied across keyword filter values.
      enum: *ref_309
    keyword-filter.component:
      type: object
      title: Keyword filter
      description: |-
        Boolean keyword filter applied to account or contact searches.

        In responses this field is always present and non-null even when no keywords are configured (`{ "values": [], "type": "or" }`).
      properties: *ref_44
    data-search-years-in-company.enum:
      type: string
      title: Years in current company
      description: Tenure band used when filtering contacts for autopilot search.
      enum: *ref_310
    filters.component:
      type: object
      title: Autopilot filters
      description: |-
        Account- and contact-level filter configuration used by autopilot when searching for new contacts to add to the sequence.

        Most collections are capped at 25 items. `accountKeywords` and `contactKeywords` are always present and non-null in responses even when empty (`{ "values": [], "type": "or" }`).
      properties: *ref_57
    autopilot-creation-settings.component:
      type: object
      title: Autopilot settings (create)
      description: Autopilot configuration applied at sequence-create time. When `enabled` is `true`, the sequence is set to actively search for and add new contacts immediately after creation.
      required: *ref_311
      properties: *ref_312
    approval-mode-creation-settings.component:
      type: object
      title: Approval mode (create)
      description: Initial approval mode for the sequence — whether AI-generated messages require human approval before being sent.
      required: *ref_313
      properties: *ref_314
    intent-signal-type.enum:
      type: string
      title: Intent signal type
      description: |-
        Discriminator selecting which intent-signal sub-object is populated.

        - `linkedInPostEngagers` — populate `postEngagers`.
        - `competitorFollowers` — populate `competitorFollowers`.
        - `technologyUsed` — populate `technologyUsed`.
        - `jobHiring` — populate `jobHiring`.
      enum: *ref_315
    post-engagers-mode.enum:
      type: string
      title: LinkedIn post engagers mode
      description: |-
        Selects which sub-object of the LinkedIn post engagers signal is populated.

        - `monitorProfiles` — populate `monitorProfiles`.
        - `monitorPosts` — populate `monitorPosts`.
      enum: *ref_316
    intent-signal.component:
      type: object
      title: Intent signal
      description: |-
        Tagged-union intent signal. Exactly one of `postEngagers`, `competitorFollowers`, `technologyUsed`, `jobHiring` is populated, matching `type`. The other three must be omitted or `null`.

        A sequence may have at most one signal per `type`. `technologyUsed` and `jobHiring` are mutually exclusive — a sequence may include at most one of the two.
      required: *ref_58
      properties: *ref_59
    sequence-creation.request:
      type: object
      title: AI SDR sequence — create
      description: |-
        Create a new AI SDR sequence with its full AI SDR settings. Generic sequence fields (`name`, `scheduleId`, `settings`, `emailAccounts`, `linkedInAccounts`) are accepted here too — sequence steps are NOT, because the AI SDR generates steps automatically.

        Exactly one of `offerId` or `offerGenerationInputs` must be provided.

        At most one intent signal per `type` is allowed.
      required: *ref_317
      properties: *ref_318
    health.component:
      type: string
      description: |-
        Overall health status of the sequence. Indicates whether the sequence can operate normally or has issues that need attention.

        - `healthy` — Sequence is functioning normally with no issues
        - `stalled` — Sequence has stalled and is not progressing
        - `degraded` — Sequence is running but with reduced effectiveness
        - `blocked` — Sequence cannot proceed due to critical issues
      enum: *ref_319
      readOnly: true
    sequence-base.model:
      type: object
      properties: *ref_185
      example: *ref_186
    email-account.component:
      type: object
      properties: *ref_320
      required: *ref_321
    sequence-linkedin-account.model:
      type: object
      title: Sequence LinkedIn Account
      description: A LinkedIn account linked to a sequence
      properties: *ref_202
      example: *ref_203
    email-variant.type:
      type: object
      title: Email Variant
      description: Individual email variant within an email step.
      properties: *ref_322
    email.type:
      type: object
      title: Email
      description: Email step with variant configuration
      properties: *ref_323
      required: *ref_324
    linkedin-variant.type:
      type: object
      title: LinkedIn Variant
      description: Individual LinkedIn message/connect variant
      properties: *ref_47
      required: *ref_48
    linkedin-message.type:
      type: object
      title: LinkedIn Message
      description: LinkedIn message action step
      properties: *ref_325
      required: *ref_326
    linkedin-connect.type:
      type: object
      title: LinkedIn Connect
      description: LinkedIn connect action step
      properties: *ref_327
      required: *ref_328
    linkedin-inmail-variant.type:
      type: object
      title: LinkedIn InMail Variant
      description: Individual LinkedIn InMail variant
      properties: *ref_329
      required: *ref_330
    linkedin-inmail.type:
      type: object
      title: LinkedIn InMail
      description: LinkedIn InMail action step
      properties: *ref_331
      required: *ref_332
    linkedin-view-profile.type:
      type: object
      title: LinkedIn View Profile
      description: LinkedIn view profile action step
      properties: *ref_206
      required: *ref_207
    linkedin-endorse-skills.type:
      type: object
      title: LinkedIn Endorse Skills
      description: LinkedIn endorse skills action step
      properties: *ref_208
      required: *ref_209
    linkedin-voice-message.type:
      type: object
      title: LinkedIn Voice Message
      description: LinkedIn voice message action step
      properties: *ref_210
      required: *ref_211
    linkedin-like-recent-posts.type:
      type: object
      title: LinkedIn Like Recent Posts
      description: LinkedIn like recent posts action step
      properties: *ref_212
      required: *ref_213
    linkedin-follow-profile.type:
      type: object
      title: LinkedIn Follow Profile
      description: LinkedIn follow profile action step
      properties: *ref_214
      required: *ref_215
    linkedin-comment-on-recent-post.type:
      type: object
      title: LinkedIn Comment On Recent Post
      description: |-
        LinkedIn comment on a recent post action step. The AI writes a comment on the contact's most recent post using the
        instructions in `aiPromptText`. Use the AI prompt preview endpoints to check what a prompt produces before saving
        it on a step. How many of these comments an account posts per day is governed by that LinkedIn account's own daily
        limits, not by this step.
      properties: *ref_216
      required: *ref_217
    linkedin.type:
      title: LinkedIn
      description: LinkedIn step with action type sub-discriminator. Uses type "linkedIn" with a second discriminator actionType to select the specific LinkedIn action.
      discriminator: *ref_333
      oneOf: *ref_334
    call.type:
      type: object
      title: Call
      description: Call step with script/notes
      properties: *ref_218
      required: *ref_219
    sms.type:
      type: object
      title: SMS
      description: SMS step with message content
      properties: *ref_220
      required: *ref_221
    whatsapp.type:
      type: object
      title: WhatsApp
      description: WhatsApp step with message content
      properties: *ref_222
      required: *ref_223
    zapier.type:
      type: object
      title: Zapier
      description: Zapier integration step
      properties: *ref_224
      required: *ref_225
    task.type:
      type: object
      title: Task
      description: Task step for manual actions
      properties: *ref_226
      required: *ref_227
    condition.type:
      type: object
      title: Condition
      description: Condition step that evaluates rules before proceeding
      properties: *ref_228
      required: *ref_229
    step.component:
      title: Sequence Step
      discriminator: *ref_187
      oneOf: *ref_188
    sequence-response.model:
      title: Sequence
      description: Full representation of a sequence, including its schedule and the email and LinkedIn accounts used to send from it.
      allOf: *ref_189
      example: *ref_190
    tone-of-voice-response.component:
      type: object
      title: Tone of voice (response)
      description: Tone-of-voice configuration as returned in sequence responses. All four fields are always populated.
      properties: *ref_335
    evergreen-sequence-status.enum:
      type: string
      title: Autopilot status
      description: |-
        Current autopilot status of the AI SDR sequence.

        - `enabled` — autopilot is actively searching and adding contacts.
        - `disabled` — autopilot is turned off.
        - `paused` — autopilot is paused.
        - `disabledByLackOfContacts` — autopilot was auto-disabled because no matching contacts were found.
        - `disabledByContactsLimitExceeded` — autopilot was auto-disabled because the team contacts limit was reached.
      enum: *ref_336
    autopilot-response.component:
      type: object
      title: Autopilot settings (response)
      description: Autopilot configuration as returned in sequence responses.
      properties: *ref_337
    approval-mode-response.component:
      type: object
      title: Approval mode (response)
      description: Current approval-mode state of the sequence.
      properties: *ref_338
    sequence.model:
      type: object
      title: AI SDR sequence settings
      description: AI SDR-specific settings of a sequence. Returned by `GET .../settings` and `PATCH .../settings`. Generic sequence fields (name, schedule, accounts, etc.) come from the generic `GET /v3/sequences/{id}` and are NOT included here.
      properties: *ref_60
    sequence-creation.response.model:
      title: Sequence Creation Response
      description: The sequence returned after creation, including its AI SDR settings.
      allOf: *ref_339
    generation-inputs-patch.component:
      type: object
      title: Offer generation inputs (patch)
      description: |-
        Partial update for the inline offer-context inputs of an AI SDR sequence.

        - Field absent from the body: skip; current value is retained.
        - Field present with `null`: rejected.
        - Array fields, when present, fully replace the current value (no item-level merge) and must contain 1-10 items.
      properties: *ref_340
    autopilot-patch.component:
      type: object
      title: Autopilot settings (patch)
      description: |-
        Partial update of autopilot configuration.

        - Field absent from the body: skip; current value is retained.
        - Field present with `null`: rejected.
        - `filters`, when present, fully replaces the current filters object (no field-level merge inside the filters tree).
        - The autopilot on/off toggle is NOT changed here — use `POST .../autopilot/enable` or `POST .../autopilot/disable`.
      properties: *ref_341
    sequence-patch.request:
      type: object
      title: AI SDR sequence — patch
      description: |-
        Partial update of AI SDR-specific sequence settings. Generic sequence fields (name, schedule, accounts, settings) are NOT updated here — use the generic `PATCH /v3/sequences/{id}`. Approval mode is NOT updated here — use `PUT .../approval-mode`. Generated step types are NOT updated here — use `PUT .../generated-step-types`. Playbook and knowledge-base attachments are NOT updated here — use the dedicated sub-resources.

        PATCH semantics:
        - Field absent from the body: skip; current value is retained.
        - Field present with `null`: rejected.
        - `offerId` and `offerGenerationInputs` are mutually exclusive — only one may be present.
        - `intentSignals`, when present, fully replaces the current list. At most one signal per `type`; `technologyUsed` and `jobHiring` are mutually exclusive.
        - `offerGenerationInputs`, `toneOfVoice` and `personalizationPoints`, when present, are deep-merged at the leaf level — array fields inside them fully replace.

        At least one field must be present in the body.
      properties: *ref_342
    autopilot-preview.request:
      type: object
      title: Autopilot preview request
      description: Autopilot filter configuration to preview. Does not need to be saved to the sequence first — supports try-before-save in the filter UI.
      required: *ref_343
      properties: *ref_344
    approval-mode-put.request:
      type: object
      title: Approval mode — set
      description: |-
        Sets the sequence's approval mode.

        When disabling (`enabled` = `false`), `approveAllPendingContacts` may be provided to immediately approve all pending contacts. When enabling (`enabled` = `true`), `approveAllPendingContacts` must be omitted.
      required: *ref_345
      properties: *ref_346
    generated-step-types-put.request:
      type: object
      title: Generated step types — set
      description: Replaces the channels of steps the AI SDR is allowed to generate, and regenerates the sequence steps using the new mix. Rejected (409) when the sequence has already acted on contacts (sent emails or LinkedIn messages, generated tasks, etc.).
      required: *ref_347
      properties: *ref_348
    playbook-summary.model:
      type: object
      title: Sequence playbook summary
      description: Compact representation of the playbook attached to a sequence.
      properties: *ref_349
      example: *ref_350
    playbook-put.request:
      type: object
      title: Sequence playbook — set
      description: Attaches a playbook to the sequence by composite id. Replaces any previously-attached playbook.
      required: *ref_351
      properties: *ref_352
    knowledge-base-summary.model:
      type: object
      title: Sequence knowledge base summary
      description: Compact representation of the knowledge base connected to a sequence.
      properties: *ref_353
      example: *ref_354
    knowledge-base-put.request:
      type: object
      title: Sequence knowledge base — set
      description: Connects a knowledge base to the sequence by id. Replaces any previously-connected knowledge base.
      required: *ref_355
      properties: *ref_356
    contact-account-stage.model:
      type: object
      title: Contact Account Stage
      description: Stage assigned to a contact account
      additionalProperties: false
      properties: *ref_62
    contact-account.model:
      type: object
      title: Contact Account
      description: A contact account representing a company or organization
      additionalProperties: false
      properties: *ref_63
    contact-account-create.request:
      type: object
      title: Create Contact Account Request
      description: Request body for creating a contact account
      additionalProperties: false
      required: *ref_66
      properties: *ref_67
    contact-account-details.model:
      type: object
      title: Contact Account Details
      description: A single contact account, including the resolved email provider
      additionalProperties: false
      properties: *ref_64
      example: *ref_65
    contact-account-filter-item.model:
      type: object
      title: Account Filter Item
      description: A single filter condition for contact account queries
      additionalProperties: false
      required: *ref_357
      properties: *ref_358
    contact-account-filter.request:
      type: object
      title: Contact Account Filter Request
      description: Request body for filtering contact accounts with advanced criteria
      additionalProperties: false
      properties: *ref_359
    contact-account-update.request:
      type: object
      title: Update Contact Account Request
      description: Request body for updating a contact account
      additionalProperties: false
      required: *ref_360
      properties: *ref_361
    contact-account-bulk-create.request:
      type: object
      title: Bulk Create Accounts Request
      description: Request body for bulk creating accounts
      additionalProperties: false
      required: *ref_362
      properties: *ref_363
    contact-account-create-item-result.model:
      type: object
      title: Create Item Result
      description: Result of a single item in a bulk create operation
      additionalProperties: false
      properties: *ref_364
    contact-account-bulk-delete.request:
      type: object
      title: Bulk Delete Accounts Request
      description: Request body for bulk deleting accounts
      additionalProperties: false
      required: *ref_365
      properties: *ref_366
    not-processed-item-result.model:
      type: object
      title: NotProcessedItemResult
      description: |-
        Per-item error for non-atomic bulk operations.
        Only failed items are returned in the response dictionary.
        Items not present in the dictionary succeeded.
      properties: *ref_68
    contact-account-update-owner.request:
      type: object
      title: Update Contact Account Owner Request
      description: Request body for updating the owner of a contact account
      additionalProperties: false
      required: *ref_367
      properties: *ref_368
    contact-account-contact.model:
      type: object
      title: Contact Account Contact
      description: A contact linked to a contact account
      additionalProperties: false
      properties: *ref_369
    contact-account-contact-ids.request:
      type: object
      title: Contact IDs Request
      description: Request body containing a list of contact IDs
      additionalProperties: false
      required: *ref_69
      properties: *ref_70
    contact-account-list.model:
      type: object
      title: Contact Account List
      description: Account list entity
      additionalProperties: false
      properties: *ref_71
    contact-account-list-create.request:
      type: object
      title: Create Contact Account List Request
      additionalProperties: false
      required: *ref_370
      properties: *ref_371
    contact-account-list-update.request:
      type: object
      title: Update Contact Account List Request
      additionalProperties: false
      required: *ref_372
      properties: *ref_373
    contact-account-list-account-ids.request:
      type: object
      title: Contact Account List Account IDs Request
      additionalProperties: false
      required: *ref_72
      properties: *ref_73
    attachment.model:
      type: object
      title: Attachment
      description: Uploaded file attachment usable across email templates, sequence steps, and direct emails.
      required: *ref_144
      properties: *ref_145
    voice-attachment.model:
      type: object
      title: VoiceAttachment
      description: Uploaded voice message attachment.
      required: *ref_374
      properties: *ref_375
    background-job-list-item.model:
      type: object
      title: Background Job List Item
      description: Compact list-item shape for background jobs. Omits the raw `jsonData` / `jsonDataResult` payloads (use the single-job endpoint to retrieve them).
      properties: *ref_376
    service-unavailable:
      allOf: *ref_74
    background-job.model:
      type: object
      title: Background Job
      description: A long-running background operation tracked by the API. Includes status, progress, timing, and the raw input/result JSON payloads.
      properties: *ref_377
    background-job-cancel.request:
      type: object
      title: Background Job Cancel
      description: Optional payload for cancelling a background job. The body itself is optional — `POST` with an empty body is valid.
      properties: *ref_378
    call-status.enum:
      type: string
      title: Contact Call Status
      description: Contact-level call status. Set via `PATCH /v3/contacts/{id}` (`callStatus` field). Pass `none` to clear.
      enum: *ref_77
    meeting-status.enum:
      type: string
      title: Contact Meeting Status
      description: Contact-level meeting status. Set via `PATCH /v3/contacts/{id}` (`meetingStatus` field). Pass `none` to clear.
      enum: *ref_78
    contact.model:
      type: object
      title: Contact
      description: Contact response model
      properties: *ref_75
      example: *ref_76
    contact-creation.request:
      type: object
      title: Contact Creation Request
      description: Request model for creating a new contact. All fields are optional — at minimum provide email or a LinkedIn URL.
      properties: *ref_379
      example: *ref_380
    contact-patch.request:
      type: object
      title: Contact Patch Request
      description: |-
        Request model for updating an existing contact.
        All fields are optional — only include the fields you want to change (PATCH semantics).
      properties: *ref_79
      example: *ref_80
    contacts-import.request.model:
      type: object
      title: Contacts Import Request
      description: Import contacts by providing an array of contact objects with optional import settings
      required: *ref_381
      properties: *ref_382
      example: *ref_383
    contacts-import.response.model:
      type: object
      title: Contacts Import Response
      description: Summary of a processed contacts import request with per-item results
      properties: *ref_384
      example: *ref_385
    count-result.model:
      type: object
      required: *ref_191
      properties: *ref_192
    sequence-step-info.model:
      type: object
      title: Sequence Step Info
      description: |-
        Position of the contact within a sequence's step graph.

        - `stepId` is the database id of the current step (or `null` when the contact has finished or is on an archived path with no current step).
        - `displayName` is a human-readable label for the step (e.g. `"Email step 2"`); rendered as `"Finished"` when the contact is no longer on any step.
      properties: *ref_386
      example: *ref_387
    thread-sequence.model:
      type: object
      title: Inbox Thread Sequence
      description: Minimal sequence reference attached to an inbox thread.
      required: *ref_133
      properties: *ref_134
    thread-category.model:
      type: object
      title: Inbox Thread Category Reference
      description: Minimal category reference embedded in thread responses.
      required: *ref_135
      properties: *ref_136
    thread-status.model:
      type: object
      title: Inbox Thread Status
      description: Aggregated thread state, derived from the latest message.
      required: *ref_137
      properties: *ref_138
    contact-inbox-thread.model:
      type: object
      title: Contact Inbox Thread
      description: Inbox thread summary as it appears on a single contact's timeline. A trimmed thread shape — no message history or body preview.
      required: *ref_388
      properties: *ref_389
    contact-status.enum:
      type: string
      title: In-Sequence Status (writable)
      description: |-
        In-sequence status values that can be set via `POST /v3/contacts/set-status-in-sequence` and `POST /v3/sequences/{id}/contacts/set-status-in-sequence`.

        Replied and Bounced are not values of this enum — they are flipped via the dedicated `set-replied` / `set-bounced` endpoints. OptedOut, Called/ToCall, and MeetingBooked are contact-level (not in-sequence) and are flipped via `PATCH /v3/contacts/{id}` (`isOptedOut`, `callStatus`, `meetingStatus`).
      enum: *ref_197
    contact-status.full.enum:
      type: string
      title: In-Sequence Status (full)
      description: All in-sequence status values that can appear in the `statusInSequence` field of `GET /v3/contacts/{id}/statuses` (per-sequence entries). Includes derived values (e.g. `inactive`, `contacted`, `opened`, `clicked`, `autoReplied`) that the API does not allow you to set directly — only the values in `contact-status.enum.yaml` are writable.
      enum: *ref_390
    domain-rule.model:
      type: object
      title: Domain Blacklist Rule
      description: A blacklist rule that blocks a domain pattern
      additionalProperties: false
      properties: *ref_81
    domain-rule-create.request:
      type: object
      title: Create Domain Blacklist Rule Request
      description: Request body for creating a domain blacklist rule
      additionalProperties: false
      required: *ref_82
      properties: *ref_83
    domain-rule-update.request:
      type: object
      title: Update Domain Blacklist Rule Request
      description: Request body for updating a domain blacklist rule
      additionalProperties: false
      required: *ref_391
      properties: *ref_392
    blacklist-rule-create-item-result.model:
      type: object
      title: Create Item Result
      description: Result of a single item in a bulk create operation
      additionalProperties: false
      properties: *ref_87
    blacklist-rule-bulk-delete.request:
      type: object
      title: Bulk Delete Blacklist Rules Request
      description: Request body for bulk deleting blacklist rules
      additionalProperties: false
      required: *ref_88
      properties: *ref_89
    email-rule.model:
      type: object
      title: Email Blacklist Rule
      description: A blacklist rule that blocks an email pattern
      additionalProperties: false
      properties: *ref_84
    email-rule-create.request:
      type: object
      title: Create Email Blacklist Rule Request
      description: Request body for creating an email blacklist rule
      additionalProperties: false
      required: *ref_85
      properties: *ref_86
    email-rule-update.request:
      type: object
      title: Update Email Blacklist Rule Request
      description: Request body for updating an email blacklist rule
      additionalProperties: false
      required: *ref_393
      properties: *ref_394
    email-exception-rule.model:
      type: object
      title: Email Exception Blacklist Rule
      description: An exception rule that allows an email pattern even if it matches a blacklist rule
      additionalProperties: false
      properties: *ref_90
    email-exception-rule-create.request:
      type: object
      title: Create Email Exception Blacklist Rule Request
      description: Request body for creating an email exception blacklist rule
      additionalProperties: false
      required: *ref_91
      properties: *ref_92
    email-exception-rule-update.request:
      type: object
      title: Update Email Exception Blacklist Rule Request
      description: Request body for updating an email exception blacklist rule
      additionalProperties: false
      required: *ref_395
      properties: *ref_396
    contact-list.model:
      type: object
      title: Contact List
      description: Contact list entity
      additionalProperties: false
      properties: *ref_93
    contact-list-create.request:
      type: object
      title: Create Contact List Request
      additionalProperties: false
      required: *ref_397
      properties: *ref_398
    contact-list-update.request:
      type: object
      title: Update Contact List Request
      additionalProperties: false
      required: *ref_399
      properties: *ref_400
    contact-list-ref.model:
      type: object
      title: Contact List Reference
      description: Lightweight contact list reference
      additionalProperties: false
      properties: *ref_401
    custom-field.model:
      type: object
      title: Custom Field
      description: A user-defined field for storing additional data on contacts.
      properties: *ref_94
    custom-field-create.request:
      type: object
      required: *ref_402
      properties: *ref_403
    custom-field-update.request:
      type: object
      required: *ref_404
      properties: *ref_405
    direct-linkedin-action-type.enum:
      type: string
      title: Direct LinkedIn Action Type
      description: The type of LinkedIn direct action performed.
      enum: *ref_406
    direct-linkedin-send.response:
      type: object
      title: Send Direct LinkedIn Response
      description: Response returned after a direct LinkedIn action is dispatched.
      required: *ref_95
      properties: *ref_96
    email-account-list-item.model:
      type: object
      title: EmailAccountListItem
      description: Summary representation of an email account returned in list endpoints.
      properties: *ref_101
      example: *ref_102
    connection.request:
      type: object
      title: EmailAccountConnectionSection
      description: SMTP and IMAP connection settings for a custom email account. Only applicable to Custom provider type.
      properties: *ref_105
      required: *ref_106
    safety.component:
      type: object
      title: EmailAccountSafetySection
      description: Sending safety and throttling configuration.
      properties: *ref_97
    signature.component:
      type: object
      title: EmailAccountSignatureSection
      description: Email signature configuration.
      properties: *ref_98
    opt-out.component:
      type: object
      title: EmailAccountOptOutSection
      description: Opt-out / unsubscribe link configuration.
      properties: *ref_99
    ramp-up.component:
      type: object
      title: EmailAccountRampUpSection
      description: Sending volume ramp-up configuration for warming up email accounts.
      properties: *ref_100
    email-account-create.request:
      type: object
      title: EmailAccountCreateRequest
      description: Request body for creating a new custom email account (SMTP/IMAP).
      properties: *ref_407
      required: *ref_408
      example: *ref_409
    connection.response:
      type: object
      title: EmailAccountConnectionResponseSection
      description: Connection settings returned in responses (passwords excluded).
      properties: *ref_410
    email-account-detail.model:
      type: object
      title: EmailAccountDetail
      description: Full detailed representation of an email account, including all configuration sections.
      properties: *ref_103
      example: *ref_104
    email-account-filter.request:
      type: object
      title: EmailAccountFilterRequest
      description: |-
        Filter criteria for searching email accounts.
        All provided filters are combined with AND logic — an account must match every specified filter to be included.
        Omitted (null) filters are ignored.
      properties: *ref_113
      example: *ref_114
    email-account-update.request:
      type: object
      title: EmailAccountUpdateRequest
      description: |-
        Request body for partially updating an email account (PATCH).
        Only provide the sections and fields you want to change.
        Omitted sections and fields are left unchanged.
      properties: *ref_411
      example: *ref_412
    connectivity-test.request:
      type: object
      title: ConnectivityTestRequest
      description: Request body for testing SMTP or IMAP connectivity.
      properties: *ref_107
      required: *ref_108
      example: *ref_109
    connectivity-test.response:
      type: object
      title: ConnectivityTestResponse
      description: Result of a mail server connectivity test.
      properties: *ref_110
      required: *ref_111
      example: *ref_112
    email-account-stats.model:
      type: object
      required: *ref_115
      properties: *ref_116
      example: *ref_117
    email-account-tag.model:
      type: object
      title: EmailAccountTag
      description: An email account tag used for organizing and filtering accounts.
      properties: *ref_413
      example: *ref_414
    email-template-attachment.model:
      type: object
      title: EmailTemplateAttachment
      description: Attachment associated with an email template.
      properties: *ref_118
      example: *ref_119
    email-template-base.model:
      type: object
      title: EmailTemplateBase
      description: Summary representation of an email template returned in list endpoints.
      properties: *ref_415
      example: *ref_416
    email-template-create.request:
      type: object
      title: EmailTemplateCreateRequest
      description: Request body for creating a new email template.
      properties: *ref_417
      required: *ref_418
      example: *ref_419
    email-template.model:
      type: object
      title: EmailTemplate
      description: Full representation of an email template including timestamps.
      properties: *ref_120
      example: *ref_121
    email-template-update.request:
      type: object
      title: EmailTemplateUpdateRequest
      description: Request body for updating an existing email template.
      properties: *ref_420
      required: *ref_421
      example: *ref_422
    email-template-move.request:
      type: object
      title: MoveEmailTemplateRequest
      description: Request body for moving an email template to a different folder.
      properties: *ref_423
      required: *ref_424
      example: *ref_425
    email-template-render.request:
      type: object
      title: RenderEmailTemplateRequest
      description: Request body for rendering an email template with variable substitution.
      properties: *ref_426
      required: *ref_427
      example: *ref_428
    email-template-render-error.model:
      type: object
      title: RenderError
      description: An error encountered during template rendering.
      properties: *ref_429
      example: *ref_430
    email-template-render-result.model:
      type: object
      title: RenderTemplateResult
      description: Result of rendering an email template with variable substitution.
      properties: *ref_431
      example: *ref_432
    email-template-send-test.request:
      type: object
      title: SendTestEmailRequest
      description: Request body for sending a test email using a template.
      properties: *ref_433
      required: *ref_434
      example: *ref_435
    email-template-variable-info.model:
      type: object
      title: VariableInfo
      description: Information about a single template variable.
      properties: *ref_122
      example: *ref_123
    email-template-variables.model:
      type: object
      title: EmailTemplateVariables
      description: Available template variables grouped by category.
      properties: *ref_436
    email-template-folder.model:
      type: object
      title: EmailTemplateFolder
      description: An email template folder for organizing templates.
      properties: *ref_124
      example: *ref_125
    email-template-folder-create.request:
      type: object
      title: EmailTemplateFolderCreateRequest
      description: Request body for creating a new email template folder.
      properties: *ref_437
      required: *ref_438
      example: *ref_439
    email-template-folder-update.request:
      type: object
      title: EmailTemplateFolderUpdateRequest
      description: Request body for updating an email template folder.
      properties: *ref_440
      required: *ref_441
      example: *ref_442
    email-validation.request:
      type: object
      title: Email Validation Request
      description: Request body shared by both `/estimate` and `/schedule`. Specifies the contacts to validate and an optional partial-credit acceptance flag.
      required: *ref_126
      properties: *ref_127
    email-validation-blocker.component:
      type: integer
      title: Email Validation Blocker
      description: |-
        Blocker codes returned by `/v3/email-validations/estimate` in the `blockers` array. The presence of any blocker (with `acceptPartial = false`) means the request cannot be scheduled.

        | Value | Name | Meaning |
        |---|---|---|
        | 1 | `FeatureDisabled` | Email validation feature is disabled for the team |
        | 2 | `AddonNotPresent` | Required addon is not on the subscription |
        | 3 | `AlreadyRunning` | Another email-validation job is already running for this user |
        | 4 | `OutOfCredits` | User has no email-validation credits available |
        | 5 | `NotEnoughCredits` | Available credits are below the eligible-contact count (and `acceptPartial = false`) |
        | 6 | `NoEligibleContacts` | No accessible contacts in `RequiresValidation` state were found in the request |
      enum: *ref_443
    email-validation-estimate.response.model:
      type: object
      title: Email Validation Estimate
      description: Synchronous probe result returned by `/v3/email-validations/estimate`. Reports counts, credit sufficiency, and a list of blockers that prevent scheduling.
      properties: *ref_444
    email-validation-schedule.response.model:
      type: object
      title: Email Validation Schedule
      description: Acknowledgement returned by `/v3/email-validations/schedule`. The `jobId` corresponds to a background job — poll `/v3/background-jobs/{jobId}` for status and result.
      properties: *ref_445
    holiday-calendar-base.model:
      type: object
      title: HolidayCalendarBase
      description: Summary representation of a holiday calendar returned in list endpoints.
      properties: *ref_446
      example: *ref_447
    holiday-input.model:
      type: object
      title: HolidayInput
      description: A holiday entry for creating or updating a calendar.
      properties: *ref_130
      required: *ref_131
      example: *ref_132
    holiday-calendar-create.request:
      type: object
      title: HolidayCalendarCreateRequest
      description: Request body for creating a new custom holiday calendar.
      properties: *ref_448
      required: *ref_449
      example: *ref_450
    holiday.model:
      type: object
      title: Holiday
      description: A single holiday entry within a calendar.
      properties: *ref_451
      example: *ref_452
    holiday-calendar.model:
      type: object
      title: HolidayCalendar
      description: Full representation of a holiday calendar including individual holidays.
      properties: *ref_128
      example: *ref_129
    holiday-calendar-update.request:
      type: object
      title: HolidayCalendarUpdateRequest
      description: Request body for updating an existing custom holiday calendar.
      properties: *ref_453
      required: *ref_454
      example: *ref_455
    thread-contact.model:
      type: object
      title: Inbox Thread Contact
      description: |-
        Contact party on the other end of an inbox thread.

        Two shapes are possible, distinguished by the `isDeleted` flag:

        - **Live contact** (`isDeleted: false`) — `id` and `ownerId` reference the live contact record; `fullName`, `email`, `linkedInProfileUrl`, `phone`, `companyName`, `title` come from the live record (any may still be `null` if the corresponding field is unset on the contact, e.g. `email` is `null` for a LinkedIn-only contact).
        - **Deleted contact** (`isDeleted: true`) — the underlying contact record has been removed, so `id` and `ownerId` are `null`. The remaining identifying fields (`fullName`, `email`, `linkedInProfileUrl`, `phone`, `companyName`, `title`) are populated from the snapshot stored on the thread when it was created — typically enough for the user to recognise *who* the thread was with even though the contact no longer exists in their workspace.
      required: *ref_141
      properties: *ref_142
    thread-list-item.model:
      type: object
      title: Inbox Thread List Item
      description: Lightweight thread shape returned from list and filter endpoints — omits the message body history in favour of a `bodyPreview`.
      required: *ref_139
      properties: *ref_140
    thread-filter.request:
      type: object
      title: Inbox Thread Filter Request
      description: Filter criteria for `POST /v3/inbox/threads/filter`. All fields are optional — omit a field to skip that filter.
      properties: *ref_456
    thread-message-status.model:
      type: object
      title: Inbox Thread Message Status
      description: Per-message status. Populated for outbound messages that surfaced a delivery error; absent (`null`) on healthy inbound or successfully delivered outbound messages.
      properties: *ref_143
    email.type-2:
      type: object
      title: Inbox Email Message
      description: Email message within an inbox thread.
      required: *ref_457
      properties: *ref_458
    linkedin.type-2:
      type: object
      title: Inbox LinkedIn Message
      description: LinkedIn message within an inbox thread.
      required: *ref_459
      properties: *ref_460
    thread-message.component:
      title: Inbox Thread Message
      description: Polymorphic message variant within an inbox thread, discriminated by `channel`. Email messages carry recipient and subject metadata; LinkedIn messages carry only the shared base fields.
      discriminator: *ref_148
      oneOf: *ref_149
    thread-ai-draft.model:
      type: object
      title: Inbox Thread AI Draft
      description: The thread's pending AI-drafted reply, awaiting review. A thread has at most one active AI draft.
      required: *ref_461
      properties: *ref_462
    thread.model:
      type: object
      title: Inbox Thread
      description: Full inbox thread with the contact, channel-specific account ids, sequence, category, meeting-intent flag, and the ordered list of messages.
      required: *ref_463
      properties: *ref_464
    thread-bulk.request:
      type: object
      title: Inbox Thread Bulk Request
      description: Identifier list for non-atomic bulk thread operations.
      required: *ref_146
      properties: *ref_147
    email.type-3:
      type: object
      title: Inbox Email Message Request
      description: Outbound email reply within an inbox thread.
      required: *ref_465
      properties: *ref_466
    linkedin.type-3:
      type: object
      title: Inbox LinkedIn Message Request
      description: Outbound LinkedIn reply within an inbox thread.
      required: *ref_467
      properties: *ref_468
    thread-send-message.request.component:
      title: Inbox Thread Send-Message Request
      description: Polymorphic outbound message body, discriminated by `channel`. The supplied channel must match the thread's channel; mismatches are rejected with errorCode 8 (ChannelMismatch).
      discriminator: *ref_469
      oneOf: *ref_470
    thread-set-category.request:
      type: object
      title: Inbox Thread Set-Category Request
      description: Assign or clear a category on a thread.
      properties: *ref_471
    thread-set-meeting-intent.request:
      type: object
      title: Inbox Thread Set-Meeting-Intent Request
      description: Toggle the meeting-intent flag on a thread.
      required: *ref_472
      properties: *ref_473
    category.model:
      type: object
      title: Inbox Category
      description: Inbox thread category. Reserved categories are owned by the system and cannot be modified or deleted.
      required: *ref_150
      properties: *ref_151
    category-creation.request:
      type: object
      title: Inbox Category Creation Request
      required: *ref_474
      properties: *ref_475
    category-update.request:
      type: object
      title: Inbox Category Update Request
      description: Full replacement of the category's name and color. Reserved categories reject this operation with 403.
      required: *ref_476
      properties: *ref_477
    linkedin-account-usage.model:
      type: object
      title: LinkedInAccountUsage
      description: Daily usage statistics for a LinkedIn account.
      properties: *ref_478
      example: *ref_479
    linkedin-account-limits-values.model:
      type: object
      title: LinkedInAccountLimitsValues
      description: Individual daily limit values for LinkedIn automation actions.
      properties: *ref_152
      example: *ref_153
    linkedin-account-limits.model:
      type: object
      title: LinkedInAccountLimits
      description: Daily limits configuration for a LinkedIn account.
      properties: *ref_156
      required: *ref_157
      example: *ref_158
    linkedin-account-revoke-settings.model:
      type: object
      title: LinkedInAccountRevokeSettings
      description: Connection revocation settings for a LinkedIn account.
      properties: *ref_480
      required: *ref_481
      example: *ref_482
    linkedin-account-voice-profile.model:
      type: object
      title: LinkedInAccountVoiceProfile
      description: Voice profile associated with a LinkedIn account.
      properties: *ref_483
      example: *ref_484
    linkedin-account.model:
      type: object
      title: LinkedInAccount
      description: Full representation of a LinkedIn account.
      properties: *ref_154
      example: *ref_155
    bulk-delete-linkedin-accounts.request:
      type: object
      title: BulkDeleteLinkedInAccountsRequest
      description: Request body for bulk deleting LinkedIn accounts.
      properties: *ref_485
      required: *ref_486
      example: *ref_487
    linkedin-account-toggle-status.model:
      type: object
      title: LinkedInAccountToggleStatus
      description: Response after toggling a LinkedIn account status.
      properties: *ref_488
      required: *ref_489
      example: *ref_490
    linkedin-account-revoke-settings-update.request:
      type: object
      title: LinkedInAccountRevokeSettingsUpdateRequest
      description: Request body for updating revocation settings on a LinkedIn account.
      properties: *ref_491
      required: *ref_492
      example: *ref_493
    create-connection-link.request:
      type: object
      title: CreateConnectionLinkRequest
      description: Request body for creating a new LinkedIn connection link.
      properties: *ref_494
      required: *ref_495
      example: *ref_496
    connection-link-with-pending.model:
      type: object
      title: ConnectionLinkWithPending
      description: A connection link with the associated pending account ID.
      properties: *ref_497
      example: *ref_498
    connection-link.model:
      type: object
      title: ConnectionLink
      description: A link for connecting a LinkedIn account via browser extension.
      properties: *ref_159
      example: *ref_160
    pending-linkedin-account.model:
      type: object
      title: PendingLinkedInAccount
      description: A LinkedIn account that is pending connection.
      properties: *ref_499
      example: *ref_500
    filters.component-2:
      type: object
      title: Live Data filters
      description: |-
        Account- and contact-level filter configuration for a Live Data search.

        Most collections are capped at 25 items. `accountKeywords` and `contactKeywords` are always present and non-null in responses even when empty (`{ "values": [], "type": "or" }`).
      properties: *ref_167
    preview.request:
      type: object
      title: Live Data preview request
      description: Filters to preview before running a full Live Data search.
      required: *ref_501
      properties: *ref_502
    search-status.enum:
      type: string
      title: Live Data search status
      description: |-
        Lifecycle status of a Live Data search.
        - `inProgress` — actively searching and adding contacts.
        - `finished` — completed; the requested number of contacts was added.
        - `noMoreContacts` — completed; the audience was exhausted before the requested count was reached.
        - `manuallyPaused` — paused by the user.
        - `pausedDueToInsufficientCredits` — paused because the team ran out of credits.
      enum: *ref_503
    search.model:
      type: object
      title: Live Data search
      description: Summary of a Live Data search.
      required: *ref_168
      properties: *ref_169
    start-search.request:
      type: object
      title: Start Live Data search request
      description: Configuration for a Live Data search that adds found contacts as prospects.
      required: *ref_504
      properties: *ref_505
    search-details.model:
      title: Live Data search details
      description: A single Live Data search, including the filters it was run with.
      allOf: *ref_506
    reporting-filters-base.component:
      type: object
      title: Reporting Filters
      description: Base filters shared across all reporting endpoints
      properties: *ref_170
    email-reporting-filters.component:
      allOf: *ref_172
    email-overview-request.component:
      type: object
      title: Email Reporting Overview Request
      description: Request body for email overview reporting with optional comparison period
      required: *ref_507
      properties: *ref_508
    emails-overview-response.model:
      type: object
      title: Emails Overview Response
      description: Email delivery and engagement metrics
      properties: *ref_509
    calls-reporting-filters.component:
      allOf: *ref_173
    calls-overview-response.model:
      type: object
      title: Calls Overview Response
      description: Aggregated call statistics with per-member breakdown
      properties: *ref_510
    tasks-reporting-filters.component:
      allOf: *ref_174
    task-info.component:
      type: object
      title: Task Info
      description: Count and percentage for a specific task type
      properties: *ref_171
    tasks-overview-response.model:
      type: object
      title: Tasks Overview Response
      description: Aggregated task statistics broken down by type, with per-member breakdown
      properties: *ref_511
    linkedin-reporting-filters.component:
      allOf: *ref_175
    linkedin-overview-response.model:
      type: object
      title: LinkedIn Overview Response
      description: LinkedIn engagement metrics overview
      properties: *ref_512
    team-performance-reporting-filters.component:
      allOf: *ref_176
    team-performance-overview-response.model:
      type: object
      title: Team Performance Overview Response
      description: Team performance metrics including meetings, contacts, and engagement rates
      properties: *ref_513
    channel-efficiency-overview-response.model:
      type: object
      title: Channel Efficiency Overview Response
      description: Cross-channel efficiency statistics
      properties: *ref_514
    email-list-item.model:
      type: object
      title: Email List Item
      description: Individual email activity record in a reporting list
      properties: *ref_515
    call-list-item.model:
      type: object
      title: Call List Item
      description: Individual call activity record in a reporting list
      properties: *ref_516
    task-list-item.model:
      type: object
      title: Task List Item
      description: Individual task record in a reporting list
      properties: *ref_517
    linkedin-action-item.model:
      type: object
      title: LinkedIn Action Item
      description: Individual LinkedIn action record in a reporting list
      properties: *ref_518
    meeting-list-item.model:
      type: object
      title: Meeting List Item
      description: Individual meeting record in a team performance reporting list
      properties: *ref_519
    schedule-time.model:
      type: object
      title: ScheduleTime
      description: A time of day represented as hour and minute.
      properties: *ref_177
      required: *ref_178
      example: *ref_179
    schedule-timing-time-range.model:
      type: object
      title: ScheduleTimingTimeRange
      description: A time range within a day.
      properties: *ref_520
      required: *ref_521
      example: *ref_522
    schedule-timing.model:
      type: object
      title: ScheduleTiming
      description: Timing configuration for a single day of the week.
      properties: *ref_180
      required: *ref_181
      example: *ref_182
    schedule.model:
      type: object
      title: Schedule
      description: Full representation of a schedule with timing configuration.
      properties: *ref_183
      example: *ref_184
    schedule-create.request:
      type: object
      title: ScheduleCreateRequest
      description: Request body for creating a new schedule.
      properties: *ref_523
      required: *ref_524
      example: *ref_525
    schedule-update.request:
      type: object
      title: ScheduleUpdateRequest
      description: Request body for updating an existing schedule.
      properties: *ref_526
      required: *ref_527
      example: *ref_528
    holiday-calendar-short.model:
      type: object
      title: HolidayCalendarShort
      description: Brief representation of a holiday calendar linked to a schedule.
      properties: *ref_529
      example: *ref_530
    schedule-holiday-calendar-link.request:
      type: object
      title: ScheduleHolidayCalendarLinkRequest
      description: Request body for linking a holiday calendar to a schedule.
      properties: *ref_531
      required: *ref_532
      example: *ref_533
    sequence-list-item-response.model:
      type: object
      title: Sequence List Model
      description: Response model for listing sequences with pagination
      properties: *ref_200
      example: *ref_201
    sequence-creation.request-2:
      title: Sequence Create
      description: Create a new sequence
      type: object
      required: *ref_534
      properties: *ref_535
      example: *ref_536
    sequence-update.request:
      type: object
      title: Sequence Update Model
      description: |-
        Model for updating an existing sequence.
        All fields are optional — only include the fields you want to change (PATCH semantics).
      properties: *ref_537
    sequence-template-base.model:
      type: object
      title: Sequence Template
      description: A sequence template
      properties: *ref_236
      example: *ref_237
    sequence-stats-filters.component:
      type: object
      description: Date range filters for sequence stats
      properties: *ref_538
    sequence-stats-request.component:
      type: object
      properties: *ref_539
    sequence-email-overview.component:
      type: object
      title: Sequence Email Overview
      description: Email engagement metrics for a sequence
      properties: *ref_193
    sequence-linkedin-overview.component:
      type: object
      title: Sequence LinkedIn Overview
      description: LinkedIn engagement metrics for a sequence
      properties: *ref_194
    sequence-stats-response.model:
      type: object
      title: Sequence Stats Response
      description: Aggregated email and LinkedIn stats for a single sequence
      properties: *ref_540
    sequence-stats-list-filters.component:
      type: object
      description: |-
        Date range filters for sequence stats list.

        **Restrictions:** Date range is limited to one month maximum.
        - `dateRangePreset` must be `lastWeek` or `lastMonth`. `lastYear` and `allTime` are rejected.
        - When using `from`/`to`, the span must not exceed 31 days.
        - `from` must be within the last 31 days from the current date.
      properties: *ref_541
    sequence-stats-list-request.component:
      type: object
      properties: *ref_542
    sequence-stats-list-item-response.model:
      type: object
      title: Sequence Stats List Item Response
      description: Email and LinkedIn stats for a single sequence in the list
      properties: *ref_543
    sequence-contact-item.model:
      type: object
      title: Sequence Contact
      description: A contact enrolled in a sequence with sequence-specific metadata
      properties: *ref_195
      example: *ref_196
    sequence-contact.model:
      type: object
      title: Sequence Contacts List
      description: Response model for listing contacts in a sequence with pagination
      properties: *ref_544
    contact-extended.model:
      type: object
      description: |-
        Contact with optional extended state columns. The base fields (`contactId`, `email`, `firstName`, `lastName`, `title`, `addedAt`) are always returned.
        The fields `currentStep`, `lastStepCompletedAt`, and `status` are **only** included when explicitly requested via the `additionalColumns` query parameter.
      required: *ref_545
      properties: *ref_546
      example: *ref_547
    sequence-contact-state.model:
      type: object
      title: Sequence Contacts List with Extended State
      description: Response model for listing contacts in a sequence with pagination, including extended state columns
      properties: *ref_548
    sequence-email-account.model:
      type: object
      title: SequenceEmailAccount
      description: An email account linked to a sequence for sending outbound emails.
      properties: *ref_549
      example: *ref_550
    sequence-folder.model:
      type: object
      title: Sequence Folder
      description: A folder for organizing sequences
      properties: *ref_198
      example: *ref_199
    sequence-folder-creation.request:
      type: object
      title: Create Sequence Folder
      description: Request body for creating a sequence folder
      properties: *ref_551
      required: *ref_552
      example: *ref_553
    sequence-folder-update.request:
      type: object
      title: Update Sequence Folder
      description: Request body for updating a sequence folder
      properties: *ref_554
      required: *ref_555
      example: *ref_556
    email-variant-update.type:
      type: object
      title: Email Variant (Update)
      description: Individual email variant within an email step for update operations. The `id` field is required to identify which variant to update.
      properties: *ref_557
      required: *ref_558
    email-update.type:
      type: object
      title: Email (Update)
      description: Email step with variant configuration for update operations
      properties: *ref_559
      required: *ref_560
    linkedin-variant-update.type:
      type: object
      title: LinkedIn Variant (Update)
      description: Individual LinkedIn message/connect variant for update operations. The `id` field is required to identify which variant to update.
      properties: *ref_204
      required: *ref_205
    linkedin-message-update.type:
      type: object
      title: LinkedIn Message (Update)
      description: LinkedIn message action step for update operations
      properties: *ref_561
      required: *ref_562
    linkedin-connect-update.type:
      type: object
      title: LinkedIn Connect (Update)
      description: LinkedIn connect action step for update operations
      properties: *ref_563
      required: *ref_564
    linkedin-inmail-variant-update.type:
      type: object
      title: LinkedIn InMail Variant (Update)
      description: Individual LinkedIn InMail variant for update operations. The `id` field is required to identify which variant to update.
      properties: *ref_565
      required: *ref_566
    linkedin-inmail-update.type:
      type: object
      title: LinkedIn InMail (Update)
      description: LinkedIn InMail action step for update operations
      properties: *ref_567
      required: *ref_568
    linkedin-update.type:
      title: LinkedIn (Update)
      description: LinkedIn step with action type sub-discriminator for update operations. Uses type "linkedIn" with a second discriminator actionType to select the specific LinkedIn action. Variants require `id` field for update operations.
      discriminator: *ref_569
      oneOf: *ref_570
    step-update.component:
      title: Sequence Step (Update)
      description: Polymorphic step schema for update operations. Variant `id` is required to identify which variant to update.
      discriminator: *ref_571
      oneOf: *ref_572
    create-item-result.model:
      type: object
      title: CreateItemResult
      description: |-
        Per-item result for non-atomic bulk create operations.
        On success, id is set. On failure, error and errorDetails are set.
        Response array order matches request array order.
      properties: *ref_235
    variant.model:
      type: object
      title: Step Variant
      description: A text variant for a sequence step
      properties: *ref_230
      example: *ref_231
    variant.request:
      type: object
      title: Variant Request
      description: Request body for creating or updating a text variant
      properties: *ref_232
      required: *ref_233
      example: *ref_234
    condition-property.response:
      type: object
      title: ConditionPropertyResponse
      description: |-
        Describes a single contact filter property available for sequence step conditions.
        Each property defines which operators can be used and, for enum-like properties, the allowed values.
      required: *ref_573
      properties: *ref_574
    sequence-templates-list.model:
      type: object
      title: Sequence Templates List
      description: Response model for listing sequence templates grouped by scope
      properties: *ref_575
    account-section.component:
      type: object
      description: User profile settings
      properties: *ref_576
    email-safety-section.component:
      type: object
      description: Email safety and throttling settings
      properties: *ref_577
    email-inbox-section.component:
      type: object
      description: Email inbox settings
      properties: *ref_578
    out-of-office-section.component:
      type: object
      description: Out-of-office detection and handling settings
      properties: *ref_579
    emails-section.component:
      type: object
      description: Email-related settings
      properties: *ref_580
    linkedin-section.component:
      type: object
      description: LinkedIn-related settings
      properties: *ref_581
    call-resolution-item.component:
      type: object
      description: A call resolution option
      required: *ref_582
      properties: *ref_583
    calls-section.component:
      type: object
      description: Call-related settings
      properties: *ref_584
    contact-handling-section.component:
      type: object
      description: Contact handling behavior settings
      properties: *ref_585
    contact-accounts-section.component:
      type: object
      description: Contact account (company) settings
      properties: *ref_586
    contact-stage-item.component:
      type: object
      description: A custom contact stage definition
      required: *ref_587
      properties: *ref_588
    account-stage-item.component:
      type: object
      description: A custom account stage definition
      required: *ref_589
      properties: *ref_590
    contacts-section.component:
      type: object
      description: Contact-related settings
      properties: *ref_591
    beta-section.component:
      type: object
      description: Beta features settings
      properties: *ref_592
    settings.model:
      type: object
      title: Settings
      description: Team and user settings. All properties are nullable — on GET, null means the setting is not configured or not applicable. On PATCH, only properties present in the JSON body are updated.
      properties: *ref_238
    task-contact-summary.component:
      type: object
      title: TaskContactSummary
      description: Minimal contact information embedded in task list responses.
      properties: *ref_593
      required: *ref_594
    task-list-item-response.model:
      type: object
      title: TaskListItemResponse
      description: Summary task item returned in list and filter responses.
      properties: *ref_240
    task-template.component:
      type: object
      title: TaskTemplate
      description: |-
        Task content template. May contain handlebars variables (e.g. `{{firstName}}`) when returned from GET endpoints.
        Variables are resolved when `includeContent=true` is requested.
      properties: *ref_239
    task-create.request:
      type: object
      title: TaskCreateRequest
      description: Request body for creating a new task.
      properties: *ref_595
      required: *ref_596
    task-content.component:
      type: object
      title: TaskContent
      description: |-
        Rendered task content with all variables resolved. Returned only when `includeContent=true` is requested on GET by ID.
        Also used as input for the execute endpoint — the final text to send.
      properties: *ref_242
    task-delivery-info.component:
      type: object
      title: TaskDeliveryInfo
      description: |-
        Delivery target information. Only one field is populated depending on task type.
        For active tasks, sourced from the prospect record. For finished ManualEmail tasks, sourced from the sent email.
      properties: *ref_597
    task-response.model:
      type: object
      title: Task
      description: Full task detail returned by GET by ID, Create, and Update endpoints.
      properties: *ref_241
    task-filter.request:
      type: object
      title: TaskFilterRequest
      description: |-
        Request body for the POST /tasks/filter endpoint.
        All fields are optional — an empty object `{}` returns all tasks visible to the caller.
      properties: *ref_598
    task-update.request:
      type: object
      title: TaskUpdateRequest
      description: Request body for updating a task. Full replacement (PUT), not partial update.
      properties: *ref_599
      required: *ref_600
    task-complete.request:
      type: object
      title: TaskCompleteRequest
      description: |-
        Request body for completing a task without execution.
        All fields are optional — an empty object `{}` is valid.
      properties: *ref_601
    task-execute.request:
      type: object
      title: TaskExecuteRequest
      description: |-
        Request body for executing a task (send email/SMS) and completing it.
        Only ManualEmail (7) and Sms (8) task types support execution.
        All fields are optional — an empty object `{}` uses server-rendered template and default email account.
      properties: *ref_602
    task-bulk-delete.request:
      type: object
      title: TaskBulkDeleteRequest
      description: Request body for bulk deleting tasks.
      properties: *ref_603
      required: *ref_604
    task-batch-assign.request:
      type: object
      title: TaskBatchAssignRequest
      description: Request body for batch reassigning tasks.
      properties: *ref_605
      required: *ref_606
    task-batch-complete.request:
      type: object
      title: TaskBatchCompleteRequest
      description: Request body for batch completing tasks (without execution).
      properties: *ref_607
      required: *ref_608
    webhook-scope.type:
      type: string
      title: WebHookScope
      description: |-
        Scope that determines which users' activity triggers the webhook.

        - `personal` — fires only for activity of the subscription owner.
        - `team` — fires for activity of any member of the owner's team. Creation requires the current user to be the team owner for private teams; anyone can create for public teams.
        - `organization` — reserved for future use. The API currently rejects creation/update with this value (`errorCode: 5`).
      enum: *ref_243
      example: personal
    webhook-payload.component:
      type: object
      title: WebHookPayloadConfig
      description: Optional flags that enrich the delivered webhook payload with extra fields from the originating email/contact.
      properties: *ref_244
      example: *ref_245
    webhook.model:
      type: object
      title: WebHook
      description: |-
        A webhook subscription. The subscription fires a single event type to a configured URL
        when activity matching the subscription's `scope` occurs.
      properties: *ref_246
      example: *ref_247
    webhook-creation.request:
      type: object
      title: WebHookCreationRequest
      description: Request body for creating a webhook subscription.
      properties: *ref_609
      required: *ref_610
      example: *ref_611
    webhook-events.model:
      type: object
      title: WebHookEvents
      description: Catalog of event types that a webhook subscription can subscribe to.
      properties: *ref_612
      example: *ref_613
    webhook-update.request:
      type: object
      title: WebHookUpdateRequest
      description: |-
        Request body for updating a webhook subscription. `PUT` performs a full replacement
        of the mutable fields — every required field listed below must be provided on every
        call. To toggle the paused state use the dedicated
        `POST /v3/webhooks/{id}/enable` / `POST /v3/webhooks/{id}/disable` endpoints — the
        `enabled` flag is not accepted on update.
      properties: *ref_614
      required: *ref_615
      example: *ref_616
    webhook-log.model:
      type: object
      title: WebHookLog
      description: One delivery-attempt record for a webhook subscription.
      properties: *ref_617
      example: *ref_618
  responses:
    too-many-requests: *ref_619
