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

# Insert Data

> Inserts data into an existing table. Accepts CSV (text/csv) or
NDJSON (application/x-ndjson) content types.

<Info>
  Minimum required API key scope: `Read/Write`
</Info>

To be able to insert into a table, it must have been created with the [/create endpoint](./uploads-create).

<Note>
  * The data in the files must conform to the schema, and must use the same column names as the schema.
  * One successful `/insert` request consumes credits based on the size of data inserted.
    * Free, Analyst, Plus: 3 credits per GB written, minimum charge is 1 credit
  * The maximum request size is 1.2GB
</Note>

<Tip>
  **Migrating from the old API?** See the [Migration Guide](./migration) for help updating your code.
</Tip>

## Consistency

A request to this endpoint has two possible outcomes: Either all of the data in the request was inserted, or none of it was.
It's not possible for parts of the request data to be inserted, while the rest is not inserted.
In other words, please use and trust the status codes that the endpoint returns.
A status code of 200 means that the data in the request was successfully inserted.
If you get any other status code, you can safely retry your request after addressing the issue that the error message indicated.

## Concurrent requests

A limited number of concurrent insertion requests per table is supported. However, there will be a slight performance penalty as we serialize the writes behind the scenes to ensure data integrity. Larger number of concurrent requests per table may result in an increased number of failures. Therefore, we recommend managing your requests within a 5-10 threshold to maintain optimal performance.

## Supported filetypes

### CSV files (`Content-Type: text/csv`)

CSV files must use a comma as delimiter, and the column names in the header must match the column names of the table.

### JSON files (`Content-Type: application/x-ndjson`)

These are files where each line is a complete JSON object which creates one table row.
Each line must have keys that match the column names of the table.

## Data types

DuneSQL supports a variety of types which are not natively supported in many data exchange formats. Here we provide guidance on how to work with such types.

### Varbinary values

When uploading varbinary data using JSON or CSV formats, you need to convert the binary data into a textual representation. Reason being, JSON or CSV don't natively support binary values. There are many ways to transform binary data to a textual representation. We support **hexadecimal** and **base64** encodings.

#### base64

Base64 is a binary-to-text encoding scheme that transforms binary data into a sequence of characters. All characters are taken from a set of 64 characters.

Example: `{"varbinary_column":"SGVsbG8gd29ybGQK"}`

#### hexadecimal

In the hexadecimal representation input data should contain an even number of characters in the range `[0-9a-fA-F]` always prefixed with `0x`.

Example: `{"varbinary_column":"0x92b7d1031988c7af"}`

<RequestExample>
  ```bash curl theme={null}
  curl --request POST \
    --url https://api.dune.com/api/v1/uploads/my_user/interest_rates/insert \
    --header 'X-DUNE-API-KEY: <x-dune-api-key>' \
    --header 'Content-Type: text/csv' \
    --upload-file interest_rates.csv
  ```

  ```python Python SDK theme={null}
  from dune_client.client import DuneClient

  dune = DuneClient()

  with open("./interest_rates.csv", "rb") as data:
      response = dune.insert_table(
              namespace="my_user",
              table_name="interest_rates",
              data=data,
              content_type="text/csv"
          )
  ```

  ```typescript TS SDK theme={null}
  import * as fs from "fs/promises";
  import { DuneClient, ContentType } from "@duneanalytics/client-sdk";

  client = new DuneClient(process.env.DUNE_API_KEY!);
  const data = await fs.readFile("./sample_table_insert.csv");
  // Or JSON
  // const data: Buffer = await fs.readFile("./sample_table_insert.json");

  const result = await client.table.insert({
    namespace: "my_user",
    table_name: "interest_rates",
    data,
    content_type: ContentType.Csv, // or ContentType.Json
  });
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.dune.com/api/v1/uploads/my_user/interest_rates/insert"

  headers = {
      "X-DUNE-API-KEY": "<x-dune-api-key>",
      "Content-Type": "text/csv"
  }

  with open("./interest_rates.csv", "rb") as data:
    response = requests.request("POST", url, data=data, headers=headers)
  ```

  ```javascript Javascript theme={null}
  const url = "https://api.dune.com/api/v1/uploads/my_user/interest_rates/insert";

  const headers = {
      "X-DUNE-API-KEY": "<x-dune-api-key>",
      "Content-Type": "text/csv"
  };

  fs.readFile('./interest_rates.csv', (err, data) => {
    if (err) {
        console.error(err);
        return;
    }

    fetch(url, {
          method: 'POST',
          headers: headers,
          body: data
      })
      .then(response => response.json())
      .then(response => console.log(response))
      .catch(err => console.error(err));
  });
  ```
</RequestExample>


## OpenAPI

````yaml POST /v1/uploads/{namespace}/{table_name}/insert
openapi: 3.0.1
info:
  contact: {}
  description: Dune API
  title: DuneAPI
  version: '1.0'
servers:
  - url: https://api.dune.com/api
security: []
paths:
  /v1/uploads/{namespace}/{table_name}/insert:
    post:
      summary: Insert data into an uploaded table
      description: |-
        Inserts data into an existing table. Accepts CSV (text/csv) or
        NDJSON (application/x-ndjson) content types.
      parameters:
        - description: API Key for the service
          in: header
          name: X-Dune-Api-Key
          required: true
          schema:
            type: string
        - description: Alternative to using the X-Dune-Api-Key header
          in: query
          name: api_key
          schema:
            type: string
        - description: The namespace of the table
          in: path
          name: namespace
          required: true
          schema:
            type: string
        - description: The table name
          in: path
          name: table_name
          required: true
          schema:
            type: string
        - description: 'Content type: text/csv or application/x-ndjson'
          in: header
          name: Content-Type
          required: true
          schema:
            type: string
      requestBody:
        content:
          '*/*':
            schema:
              type: string
        description: The data to insert (CSV or NDJSON format)
        required: true
        x-originalParamName: data
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/models.TableInsertResponse'
          description: OK
        '400':
          content:
            application/json:
              schema: {}
          description: Bad Request
        '404':
          content:
            application/json:
              schema: {}
          description: Not Found
        '500':
          content:
            application/json:
              schema: {}
          description: Internal Server Error
components:
  schemas:
    models.TableInsertResponse:
      properties:
        bytes_written:
          type: integer
        name:
          type: string
        rows_written:
          type: integer
      type: object

````