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

# Append rows

> Append rows to a table. The body is an Arrow IPC stream, or a JSON `{"data": [...]}` envelope. A column the table does not have is added, typed from the rows; a value that disagrees with a column it does have is rejected.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/append/{database}
openapi: 3.1.0
info:
  title: Infino API
  description: >-
    The Infino hosted data-plane API: per-database table operations — create,
    ingest, search, and SQL.
  version: 0.1.0
servers:
  - url: https://api.platform.infino.ws
    description: Infino Cloud
security:
  - api_key: []
tags:
  - name: Databases
    description: Create, list, and delete the databases in your account.
  - name: Tables
    description: Create, drop, and list tables, and describe a table's schema.
  - name: Rows
    description: Append, update, and delete rows.
  - name: Search
    description: BM25, vector, and hybrid search, token and exact match, count, and SQL.
paths:
  /v1/append/{database}:
    post:
      tags:
        - Rows
      summary: Append rows
      description: >-
        Append rows to a table. The body is an Arrow IPC stream, or a JSON
        `{"data": [...]}` envelope. A column the table does not have is added,
        typed from the rows; a value that disagrees with a column it does have
        is rejected.
      operationId: append
      parameters:
        - name: database
          in: path
          description: Target database.
          required: true
          schema:
            type: string
        - name: table
          in: query
          description: Target table.
          required: true
          schema:
            type: string
      requestBody:
        description: >-
          The rows to append: a JSON `{"data": [...]}` envelope of rows keyed by
          column name (`application/json`), or an Arrow IPC stream of one record
          batch (`application/vnd.apache.arrow.stream`).
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RowsEnvelope'
          application/vnd.apache.arrow.stream:
            schema:
              $ref: '#/components/schemas/ArrowIpcRows'
        required: true
      responses:
        '200':
          description: >-
            Rows appended. Body is an Arrow IPC row stream
            (application/vnd.apache.arrow.stream), or a JSON `{"data": [...]}`
            envelope.
        '400':
          description: >-
            Invalid request body, or rows the table refuses. A key the table has
            no column for adds one, typed from the values; a value whose type
            disagrees with a column the table already has is refused, naming the
            column, the type it holds and the one offered. Growing past the
            table's `max_fields` is refused the same way. A column a write adds
            is held to the same two rules a declared one is: its values may
            allocate at most 16384 bytes each even when null (a struct's
            fixed-width children add up, so `Struct{vector(4096), i32}` is 16388
            and refused), and the engine must be able to write its type. Not
            transient: the same body fails identically. Change the value, or
            change the column with a `schema` patch first.
        '401':
          description: Missing or invalid API key.
        '403':
          description: >-
            The account already stores one of its limits — rows, or vectors (one
            per row of a table with a vector column) — so no more can be added.
            Which ceiling applies depends on the account: one with no payment
            method on file is held to the smaller free-plan ceiling, and adding
            a payment method raises it. The response body names which limit was
            reached, the numbers, and whether a payment method would raise it.
            Delete rows to free space; reads and deletes are never refused for
            this reason. Not transient: retrying without freeing space fails
            identically.
        '404':
          description: >-
            The target table does not exist. Append never creates a table —
            create it first with create_table.
        '409':
          description: >-
            Another write to the same table was in flight, so this one was not
            applied. A table takes one write at a time. Transient — reissue the
            identical request after the `Retry-After` interval, or batch more
            rows per request to need fewer of them.
        '503':
          description: >-
            The database's workers are still activating, or no capacity is free
            to place them. Transient — retry after the `Retry-After` interval.
      security:
        - api_key: []
components:
  schemas:
    RowsEnvelope:
      type: object
      description: >-
        JSON row envelope for `POST /v1/append/{database}` and

        `POST /v1/update/{database}` — the `Content-Type: application/json`

        alternative to an Arrow IPC stream body. Rows are JSON objects keyed by

        column name, converted server-side into one Arrow batch against the

        table's schema.


        A key the table has no column for **adds** one, typed from the values in

        the request and nullable, so earlier rows read back null for it. That is

        the table's behaviour and not this encoding's: an Arrow batch carrying a

        column the table lacks adds it on the same terms. What is specific to
        JSON

        is how a row is read — a nested object flattens to dot-path columns, an

        array becomes a list column, and the column's type is inferred from the

        values rather than stated by the caller.


        A value whose type disagrees with a column the table already has is a
        400,

        naming the column, the type it holds and the one offered; the write
        lands

        no rows. Growing past the table's `max_fields` is a 400 too. Neither is

        retryable as sent: change the value, or change the column with a
        `schema`

        patch first. Appending never creates a table — an unknown table name is
        a

        404.
      required:
        - data
      properties:
        data:
          type: array
          items:
            type: object
          description: Rows as JSON objects keyed by column name.
      additionalProperties: false
    ArrowIpcRows:
      type: string
      format: binary
      description: |-
        A raw Arrow IPC stream request body: one record batch of rows, sent as
        `Content-Type: application/vnd.apache.arrow.stream`. The most efficient
        ingest path — no JSON conversion; the batch's schema must match the
        table's.
  securitySchemes:
    api_key:
      type: http
      scheme: bearer

````

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