Skip to main content

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
  }
}
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);
}

Next Steps

GraphQL Queries

Learn how to query your data

GraphQL Subscriptions

Get real-time updates with subscriptions