Overview
GraphQL mutations allow you to create, update, and delete data in your Supabase database. All mutations respect Row Level Security policies.
GraphQL mutations are currently in beta. The API is functional but may receive updates.
Insert Data
Insert Single Row
Insert a single row into a table:
mutation {
insertIntoCountriesCollection (
objects : [{
name : "Denmark" ,
code : "DK" ,
capital : "Copenhagen"
}]
) {
records {
id
name
code
capital
}
}
}
Response
{
"data" : {
"insertIntoCountriesCollection" : {
"records" : [
{
"id" : 42 ,
"name" : "Denmark" ,
"code" : "DK" ,
"capital" : "Copenhagen"
}
]
}
}
}
Array of inserted records.
Insert Multiple Rows
Insert multiple rows at once:
mutation {
insertIntoCountriesCollection (
objects : [
{ name : "Denmark" , code : "DK" , capital : "Copenhagen" },
{ name : "Norway" , code : "NO" , capital : "Oslo" },
{ name : "Sweden" , code : "SE" , capital : "Stockholm" }
]
) {
records {
id
name
code
}
affectedCount
}
}
Insert with Variables
Use variables for dynamic inserts:
mutation InsertCountry (
$name : String ! ,
$code : String ! ,
$capital : String
) {
insertIntoCountriesCollection (
objects : [{
name : $name ,
code : $code ,
capital : $capital
}]
) {
records {
id
name
}
}
}
Variables:
{
"name" : "Finland" ,
"code" : "FI" ,
"capital" : "Helsinki"
}
Update Data
Update Rows
Update rows matching a filter:
mutation {
updateCountriesCollection (
filter : { code : { eq : "US" } },
set : { name : "United States of America" }
) {
records {
id
name
code
}
affectedCount
}
}
Filter to select rows to update.
Fields to update with new values.
Update Multiple Fields
mutation {
updateCountriesCollection (
filter : { id : { eq : 1 } },
set : {
name : "United States of America" ,
capital : "Washington, D.C." ,
population : 331000000
}
) {
records {
id
name
capital
population
}
}
}
Update with Variables
mutation UpdateCountry (
$id : BigInt ! ,
$name : String !
) {
updateCountriesCollection (
filter : { id : { eq : $id } },
set : { name : $name }
) {
records {
id
name
}
}
}
Variables:
{
"id" : 1 ,
"name" : "USA"
}
Update Multiple Rows
mutation {
updateCountriesCollection (
filter : { population : { lt : 1000000 } },
set : { category : "small" }
) {
affectedCount
}
}
Delete Data
Delete Rows
Delete rows matching a filter:
mutation {
deleteFromCountriesCollection (
filter : { id : { eq : 1 } }
) {
records {
id
name
}
affectedCount
}
}
Filter to select rows to delete.
Always include a filter when deleting to avoid removing all rows.
Delete with Variables
mutation DeleteCountry ( $id : BigInt ! ) {
deleteFromCountriesCollection (
filter : { id : { eq : $id } }
) {
records {
id
name
}
}
}
Variables:
Delete Multiple Rows
mutation {
deleteFromCountriesCollection (
filter : {
code : { in : [ "XX" , "YY" , "ZZ" ] }
}
) {
affectedCount
}
}
Upsert Data
Insert or update based on conflict:
mutation {
insertIntoCountriesCollection (
objects : [{
id : 1 ,
name : "United States of America" ,
code : "US"
}],
onConflict : {
constraint : "countries_pkey" ,
update : [ "name" ]
}
) {
records {
id
name
code
}
}
}
Conflict resolution strategy. Show onConflict properties
The constraint name to check for conflicts.
List of columns to update on conflict.
Batching Mutations
Execute multiple mutations in a single request:
mutation BatchOperations {
insertCountry : insertIntoCountriesCollection (
objects : [{ name : "Denmark" , code : "DK" }]
) {
affectedCount
}
updateCountry : updateCountriesCollection (
filter : { code : { eq : "US" } },
set : { name : "USA" }
) {
affectedCount
}
deleteCountry : deleteFromCountriesCollection (
filter : { code : { eq : "XX" } }
) {
affectedCount
}
}
Relationships
Insert a country with cities:
mutation {
insertIntoCountriesCollection (
objects : [{
name : "Denmark" ,
code : "DK" ,
cities : {
create : [
{ name : "Copenhagen" , population : 794128 },
{ name : "Aarhus" , population : 285273 }
]
}
}]
) {
records {
id
name
citiesCollection {
edges {
node {
name
population
}
}
}
}
}
}
Error Handling
Validation Errors
Handle validation errors in the response:
{
"errors" : [
{
"message" : "null value in column \" name \" violates not-null constraint" ,
"locations" : [{ "line" : 2 , "column" : 3 }],
"path" : [ "insertIntoCountriesCollection" ]
}
]
}
Constraint Violations
{
"errors" : [
{
"message" : "duplicate key value violates unique constraint \" countries_code_key \" " ,
"locations" : [{ "line" : 2 , "column" : 3 }],
"path" : [ "insertIntoCountriesCollection" ]
}
]
}
Transactions
All mutations in a single GraphQL request are executed in a transaction:
mutation TransferBalance (
$senderId : UUID ! ,
$receiverId : UUID ! ,
$amount : Numeric !
) {
debit : updateAccountsCollection (
filter : { id : { eq : $senderId } },
set : { balance : { decrement : $amount } }
) {
affectedCount
}
credit : updateAccountsCollection (
filter : { id : { eq : $receiverId } },
set : { balance : { increment : $amount } }
) {
affectedCount
}
}
If any mutation in the request fails, all mutations are rolled back.
Optimistic Updates
Return updated data immediately:
mutation UpdateCountryPopulation (
$id : BigInt ! ,
$population : BigInt !
) {
updateCountriesCollection (
filter : { id : { eq : $id } },
set : { population : $population }
) {
records {
id
name
population
updatedAt
}
}
}
Row Level Security
Mutations respect RLS policies:
-- Users can only update their own data
CREATE POLICY "Users can update own data"
ON countries
FOR UPDATE
USING ( auth . uid () = user_id)
WITH CHECK ( auth . uid () = user_id);
Best Practices
Always use filters for updates/deletes
Prevent accidental bulk operations by always including specific filters: filter : { id : { eq : $ id } }
Use variables for dynamic values
Never interpolate values into mutation strings - use variables: mutation UpdateUser ( $id : UUID ! , $name : String ! ) { ... }
Always request the updated fields to confirm changes: records { id name updatedAt }
Check for errors in the response and handle them appropriately.
Use transactions for related mutations
Group related mutations in a single request to ensure atomicity.
Next Steps
Queries Learn about querying data
Client Libraries Use GraphQL with client SDKs