
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeYou're running into the fundamental difference between how patch and create operations work. Here's what's happening and the correct approach:
The patch operation in Sanity only works on existing documents - it cannot create new documents. When you want to create a draft programmatically, you need to create a new document with the drafts. prefix in the _id. Since this is a creation operation (not modifying an existing document), you must use a create-type mutation like createOrReplace.
From the Mutation API documentation, the available create operations are:
create - Creates a new document, fails if _id already existscreateIfNotExists - Creates only if the _id doesn't existcreateOrReplace - Creates or replaces a document with that _idUse createOrReplace with the draft _id:
client.createOrReplace({
_id: `drafts.${documentId}`,
_type: 'yourDocumentType',
// ... your document fields
})Why this triggers a "create" webhook event: In Sanity's architecture, a draft is a separate document from its published counterpart - it just has drafts. prepended to the _id. When you use createOrReplace with drafts.post-123, you're creating (or replacing) that specific draft document, which the webhook system correctly identifies as a create event for that document ID.
Since you're using webhooks to react to content changes, I'd strongly recommend switching to Sanity Functions instead. Functions are the modern, recommended approach for automation and event handling in Sanity, with several advantages:
Functions can handle the same use cases as webhooks but with tighter integration and less complexity around event types.
If you need to stick with webhooks, you can distinguish between "true creates" and "draft updates" by:
Checking for the published version - When your webhook receives a create event for a draft ID, query whether the published version exists:
const publishedExists = await client.fetch(
`defined(*[_id == $publishedId][0])`,
{ publishedId: documentId.replace('drafts.', '') }
)
// If publishedExists is true, treat as updateUsing GROQ filters in webhooks - The webhook filtering system allows you to create separate webhooks for drafts vs published documents using path filters like _id in path("drafts.*") to separate draft events from published events.
The key takeaway: patch operations fundamentally cannot create documents - they only modify existing ones. Creating a draft requires a create-type operation, which will always trigger a create event in webhooks.
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store