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

# Upsert rows into a table

> Insert-or-update rows keyed on their business columns. Each row's stable primary key (s_id) is derived from the key columns, so rows whose key already exists are updated in place and new keys are inserted — sending the same entity again is idempotent. `key_columns` is optional: omit it to use the table's own declared business keys (the usual case), or pass it to override — an override must match the declared keys exactly unless the rows leave the declared key columns out entirely. Returns 200 when all succeed, 207 when some fail (see errors), and 422 when none do. Requires the tables:append scope.



## OpenAPI

````yaml https://api.summation.com/openapi.json put /v1/tables/{table_id}/rows
openapi: 3.1.0
info:
  title: summation-api public API
  version: 0.1.0
servers: []
security: []
tags:
  - name: Auth
    description: Machine authentication for API clients.
  - name: Tenant
    description: Organization and tenant context resolved by summation-api.
  - name: Projects
    description: Project resources.
  - name: Conversations
    description: Conversation and message resources.
  - name: Reports
    description: Report resources and report operations.
  - name: Runs
    description: Project run history and execution status.
  - name: Playbooks
    description: Playbook resources.
  - name: Files
    description: Project file resources.
  - name: Catalog Entries
    description: Project-scoped data asset attachments.
  - name: Data Connectors
    description: Reusable external data source connections.
  - name: App Connectors
    description: External app connectors whose tools the agent can use during chat.
  - name: Tables
    description: Canonical table metadata and catalog.
  - name: Views
    description: Canonical Summation view metadata and catalog.
  - name: Query Executions
    description: Read-only SQL query execution.
  - name: Grid
    description: Materialized grid status, sync, and lineage.
  - name: Schedules
    description: Schedule and schedule run inspection.
paths:
  /v1/tables/{table_id}/rows:
    put:
      tags:
        - Tables
      summary: Upsert rows into a table
      description: >-
        Insert-or-update rows keyed on their business columns. Each row's stable
        primary key (s_id) is derived from the key columns, so rows whose key
        already exists are updated in place and new keys are inserted — sending
        the same entity again is idempotent. `key_columns` is optional: omit it
        to use the table's own declared business keys (the usual case), or pass
        it to override — an override must match the declared keys exactly unless
        the rows leave the declared key columns out entirely. Returns 200 when
        all succeed, 207 when some fail (see errors), and 422 when none do.
        Requires the tables:append scope.
      operationId: upsert_table_rows
      parameters:
        - name: table_id
          in: path
          required: true
          schema:
            type: string
            title: Table Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TableUpsertRowsRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '207':
          description: Some rows upserted; response includes errors for failed rows.
        '400':
          description: Invalid request or unsupported option.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemError'
        '401':
          description: Missing, invalid, or expired credentials.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemError'
        '403':
          description: Authenticated but missing the required scope.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemError'
        '404':
          description: Resource not found or not accessible.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemError'
        '422':
          description: No rows upserted; response includes row-level errors.
        '429':
          description: Rate limit exceeded.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemError'
        '500':
          description: Internal server error.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemError'
      security:
        - SummationMachineAuth:
            - tables:append
components:
  schemas:
    TableUpsertRowsRequest:
      properties:
        rows:
          items:
            additionalProperties:
              anyOf:
                - type: string
                - type: integer
                - type: number
                - type: boolean
                - type: 'null'
            type: object
          type: array
          maxItems: 500
          minItems: 1
          title: Rows
          description: >-
            Rows to upsert, 1 to 500 per request. Each row is an object of
            column_name to scalar value; values are coerced to their column type
            by the table's schema. Every row must carry the same column names.
            Do NOT include the primary key (s_id) — it is derived from
            key_columns.
        key_columns:
          anyOf:
            - items:
                type: string
              type: array
              minItems: 1
            - type: 'null'
          title: Key Columns
          description: >-
            Business-key column names that identify a row. The stable primary
            key (s_id) is derived deterministically from just these columns, so
            the same entity always maps to the same row: re-sending it updates
            in place. Each must be present and non-empty in every row. Omit to
            use the table's own declared business keys — the usual case, so a
            caller need not restate keys the table already defines. If provided,
            must not be empty, and must match the table's declared key columns
            exactly whenever the rows carry any of them: the declared keys are
            the row identity the backend enforces, so no other identity can
            upsert them idempotently.
      additionalProperties: false
      type: object
      required:
        - rows
      title: TableUpsertRowsRequest
      description: >-
        Upsert rows keyed on their business columns.


        The primary key (s_id) is derived server-side from key_columns, so rows
        must

        NOT carry s_id; re-sending the same entity updates it in place rather
        than

        duplicating. Inherits the same per-row validation as append.
    ProblemError:
      description: >-
        Public error envelope (RFC 7807 ``application/problem+json``).


        Mirrors the body produced by :func:`api_error`. Declaring it in the
        contract

        lets generated clients type error handling instead of guessing.
      properties:
        type:
          description: URI reference identifying the problem type.
          title: Type
          type: string
        title:
          description: Short, human-readable summary of the problem type.
          title: Title
          type: string
        status:
          description: HTTP status code.
          title: Status
          type: integer
        detail:
          description: Human-readable explanation specific to this occurrence.
          title: Detail
          type: string
        code:
          description: Stable, machine-readable error code.
          title: Code
          type: string
        request_id:
          description: Correlation id, echoed in the x-request-id header.
          title: Request Id
          type: string
      required:
        - type
        - title
        - status
        - detail
        - code
        - request_id
      title: ProblemError
      type: object
  securitySchemes:
    SummationMachineAuth:
      type: oauth2
      flows:
        clientCredentials:
          scopes:
            agent:read: agent:read
            agent:write: agent:write
          tokenUrl: /v1/auth/m2m/token

````