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

# Preview one step for one contact with the waiting changes

> The step as the contact would get it once the change set is applied, applying nothing and saving nothing. Nothing is written while the changes leave the step's words as they are or the contact keeps the words they have (`changed` false), or when another contact of `candidate_record_ids` is offered in place of one the changes do not reach. A step the agent writes is written again from the changes, spending one of the day's free previews per step written; the words are kept for 30 minutes for this contact and these changes, so another step's Preview and a test send read them and spend nothing.



## OpenAPI

````yaml /openapi.json post /sequences/{sequence_id}/changes/step-preview/
openapi: 3.1.0
info:
  contact:
    email: support@getoneprofile.ai
    name: Oneprofile Support
  description: >-
    REST API reference for Oneprofile, the GTM data layer for your CRM. Manage
    tables, enrichments, and integrations. Authenticate with an API key to get
    started.
  termsOfService: https://www.getoneprofile.ai/terms
  title: API Reference | Oneprofile
  version: '0.0'
servers:
  - url: https://api.getoneprofile.ai
security: []
tags:
  - description: >-
      The docked AI Assistant: its general chat about the workspace and the
      product, streamed as Server-Sent Events, and the one list of a person's
      threads across every assistant, with pin, rename, delete and the
      search-to-table link.
    name: assistant
  - description: >-
      The messages a person keeps to send the assistant again: the ones the
      workspace saved and the ones that ship with the product, with save,
      rename, edit and delete.
    name: assistant-prompt
  - description: >-
      Granted workspace actions: what the AI Assistant proposed or applied in a
      conversation, the approve and dismiss decisions on each card, the
      workspace's approval threshold and default grants, and the eight verbs.
    name: workspace-actions
  - description: >-
      The Getting started checklist: a workspace's progress through the six
      steps from its first people search to its first launched sequence.
    name: onboarding
  - description: Senders, connected mailboxes, tags, and the Google connect flow.
    name: senders
  - description: The workspace do-not-contact list, enforced before every send.
    name: suppression
  - description: >-
      The workspace's recontact rule: how long before anyone hears from us
      again.
    name: contact_cooldown
  - description: 'Sequence authoring: the graph, the table-backed audience, previews.'
    name: sequences
  - description: >-
      The outbound agent behind a sequence: the voice it writes in, its
      per-message prompts, what it wrote and what people told it.
    name: outbound-agents
  - description: >-
      The LinkedIn channel: connecting an account to a sender, its safety limits
      and history, and the protocol the browser extension speaks.
    name: linkedin
  - description: >-
      The approval queue: everything waiting on a person across every sender and
      channel, and the workspace's manual or automatic modes per channel.
    name: outreach
  - description: 'The unified outreach inbox: threads, replies, labels, events.'
    name: inbox
  - description: 'The AI reply layer: workspace settings, drafts, and approval.'
    name: inbox-ai
  - description: Notification rules, per-user preferences, and the Slack connection.
    name: notifications
  - description: Endpoints for seeing all available integration types.
    name: integration-types
  - description: Endpoints for creating and managing integrations.
    name: integrations
  - description: Endpoints for the generic OAuth install/claim app-listings engine.
    name: app-listings
  - description: Endpoints for creating and managing API keys.
    name: apikey
  - description: >-
      AI apps connected to the workspace: Claude, ChatGPT, Claude Code or any
      other MCP client a person signed in to Oneprofile's MCP server with.
    name: ai_apps
  - description: Endpoints for managing billing and subscription information.
    name: billing
  - description: Endpoints for creating and managing tables.
    name: tables
  - description: Endpoints for table columns, formula previews, and on-demand column runs.
    name: table-columns
  - description: Endpoints for table rows and manual cell edits.
    name: table-rows
  - description: Endpoints for observing and cancelling table recompute runs.
    name: table-runs
  - description: >-
      Endpoints for org-shared per-column display preferences: hidden, pinned,
      width, and colour tint.
    name: table-ui-prefs
  - description: >-
      Endpoints for the org-shared names given to the column tint palette: what
      this organisation calls each colour. Org-level, not per-table.
    name: table-column-color-labels
  - description: >-
      Endpoints for the enrichment action catalog, model list, presets, draft
      generation, and saved agents.
    name: table-enrichments
  - description: >-
      Endpoints for teaching a saved agent from example rows: training sessions,
      per-row feedback, and the proposed prompt to approve.
    name: agent-training
  - description: >-
      The durable audit trail of a table's enrichment actions: configured,
      edited, run, cancelled, and settled cost.
    name: table-enrichment-audit-logs
  - description: Endpoints for saving and applying column templates.
    name: table-templates
  - description: Server-sent change feed for a table's grid.
    name: table-events
  - description: 'Endpoints for org-shared saved table views: sort, filters, hidden columns.'
    name: table-views
  - description: >-
      Endpoints for PER-USER table preferences: favourites and recently opened.
      Unlike the rest of the table surface these are personal, so two members of
      one organisation legitimately see different answers.
    name: table-user-prefs
  - description: >-
      Endpoints for building a table from an uploaded CSV: upload and preview
      the inferred columns, commit the reviewed mapping, then poll the row load.
    name: table-imports
  - description: Endpoint for downloading a table's rows as CSV.
    name: table-export
  - description: >-
      Endpoints for the integration a table imports from: attach and preview it,
      promote imported fields into columns, and run the import on demand.
    name: table-sources
  - description: >-
      Endpoints for a table's recurring import cadence: set it, pause it, and
      read the next fire times.
    name: table-schedules
  - description: >-
      Endpoints for pushing a table's rows out to a connected integration: list
      writable destinations, derive their write capabilities, and map export
      columns.
    name: table-writeback
  - description: >-
      Endpoints backing a lookup column's setup: the connections whose records a
      column could read, and the identity fields one record type can be looked
      up by.
    name: table-integration-lookup
  - description: >-
      Endpoints for sourcing leads from the lead database: count and preview
      matches, land them in a table, and keep saved searches. Alongside people
      and company searches, leads can be sourced from buying signals (what a
      company or person just did), with a catalogue endpoint behind the picker
      that builds them.
    name: find-leads
  - description: >-
      Endpoints for discovering a domain's subdomains from public certificate
      logs and landing the results in a table.
    name: find-subdomains
  - description: Endpoints for the credit balance meter and usage reporting.
    name: credits
  - description: >-
      Endpoints for the workspace referral program: the shareable link, the
      friends who joined through it, and claiming a code after signup.
    name: referral
  - description: >-
      Endpoints for the affiliate program's own dashboard: enrolling and
      claiming a code, the summary, stats and activity feed, the commission
      ledger, and identity verification and payouts.
    name: affiliate
  - description: >-
      Endpoints for the design partner program's customer surface: whether this
      workspace is a design partner, the badges its feedback has earned, and
      sending and reading that feedback.
    name: design-partner
  - description: >-
      Endpoints for the org-level AI business context (company description,
      ideal customer profile, buyer personas, interest signals and social
      proof), plus domain-based generation and the reference documents whose
      summaries ride alongside those fields.
    name: ai-context
  - description: >-
      Endpoints for the signed-in user's Google Drive connection: starting and
      finishing the OAuth grant, checking or dropping it, and minting the
      short-lived token the Google Picker needs.
    name: google-drive
