Connect GA4 (tagless)
One-click GA4 measurement with no page tag — creates (or updates) the google_analytics Data Manager server destination, mapped to the Mythic commerce spec. Server-only by design: Mythic is the single source, so every event arrives with resolved identity and full line items (cart_data), which a browser tag cannot supply once an ad blocker is in play. There is no browser half, so the response always has browser_tag false and tag_id null.
event_mapping defaults to the whole commerce spec — identity names, since the spec uses GA4's own — and anything you pass is MERGED over that default. cart_data is the opposite: an explicit object REPLACES the default wholesale. Requires the google_analytics Data Manager OAuth credential to be stored first.
curl -X POST "https://mythic-analytics.gulp.workers.dev/client/v1/destinations/integrations/google_analytics" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"measurement_id": "G-TWL9RRGMYF",
"property_id": "426621937",
"event_mapping": {},
"cart_data": {},
"client_id_strategy": "example_string",
"debug_mode": true
}'
import requests
import json
url = "https://mythic-analytics.gulp.workers.dev/client/v1/destinations/integrations/google_analytics"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"measurement_id": "G-TWL9RRGMYF",
"property_id": "426621937",
"event_mapping": {},
"cart_data": {},
"client_id_strategy": "example_string",
"debug_mode": true
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://mythic-analytics.gulp.workers.dev/client/v1/destinations/integrations/google_analytics", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"measurement_id": "G-TWL9RRGMYF",
"property_id": "426621937",
"event_mapping": {},
"cart_data": {},
"client_id_strategy": "example_string",
"debug_mode": true
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"measurement_id": "G-TWL9RRGMYF",
"property_id": "426621937",
"event_mapping": {},
"cart_data": {},
"client_id_strategy": "example_string",
"debug_mode": true
}`)
req, err := http.NewRequest("POST", "https://mythic-analytics.gulp.workers.dev/client/v1/destinations/integrations/google_analytics", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://mythic-analytics.gulp.workers.dev/client/v1/destinations/integrations/google_analytics')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"measurement_id": "G-TWL9RRGMYF",
"property_id": "426621937",
"event_mapping": {},
"cart_data": {},
"client_id_strategy": "example_string",
"debug_mode": true
}'
response = http.request(request)
puts response.body
{
"success": true,
"data": {
"platform": "example_string",
"destination_id": "example_string",
"tag_id": "example_string",
"browser_tag": true
}
}
{
"error": "Bad Request",
"message": "The request contains invalid parameters or malformed data",
"code": 400,
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
{
"error": "Unauthorized",
"message": "Authentication required. Please provide a valid API token",
"code": 401
}
{
"error": "Forbidden",
"message": "You don't have permission to access this resource",
"code": 403
}
{
"error": "Conflict",
"message": "The request conflicts with the current state of the resource",
"code": 409,
"details": "Resource already exists"
}
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. Please try again later",
"code": 429,
"retryAfter": 3600
}
/client/v1/destinations/integrations/google_analytics
Target server for requests. Edit to use your own host.
Client key as bearer token. Use an agency key (Bearer ak_...) for read-write access or a location secret key (Bearer sk_...) for read-only access. Scoped keys (mcp_) are accepted too and need destinations:read or destinations:write. See Using an mcp_ key over HTTP.
Bearer ak_...) for read-write access or a location secret key (Bearer sk_...) for read-only access. Scoped keys (mcp_) are accepted too and need destinations:read or destinations:write. See Using an mcp_ key over HTTP.
The media type of the request body
GA4 measurement id.
Numeric GA4 property id. The Data Manager API addresses the property by this, not by the measurement id.
Mythic event name -> GA4 event name. Merged OVER the commerce-spec default, so omit it unless renaming.
Google CartData config. REPLACES the commerce default wholesale — pass it only if your items live somewhere other than "items".
How to derive the GA4 client id without a page tag.
Route events into GA4 DebugView. Debug events are EXCLUDED from reports — leave off in production.
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. Client key as bearer token. Use an agency key (Bearer ak_...) for read-write access or a location secret key (Bearer sk_...) for read-only access. Scoped keys (mcp_) are accepted too and need destinations:read or destinations:write. See Using an mcp_ key over HTTP.
Body
Numeric GA4 property id. The Data Manager API addresses the property by this, not by the measurement id.
426621937Mythic event name -\> GA4 event name. Merged OVER the commerce-spec default, so omit it unless renaming.
Google CartData config. REPLACES the commerce default wholesale — pass it only if your items live somewhere other than "items".
How to derive the GA4 client id without a page tag.
Route events into GA4 DebugView. Debug events are EXCLUDED from reports — leave off in production.