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

# Upload CSV

> Upload a CSV file to create a table with automatic schema inference.
The size limit per upload is 500MB. Storage limits: 100MB (free), 1GB (analyst), 15GB (plus).

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

<Warning>
  Consider using the [`/create`](./uploads-create) and [`/insert`](./uploads-insert) endpoints if you want more flexibility, performance, and the ability to append.
</Warning>

<Tip>
  You can also upload CSV through the [Dune UI](https://dune.com/) by pressing the "create" dropdown.

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

<Note>
  For working with uploads, keep in mind that:

  * File has to be \< 500 MB
  * Column names in the table can't start with a special character or digits.
  * Consumes credits based on the size of data uploaded.
    * Free, Analyst, Plus: 3 credits per GB written, minimum charge is 1 credit
  * If you upload to an existing table name, it will delete the old data and overwite it with your new data. Appends are only supported for the [`/create`](./uploads-create), [`/insert`](./uploads-insert) endpoints.
  * To delete an upload table, you must go to `user settings (dune.com) -> data -> delete`.

  If you have larger datasets you want to upload, please [contact us here](https://docs.google.com/forms/d/e/1FAIpQLSekx61WzIh-MII18zRj1G98aJeLM7U0VEBqaa6pVk_DQ7lq6Q/viewform)
</Note>

<RequestExample>
  ```bash curl theme={null}
  curl --request POST \
    --url https://api.dune.com/api/v1/uploads/csv \
    --header 'Content-Type: application/json' \
    --header 'X-DUNE-API-KEY: <x-dune-api-key>' \
    --data '{
    "data": "DATE,DGS10,\n2023-12-04,4.28,\n2023-12-05,4.18,\n2023-12-06,4.12,\n2023-12-07,4.14,\n2023-12-08,4.23,\n2023-12-11,4.23",
    "description": "10 year daily interest rates, sourced from https://fred.stlouisfed.org/series/DGS10",
    "table_name": "ten_year_us_interest_rates",
    "is_private": false
  }'
  ```

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

  dune = DuneClient()

  file_path = r'/data/example.csv'
  with open(file_path) as file:
      data = file.read()

  table = dune.upload_csv(
      data=str(data),
      description="10 year daily interest rates, sourced from https://fred.stlouisfed.org/series/DGS10",
      table_name="ten_year_us_interest_rates",
      is_private=False
  )
  ```

  ```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");

  const result = await client.table.uploadCsv({
    table_name: "ten_year_us_interest_rates",
    description: "10 year daily interest rates, sourced from https://fred.stlouisfed.org/series/DGS10",
    data,
    is_private: false,
  });
  ```

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

  url = "https://api.dune.com/api/v1/uploads/csv"

  payload = {
      "data": "DATE,DGS10,\n2023-12-04,4.28,\n2023-12-05,4.18,\n2023-12-06,4.12,\n2023-12-07,4.14,\n2023-12-08,4.23,\n2023-12-11,4.23",
      "description": "10 year daily interest rates, sourced from https://fred.stlouisfed.org/series/DGS10",
      "table_name": "ten_year_us_interest_rates",
      "is_private": False
  }
  headers = {
      "X-DUNE-API-KEY": "<x-dune-api-key>",
      "Content-Type": "application/json"
  }

  response = requests.request("POST", url, json=payload, headers=headers)

  print(response.text)
  ```

  ```javascript Javascript theme={null}
  const options = {
    method: 'POST',
    headers: {'X-DUNE-API-KEY': '<x-dune-api-key>', 'Content-Type': 'application/json'},
    body: '{"data":"DATE,DGS10,\n2023-12-04,4.28,\n2023-12-05,4.18,\n2023-12-06,4.12,\n2023-12-07,4.14,\n2023-12-08,4.23,\n2023-12-11,4.23","description":"10 year daily interest rates, sourced from https://fred.stlouisfed.org/series/DGS10","table_name":"ten_year_us_interest_rates","is_private":false}'
  };

  fetch('https://api.dune.com/api/v1/uploads/csv', options)
    .then(response => response.json())
    .then(response => console.log(response))
    .catch(err => console.error(err));
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"strings"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://api.dune.com/api/v1/uploads/csv"

  	payload := strings.NewReader("{\n  \"data\": \"DATE,DGS10,\\n2023-12-04,4.28,\\n2023-12-05,4.18,\\n2023-12-06,4.12,\\n2023-12-07,4.14,\\n2023-12-08,4.23,\\n2023-12-11,4.23\",\n  \"description\": \"10 year daily interest rates, sourced from https://fred.stlouisfed.org/series/DGS10\",\n  \"table_name\": \"ten_year_us_interest_rates\",\n  \"is_private\": false\n}")

  	req, _ := http.NewRequest("POST", url, payload)

  	req.Header.Add("X-DUNE-API-KEY", "<x-dune-api-key>")
  	req.Header.Add("Content-Type", "application/json")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```php PHP theme={null}
  <?php

  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.dune.com/api/v1/uploads/csv",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "{\n  \"data\": \"DATE,DGS10,\\n2023-12-04,4.28,\\n2023-12-05,4.18,\\n2023-12-06,4.12,\\n2023-12-07,4.14,\\n2023-12-08,4.23,\\n2023-12-11,4.23\",\n  \"description\": \"10 year daily interest rates, sourced from https://fred.stlouisfed.org/series/DGS10\",\n  \"table_name\": \"ten_year_us_interest_rates\",\n  \"is_private\": false\n}",
    CURLOPT_HTTPHEADER => [
      "Content-Type: application/json",
      "X-DUNE-API-KEY: <x-dune-api-key>"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```java Java theme={null}
  HttpResponse<String> response = Unirest.post("https://api.dune.com/api/v1/uploads/csv")
    .header("X-DUNE-API-KEY", "<x-dune-api-key>")
    .header("Content-Type", "application/json")
    .body("{\n  \"data\": \"DATE,DGS10,\\n2023-12-04,4.28,\\n2023-12-05,4.18,\\n2023-12-06,4.12,\\n2023-12-07,4.14,\\n2023-12-08,4.23,\\n2023-12-11,4.23\",\n  \"description\": \"10 year daily interest rates, sourced from https://fred.stlouisfed.org/series/DGS10\",\n  \"table_name\": \"ten_year_us_interest_rates\",\n  \"is_private\": false\n}")
    .asString();
  ```
</RequestExample>

### Upload via google sheet

To automate the upload of a Google Sheet's contents to Dune via API, use the following Google Apps Script:

```javascript theme={null}
function uploadToDune() {
  var apiKey = "YOUR_DUNE_API_KEY"; // Replace with your actual Dune API key, keep the quotes
  var tableName = "example_table"; // Update with your desired table name
  var description = "Example table description";

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var range = sheet.getDataRange();
  var values = range.getValues();

  // Convert data to CSV format
  var csvData = "";
  for (var i = 0; i < values.length; i++) {
    csvData += values[i].join(",") + "\n";
  }

  var payload = {
    data: csvData.trim(),
    description: description,
    table_name: tableName,
    is_private: false
  };

  var options = {
    method: "post",
    contentType: "application/json",
    headers: {
      "X-DUNE-API-KEY": apiKey
    },
    payload: JSON.stringify(payload)
  };

  var response = UrlFetchApp.fetch("https://api.dune.com/api/v1/uploads/csv", options);
  Logger.log(response.getContentText());
}
```

Steps to Use:

1. Open your Google Sheet
2. Navigate to Extensions → Apps Script
3. Replace the script with the code above
4. Save and run uploadToDune
5. (Optional) For easier execution, you can assign this script to a button in your Google Sheet:
   * Click "Insert" in the Google Sheets menu
   * Select "Drawing"
   * Create a button shape and add text like "Upload to Dune"
   * Click "Save and Close"
   * Right-click the button and select "Assign script"
   * Enter "uploadToDune" as the function name
6. Clicking the button will now upload your active sheet's data to Dune!


## OpenAPI

````yaml POST /v1/uploads/csv
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/csv:
    post:
      summary: Upload CSV file as a table
      description: >-
        Upload a CSV file to create a table with automatic schema inference.

        The size limit per upload is 500MB. Storage limits: 100MB (free), 1GB
        (analyst), 15GB (plus).
      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
      requestBody:
        content:
          '*/*':
            schema:
              $ref: '#/components/schemas/models.CSVUploadRequest'
        description: payload
        required: true
        x-originalParamName: payload
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/models.CSVUploadResponse'
          description: OK
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/models.Error400'
          description: Bad Request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/models.Error401'
          description: Unauthorized
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/models.Error500'
          description: Internal Server Error
components:
  schemas:
    models.CSVUploadRequest:
      properties:
        data:
          description: The data to be uploaded in CSV format.
          type: string
        description:
          description: Description of the upload.
          type: string
        is_private:
          description: Indicates if the upload is private.
          type: boolean
        table_name:
          description: The name of the table to store the data.
          type: string
      type: object
    models.CSVUploadResponse:
      properties:
        full_name:
          description: the full name of the table that was created
          example: dune.my_team.dataset_ten_year_us_interest_rates
          type: string
        success:
          description: Indicator if the request was successful
          type: boolean
        table_name:
          description: The name of the table that was created
          example: ten_year_us_interest_rates
          type: string
      type: object
    models.Error400:
      properties:
        error:
          example: Bad Request
          type: string
      type: object
    models.Error401:
      properties:
        error:
          example: Invalid API Key
          type: string
      type: object
    models.Error500:
      properties:
        error:
          example: Internal error
          type: string
      type: object

````