TrustData crawls your top pages and notices when they change. A webhook does better: it tells us the moment you publish, names the exact page, and dates the change precisely. That date is what the before/after comparison splits on, so a precise one is the difference between a verdict and a shrug.
Point your CMS at one URL and every publish becomes a measured change.
TrustData compares the pages you changed against a matched group of your other pages over the same period. If organic clicks to your site rose everywhere, that is not a win for your rewrite, and the comparison says so.
Your webhook URL is:
https://app.trustdata.tech/webhooks/content/{provider}/{key}/
Where {provider} is wordpress, webflow, or contentful.
A content key can only report content changes on one website. It cannot read your data or send conversions, and a conversion key cannot report content changes. Revoking a key stops it immediately.
Any plugin that posts JSON on publish works. With WP Webhooks:
wordpress as the providerOr add this to your theme's functions.php:
add_action('transition_post_status', function ($new, $old, $post) {
if ($new !== 'publish' || $post->post_type !== 'post') {
return;
}
wp_remote_post('https://app.trustdata.tech/webhooks/content/wordpress/YOUR_KEY/', [
'headers' => ['Content-Type' => 'application/json'],
'blocking' => false,
'body' => wp_json_encode([
'ID' => $post->ID,
'post_title' => $post->post_title,
'permalink' => get_permalink($post),
'post_date' => $post->post_date,
'post_modified' => $post->post_modified,
'post_modified_gmt' => $post->post_modified_gmt,
]),
]);
}, 10, 3);
blocking => false matters: it stops the request from slowing down your editors' save.
TrustData reads a post whose post_date and post_modified match as a first publish, and anything later as a rewrite.
webflow as the providerWebflow sends a slug rather than a full URL. TrustData resolves it against the website on your attribution ID, so make sure that field is filled in.
contentful as the providerContentful holds fields, not URLs — your site decides the path. If your content model has a url or slug field, TrustData uses it and can measure the change. Without one, the change still lands on your timeline as an annotation, which explains a traffic movement but carries no verdict.
Each webhook creates one change on your timeline:
| Field | Where it comes from |
|---|---|
| Date | The publish timestamp in the payload |
| Page | The permalink, or the slug resolved against your site |
| Type | First publish or rewrite |
| What changed | TrustData crawls the page and diffs it against the last version |
After 21 days TrustData publishes a verdict: winner, regressed, no effect, or inconclusive. Until then the change shows how many days of its window have passed.
A verdict compares the pages you changed against a matched group of pages you did not. One page on its own is one observation, however many days it runs, so a single-page change reports its measured movement without a verdict. Change several pages in a batch and the comparison has enough to conclude.
Nothing is published before Google has re-indexed and re-served the page. A page that drew no impressions after the change is reported as such rather than scored as a flat result.
Webhook senders retry. TrustData keys each change on an id from your CMS — the post revision, the Webflow publish time, the Contentful revision number — so a retry returns the change that already exists instead of creating a second one. Two changes on one edit would split it across two measurements and both would come back inconclusive.
| Limit | Value | What happens past it |
|---|---|---|
| Requests per key | 60/minute | 429, retry after 60 seconds |
| Crawls per organization | 200/day | The change is still recorded. The page picks up its diff on the weekly crawl instead |
| Repeat saves of one page | One crawl per 10 minutes | Every save is recorded; they share one crawl |
Saving four times while you finish an edit is one edit. TrustData records each save and crawls once, so the diff you see is the finished page rather than three snapshots of unfinished work.
| Status | Meaning |
|---|---|
200 {"created": true} | Change recorded |
200 {"created": false} | A redelivery of a change already recorded |
200 {"status": "ignored"} | The payload could not be mapped to a page. Check the fields your CMS sends |
400 | The body was not valid JSON |
404 | Unknown, revoked, or expired key, or an unsupported provider |
429 | Over the rate limit |
Anything that can POST on publish can report changes through the change events API directly. Send event_type, changed_at, title, the page URL, and a stable external_id from your system. AI agents can report changes the same way through the create_change_event MCP tool.