Read a Google Tag Manager container, plan a migration, and change tags, triggers and variables under Manual, Hybrid or Autonomous mode.
GET
/api/v1/gtm/containers
Your Google Tag Manager accounts and containers, which site each one is chosen for, its mode, and the Tag Manager permissions you gave Woodander.
MCP tool gtm_list_containers
Scope read:gtm
Plan Pro and above
Parameters
No parameters.
Example request
curl
MCP
bash Kopieren
curl "https://woodander.com/api/v1/gtm/containers" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_list_containers" ,
"arguments" : {}
}
}
Example response Example
json Kopieren
{
"data" : [
{
"public_id" : "GTM-AB12CD" ,
"name" : "example.com" ,
"account" : "Example" ,
"site" : "example.com" ,
"mode" : "hybrid" ,
"usage" : [
"web"
]
}
],
"meta" : {
"total" : 1 ,
"permissions" : {
"read" : true ,
"edit" : true ,
"publish" : false
}
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the read:gtm scope.
403 plan_requiredThe plan does not include API access.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
429 rate_limitedToo many requests. See the Retry-After header.
GET
/api/v1/sites/{site}/gtm/workspaces
The workspaces of the site's container and the one Woodander reads (its own "Woodander" workspace when it exists, else the Default Workspace).
MCP tool gtm_list_workspaces
Scope read:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
Example request
curl
MCP
bash Kopieren
curl "https://woodander.com/api/v1/sites/example.com/gtm/workspaces" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_list_workspaces" ,
"arguments" : {
"site" : "example.com"
}
}
}
Example response Example
json Kopieren
{
"data" : {
"site" : "example.com" ,
"container" : "GTM-AB12CD" ,
"workspaces" : [
{
"id" : "7" ,
"name" : "Default Workspace"
},
{
"id" : "9" ,
"name" : "Woodander"
}
],
"in_use" : {
"id" : "9" ,
"name" : "Woodander" ,
"fingerprint" : "1697623" ,
"is_woodander" : true
}
},
"meta" : {
"source" : "gtm_snapshot"
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the read:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
429 rate_limitedToo many requests. See the Retry-After header.
GET
/api/v1/sites/{site}/gtm/container
The container snapshot: tags, triggers and variables in plain words, enabled built-in variables and the versions. Served from a cache keyed by the workspace fingerprint; refresh=true asks Google again.
MCP tool gtm_get_container
Scope read:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
refresh
query
boolean
No
Read from Google instead of the cached snapshot (uses the shared quota).
Example request
curl
MCP
bash Kopieren
curl "https://woodander.com/api/v1/sites/example.com/gtm/container" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_get_container" ,
"arguments" : {
"site" : "example.com"
}
}
}
Example response Example
json Kopieren
{
"data" : {
"site" : "example.com" ,
"mode" : "hybrid" ,
"container" : {
"public_id" : "GTM-AB12CD" ,
"name" : "example.com"
},
"workspace" : {
"id" : "9" ,
"name" : "Woodander" ,
"is_woodander" : true
},
"tags" : [
{
"id" : "3" ,
"name" : "Google tag - G-ABC123" ,
"type" : "googtag" ,
"details" : [
{
"label" : "Type" ,
"value" : "Google tag"
},
{
"label" : "ID" ,
"value" : "G-ABC123"
},
{
"label" : "Fires on" ,
"value" : "All Pages"
}
],
"firing_trigger_ids" : [
"2147479553"
],
"paused" : false
}
],
"triggers" : [],
"variables" : [],
"built_in_variables" : [
"Page URL" ,
"Event"
],
"versions" : [
{
"id" : "4" ,
"name" : "Launch" ,
"tags" : 3 ,
"deleted" : false
}
],
"fetched_at" : "2026-10-18T10:00:00+00:00"
},
"meta" : {
"stale" : false ,
"source" : "gtm_snapshot"
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the read:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 invalid_requestA parameter is not valid (range, type, cursor).
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
429 rate_limitedToo many requests. See the Retry-After header.
GET
/api/v1/sites/{site}/gtm/analysis
Compares the container with a tracking plan (default page_view, sign_up, begin_checkout, purchase): missing events, duplicates (two Google tags or GA4 configurations with the same measurement id, an event sent twice), tags without or with broken triggers, undefined variables, unused triggers, and sign-ups or purchases sent on a click.
MCP tool gtm_analyze_tracking
Scope read:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
events
query
string
No
Your plan: GA4 event names separated by commas, e.g. page_view,sign_up,test_started,purchase.
Example request
curl
MCP
bash Kopieren
curl "https://woodander.com/api/v1/sites/example.com/gtm/analysis" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_analyze_tracking" ,
"arguments" : {
"site" : "example.com"
}
}
}
Example response Example
json Kopieren
{
"data" : {
"site" : "example.com" ,
"plan" : [
{
"event" : "page_view" ,
"status" : "ok" ,
"tags" : [
"Google tag - G-ABC123"
]
},
{
"event" : "sign_up" ,
"status" : "missing" ,
"tags" : []
}
],
"issues" : [
{
"code" : "missing_events" ,
"severity" : "warning" ,
"message" : "Events of the tracking plan that no tag sends." ,
"items" : [
"sign_up"
]
}
],
"counts" : {
"tags" : 1 ,
"triggers" : 0 ,
"variables" : 0
}
},
"meta" : {
"source" : "gtm_snapshot"
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the read:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 invalid_requestA parameter is not valid (range, type, cursor).
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
429 rate_limitedToo many requests. See the Retry-After header.
GET
/api/v1/sites/{site}/gtm/scan
Reads one live page of your site and finds tags hard-coded in its HTML: gtag.js / GA4 (G-), Google Ads (AW-), Meta Pixel, Microsoft Clarity, Hotjar, LinkedIn Insight, TikTok Pixel and an existing GTM snippet. Changes nothing.
MCP tool gtm_scan_site
Scope read:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
url
query
string
No
A page of this site (path or full https URL). Default: the start page.
Example request
curl
MCP
bash Kopieren
curl "https://woodander.com/api/v1/sites/example.com/gtm/scan" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_scan_site" ,
"arguments" : {
"site" : "example.com"
}
}
}
Example response Example
json Kopieren
{
"data" : {
"site" : "example.com" ,
"url" : "https://example.com/" ,
"status" : 200 ,
"found" : [
{
"vendor" : "ga4" ,
"label" : "Google Analytics 4 (gtag.js)" ,
"id" : "G-ABC123" ,
"evidence" : "gtag.js"
},
{
"vendor" : "meta_pixel" ,
"label" : "Meta Pixel" ,
"id" : "1234567890" ,
"evidence" : "fbq init"
}
],
"gtm_snippets" : [
"GTM-AB12CD"
]
},
"meta" : {
"changes_site" : false
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the read:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 invalid_requestA parameter is not valid (range, type, cursor).
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
429 rate_limitedToo many requests. See the Retry-After header.
GET
/api/v1/sites/{site}/gtm/migration-plan
Site → GTM: the tags that would replace the snippets hard-coded on the page, as ready inputs for gtm_create_tag, plus warnings. Never publishes and never edits the site: remove the snippets in the site's code and publish together with that deploy, or everything is counted twice.
MCP tool gtm_plan_migration
Scope read:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
url
query
string
No
A page of this site. Default: the start page.
Example request
curl
MCP
bash Kopieren
curl "https://woodander.com/api/v1/sites/example.com/gtm/migration-plan" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_plan_migration" ,
"arguments" : {
"site" : "example.com"
}
}
}
Example response Example
json Kopieren
{
"data" : {
"site" : "example.com" ,
"container" : "GTM-AB12CD" ,
"scan" : {
"url" : "https://example.com/" ,
"found" : []
},
"steps" : [
{
"action" : "gtm.create_tag" ,
"vendor" : "meta_pixel" ,
"input" : {
"name" : "Meta Pixel - base code" ,
"type" : "html" ,
"html" : "<script>...</script>" ,
"firing_trigger_ids" : [
"2147479553"
]
},
"reason" : "Replaces the hard-coded Meta Pixel (1234567890)."
}
],
"already_in_gtm" : [
"Google tag - G-ABC123"
],
"manual" : [],
"warnings" : [
"While a snippet stays in the site’s code and the same tag is live in Tag Manager, every visit and event is counted twice. Publish the version only together with the deploy that removes the snippets from the site."
]
},
"meta" : {
"publishes" : false ,
"source" : "gtm_snapshot"
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the read:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 invalid_requestA parameter is not valid (range, type, cursor).
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
429 rate_limitedToo many requests. See the Retry-After header.
GET
/api/v1/sites/{site}/gtm/changes
The last 50 change requests for the site's container: proposals, changes waiting for the owner's confirmation, queued, done, failed and rejected ones, each with its diff.
MCP tool gtm_list_changes
Scope read:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
Example request
curl
MCP
bash Kopieren
curl "https://woodander.com/api/v1/sites/example.com/gtm/changes" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_list_changes" ,
"arguments" : {
"site" : "example.com"
}
}
}
Example response Example
json Kopieren
{
"data" : [
{
"id" : 12 ,
"action" : "gtm.create_tag" ,
"risk" : "reversible" ,
"status" : "pending" ,
"needs" : "apply" ,
"summary" : "Create tag “GA4 event - sign_up” (GA4 event)" ,
"diff" : [
{
"op" : "+" ,
"kind" : "tag" ,
"name" : "GA4 event - sign_up" ,
"details" : [
"Type: GA4 event" ,
"ID: G-ABC123" ,
"Event: sign_up" ,
"Fires on: CE - sign_up"
]
}
],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : null ,
"confirm_url" : "https://woodander.com/workspace/seo/tag-manager?site=example.com&change=12" ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
}
],
"meta" : {
"total" : 1 ,
"site" : "example.com"
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the read:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
429 rate_limitedToo many requests. See the Retry-After header.
GET
/api/v1/gtm/changes/{id}
One change request (or a queued read) by id: its status (pending, queued, running, done, failed, rejected), what it waits for and the result, e.g. the GTM version id.
MCP tool gtm_change_status
Scope read:gtm
Plan Pro and above
Parameters
Name In Type Required Description
id
path
integer
Yes
The id a change or a queued read returned.
Example request
curl
MCP
bash Kopieren
curl "https://woodander.com/api/v1/gtm/changes/12" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_change_status" ,
"arguments" : {
"id" : 12
}
}
}
Example response Example
json Kopieren
{
"data" : {
"id" : 12 ,
"action" : "gtm.create_version" ,
"risk" : "reversible" ,
"status" : "done" ,
"needs" : null ,
"summary" : "Create version “sign_up tracking” from the Woodander workspace" ,
"diff" : [],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : {
"summary" : "Create version “sign_up tracking” from the Woodander workspace" ,
"ids" : {
"tag_id" : "25"
}
},
"confirm_url" : null ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
},
"meta" : {
"outcome" : "done" ,
"mode" : "hybrid" ,
"hint" : null
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the read:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
429 rate_limitedToo many requests. See the Retry-After header.
POST
/api/v1/sites/{site}/gtm/tags
Create a tag in the "Woodander" workspace (never the live Default Workspace). A duplicate (same name, same Google tag id, same GA4 event to the same id) is refused. Manual mode: stored as a proposal the owner applies.
MCP tool gtm_create_tag
Scope write:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
name
body
string
Yes
Tag name, e.g. "GA4 event - sign_up".
type
body
string
Yes
googtag = Google tag (GA4 / Ads id), gaawe = GA4 event, html = Custom HTML, awct = Google Ads conversion, gclidw = Conversion Linker. One of: googtag, gaawe, html, awct, gclidw.
google_tag_id
body
string
No
googtag: the id it loads, e.g. G-ABC123 or AW-123456.
measurement_id
body
string
No
gaawe: the GA4 measurement id the event is sent to, e.g. G-ABC123.
event_name
body
string
No
gaawe: the GA4 event name, e.g. sign_up, or one variable reference such as {{Event}} (a variable of the container or a built-in one) to send many events with one tag.
event_parameters
body
array<object>
No
gaawe: event parameters, a list of {"name", "value"} (value may be a {{Variable}}).
html
body
string
No
html: the Custom HTML.
conversion_id
body
string
No
awct: Google Ads conversion id.
conversion_label
body
string
No
awct: Google Ads conversion label.
firing_trigger_ids
body
array<string>
No
Ids of the triggers that fire it (2147479553 = All Pages). One of firing_trigger_ids or firing_trigger_names is required to create.
firing_trigger_names
body
array<string>
No
Trigger names instead of ids, resolved when the change runs (use it for a trigger another change creates first).
paused
body
boolean
No
Pause the tag.
notes
body
string
No
Notes kept on the tag.
Example request
curl
MCP
bash Kopieren
curl -X POST "https://woodander.com/api/v1/sites/example.com/gtm/tags" \
-H "Authorization: Bearer wdr_..." \
-H "Content-Type: application/json" \
-d '{"name":"example","type":"googtag"}'
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_create_tag" ,
"arguments" : {
"site" : "example.com" ,
"name" : "example" ,
"type" : "googtag"
}
}
}
Example response Example
json Kopieren
{
"data" : {
"id" : 12 ,
"action" : "gtm.create_tag" ,
"risk" : "reversible" ,
"status" : "pending" ,
"needs" : "apply" ,
"summary" : "Create tag “GA4 event - sign_up” (GA4 event)" ,
"diff" : [
{
"op" : "+" ,
"kind" : "tag" ,
"name" : "GA4 event - sign_up" ,
"details" : [
"Type: GA4 event" ,
"ID: G-ABC123" ,
"Event: sign_up" ,
"Fires on: CE - sign_up"
]
}
],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : null ,
"confirm_url" : "https://woodander.com/workspace/seo/tag-manager?site=example.com&change=12" ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
},
"meta" : {
"outcome" : "proposed" ,
"mode" : "manual" ,
"hint" : null
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the write:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 validation_failedThe body is not valid; details.errors names the fields.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
409 duplicateThe change would duplicate a tag, trigger or variable the container already has.
429 rate_limitedToo many requests. See the Retry-After header.
PATCH
/api/v1/sites/{site}/gtm/tags/{id}
Update a tag in the "Woodander" workspace. Fields you send replace those of the tag; the others stay.
MCP tool gtm_update_tag
Scope write:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
id
path
string
Yes
GTM tag id (numeric, see gtm_get_container).
name
body
string
No
Tag name, e.g. "GA4 event - sign_up".
google_tag_id
body
string
No
googtag: the id it loads, e.g. G-ABC123 or AW-123456.
measurement_id
body
string
No
gaawe: the GA4 measurement id the event is sent to, e.g. G-ABC123.
event_name
body
string
No
gaawe: the GA4 event name, e.g. sign_up, or one variable reference such as {{Event}} (a variable of the container or a built-in one) to send many events with one tag.
event_parameters
body
array<object>
No
gaawe: event parameters, a list of {"name", "value"} (value may be a {{Variable}}).
html
body
string
No
html: the Custom HTML.
conversion_id
body
string
No
awct: Google Ads conversion id.
conversion_label
body
string
No
awct: Google Ads conversion label.
firing_trigger_ids
body
array<string>
No
Ids of the triggers that fire it (2147479553 = All Pages). One of firing_trigger_ids or firing_trigger_names is required to create.
firing_trigger_names
body
array<string>
No
Trigger names instead of ids, resolved when the change runs (use it for a trigger another change creates first).
paused
body
boolean
No
Pause the tag.
notes
body
string
No
Notes kept on the tag.
Example request
curl
MCP
bash Kopieren
curl -X PATCH "https://woodander.com/api/v1/sites/example.com/gtm/tags/12" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_update_tag" ,
"arguments" : {
"site" : "example.com" ,
"id" : 12
}
}
}
Example response Example
json Kopieren
{
"data" : {
"id" : 12 ,
"action" : "gtm.update_tag" ,
"risk" : "reversible" ,
"status" : "done" ,
"needs" : null ,
"summary" : "Update tag #25" ,
"diff" : [
{
"op" : "~" ,
"kind" : "tag" ,
"name" : "GA4 event - sign_up" ,
"details" : [
"Event: signup → sign_up"
]
}
],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : {
"summary" : "Update tag #25" ,
"ids" : {
"tag_id" : "25"
}
},
"confirm_url" : null ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
},
"meta" : {
"outcome" : "done" ,
"mode" : "hybrid" ,
"hint" : null
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the write:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 validation_failedThe body is not valid; details.errors names the fields.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
409 duplicateThe change would duplicate a tag, trigger or variable the container already has.
429 rate_limitedToo many requests. See the Retry-After header.
DELETE
/api/v1/sites/{site}/gtm/tags/{id}
Delete a tag in the "Woodander" workspace. Deleting always waits for the owner's confirmation in the Workspace (confirm_url), in every mode.
MCP tool gtm_delete_tag
Scope write:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
id
path
string
Yes
GTM tag id (numeric, see gtm_get_container).
Example request
curl
MCP
bash Kopieren
curl -X DELETE "https://woodander.com/api/v1/sites/example.com/gtm/tags/12" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_delete_tag" ,
"arguments" : {
"site" : "example.com" ,
"id" : 12
}
}
}
Example response Example
json Kopieren
{
"data" : {
"id" : 12 ,
"action" : "gtm.delete_tag" ,
"risk" : "destructive" ,
"status" : "pending" ,
"needs" : "confirm" ,
"summary" : "Delete tag #25" ,
"diff" : [
{
"op" : "-" ,
"kind" : "tag" ,
"name" : "Old pixel" ,
"details" : [
"Type: Custom HTML"
]
}
],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : null ,
"confirm_url" : "https://woodander.com/workspace/seo/tag-manager?site=example.com&change=12" ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
},
"meta" : {
"outcome" : "pending_confirmation" ,
"mode" : "hybrid" ,
"hint" : null
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the write:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
409 duplicateThe change would duplicate a tag, trigger or variable the container already has.
429 rate_limitedToo many requests. See the Retry-After header.
POST
/api/v1/sites/{site}/gtm/triggers
Create a trigger in the "Woodander" workspace. A custom event trigger for an event that already has one is refused.
MCP tool gtm_create_trigger
Scope write:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
name
body
string
Yes
Trigger name, e.g. "CE - sign_up".
type
body
string
Yes
Trigger type. One of: pageview, domReady, windowLoaded, customEvent, click, linkClick, formSubmission, historyChange.
event_name
body
string
No
customEvent: the dataLayer event it listens for.
filters
body
array<object>
No
Conditions, a list of {"variable": "Page Path", "operator": "equals|contains|startsWith|endsWith|matchRegex", "value"}.
notes
body
string
No
Notes kept on the trigger.
Example request
curl
MCP
bash Kopieren
curl -X POST "https://woodander.com/api/v1/sites/example.com/gtm/triggers" \
-H "Authorization: Bearer wdr_..." \
-H "Content-Type: application/json" \
-d '{"name":"example","type":"pageview"}'
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_create_trigger" ,
"arguments" : {
"site" : "example.com" ,
"name" : "example" ,
"type" : "pageview"
}
}
}
Example response Example
json Kopieren
{
"data" : {
"id" : 12 ,
"action" : "gtm.create_trigger" ,
"risk" : "reversible" ,
"status" : "done" ,
"needs" : null ,
"summary" : "Create trigger “CE - sign_up” (Custom event)" ,
"diff" : [
{
"op" : "+" ,
"kind" : "trigger" ,
"name" : "CE - sign_up" ,
"details" : [
"Type: Custom event" ,
"Event: sign_up"
]
}
],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : {
"summary" : "Create trigger “CE - sign_up” (Custom event)" ,
"ids" : {
"tag_id" : "25"
}
},
"confirm_url" : null ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
},
"meta" : {
"outcome" : "done" ,
"mode" : "hybrid" ,
"hint" : null
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the write:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 validation_failedThe body is not valid; details.errors names the fields.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
409 duplicateThe change would duplicate a tag, trigger or variable the container already has.
429 rate_limitedToo many requests. See the Retry-After header.
PATCH
/api/v1/sites/{site}/gtm/triggers/{id}
Update a trigger in the "Woodander" workspace.
MCP tool gtm_update_trigger
Scope write:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
id
path
string
Yes
GTM trigger id (numeric, see gtm_get_container).
name
body
string
No
Trigger name, e.g. "CE - sign_up".
event_name
body
string
No
customEvent: the dataLayer event it listens for.
filters
body
array<object>
No
Conditions, a list of {"variable": "Page Path", "operator": "equals|contains|startsWith|endsWith|matchRegex", "value"}.
notes
body
string
No
Notes kept on the trigger.
Example request
curl
MCP
bash Kopieren
curl -X PATCH "https://woodander.com/api/v1/sites/example.com/gtm/triggers/12" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_update_trigger" ,
"arguments" : {
"site" : "example.com" ,
"id" : 12
}
}
}
Example response Example
json Kopieren
{
"data" : {
"id" : 12 ,
"action" : "gtm.update_trigger" ,
"risk" : "reversible" ,
"status" : "done" ,
"needs" : null ,
"summary" : "Update trigger #31" ,
"diff" : [],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : {
"summary" : "Update trigger #31" ,
"ids" : {
"tag_id" : "25"
}
},
"confirm_url" : null ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
},
"meta" : {
"outcome" : "done" ,
"mode" : "hybrid" ,
"hint" : null
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the write:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 validation_failedThe body is not valid; details.errors names the fields.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
409 duplicateThe change would duplicate a tag, trigger or variable the container already has.
429 rate_limitedToo many requests. See the Retry-After header.
POST
/api/v1/sites/{site}/gtm/variables
Create a variable in the "Woodander" workspace.
MCP tool gtm_create_variable
Scope write:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
name
body
string
Yes
Variable name.
type
body
string
Yes
v = data layer variable, c = constant, u = URL, k = 1st-party cookie, jsm = custom JavaScript. One of: v, c, u, k, jsm.
data_layer_name
body
string
No
v: the dataLayer key, e.g. ecommerce.value.
value
body
string
No
c: the constant value.
component
body
string
No
u: the part of the URL. One of: URL, HOST, PATH, QUERY, FRAGMENT.
cookie_name
body
string
No
k: the cookie name.
javascript
body
string
No
jsm: function () { return ...; }
notes
body
string
No
Notes kept on the variable.
Example request
curl
MCP
bash Kopieren
curl -X POST "https://woodander.com/api/v1/sites/example.com/gtm/variables" \
-H "Authorization: Bearer wdr_..." \
-H "Content-Type: application/json" \
-d '{"name":"example","type":"v"}'
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_create_variable" ,
"arguments" : {
"site" : "example.com" ,
"name" : "example" ,
"type" : "v"
}
}
}
Example response Example
json Kopieren
{
"data" : {
"id" : 12 ,
"action" : "gtm.create_variable" ,
"risk" : "reversible" ,
"status" : "done" ,
"needs" : null ,
"summary" : "Create variable “DLV - value” (Data layer variable)" ,
"diff" : [],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : {
"summary" : "Create variable “DLV - value” (Data layer variable)" ,
"ids" : {
"tag_id" : "25"
}
},
"confirm_url" : null ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
},
"meta" : {
"outcome" : "done" ,
"mode" : "hybrid" ,
"hint" : null
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the write:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 validation_failedThe body is not valid; details.errors names the fields.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
409 duplicateThe change would duplicate a tag, trigger or variable the container already has.
429 rate_limitedToo many requests. See the Retry-After header.
PATCH
/api/v1/sites/{site}/gtm/variables/{id}
Update a variable in the "Woodander" workspace.
MCP tool gtm_update_variable
Scope write:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
id
path
string
Yes
GTM variable id (numeric, see gtm_get_container).
name
body
string
No
Variable name.
data_layer_name
body
string
No
v: the dataLayer key, e.g. ecommerce.value.
value
body
string
No
c: the constant value.
component
body
string
No
u: the part of the URL. One of: URL, HOST, PATH, QUERY, FRAGMENT.
cookie_name
body
string
No
k: the cookie name.
javascript
body
string
No
jsm: function () { return ...; }
notes
body
string
No
Notes kept on the variable.
Example request
curl
MCP
bash Kopieren
curl -X PATCH "https://woodander.com/api/v1/sites/example.com/gtm/variables/12" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_update_variable" ,
"arguments" : {
"site" : "example.com" ,
"id" : 12
}
}
}
Example response Example
json Kopieren
{
"data" : {
"id" : 12 ,
"action" : "gtm.update_variable" ,
"risk" : "reversible" ,
"status" : "done" ,
"needs" : null ,
"summary" : "Update variable #40" ,
"diff" : [],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : {
"summary" : "Update variable #40" ,
"ids" : {
"tag_id" : "25"
}
},
"confirm_url" : null ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
},
"meta" : {
"outcome" : "done" ,
"mode" : "hybrid" ,
"hint" : null
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the write:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 validation_failedThe body is not valid; details.errors names the fields.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
409 duplicateThe change would duplicate a tag, trigger or variable the container already has.
429 rate_limitedToo many requests. See the Retry-After header.
POST
/api/v1/sites/{site}/gtm/versions
Turn the "Woodander" workspace into a container version. Not live: publishing is a separate step (gtm_publish_version). Google removes the workspace afterwards; the next change makes a new one.
MCP tool gtm_create_version
Scope write:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
name
body
string
Yes
Version name.
notes
body
string
No
What changed and why.
Example request
curl
MCP
bash Kopieren
curl -X POST "https://woodander.com/api/v1/sites/example.com/gtm/versions" \
-H "Authorization: Bearer wdr_..." \
-H "Content-Type: application/json" \
-d '{"name":"example"}'
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_create_version" ,
"arguments" : {
"site" : "example.com" ,
"name" : "example"
}
}
}
Example response Example
json Kopieren
{
"data" : {
"id" : 12 ,
"action" : "gtm.create_version" ,
"risk" : "reversible" ,
"status" : "done" ,
"needs" : null ,
"summary" : "Create version “sign_up tracking” from the Woodander workspace" ,
"diff" : [],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : {
"summary" : "Create version “sign_up tracking” from the Woodander workspace" ,
"ids" : {
"tag_id" : "25"
}
},
"confirm_url" : null ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
},
"meta" : {
"outcome" : "done" ,
"mode" : "hybrid" ,
"hint" : null
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the write:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 validation_failedThe body is not valid; details.errors names the fields.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
409 duplicateThe change would duplicate a tag, trigger or variable the container already has.
429 rate_limitedToo many requests. See the Retry-After header.
POST
/api/v1/sites/{site}/gtm/versions/{version_id}/publish
Make a version live. Guarded: in Manual and Hybrid it returns a pending confirmation (confirm_url) the owner gives in the Workspace; only in Autonomous mode, with a token that also holds publish:gtm and within the daily publish cap, it publishes at once (duplicate check, the previous version kept for rollback, an email to the owner).
MCP tool gtm_publish_version
Scope write:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
version_id
path
string
Yes
The version id (from gtm_create_version or gtm_get_container).
Example request
curl
MCP
bash Kopieren
curl -X POST "https://woodander.com/api/v1/sites/example.com/gtm/versions/12/publish" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_publish_version" ,
"arguments" : {
"site" : "example.com" ,
"version_id" : 12
}
}
}
Example response Example
json Kopieren
{
"data" : {
"id" : 12 ,
"action" : "gtm.publish_version" ,
"risk" : "publish" ,
"status" : "pending" ,
"needs" : "confirm" ,
"summary" : "Publish version 5" ,
"diff" : [
{
"op" : "~" ,
"kind" : "live version" ,
"name" : "version 5 “sign_up tracking”" ,
"details" : [
"Becomes live on the site for every visitor"
]
}
],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : null ,
"confirm_url" : "https://woodander.com/workspace/seo/tag-manager?site=example.com&change=12" ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
},
"meta" : {
"outcome" : "pending_confirmation" ,
"mode" : "hybrid" ,
"hint" : null
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the write:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
409 duplicateThe change would duplicate a tag, trigger or variable the container already has.
429 rate_limitedToo many requests. See the Retry-After header.
POST
/api/v1/sites/{site}/gtm/rollback
Republish the version that was live before the last publish through Woodander (or the version you name). Same guard as gtm_publish_version.
MCP tool gtm_rollback
Scope write:gtm
Plan Pro and above
Parameters
Name In Type Required Description
site
path
string
Yes
Host of one of your sites with a Tag Manager container chosen for it (see gtm_list_containers).
version_id
body
string
No
A version to go back to. Default: the one live before the last publish.
Example request
curl
MCP
bash Kopieren
curl -X POST "https://woodander.com/api/v1/sites/example.com/gtm/rollback" \
-H "Authorization: Bearer wdr_..."
tools/call Kopieren
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"method" : "tools/call" ,
"params" : {
"name" : "gtm_rollback" ,
"arguments" : {
"site" : "example.com"
}
}
}
Example response Example
json Kopieren
{
"data" : {
"id" : 12 ,
"action" : "gtm.rollback" ,
"risk" : "publish" ,
"status" : "pending" ,
"needs" : "confirm" ,
"summary" : "Roll back to the version live before the last publish" ,
"diff" : [],
"requested_by" : "Token “Claude Code”" ,
"note" : null ,
"error" : null ,
"result" : null ,
"confirm_url" : "https://woodander.com/workspace/seo/tag-manager?site=example.com&change=12" ,
"created_at" : "2026-10-18T10:00:00+00:00" ,
"decided_at" : null
},
"meta" : {
"outcome" : "pending_confirmation" ,
"mode" : "hybrid" ,
"hint" : null
}
}
Errors
HTTP Code Meaning
401 unauthenticatedMissing, invalid, expired or revoked token.
403 insufficient_scopeThe token does not have the write:gtm scope.
403 plan_requiredThe plan does not include API access.
404 not_foundNot found, or not yours.
422 validation_failedThe body is not valid; details.errors names the fields.
404 gtm_container_not_chosenNo Tag Manager container is chosen for the site.
409 google_reconnectGoogle no longer accepts the owner's Tag Manager access.
409 duplicateThe change would duplicate a tag, trigger or variable the container already has.
429 rate_limitedToo many requests. See the Retry-After header.