Documentation Index Fetch the complete documentation index at: https://mintlify.com/directus/directus/llms.txt
Use this file to discover all available pages before exploring further.
Introduction
Mutations in Directus GraphQL allow you to modify data in your collections. Each collection automatically gets mutation operations for creating, updating, and deleting items.
Mutations must be sent via POST requests. Attempting to send mutations via GET will result in an error.
Mutation Types
For each non-singleton collection, Directus generates the following mutations:
create_<collection>_item - Create a single item
create_<collection>_items - Create multiple items
update_<collection>_item - Update a single item by ID
update_<collection>_items - Update multiple items by IDs
update_<collection>_batch - Update multiple items with different data
delete_<collection>_item - Delete a single item by ID
delete_<collection>_items - Delete multiple items by IDs
For singleton collections:
update_<collection> - Upsert the singleton item
Read-only system collections like directus_activity and directus_revisions don’t have mutation operations.
Create Operations
Create Single Item
Create a single item and return specified fields:
mutation {
create_articles_item (
data : {
title : "Getting Started with GraphQL"
content : "GraphQL is a powerful query language..."
status : "draft"
}
) {
id
title
status
created_at
}
}
Create Multiple Items
Create multiple items in a single mutation:
mutation {
create_articles_items (
data : [
{
title : "First Article"
status : "published"
}
{
title : "Second Article"
status : "draft"
}
]
) {
id
title
status
}
}
Create with Relationships
Create an item with related items:
mutation {
create_articles_item (
data : {
title : "Article with Categories"
status : "published"
categories : {
create : [
{ categories_id : { name : "Technology" } }
{ categories_id : { name : "Tutorial" } }
]
}
}
) {
id
title
categories {
categories_id {
id
name
}
}
}
}
Create with Existing Relations
Link to existing related items:
mutation {
create_articles_item (
data : {
title : "New Article"
author : "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
categories : {
create : [
{ categories_id : 1 }
{ categories_id : 2 }
]
}
}
) {
id
title
author {
id
name
}
}
}
Update Operations
Update Single Item
Update a single item by its ID:
mutation {
update_articles_item (
id : "123"
data : {
title : "Updated Title"
status : "published"
}
) {
id
title
status
updated_at
}
}
Update Multiple Items
Update multiple items with the same data:
mutation {
update_articles_items (
ids : [ "123" , "456" , "789" ]
data : {
status : "archived"
}
) {
id
title
status
}
}
Batch Update
Update multiple items with different data for each:
mutation {
update_articles_batch (
data : [
{
id : "123"
title : "First Updated Title"
}
{
id : "456"
title : "Second Updated Title"
}
]
) {
id
title
updated_at
}
}
Update Singleton
For singleton collections, use the upsert operation:
mutation {
update_settings (
data : {
site_name : "My Awesome Site"
maintenance_mode : false
}
) {
site_name
maintenance_mode
updated_at
}
}
Update Relationships
Update related items:
mutation {
update_articles_item (
id : "123"
data : {
categories : {
create : [{ categories_id : 3 }]
update : [{ id : 1 , categories_id : { name : "Updated Category" } }]
delete : [ 2 ]
}
}
) {
id
title
categories {
id
categories_id {
id
name
}
}
}
}
Delete Operations
Delete Single Item
Delete a single item by its ID:
mutation {
delete_articles_item ( id : "123" ) {
id
}
}
Delete Multiple Items
Delete multiple items by their IDs:
mutation {
delete_articles_items ( ids : [ "123" , "456" , "789" ]) {
ids
}
}
Delete operations are permanent and cannot be undone. Consider implementing a “soft delete” pattern with a status field instead.
Using Variables
Make mutations reusable and secure with variables:
mutation CreateArticle (
$title : String !
$content : String !
$status : String
) {
create_articles_item (
data : {
title : $title
content : $content
status : $status
}
) {
id
title
status
created_at
}
}
Variables payload:
{
"title" : "My New Article" ,
"content" : "This is the article content..." ,
"status" : "draft"
}
Return Values
You can control what data is returned after a mutation:
Return Specific Fields
mutation {
create_articles_item (
data : {
title : "New Article"
status : "draft"
}
) {
id
title
created_at
}
}
Return Boolean
If you don’t request any fields, the mutation returns true on success:
mutation {
update_articles_item (
id : "123"
data : { views : 100 }
)
}
Response:
{
"data" : {
"update_articles_item" : true
}
}
Return nested relationship data:
mutation {
create_articles_item (
data : {
title : "Article with Author"
author : "author-uuid"
}
) {
id
title
author {
id
name
email
}
}
}
System Collection Mutations
Use the /graphql/system endpoint to mutate system collections:
Create User
mutation {
create_users_item (
data : {
first_name : "John"
last_name : "Doe"
email : "john@example.com"
password : "secure-password"
role : "role-uuid"
}
) {
id
first_name
last_name
email
}
}
Update Role Permissions
mutation {
update_roles_item (
id : "role-uuid"
data : {
name : "Editor"
description : "Can edit content"
}
) {
id
name
description
}
}
File Uploads
To upload files via GraphQL, you need to use multipart form data. Most GraphQL clients support this:
Using Apollo Client
import { createUploadLink } from 'apollo-upload-client' ;
const uploadLink = createUploadLink ({
uri: 'https://your-directus-instance.com/graphql' ,
headers: {
authorization: `Bearer ${ token } ` ,
},
});
Mutation with File Upload
mutation UploadFile ( $file : Upload ! ) {
create_files_item (
data : {
file : $file
title : "My Image"
}
) {
id
filename_disk
filename_download
}
}
Error Handling
Mutations return errors in the standard GraphQL format:
{
"errors" : [
{
"message" : "You don't have permission to create this." ,
"extensions" : {
"code" : "FORBIDDEN"
}
}
],
"data" : {
"create_articles_item" : null
}
}
Common Error Codes
FORBIDDEN - Insufficient permissions
INVALID_PAYLOAD - Invalid data provided
INVALID_QUERY - Invalid GraphQL syntax
RECORD_NOT_FOUND - Item with specified ID doesn’t exist
FAILED_VALIDATION - Data doesn’t meet validation rules
Combining Multiple Mutations
Execute multiple mutations in a single request:
mutation {
createAuthor : create_authors_item (
data : {
name : "Jane Smith"
email : "jane@example.com"
}
) {
id
name
}
createArticle : create_articles_item (
data : {
title : "New Article"
status : "published"
}
) {
id
title
}
updateSettings : update_settings (
data : {
maintenance_mode : false
}
) {
maintenance_mode
}
}
Mutations in a single request are executed sequentially in the order they appear.
Example: Complete CRUD Operations
Here’s a comprehensive example showing create, read, update, and delete:
mutation ManageArticle (
$createData : create_articles_input !
$updateId : ID !
$updateData : update_articles_input !
$deleteId : ID !
) {
# Create new article
created : create_articles_item ( data : $createData ) {
id
title
status
created_at
}
# Update existing article
updated : update_articles_item (
id : $updateId
data : $updateData
) {
id
title
status
updated_at
}
# Delete article
deleted : delete_articles_item ( id : $deleteId ) {
id
}
}
Variables:
{
"createData" : {
"title" : "New Article" ,
"content" : "Article content..." ,
"status" : "draft"
},
"updateId" : "123" ,
"updateData" : {
"status" : "published"
},
"deleteId" : "456"
}
Best Practices
Never hardcode values in mutations. Always use variables for security and reusability: # Good
mutation CreateArticle ( $data : create_articles_input ! ) {
create_articles_item ( data : $data ) {
id
}
}
# Avoid
mutation {
create_articles_item ( data : { title : "Hardcoded" }) {
id
}
}
Request Only Needed Fields
Only request the fields you need in the response: # If you only need the ID
mutation {
create_articles_item ( data : { title : "New" }) {
id
}
}
# If you don't need any data back
mutation {
update_articles_item ( id : "123" , data : { views : 100 })
}
Always check for errors in mutation responses: const result = await client . mutate ({ mutation , variables });
if ( result . errors ) {
console . error ( 'Mutation failed:' , result . errors );
// Handle errors
} else {
console . log ( 'Success:' , result . data );
}
Use Transactions for Related Operations
Next Steps
GraphQL Queries Learn how to query your data
GraphQL Subscriptions Get real-time updates with subscriptions