paths:
  /sequences/{sequence_id}/changes/step-preview/:
    post:
      tags:
        - sequences
      summary: Preview one step for one contact with the waiting changes
      description: >-
        The step as the contact would get it once the change set is applied,
        applying nothing and saving nothing. Nothing is written while the
        changes leave the step's words as they are or the contact keeps the
        words they have (`changed` false), or when another contact of
        `candidate_record_ids` is offered in place of one the changes do not
        reach. A step the agent writes is written again from the changes,
        spending one of the day's free previews per step written; the words are
        kept for 30 minutes for this contact and these changes, so another
        step's Preview and a test send read them and spend nothing.
      operationId: preview_step_with_changes
      parameters:
        - in: path
          name: sequence_id
          required: true
          schema:
            format: uuid
            title: Sequence Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SequenceChangesStepPreviewSchema'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SequenceChangesStepPreviewReadSchema'
          description: Successful Response
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedResponse'
          description: Unauthorized
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenResponse'
          description: Forbidden
        '404':
          description: The sequence, the step, the contact or a writing setup is gone.
        '409':
          description: The audience is not configured yet.
        '422':
          description: >-
            The changes set an Effort the catalog does not offer (`model_key`),
            or the agent wrote nothing usable with them (`step_id`, error type
            `draft_not_written`).
        '429':
          description: Today's free agent-written previews are spent.
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerErrorResponse'
          description: Internal server error.
        '502':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerErrorResponse'
          description: Bad gateway error.
        '503':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerErrorResponse'
          description: Service unavailable.
      security:
        - APIKeyHeader: []
        - HTTPBearer: []
