API Reference

TagHelper API

Programmatically run GTM container audits, retrieve scores, and integrate TagHelper into your CI/CD pipeline or client reporting workflow.

Base URL: https://taghelper.io/api/v1Get an API key

Authentication

All API requests require authentication via a Bearer token in the Authorization header. API keys are available on the Pro and Agency plans.

Getting your API key:

  1. Go to Dashboard → API Keys
  2. Click Create Key and give it a name
  3. Copy the key immediately — it won't be shown again

Include the key in every request:

http
Authorization: Bearer th_live_xxxxxxxxxxxx

Keep your API keys secret. Do not expose them in client-side code, public repositories, or browser requests. Use environment variables and server-side calls only.

Endpoints

POST/api/v1/scan

Start a new GTM container audit. Returns a job ID that you can poll for status and results.

Request body

ParameterTypeRequiredDescription
container_idstringRequiredGTM container ID (e.g. "GTM-XXXXXX") or a URL containing a GTM container.
workspace_typestringOptional"ecommerce" or "lead_generation". Defaults to "ecommerce".

Response

json
{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending"
}

Example

bash
curl -X POST https://taghelper.io/api/v1/scan \
  -H "Authorization: Bearer th_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "container_id": "GTM-XXXXXX",
    "workspace_type": "ecommerce"
  }'
GET/api/v1/scan/:jobId

Check the status of a running audit. Poll this endpoint until status is "completed" or "failed".

Path parameters

ParameterTypeRequiredDescription
jobIdstringRequiredThe job ID returned by POST /scan.

Response

json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "input_type": "gtm_id",
  "input_value": "GTM-XXXXXX",
  "workspace_type": "ecommerce",
  "gtm_container_id": "GTM-XXXXXX",
  "audit_id": "660e8400-e29b-41d4-a716-446655440001",
  "score": 72,
  "score_label": "Good",
  "error_message": null,
  "created_at": "2026-02-21T10:00:00.000Z",
  "started_at": "2026-02-21T10:00:01.000Z",
  "completed_at": "2026-02-21T10:00:12.000Z"
}

Example

bash
curl https://taghelper.io/api/v1/scan/JOB_ID \
  -H "Authorization: Bearer th_live_xxxxxxxxxxxx"
GET/api/v1/scan/:jobId/result

Retrieve the full audit results including scores, issues, detected platforms, and recommendations.

Path parameters

ParameterTypeRequiredDescription
jobIdstringRequiredThe job ID returned by POST /scan.

Response

json
{
  "id": "660e8400-e29b-41d4-a716-446655440001",
  "score": 72,
  "score_label": "Good",
  "workspace_type": "ecommerce",
  "gtm_container_id": "GTM-XXXXXX",
  "summary": "Your GTM container has a solid foundation...",
  "category_scores": {
    "core_analytics": 85,
    "advertising_platforms": 60,
    "conversion_tracking": 75,
    "event_quality": 70,
    "data_quality": 80
  },
  "platforms_detected": {
    "ga4": true,
    "facebook_pixel": true,
    "google_ads": false,
    "tiktok": false,
    "linkedin": false,
    "other": ["hotjar"]
  },
  "events_detected": {
    "purchase": true,
    "add_to_cart": true,
    "begin_checkout": true,
    "view_item": false,
    "lead": false,
    "form_submission": false,
    "meeting_booking": false,
    "content_download": false,
    "custom_events": ["newsletter_signup"]
  },
  "issues": {
    "critical": [
      {
        "category": "conversion_tracking",
        "severity": "critical",
        "message": "Missing Google Ads conversion tag",
        "recommendation": "Add a Google Ads conversion tracking tag..."
      }
    ],
    "warnings": [
      {
        "category": "event_quality",
        "severity": "warning",
        "message": "view_item event not detected",
        "recommendation": "Implement the view_item event..."
      }
    ],
    "passed": [
      "GA4 configuration tag present",
      "Facebook Pixel properly initialized"
    ]
  },
  "created_at": "2026-02-21T10:00:12.000Z"
}

Example

bash
curl https://taghelper.io/api/v1/scan/JOB_ID/result \
  -H "Authorization: Bearer th_live_xxxxxxxxxxxx"

Rate Limits

Rate limits vary by plan tier. Exceeding the limit returns a 429 response with a Retry-After header.

LimitFreeProAgency
API access
Requests per minute60100
Audits per day2001,000
Audits per month50500
Max API keys35

Rate limit headers are included in every response:

http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1708520460

Error Codes

All errors return a consistent JSON format:

json
{
  "error": {
    "code": "invalid_request",
    "message": "container_id is required"
  }
}
HTTP StatusCodeDescription
400invalid_requestMissing or invalid request parameters.
401unauthorizedMissing or invalid API key.
403forbiddenAPI access not available on your plan, or key revoked.
404not_foundThe requested resource (job, audit) was not found.
422unprocessable_entityRequest body is valid JSON but contains semantic errors.
429rate_limit_exceededToo many requests. Check Retry-After header.
500internal_errorSomething went wrong on our end. Retry or contact support.

Full Examples

A complete workflow: start a scan, poll for completion, then fetch the full results.

1. Start the scan

bash
curl -X POST https://taghelper.io/api/v1/scan \
  -H "Authorization: Bearer th_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "container_id": "GTM-XXXXXX",
    "workspace_type": "ecommerce"
  }'

2. Poll until complete

javascript
// Poll until complete (JavaScript)
async function waitForScan(jobId, apiKey) {
  while (true) {
    const res = await fetch(
      `https://taghelper.io/api/v1/scan/${jobId}`,
      { headers: { Authorization: `Bearer ${apiKey}` } }
    );
    const data = await res.json();

    if (data.status === "completed") return data;
    if (data.status === "failed") throw new Error(data.error_message);

    await new Promise((r) => setTimeout(r, 3000)); // wait 3s
  }
}

3. Fetch full results

bash
curl https://taghelper.io/api/v1/scan/JOB_ID/result \
  -H "Authorization: Bearer th_live_xxxxxxxxxxxx"