> ## 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.

# Dry-run an export against real rows

> Render each row's outgoing payload exactly as a real run would, ask the destination (READ-ONLY) whether the row matches an existing record, and report what a real run would do — create, update or skip.

NOTHING is written. The write half of the executor is unreachable from this path.



## OpenAPI

````yaml /openapi.json post /table-writeback/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: Sender profiles, connected mailboxes, tags, and the Google connect flow.
    name: senders
  - description: The workspace do-not-contact list, enforced before every send.
    name: suppression
  - description: 'Sequence authoring: the graph, the table-backed audience, previews.'
    name: sequences
  - 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 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: 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: >-
      The per-table AI Assistant: named conversations, the column suggestions a
      build turn produces, and the questions an analyze turn answers.
    name: table-assistant
  - 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.
    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 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 and interest signals — plus
      domain-based generation.
    name: ai-context
paths:
  /table-writeback/preview/:
    post:
      tags:
        - table-writeback
      summary: Dry-run an export against real rows
      description: >-
        Render each row's outgoing payload exactly as a real run would, ask the
        destination (READ-ONLY) whether the row matches an existing record, and
        report what a real run would do — create, update or skip.


        NOTHING is written. The write half of the executor is unreachable from
        this path.
      operationId: preview_export
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExportPreviewRequestSchema'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExportPreviewResponseSchema'
          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':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFoundResponse'
          description: Table or integration not found
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnprocessableEntityResponse'
          description: Invalid request made to the API.
        '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:
        - HTTPBearer: []
        - APIKeyHeader: []
