---
id: insert
title: "Create data: insert()"
slug: insert
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml
---

import Tabs from '@theme/Tabs';
import TabsPanel from '@theme/TabsPanel';

Performs an INSERT into the table.

<Tabs
  defaultActiveId="js"
  groupId="reference/supabase-js"
  values={[{ label: 'JavaScript', value: 'js' }]}>

<TabsPanel id="js" label="js">

```js
const { data, error } = await supabase
  .from('cities')
  .insert([
    { name: 'The Shire', country_id: 554 }
  ])
```


</TabsPanel>

</Tabs>

## Parameters


<ul className="method-list-group">
  
<li className="method-list-item">
  <h4 className="method-list-item-label">
    <span className="method-list-item-label-name">
      values
    </span>
    <span className="method-list-item-label-badge required">
      required
    </span>
    <span className="method-list-item-validation">
      <code>Partial</code> | <code>array</code>
    </span>
  </h4>
  <div class="method-list-item-description">

The values to insert.

  </div>
  
</li>


<li className="method-list-item">
  <h4 className="method-list-item-label">
    <span className="method-list-item-label-name">
      options
    </span>
    <span className="method-list-item-label-badge false">
      optional
    </span>
    <span className="method-list-item-validation">
      <code>undefined</code> | <code>reflection</code>
    </span>
  </h4>
  <div class="method-list-item-description">

No description provided. 

  </div>
  
</li>

</ul>


## Notes

- By default, every time you run `insert()`, the client library will make a `select` to return the full record.
This is convenient, but it can also cause problems if your Policies are not configured to allow the `select` operation. 
If you are using Row Level Security and you are encountering problems, try setting the `returning` param to `minimal`.










## Examples

### Create a record



<Tabs
  defaultActiveId="js"
  groupId="reference/supabase-js"
  values={[{ label: 'JavaScript', value: 'js' }]}>

<TabsPanel id="js" label="js">

```js
const { data, error } = await supabase
  .from('cities')
  .insert([
    { name: 'The Shire', country_id: 554 }
  ])
```


</TabsPanel>

</Tabs>

### Bulk create



<Tabs
  defaultActiveId="js"
  groupId="reference/supabase-js"
  values={[{ label: 'JavaScript', value: 'js' }]}>

<TabsPanel id="js" label="js">

```js
const { data, error } = await supabase
  .from('cities')
  .insert([
    { name: 'The Shire', country_id: 554 },
    { name: 'Rohan', country_id: 555 },
  ])
```


</TabsPanel>

</Tabs>

### Upsert

For upsert, if set to true, primary key columns would need to be included 
in the data parameter in order for an update to properly happen. Also, primary keys 
used must be natural, not surrogate. There are however, 
[workarounds](https://github.com/PostgREST/postgrest/issues/1118) 
for surrogate primary keys.


<Tabs
  defaultActiveId="js"
  groupId="reference/supabase-js"
  values={[{ label: 'JavaScript', value: 'js' }]}>

<TabsPanel id="js" label="js">

```js
const { data, error } = await supabase
  .from('cities')
  .insert(
    [
      { name: 'The Shire', country_id: 554 },
      { name: 'Rohan', country_id: 555 },
      { name: 'City by the Bay', country_id:840}
    ],
    { upsert: true })
```


</TabsPanel>

</Tabs>