Missing _modelApiKey in meta fields after webhook trigger

Hello,

I am using a webhook to revalidate the cache of certain Dato models using an API route in a Next.js project. So I use the custom payload to pass my page slug. So far, so good.

Except that in some cases, my slugs have a prefix, defined in my Next.js project:

const PROGRAM_SLUG_PREFIX = 'programmes/'

This constant is mapped to an object, with Dato’s model API key as the key:

const slugPrefixes = {
    program: PROGRAM_SLUG_PREFIX
}

In my current webhook, here is my payload:

{
    "entity": "{{entity}}",
    "path": "/programmes/{{#entity}}{{#attributes}}{{slug}}{{/attributes}}{{/entity}}"
}

It works, but I have to create as many webhooks as there are Dato models and enter the prefix manually. I would like to be able to retrieve the _modelApiKey dynamically from the webhook’s triggered record, but when I inspect the entity’s content, I don’t have a _modelApiKey in the meta key, as shown in the documentation.

Here is the meta content after my webhook trigger:

"meta": {
    "created_at": "2025-08-20T10:19:14.237+02:00",
    "updated_at": "2025-10-13T17:55:56.195+02:00",
    "published_at": "2025-10-13T17:55:57.836+02:00",
    "publication_scheduled_at": null,
    "unpublishing_scheduled_at": null,
    "first_published_at": "2025-08-30T00:00:02.545+02:00",
    "is_valid": true,
    "is_current_version_valid": true,
    "is_published_version_valid": true,
    "has_children": null,
    "status": "published",
    "current_version": "dSsTa9gkRySYK3iw6GosEQ",
    "stage": null
}

Would it be possible to include it, please? Or do you have another idea?

Thank you in advance.

Hello @orphee.b

Great question, and thanks for the clear context. What you are seeing is expected. The _modelApiKey field exists in the Content Delivery API meta only, not in the Content Management API representation that webhooks use. Our webhook payloads serialize the entity following the CMA schema, so entity.meta will not contain _modelApiKey. You can see the Delivery API meta fields documented here https://www.datocms.com/docs/content-delivery-api/meta-fields and the webhook payload structure here https://www.datocms.com/docs/general-concepts/webhooks. In that webhook doc you will notice the related_entities array, which includes the linked item_type, and that object exposes its attributes.api_key.

So you do not need to create one webhook per model or ask for _modelApiKey to be injected into meta. You can keep a single webhook and either read the model API key directly from related_entities on your endpoint, or add it to your custom payload via Mustache.

If you prefer to keep the default webhook body, your Next.js route can extract the model API key and slug and then compute the prefix. Example for the App Router:

// app/api/revalidate/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { revalidatePath } from 'next/cache';

const slugPrefixes: Record<string, string> = {
  program: 'programmes/',
  // add more model -> prefix pairs here
};

export async function POST(req: NextRequest) {
  const body = await req.json();

  const slug: string | undefined = body?.entity?.attributes?.slug;
  const itemType = body?.related_entities?.find((e: any) => e?.type === 'item_type');
  const modelApiKey: string | undefined = itemType?.attributes?.api_key;

  if (!slug || !modelApiKey) {
    return NextResponse.json({ revalidated: false, reason: 'Missing slug or modelApiKey' }, { status: 400 });
  }

  const prefix = slugPrefixes[modelApiKey] ?? '';
  const path = `/${prefix}${slug}`;

  revalidatePath(path);
  return NextResponse.json({ revalidated: true, path });
}

If you are on the Pages Router in Next 12 or 13 pages, call res.revalidate(path) inside pages/api/revalidate.ts instead of revalidatePath.

If you prefer to keep using a custom webhook payload, you can add both the slug and the model API key to it so your endpoint receives just what it needs. Since the enhanced webhook payload includes the item_type in related_entities, this Mustache template will work:

{
  "slug": "{{#entity}}{{#attributes}}{{slug}}{{/attributes}}{{/entity}}",
  "model_api_key": "{{#related_entities}}{{#attributes}}{{api_key}}{{/attributes}}{{/related_entities}}"
}

Then your endpoint simply maps model_api_key through your slugPrefixes object to build the path. The related_entities addition is described here https://www.datocms.com/product-updates/introducing-enhanced-webhook-payloads-get-more-information-with-less-effort and the item_type resource with its api_key is documented here https://www.datocms.com/docs/content-management-api/resources/item-type.

1 Like

@m.finamor thank you for your quick response!

I just tested it and it’s exactly what I needed. It works perfectly, thank you again!

Orphée

1 Like