components:
  schemas:
    ExportPreviewRequestSchema:
      description: 'A dry run: render an export against real rows, write nothing.'
      properties:
        definition:
          $ref: '#/components/schemas/ExportColumnDefinition-Input'
          description: >-
            The export definition to preview — passed inline so the editor can
            preview BEFORE the column exists.
        record_ids:
          description: The rows to preview; the server caps how many render.
          items:
            format: uuid
            type: string
          maxItems: 25
          minItems: 1
          title: Record Ids
          type: array
        table_id:
          format: uuid
          title: Table Id
          type: string
      required:
        - table_id
        - definition
        - record_ids
      title: ExportPreviewRequestSchema
      type: object
    ExportPreviewResponseSchema:
      description: 'The dry run''s rows. Counters are absent on purpose: nothing ran.'
      properties:
        rows:
          items:
            $ref: '#/components/schemas/ExportPreviewRowSchema'
          title: Rows
          type: array
      required:
        - rows
      title: ExportPreviewResponseSchema
      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
    NotFoundResponse:
      properties:
        detail:
          description: The detail of why the resource was not found.
          title: Detail
          type: string
      required:
        - detail
      title: NotFoundResponse
      type: object
    UnprocessableEntityResponse:
      properties:
        detail:
          description: >-
            The detail of the error. This is the error message to show to the
            user. You should also use the issues field to show more detailed
            error messages per field. Use this field for a single liner error
            message.
          title: Detail
          type: string
        issues:
          description: >-
            The issues that caused the error. There can be multiple issues. Each
            issue is a user-facing error message.
          items:
            $ref: '#/components/schemas/UnprocessableEntityIssue'
          title: Issues
          type: array
      required:
        - detail
        - issues
      title: UnprocessableEntityResponse
      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
    ExportColumnDefinition-Input:
      description: >-
        Definition of an export column: one row pushed to a connected
        destination.


        The cell holds the RECEIPT of that push — status, the destination record

        id, when it happened — never the row's own data (see

        ``TableColumnKind.EXPORT``). The destination integration is named by id

        plus a denormalized ``integration_type``, for the same reason

        ``table_import_integration`` denormalizes it: rendering a column must
        not need a join

        into the integration stratum.
      properties:
        action:
          $ref: '#/components/schemas/ExportWriteAction'
          default: upsert
        batched:
          default: false
          description: >-
            Write rows in destination-sized batches instead of one at a time.
            Faster, at a cost: the destination reports batch-level results, so
            receipts say 'pushed' rather than created-versus-updated, and a
            burst of writes can overwhelm automations attached to the
            destination. Off by default for that reason.
          title: Batched
          type: boolean
        fields:
          description: The destination properties written, in mapping order.
          items:
            $ref: '#/components/schemas/ExportFieldMapping-Input'
          maxItems: 200
          minItems: 1
          title: Fields
          type: array
        identity:
          description: >-
            The destination fields the row may be identified by — the match key
            that decides create-versus-update, required for every action. More
            than one is an ordered FALLBACK, not a composite key: the first
            entry that renders a non-empty value for a row is the one that row
            is matched on, and the rest are not consulted. Order them most to
            least trustworthy ('match on work email, failing that personal
            email'). Matching on two fields at once is not offered because the
            destination contract takes a single identity field.
          items:
            $ref: '#/components/schemas/ExportIdentityMapping-Input'
          maxItems: 4
          title: Identity
          type: array
        integration_id:
          description: The connected DESTINATION integration this column writes to.
          format: uuid
          title: Integration Id
          type: string
        integration_type:
          description: Provider slug, denormalized so display needs no cross-stratum join.
          maxLength: 100
          minLength: 1
          title: Integration Type
          type: string
        kind:
          const: export
          default: export
          title: Kind
          type: string
        only_on_change:
          default: true
          description: >-
            Skip a row whose outgoing payload is identical to the one last
            successfully written. The row-level idempotency knob; off, every run
            re-writes every row.
          title: Only On Change
          type: boolean
        record_type:
          description: >-
            Which destination object to write — 'contacts', 'deals', a custom
            type.
          maxLength: 255
          minLength: 1
          title: Record Type
          type: string
        remove_blanks:
          default: true
          description: >-
            Drop fields whose rendered value is empty from the outgoing payload
            rather than sending a blank. Off, a blank clears the destination
            value — a deliberate act, not a default.
          title: Remove Blanks
          type: boolean
        retry:
          $ref: '#/components/schemas/ExportRetryPolicy'
          description: Retry, timeout and rate-limit behaviour for this column's writes.
        typecast:
          default: true
          description: >-
            Coerce each rendered value into the destination property's declared
            type before writing. Off, values are sent verbatim and the
            destination's own coercion applies.
          title: Typecast
          type: boolean
        update_mode:
          default: patch
          description: >-
            replace overwrites the whole record, patch touches only the mapped
            fields, set_once writes only where the destination is empty.
            Degrades to patch at run time when the destination does not declare
            replace — the same fallback the sync export makes.
          enum:
            - replace
            - patch
            - set_once
          title: Update Mode
          type: string
      required:
        - integration_id
        - integration_type
        - record_type
        - fields
      title: ExportColumnDefinition
      type: object
    ExportPreviewRowSchema:
      description: What a real run WOULD do for one row.
      properties:
        error:
          anyOf:
            - type: string
            - type: 'null'
          description: A per-row resolution failure, if any.
          title: Error
        identity:
          additionalProperties: true
          description: The rendered match values.
          title: Identity
          type: object
        matched_record_id:
          anyOf:
            - type: string
            - type: 'null'
          description: The destination record the row matched, when one exists.
          title: Matched Record Id
        properties:
          additionalProperties: true
          description: The rendered outgoing payload.
          title: Properties
          type: object
        record_id:
          format: uuid
          title: Record Id
          type: string
        skipped_reason:
          anyOf:
            - type: string
            - type: 'null'
          description: Why a row would be skipped.
          title: Skipped Reason
        would:
          description: '''create'', ''update'' or ''skip'' — resolved by read-only matching.'
          title: Would
          type: string
      required:
        - record_id
        - would
        - identity
        - properties
        - matched_record_id
        - skipped_reason
        - error
      title: ExportPreviewRowSchema
      type: object
    UnprocessableEntityIssue:
      properties:
        input:
          anyOf:
            - type: string
            - type: integer
            - type: number
            - type: boolean
            - items: {}
              type: array
            - additionalProperties: true
              type: object
          description: The user's input that caused the error.
          title: Input
        loc:
          description: >-
            The location of the error. Always contains 1 or 2 elements. The
            first element is the type of location (e.g. 'body', 'query', 'path',
            'header'). The second element is the name of the field that caused
            the error. If the error is not related to a specific field, the
            second element is not present.
          items:
            type: string
          title: Loc
          type: array
        msg:
          description: The message of the error. The error message to show to the user.
          title: Msg
          type: string
        type:
          description: >-
            The type of the error. Useful for frontend code to handle different
            types of errors.
          title: Type
          type: string
      required:
        - loc
        - msg
        - type
        - input
      title: UnprocessableEntityIssue
      type: object
    ExportWriteAction:
      description: >-
        What one export cell does at the destination.


        Its own vocabulary, not a copy of the integration stratum's

        ``WriteBehavior``: the members and their values differ, and

        ``table_export_integration`` translates between the two at the seam

        (``_WRITE_BEHAVIOR_TO_EXPORT_ACTION``). Mirroring has no member here

        because it deletes and recreates the whole destination object, which is
        a

        whole-object concern rather than a per-row one.
      enum:
        - create
        - update
        - upsert
      title: ExportWriteAction
      type: string
    ExportFieldMapping-Input:
      description: One destination property and where its value comes from.
      properties:
        destination_field:
          maxLength: 255
          minLength: 1
          title: Destination Field
          type: string
        property_type:
          anyOf:
            - $ref: '#/components/schemas/PropertyType'
            - type: 'null'
          description: >-
            The type this property is CREATED with when it does not exist and
            the destination supports property creation. None means the
            destination already holds it and its type is authoritative.
        skip_if_blank:
          anyOf:
            - type: boolean
            - type: 'null'
          description: >-
            Per-field override of the definition's ``remove_blanks``; None
            inherits it. Set False on one field to send an explicit blank that
            clears a destination value.
          title: Skip If Blank
        source:
          $ref: '#/components/schemas/ExportValueSource-Input'
      required:
        - destination_field
        - source
      title: ExportFieldMapping
      type: object
    ExportIdentityMapping-Input:
      description: |-
        One destination field the row may be IDENTIFIED by.

        Distinct from ``fields`` because identity is not written the way a
        property is: it selects the record for update/upsert, and it is what a
        create-only column matches on to avoid making a second copy. A row whose
        identity renders empty is SKIPPED, never written — an unidentifiable row
        is the case the skip exists for.

        Several of these form an ordered FALLBACK, not a composite key: see
        ``ExportColumnDefinition.identity``.
      properties:
        destination_field:
          maxLength: 255
          minLength: 1
          title: Destination Field
          type: string
        source:
          $ref: '#/components/schemas/ExportValueSource-Input'
      required:
        - destination_field
        - source
      title: ExportIdentityMapping
      type: object
    ExportRetryPolicy:
      description: |-
        One export column's reliability contract with its destination.

        Defaults are chosen so the common case needs no configuration: retry the
        errors worth retrying (rate limits, server errors, network failures) a
        few times, honour the destination's own Retry-After when it names one,
        and otherwise write as fast as the destination accepts.
      properties:
        max_retries:
          default: 3
          description: Retry attempts per row beyond the first, when retrying at all.
          maximum: 10
          minimum: 0
          title: Max Retries
          type: integer
        requests_per_minute:
          anyOf:
            - maximum: 6000
              minimum: 1
              type: integer
            - type: 'null'
          description: >-
            Custom ceiling on write calls per minute. None means the
            destination's own pace — its live rate-limit answers are honoured
            either way.
          title: Requests Per Minute
        retry_on_failure:
          default: true
          description: >-
            Retry a row whose failure is retryable — rate limits, server errors,
            network failures. Bad requests never retry: the same payload would
            fail the same way.
          title: Retry On Failure
          type: boolean
        timeout_seconds:
          anyOf:
            - maximum: 600
              minimum: 1
              type: integer
            - type: 'null'
          description: >-
            Response timeout per destination request. None uses the platform
            default.
          title: Timeout Seconds
      title: ExportRetryPolicy
      type: object
    PropertyType:
      description: Type of a property. Used while creating/updating/deleting properties.
      enum:
        - string
        - integer
        - float
        - boolean
        - datetime
        - date
        - list
        - dict
      title: PropertyType
      type: string
    ExportValueSource-Input:
      description: >-
        The per-row value written into ONE destination field.


        ``template`` reuses the enrichment prompt format verbatim — ordered text

        and column-reference segments, references stored by column identity so a

        rename can never silently repoint a mapping and a delete is detectable.


        PASSTHROUGH RULE: when the template is exactly one whole-cell column

        reference (one segment, no path), the RAW stored cell value is sent, not

        its rendered text — a LIST cell reaches a multi-select property as a
        list

        and a NUMBER cell as a number. Any other shape (text around a reference,

        two references, a path) renders to a string, because concatenation only

        has a string answer.
      properties:
        template:
          $ref: '#/components/schemas/EnrichmentPromptTemplate'
      title: ExportValueSource
      type: object
    EnrichmentPromptTemplate:
      description: >-
        The persisted prompt: an ordered mix of text and column references.


        Resolution to a per-row string happens at run time; the segment list is

        the single source of truth the editor renders pills from and the
        executor

        substitutes values into.
      properties:
        format:
          default: plain
          description: >-
            How the editor reads text segments: 'markdown' renders them as
            markdown source, 'plain' verbatim. Templates saved before the field
            existed carry no value and default to 'plain', the safe reading.
            Purely editor metadata — run-time resolution concatenates text
            segments identically either way.
          enum:
            - plain
            - markdown
          title: Format
          type: string
        segments:
          items:
            discriminator:
              mapping:
                column_ref:
                  $ref: '#/components/schemas/EnrichmentPromptColumnRefSegment'
                text:
                  $ref: '#/components/schemas/EnrichmentPromptTextSegment'
              propertyName: type
            oneOf:
              - $ref: '#/components/schemas/EnrichmentPromptTextSegment'
              - $ref: '#/components/schemas/EnrichmentPromptColumnRefSegment'
          maxItems: 100
          title: Segments
          type: array
      title: EnrichmentPromptTemplate
      type: object
    EnrichmentPromptColumnRefSegment:
      description: |-
        An inline reference to another column's per-row value.

        Stored by column IDENTITY, never by display name — renaming a column can
        never change what a prompt means, and a deleted column is detectable
        rather than silently resolving to nothing.
      properties:
        column_id:
          format: uuid
          title: Column Id
          type: string
        path:
          anyOf:
            - maxLength: 300
              type: string
            - type: 'null'
          description: >-
            Dot-separated address of a sub-value inside a structured cell —
            output field names and zero-based list indices, e.g.
            'competitors.0'. None references the whole cell. Emptiness for the
            required rule is judged on the addressed sub-value.
          title: Path
        required:
          default: true
          description: >-
            Whether a row whose value for this column is empty is skipped
            entirely instead of run with a blank substituted.
          title: Required
          type: boolean
        type:
          const: column_ref
          default: column_ref
          title: Type
          type: string
      required:
        - column_id
      title: EnrichmentPromptColumnRefSegment
      type: object
    EnrichmentPromptTextSegment:
      description: A literal run of prompt text.
      properties:
        text:
          maxLength: 20000
          title: Text
          type: string
        type:
          const: text
          default: text
          title: Type
          type: string
      required:
        - text
      title: EnrichmentPromptTextSegment
      type: object
  securitySchemes:
    HTTPBearer:
      scheme: bearer
      type: http
    APIKeyHeader:
      in: header
      name: X-API-Key
      type: apiKey

````