components:
  schemas:
    SequenceChangesStepPreviewSchema:
      description: One step for one contact, as a person's waiting changes would have it.
      properties:
        candidate_record_ids:
          description: >-
            Contacts the Preview may show instead, in the order it lists them.
            When the changes do not reach `record_id` and one of these they do
            reach, that one is offered as `suggested_record_id` and nothing is
            written.
          items:
            format: uuid
            type: string
          maxItems: 50
          title: Candidate Record Ids
          type: array
        changes:
          $ref: '#/components/schemas/SequenceChangesSchema'
        record_id:
          description: The contact the step is shown for.
          format: uuid
          title: Record Id
          type: string
        step_id:
          format: uuid
          title: Step Id
          type: string
        write:
          default: true
          description: >-
            False answers whether the changes change this step and reach the
            contact, and writes nothing for a step the agent writes: no preview
            is spent. A typed step is filled in either way, which costs nothing.
          title: Write
          type: boolean
      required:
        - changes
        - step_id
        - record_id
      title: SequenceChangesStepPreviewSchema
      type: object
    SequenceChangesStepPreviewReadSchema:
      description: What a step's Preview shows of the waiting changes for one contact.
      properties:
        changed:
          description: >-
            Whether the waiting changes change this step's words for this
            contact. False: the step reads as it does live (the changes touch
            something else, or the contact keeps the words they have: a person's
            own, words a person approved or a send holds, or, for a lesson,
            words already written for them or a thread marked Looks good), and
            nothing was written.
          title: Changed
          type: boolean
        message:
          anyOf:
            - $ref: '#/components/schemas/RenderedMessageReadSchema'
            - type: 'null'
          description: >-
            The step as the contact would get it once the changes are live. A
            step the agent writes is written again from the changes, spending
            one of the day's free previews per step written, and is saved
            nowhere: it names no `message_id`. The words written are kept for 30
            minutes for this contact and these changes, so another step's
            Preview and a test send read them and spend nothing.
        reaches:
          default: true
          description: >-
            Whether the changes reach this contact: false once this step has
            gone to them, when they are past it or down another branch, when
            they are done with the sequence and the changes do not carry them
            on, or when they are not in it.
          title: Reaches
          type: boolean
        sent_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          description: When this step went to the contact, when it has.
          title: Sent At
        suggested_record_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: >-
            A contact of `candidate_record_ids` the changes do reach, offered in
            place of `record_id`, which they do not; `message` is then empty.
          title: Suggested Record Id
      required:
        - changed
      title: SequenceChangesStepPreviewReadSchema
      type: object
    UnauthorizedResponse:
      properties:
        detail:
          description: The detail of why the request is unauthorized.
          title: Detail
          type: string
      required:
        - detail
      title: UnauthorizedResponse
      type: object
    ForbiddenResponse:
      properties:
        detail:
          description: The detail of why the request is forbidden.
          title: Detail
          type: string
      required:
        - detail
      title: ForbiddenResponse
      type: object
    ServerErrorResponse:
      properties:
        detail:
          description: The detail of why the server returned an error.
          title: Detail
          type: string
      required:
        - detail
      title: ServerErrorResponse
      type: object
    SequenceChangesSchema:
      description: >-
        A person's waiting changes to a live sequence, as Review changes holds
        them.
      properties:
        agent:
          anyOf:
            - $ref: '#/components/schemas/OutboundAgentUpdateSchema'
            - type: 'null'
        audience:
          anyOf:
            - $ref: '#/components/schemas/AudiencePutSchema'
            - type: 'null'
        copy_from_sequence_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          title: Copy From Sequence Id
        expected_agent_version:
          anyOf:
            - type: integer
            - type: 'null'
          title: Expected Agent Version
        expected_updated_at:
          format: date-time
          title: Expected Updated At
          type: string
        graph:
          anyOf:
            - $ref: '#/components/schemas/SequenceGraphPutSchema'
            - type: 'null'
        mapping:
          anyOf:
            - $ref: '#/components/schemas/ColumnMappingSchema'
            - type: 'null'
        prompt_proposal:
          anyOf:
            - $ref: '#/components/schemas/OutboundPromptProposalAcceptSchema'
            - type: 'null'
        restore_version:
          anyOf:
            - minimum: 1
              type: integer
            - type: 'null'
          title: Restore Version
        review_token:
          anyOf:
            - maxLength: 255
              type: string
            - type: 'null'
          title: Review Token
        sender_profile_ids:
          anyOf:
            - items:
                format: uuid
                type: string
              maxItems: 100
              type: array
            - type: 'null'
          title: Sender Profile Ids
        settings:
          anyOf:
            - $ref: '#/components/schemas/SequenceUpdateSchema'
            - type: 'null'
        training_revision:
          anyOf:
            - type: integer
            - type: 'null'
          title: Training Revision
        training_rewrite:
          default: false
          title: Training Rewrite
          type: boolean
        training_session_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          title: Training Session Id
        training_slot_keys:
          anyOf:
            - items:
                maxLength: 255
                type: string
              maxItems: 100
              type: array
            - type: 'null'
          title: Training Slot Keys
      required:
        - expected_updated_at
      title: SequenceChangesSchema
      type: object
    RenderedMessageReadSchema:
      properties:
        agent_written:
          default: false
          description: >-
            The agent wrote this for the contact. A preview is one draft; the
            real send is written fresh, unless `approved`.
          title: Agent Written
          type: boolean
        approved:
          default: false
          description: >-
            The words were marked Looks good, with the contact's thread on the
            AI writing tab or as this one email from the Builder, and still
            stand, so they are what sends. They stop standing, and the agent
            writes the step fresh, once the agent's writing or the contact's row
            changes.
          title: Approved
          type: boolean
        body:
          title: Body
          type: string
        in_thread:
          title: In Thread
          type: boolean
        is_sample:
          default: false
          title: Is Sample
          type: boolean
        message_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: >-
            The agent's message these words are, on an agent-written step: the
            sample on screen, or the one marked Looks good. The looks-good route
            takes it back as `message_id`, so a mark lands only on the words
            that were read.
          title: Message Id
        missing_columns:
          items:
            type: string
          title: Missing Columns
          type: array
        pinned:
          default: false
          description: >-
            The words are pinned for this contact by a person (their own edit)
            or by the approval queue, and send exactly as they are. A thread
            marked Looks good is `approved` instead.
          title: Pinned
          type: boolean
        sample_created_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          title: Sample Created At
        sample_version:
          anyOf:
            - type: integer
            - type: 'null'
          title: Sample Version
        sent:
          anyOf:
            - $ref: '#/components/schemas/SentStepEmailReadSchema'
            - type: 'null'
          description: >-
            The email this step already got out to this contact, as it went,
            when one did: what they received, whoever wrote it, rather than the
            words above. Set by the preview route; null when the step has not
            reached them.
        spam_findings:
          description: >-
            The spam check and the placeholder scan, run on the agent's words
            for this contact. Always empty for a written step, whose text the
            composer's own check covers. Advice, never a refusal.
          items:
            $ref: '#/components/schemas/SpamFindingReadSchema'
          title: Spam Findings
          type: array
        subject:
          title: Subject
          type: string
        waiting_for_approval:
          default: false
          description: >-
            This contact's message at this step waits for a person's approval on
            its Tasks card, where its words are changed, approved or rejected.
            Set by the preview route; false once the card is decided, or when
            the step never asked.
          title: Waiting For Approval
          type: boolean
        written:
          default: true
          description: >-
            False only when the preview was asked to write nothing and nothing
            is written for this contact at this step yet: subject and body are
            empty.
          title: Written
          type: boolean
      required:
        - subject
        - body
        - missing_columns
        - in_thread
      title: RenderedMessageReadSchema
      type: object
    OutboundAgentUpdateSchema:
      description: >-
        A change to an agent, sent whole against the version it was read at.


        The configuration travels as one object rather than as fifteen optional

        fields: the AI writing tab reads the agent, edits it and sends it back,
        and

        ``expected_version`` makes two people editing at once a 409 rather than
        a

        silent overwrite.
      properties:
        config:
          anyOf:
            - $ref: '#/components/schemas/OutboundAgentConfig'
            - type: 'null'
          description: >-
            The whole configuration; omitted leaves it as it is. Its `campaign`
            is ignored: the campaign is written by tailoring alone.
        expected_version:
          description: The version the editor was opened at.
          minimum: 1
          title: Expected Version
          type: integer
        model_key:
          anyOf:
            - type: string
            - type: 'null'
          description: 'The model it writes with: swift, core or deep.'
          title: Model Key
        research:
          anyOf:
            - type: boolean
            - type: 'null'
          description: Whether the first message may research the person on the web.
          title: Research
      required:
        - expected_version
      title: OutboundAgentUpdateSchema
      type: object
    AudiencePutSchema:
      properties:
        column_mapping:
          $ref: '#/components/schemas/ColumnMappingSchema'
          description: >-
            Omit it. An empty mapping means the columns are detected from the
            table, which is what the dashboard sends.
        existing_contacts:
          default: keep
          enum:
            - keep
            - restart
          title: Existing Contacts
          type: string
        expected_updated_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          title: Expected Updated At
        pause_if_running:
          default: false
          title: Pause If Running
          type: boolean
        table_id:
          format: uuid
          title: Table Id
          type: string
        view_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: >-
            A saved view narrowing the audience to its rows; null is the whole
            table.
          title: View Id
      required:
        - table_id
      title: AudiencePutSchema
      type: object
    SequenceGraphPutSchema:
      properties:
        edges:
          items:
            $ref: '#/components/schemas/SequenceEdgeSchema'
          maxItems: 1000
          title: Edges
          type: array
        expected_updated_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          description: >-
            Autosave concurrency token; a mismatch means another tab saved first
            (409).
          title: Expected Updated At
        steps:
          items:
            $ref: '#/components/schemas/SequenceStepSchema-Input'
          maxItems: 200
          title: Steps
          type: array
      title: SequenceGraphPutSchema
      type: object
    ColumnMappingSchema:
      description: >-
        Which audience columns carry a meaning, all detected from the table.


        One field per channel (email, LinkedIn) plus the company domain the

        coverage line reports on. Leave the whole object out when binding an

        audience and the columns are detected server-side. Send it only to
        correct

        a detection: a first name, a company or a last-contacted date is no
        longer

        part of this, because every column on the table is already addressable
        as a

        `{{Column name}}` variable.
      properties:
        company_domain_column_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: >-
            The account identity, reported on by the audience coverage counts.
            Unmapped, the coverage count is zero.
          title: Company Domain Column Id
        email_column_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: >-
            Where the send address is read from, and the deduplication key: two
            rows sharing an address are one contact.
          title: Email Column Id
        email_deliverability_column_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: >-
            The column holding each address's deliverability verdict, usually
            the Verify email column over the email column; detected when the
            table has one. Read only while an email column is mapped, and
            dropped without one. An address is emailed only when its verdict is
            one of `email_deliverability_results`; any other verdict skips the
            email step (LinkedIn steps still run), and an address not verified
            yet waits for its verdict. Unmapped, every address is emailed
            unverified.
          title: Email Deliverability Column Id
        email_deliverability_results:
          description: >-
            The verdicts the sequence emails: valid, catch-all, risky, unknown,
            invalid or disposable. Valid alone by default; an empty list reads
            as the default. An answer the column could not give counts as
            unknown.
          items:
            $ref: '#/components/schemas/EmailDeliverability'
          maxItems: 6
          title: Email Deliverability Results
          type: array
        linkedin_url_column_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: Required by LinkedIn steps; a row without one skips them.
          title: Linkedin Url Column Id
      title: ColumnMappingSchema
      type: object
    OutboundPromptProposalAcceptSchema:
      description: Accept a proposal, writing the prompts as the agent's next version.
      properties:
        base_version:
          description: The version the proposal was written against.
          minimum: 1
          title: Base Version
          type: integer
        feedback_cutoff:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          description: The proposal's read time; feedback edited later stays pending.
          title: Feedback Cutoff
        feedback_ids:
          description: The feedback the proposal read, stamped as consumed.
          items:
            format: uuid
            type: string
          title: Feedback Ids
          type: array
        items:
          additionalProperties:
            maxLength: 4000
            type: string
          description: >-
            The accepted prompt per slot key; the reply prompt travels under
            'reply'.
          maxProperties: 50
          propertyNames:
            maxLength: 64
          title: Items
          type: object
      required:
        - base_version
        - items
      title: OutboundPromptProposalAcceptSchema
      type: object
    SequenceUpdateSchema:
      properties:
        bcc_addresses:
          anyOf:
            - items:
                type: string
              maxItems: 5
              type: array
            - type: 'null'
          title: Bcc Addresses
        cc_addresses:
          anyOf:
            - items:
                type: string
              maxItems: 5
              type: array
            - type: 'null'
          title: Cc Addresses
        continuous_enrolment:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Continuous Enrolment
        email_approval_mode:
          anyOf:
            - maxLength: 16
              type: string
            - type: 'null'
          title: Email Approval Mode
        expected_updated_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          description: >-
            The updated_at the client last saw; a stale value is refused with
            409 instead of clobbering a concurrent editor.
          title: Expected Updated At
        linkedin_approval_mode:
          anyOf:
            - maxLength: 16
              type: string
            - type: 'null'
          title: Linkedin Approval Mode
        linkedin_check_max_seconds:
          anyOf:
            - type: integer
            - type: 'null'
          deprecated: true
          description: Retired. Acceptance checks now use the service-managed interval.
          title: Linkedin Check Max Seconds
        linkedin_check_min_seconds:
          anyOf:
            - type: integer
            - type: 'null'
          deprecated: true
          description: Retired. Acceptance checks now use the service-managed interval.
          title: Linkedin Check Min Seconds
        multithreading:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Multithreading
        name:
          anyOf:
            - maxLength: 255
              minLength: 1
              type: string
            - type: 'null'
          title: Name
        opportunity_values:
          anyOf:
            - additionalProperties:
                type: integer
              type: object
            - type: 'null'
          title: Opportunity Values
        opt_out_footer_text:
          anyOf:
            - type: string
            - type: 'null'
          title: Opt Out Footer Text
        plain_text_only:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Plain Text Only
        sending_priority:
          anyOf:
            - maxLength: 16
              type: string
            - type: 'null'
          title: Sending Priority
        sending_window:
          anyOf:
            - $ref: '#/components/schemas/SendingWindowSchema'
            - type: 'null'
          description: >-
            When the sequence may send; replaces the whole window. Null clears
            it, which sends at any hour with automatic spacing. Leave it out to
            keep the one it has.
        spending_limit_tenths:
          anyOf:
            - maximum: 1000000000
              minimum: 0
              type: integer
            - type: 'null'
          title: Spending Limit Tenths
      title: SequenceUpdateSchema
      type: object
    SentStepEmailReadSchema:
      description: The email a step got out to one contact, as it went.
      properties:
        body:
          anyOf:
            - type: string
            - type: 'null'
          title: Body
        sent_at:
          format: date-time
          title: Sent At
          type: string
        subject:
          anyOf:
            - type: string
            - type: 'null'
          title: Subject
      required:
        - subject
        - body
        - sent_at
      title: SentStepEmailReadSchema
      type: object
    SpamFindingReadSchema:
      properties:
        code:
          title: Code
          type: string
        detail:
          description: 'The evidence: "3 in the message. One is safest, two at most."'
          title: Detail
          type: string
        excerpt:
          anyOf:
            - type: string
            - type: 'null'
          title: Excerpt
        excerpts:
          description: Every piece of text the finding is about; excerpt is the first.
          items:
            type: string
          title: Excerpts
          type: array
        message:
          description: Title and detail as one sentence, for a single line.
          title: Message
          type: string
        severity:
          description: warning (likely hurts) or info (worth knowing).
          title: Severity
          type: string
        title:
          description: 'The problem, named: "Too many links".'
          title: Title
          type: string
      required:
        - code
        - severity
        - title
        - detail
        - message
      title: SpamFindingReadSchema
      type: object
    OutboundAgentConfig:
      additionalProperties: false
      description: >-
        The versioned configuration one outbound agent carries, stored as JSON
        on its row.


        Everything a person sets on the Agent tab that is not already a column
        of

        the saved-agent row (``model_key`` and the research switch live there).

        ``message_prompts`` is keyed by an opaque slot key the caller mints (the

        step id); the agent never learns what a slot means.
      properties:
        campaign:
          anyOf:
            - $ref: '#/components/schemas/CampaignBrief'
            - type: 'null'
        cta_label:
          anyOf:
            - maxLength: 200
              type: string
            - type: 'null'
          title: Cta Label
        cta_url:
          anyOf:
            - maxLength: 2000
              type: string
            - type: 'null'
          title: Cta Url
        goal:
          default: ''
          maxLength: 1000
          title: Goal
          type: string
        language:
          default: English
          maxLength: 16
          title: Language
          type: string
        message_prompts:
          additionalProperties:
            maxLength: 4000
            type: string
          maxProperties: 50
          propertyNames:
            maxLength: 64
          title: Message Prompts
          type: object
        person_research:
          default: false
          title: Person Research
          type: boolean
        personality_preset:
          $ref: '#/components/schemas/PersonalityPreset'
          default: direct
        personality_prompt:
          default: ''
          maxLength: 4000
          title: Personality Prompt
          type: string
        reply_drafting:
          default: true
          title: Reply Drafting
          type: boolean
        reply_prompt:
          default: ''
          maxLength: 4000
          title: Reply Prompt
          type: string
        translate:
          default: false
          title: Translate
          type: boolean
        write_from_excluded_column_ids:
          items:
            maxLength: 64
            type: string
          maxItems: 200
          title: Write From Excluded Column Ids
          type: array
      title: OutboundAgentConfig
      type: object
    SequenceEdgeSchema:
      properties:
        branch:
          $ref: '#/components/schemas/SequenceEdgeBranch'
          default: default
          description: >-
            Which way the connection leaves its step. `default` is the one way
            on from an email or a LinkedIn step; a condition leaves by `yes` and
            `no`. A connection request leaves by the answer it gets: `connected`
            (accepted, or connected already) and `not_accepted` (not accepted
            within its window), plus `already_connected` when already-connected
            contacts get a branch of their own; any of them may go to the same
            step. A connection request saved with one `default` connection, or
            none, gets both branches going where it went.
        from_step_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: None = the start node.
          title: From Step Id
        to_step_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: None = an end node.
          title: To Step Id
      title: SequenceEdgeSchema
      type: object
    SequenceStepSchema-Input:
      properties:
        agent_prompt_key:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Read-only: the agent's slot for this step's prompt (the step's id).
            Set by the server on every agent-written step; ignored on write.
          title: Agent Prompt Key
        agent_subject:
          default: false
          description: >-
            On an agent-written email that starts a thread: the agent writes the
            subject line too, and `subject_segments` is ignored. Off, the typed
            subject is sent. Ignored on a reply and on written steps.
          title: Agent Subject
          type: boolean
        authoring:
          $ref: '#/components/schemas/StepAuthoring'
          default: written
          description: >-
            Who writes the words. 'written' sends the subject and body below;
            'agent' has the sequence's outbound agent write them for each
            contact from `prompt`, the contact's row and the workspace's
            business context, priced per contact. An email, a connection note, a
            LinkedIn message or an InMail.
        body_segments:
          items:
            $ref: '#/components/schemas/TemplateSegmentSchema'
          title: Body Segments
          type: array
        condition_kind:
          anyOf:
            - $ref: '#/components/schemas/SequenceConditionKind'
            - type: 'null'
        condition_window_days:
          anyOf:
            - maximum: 90
              minimum: 1
              type: integer
            - type: 'null'
          description: >-
            How many days the step waits for its answer. On a check that waits
            (Replied?, Email bounced?), its window. On a connection request, how
            long it waits for the request to be accepted before the contact goes
            down its `not_accepted` branch: null is saved as 14, and a change
            holds every contact already waiting to the new window.
          title: Condition Window Days
        id:
          format: uuid
          title: Id
          type: string
        kind:
          $ref: '#/components/schemas/SequenceStepKind'
        position:
          default: 0
          minimum: 0
          title: Position
          type: integer
        prompt:
          default: ''
          description: >-
            What the agent is asked to write at this step. Stored on the agent,
            not the step, and saved with the graph: this is the one way to
            change it.
          maxLength: 4000
          title: Prompt
          type: string
        reply_to_step_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: >-
            The earlier email step this email replies to: it goes out under that
            step's send to the contact (Re: its subject, In-Reply-To its
            Message-ID), from the mailbox that sent it. Must be an email step
            that comes before this one on the graph. Null starts a new thread.
            Only on email steps.
          title: Reply To Step Id
        requires_approval:
          default: false
          description: >-
            Hold this step for approval even when its channel would run on its
            own. One-way: true adds an approval, false never removes the one the
            channel's resolved mode already wants.
          title: Requires Approval
          type: boolean
        subject_segments:
          anyOf:
            - items:
                $ref: '#/components/schemas/TemplateSegmentSchema'
              type: array
            - type: 'null'
          description: >-
            The subject of an email that starts a thread. Ignored on a reply
            (`reply_to_step_id`), whose subject is the thread's, and on an email
            whose subject the agent writes (`agent_subject`). An email that
            starts a thread with neither fails preflight until a subject is
            added. A blank subject on an email after another one, with no
            `reply_to_step_id`, is saved as a reply to the nearest earlier
            email, which is what it used to mean.
          title: Subject Segments
        title:
          anyOf:
            - maxLength: 80
              type: string
            - type: 'null'
          description: >-
            What the step is called on its card, in the customer's words: set by
            the library campaign that laid it out, or by whoever saves the
            graph. Null names it by its place in the cadence (Opener, New angle,
            Break-up). Sending the stored title back, or leaving it out, keeps
            it while the step keeps its kind and who writes it; a different
            title renames the step, and an empty one clears the name.
          title: Title
        wait_amount:
          default: 0
          maximum: 365
          minimum: 0
          title: Wait Amount
          type: integer
        wait_unit:
          $ref: '#/components/schemas/SequenceWaitUnit'
          default: days
      required:
        - id
        - kind
      title: SequenceStepSchema
      type: object
    EmailDeliverability:
      description: >-
        The verdicts a Verify email column answers with, in the words its cells
        hold.


        The ``verify_email`` chain respells every supplier's verdict onto
        exactly

        these words (``email_verdict_canonical`` in ``table_enrichments``), so a

        sequence that reads the column compares its cells against them. Ordered

        from the safest to send to, which is the order the Audience tab lists
        them.
      enum:
        - valid
        - catch-all
        - risky
        - unknown
        - invalid
        - disposable
      title: EmailDeliverability
      type: string
    SendingWindowSchema:
      additionalProperties: false
      description: |-
        When a sequence may send, as the send engine reads it.

        Without ``days`` it sends at any hour of any day, which is the settings
        page's Send any time: it keeps its timezone and its minimum gap between
        emails. Every rule here is checked on save, running or not, and a window
        that breaks one is refused with a 422 naming the part at fault.
      properties:
        days:
          anyOf:
            - $ref: '#/components/schemas/SendingDaysSchema'
            - type: 'null'
          description: >-
            The days it may send on, each with its hours. Leave it out to send
            at any hour; given, at least one day must be open.
        min_interval_minutes:
          anyOf:
            - type: integer
            - type: 'null'
          description: >-
            The shortest gap between two emails from one mailbox, a whole number
            from 0 to 240 minutes. Null or 0 spaces them automatically from each
            mailbox's daily capacity.
          maximum: 240
          minimum: 0
          title: Min Interval Minutes
        sender_timezone:
          anyOf:
            - type: boolean
            - type: 'null'
          description: >-
            Whether the hours are read in each sender's own timezone, so a New
            York sender and a London one each send 9 to 5 their time. False
            reads them in `timezone` for everyone. Absent or null means each
            sender's; an update that leaves it out keeps what is stored.
          title: Sender Timezone
        timezone:
          anyOf:
            - maxLength: 64
              minLength: 1
              type: string
            - type: 'null'
          description: >-
            The IANA timezone the hours are read in, such as Europe/Berlin: the
            one timezone when `sender_timezone` is false, else the fallback for
            a sender with none. UTC when absent.
          title: Timezone
      title: SendingWindowSchema
      type: object
    CampaignBrief:
      additionalProperties: false
      description: |-
        What one sequence's campaign is: the tested campaign it runs and why.

        Written by tailoring and by nothing else; the Agent tab reads it and
        never sends it back (the service keeps the stored one on every other
        write). Tailoring now rewrites the steps' instructions themselves and
        writes only ``reason`` and ``goal`` here. ``audience``, ``why_now``,
        ``angle`` and ``step_notes`` are what it wrote before: kept, and still
        read by the writer, for the agents that carry them. They were written by
        a model from the audience table, so they are background, never facts:
        only ``intent``, the person's own words, may be stated as fact.
      properties:
        angle:
          default: ''
          maxLength: 300
          title: Angle
          type: string
        audience:
          default: ''
          maxLength: 300
          title: Audience
          type: string
        campaign_key:
          maxLength: 64
          title: Campaign Key
          type: string
        chosen_by_person:
          default: false
          title: Chosen By Person
          type: boolean
        goal:
          default: ''
          maxLength: 1000
          title: Goal
          type: string
        intent:
          default: ''
          maxLength: 500
          title: Intent
          type: string
        minted:
          items:
            maxLength: 64
            type: string
          maxItems: 50
          title: Minted
          type: array
        reason:
          default: ''
          maxLength: 300
          title: Reason
          type: string
        step_notes:
          additionalProperties:
            maxLength: 300
            type: string
          maxProperties: 50
          propertyNames:
            maxLength: 64
          title: Step Notes
          type: object
        table_name:
          default: ''
          maxLength: 255
          title: Table Name
          type: string
        tailoring_off:
          default: false
          title: Tailoring Off
          type: boolean
        why_now:
          anyOf:
            - maxLength: 300
              type: string
            - type: 'null'
          title: Why Now
      required:
        - campaign_key
      title: CampaignBrief
      type: object
    PersonalityPreset:
      description: >-
        The voice an agent writes in. Each preset is a real prompt; CUSTOM is
        the author's.
      enum:
        - direct
        - consultative
        - bold
        - custom
      title: PersonalityPreset
      type: string
    SequenceEdgeBranch:
      description: >-
        Which way an edge leaves its step.


        DEFAULT for message-step flow; YES/NO for a condition's two branches. A

        connection request leaves by the answer it got: CONNECTED (accepted, and

        already connected unless that has a branch of its own),
        ALREADY_CONNECTED

        (present only when the request splits it out) and NOT_ACCEPTED.
      enum:
        - default
        - 'yes'
        - 'no'
        - connected
        - already_connected
        - not_accepted
      title: SequenceEdgeBranch
      type: string
    StepAuthoring:
      description: >-
        Who writes an email step's words.


        WRITTEN is the default and what every step was before: the author's own

        subject and body, with variables, snippets and spintax resolved per

        contact. AGENT holds an instruction instead of a body; the whole email
        is

        written for each contact at send time from that instruction, the row and

        the workspace's written business context, and priced per contact.
      enum:
        - written
        - agent
      title: StepAuthoring
      type: string
    TemplateSegmentSchema:
      properties:
        builtin:
          anyOf:
            - $ref: '#/components/schemas/BuiltinVariable'
            - type: 'null'
        column_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          title: Column Id
        kind:
          $ref: '#/components/schemas/SegmentKind'
        options:
          description: Spintax alternatives; one is chosen per contact.
          items:
            type: string
          maxItems: 20
          title: Options
          type: array
        required:
          default: true
          title: Required
          type: boolean
        text:
          default: ''
          title: Text
          type: string
      required:
        - kind
      title: TemplateSegmentSchema
      type: object
    SequenceConditionKind:
      description: >-
        The branching conditions.


        ``BOUNCED`` and ``REPLIED`` are only pickable after a message step
        exists

        earlier on the same path: enforced at save, explained in the picker.
      enum:
        - has_email
        - has_linkedin_url
        - linkedin_connected
        - bounced
        - replied
        - linkedin_invite_accepted
        - linkedin_open_profile
      title: SequenceConditionKind
      type: string
    SequenceStepKind:
      description: >-
        What a graph node does.


        The LINKEDIN_* kinds do not send anything themselves. They enqueue
        browser

        work and park the contact until it runs, because the action happens in
        the

        customer's own browser and that browser may be closed.


        Every kind here is something the product can carry out end to end. There
        is

        deliberately no phone-call or text-message kind: the engine cannot dial
        or

        text, and a step it can only hand to a person to do elsewhere is a to-do

        list wearing a sequence's clothes, not a channel this product supports.
      enum:
        - message
        - condition
        - linkedin_profile_view
        - linkedin_connection_request
        - linkedin_message
        - linkedin_inmail
        - linkedin_withdraw_invitation
        - linkedin_follow
        - linkedin_like_post
      title: SequenceStepKind
      type: string
    SequenceWaitUnit:
      enum:
        - days
        - hours
      title: SequenceWaitUnit
      type: string
    SendingDaysSchema:
      additionalProperties: false
      description: The days a sequence may send on. A day left out, or null, is closed.
      properties:
        fri:
          anyOf:
            - $ref: '#/components/schemas/SendingHoursSchema'
            - type: 'null'
        mon:
          anyOf:
            - $ref: '#/components/schemas/SendingHoursSchema'
            - type: 'null'
        sat:
          anyOf:
            - $ref: '#/components/schemas/SendingHoursSchema'
            - type: 'null'
        sun:
          anyOf:
            - $ref: '#/components/schemas/SendingHoursSchema'
            - type: 'null'
        thu:
          anyOf:
            - $ref: '#/components/schemas/SendingHoursSchema'
            - type: 'null'
        tue:
          anyOf:
            - $ref: '#/components/schemas/SendingHoursSchema'
            - type: 'null'
        wed:
          anyOf:
            - $ref: '#/components/schemas/SendingHoursSchema'
            - type: 'null'
      title: SendingDaysSchema
      type: object
    BuiltinVariable:
      description: |-
        Non-column variables the composer offers.

        Weekday variables render the *name* of the day ("Thursday") so a cadence
        can reference real days without weekly rewrites.
      enum:
        - sender_first_name
        - sender_full_name
        - sender_title
        - sender_booking_link
        - sending_domain
        - sequence_name
        - greeting
        - today
        - yesterday
        - tomorrow
        - day_plus_2
        - day_plus_3
        - day_plus_4
      title: BuiltinVariable
      type: string
    SegmentKind:
      description: One piece of a subject or body template.
      enum:
        - text
        - column
        - builtin
        - spintax
      title: SegmentKind
      type: string
    SendingHoursSchema:
      additionalProperties: false
      description: One open day's sending hours, read on the window's timezone.
      properties:
        end:
          description: >-
            When it closes, as HH:MM, after start on the same day. Hours cannot
            run past midnight, so 23:59 is the latest close.
          maxLength: 16
          minLength: 1
          title: End
          type: string
        start:
          description: When sending opens, as HH:MM on a 24-hour clock, such as 09:00.
          maxLength: 16
          minLength: 1
          title: Start
          type: string
      required:
        - start
        - end
      title: SendingHoursSchema
      type: object
  securitySchemes:
    APIKeyHeader:
      in: header
      name: X-API-Key
      type: apiKey
    HTTPBearer:
      scheme: bearer
      type: http

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.