Base URLs & Authentication

Base URLs
• API URL:  https://gtrack-api.wiremo.co
• MCP URL:  https://gtrack-mcp.wiremo.co/?key=gtrk_live_XXXXXXXXXXXXXXXXX
Authentication

All endpoints require an API key header:

x-api-key: gtrk_live_XXXXXXXXXXXXXXXXX
scans:write - contact support for this elevated permission.
Rate Limits
PlanReads/HourWrites/Hour
Business20001000
Pro50002000
Rate Limit Headers
X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset HTTP 429 is returned when limits are exceeded.

POST Initiate Scan – No Polling (with Center)

/api/initiate-scan

Creates a new scan using a center coordinate. Grid coordinates are auto-generated.

scans:write
ParameterTypeRequiredDescription
centerArray [lat, lng]OptionalCenter coordinate for grid generation
coordinatesArray of [lat, lng]OptionalManual coordinates (use either center OR coordinates)
gridSizeIntegerRequiredGrid dimension (3-13, e.g., 3 = 3x3 = 9 points)
distanceNumberRequiredDistance from center (0.1+ km/miles)
unitStringRequired"kilometer" or "mile"
scanTypeStringOptional"maps" (1 credit) or "local" (2 credits), defaults to "maps"
keywordStringRequiredSearch keyword
placeIdStringRequiredGoogle Place ID
customZoomIntegerOptionalZoom level 1-20 (default: 13, maps only)
languageStringOptionalISO language code (default: 'en')
Important: Provide either center or coordinates, not both. If neither provided, uses placeId coordinates as center.
Example with Coordinates Array
curl -X POST https://gtrack-api.wiremo.co/api/initiate-scan \
  -H "Content-Type: application/json" \
  -H "x-api-key: gtrk_demo_sample_key_here" \
  -d '{
    "coordinates": [
      [40.7128, -74.0060],
      [40.7138, -74.0070],
      [40.7148, -74.0080],
      [40.7158, -74.0090],
      [40.7168, -74.0100],
      [40.7178, -74.0110],
      [40.7188, -74.0120],
      [40.7198, -74.0130],
      [40.7208, -74.0140]
    ],
    "gridSize": 3,
    "scanType": "maps",
    "keyword": "pizza restaurant",
    "placeId": "ChIJN1t_tDeuEmsRUsoyG83frY4",
    "customZoom": 18,
    "language": "es"
  }'
curl -X POST https://gtrack-api.wiremo.co/api/initiate-scan \
  -H "Content-Type: application/json" \
  -H "x-api-key: gtrk_demo_sample_key_here" \
  -d '{
    "center": [40.7128, -74.0060],
    "gridSize": 5,
    "distance": 0.5,
    "unit": "kilometer",
    "scanType": "maps",
    "keyword": "coffee shop",
    "placeId": "ChIJOwg_06VPwokRYv534QaPC8g",
    "customZoom": 18,
    "language": "es"
  }'
import fetch from 'node-fetch';

const res = await fetch('https://gtrack-api.wiremo.co/api/initiate-scan', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'gtrk_demo_sample_key_here'
  },
  body: JSON.stringify({
    center: [40.7128, -74.0060],
    gridSize: 5,
    distance: 0.5,
    unit: 'kilometer',
    scanType: 'maps',
    keyword: 'coffee shop',
    placeId: 'ChIJOwg_06VPwokRYv534QaPC8g',
    customZoom: 18,
    language: 'es'
  })
});
console.log(await res.json());
import requests

url = 'https://gtrack-api.wiremo.co/api/initiate-scan'
headers = {'x-api-key': 'gtrk_demo_sample_key_here', 'Content-Type': 'application/json'}
payload = {
  'center': [40.7128, -74.0060],
  'gridSize': 5,
  'distance': 0.5,
  'unit': 'kilometer',
  'scanType': 'maps',
  'keyword': 'coffee shop',
  'placeId': 'ChIJOwg_06VPwokRYv534QaPC8g',
  'customZoom': 18,
  'language': 'es'
}
resp = requests.post(url, json=payload, headers=headers)
print(resp.json())
 [40.7128, -74.0060],
  'gridSize' => 5,
  'distance' => 0.5,
  'unit' => 'kilometer',
  'scanType' => 'maps',
  'keyword' => 'coffee shop',
  'placeId' => 'ChIJOwg_06VPwokRYv534QaPC8g',
  'customZoom' => 18,
  'language' => 'es'
];
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'x-api-key: gtrk_demo_sample_key_here'
  ],
  CURLOPT_POSTFIELDS => json_encode($payload)
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
import { useState } from 'react';

export default function StartScan(){
  const [result,setResult] = useState(null);
  const start = async () => {
    const res = await fetch('https://gtrack-api.wiremo.co/api/initiate-scan', {
      method: 'POST',
      headers: { 'Content-Type':'application/json', 'x-api-key':'gtrk_demo_sample_key_here' },
      body: JSON.stringify({
        center: [40.7128, -74.0060], 
        gridSize: 5, 
        distance: 0.5, 
        unit: 'kilometer',
        scanType: 'maps', 
        keyword: 'coffee shop', 
        placeId: 'ChIJOwg_06VPwokRYv534QaPC8g',
        customZoom: 18,
        language: 'es'
      })
    });
    setResult(await res.json());
  };
  return (
    
{JSON.stringify(result,null,2)}
); }
200 OK example shown earlier in original docs.
Errors: 403 missing scans:write, 400 insufficient credits / invalid params, 404 user not found, 500 scraper unavailable.

POST Initiate Scan – With Polling

/api/initiate-scan?wait=true&timeout=300
Polling: initial delay 5s · interval 30s · max 600s. Returns full results when status = COMPLETED.
curl -X POST "https://gtrack-api.wiremo.co/api/initiate-scan?wait=true&timeout=300" \
  -H "Content-Type: application/json" \
  -H "x-api-key: gtrk_demo_sample_key_here" \
  -d '{
    "center": [51.5074, -0.1278],
    "gridSize": 4,
    "distance": 0.3,
    "unit": "kilometer",
    "scanType": "maps",
    "keyword": "hotel",
    "placeId": "ChIJ3S-JXmauEmsRUcIaWtf4MzE",
    "customZoom": 18,
    "language": "es"
  }'
import fetch from 'node-fetch';

const url = 'https://gtrack-api.wiremo.co/api/initiate-scan?wait=true&timeout=300';
const payload = {
  center: [51.5074, -0.1278],
  gridSize: 3,
  distance: 300,
  unit: 'kilometer',
  scanType: 'both',
  keyword: 'hotel',
  placeId: 'ChIJ3S-JXmauEmsRUcIaWtf4MzE',
  businessName: 'The London Hotel'
};

const res = await fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'gtrk_live_0202d7fcf814dd6f09d0feee'
  },
  body: JSON.stringify(payload)
});
console.log(await res.json());
 [51.5074, -0.1278],
  'gridSize' => 4,
  'distance' => 0.3,
  'unit' => 'kilometer',
  'scanType' => 'maps',
  'keyword' => 'hotel',
  'placeId' => 'ChIJ3S-JXmauEmsRUcIaWtf4MzE',
  'customZoom' => 18,
  'language' => 'es'
];

curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'x-api-key: gtrk_demo_sample_key_here'
  ],
  CURLOPT_POSTFIELDS => json_encode($payload)
]);

$response = curl_exec($ch);

if ($response === false) {
  $error = curl_error($ch);
  curl_close($ch);
  http_response_code(500);
  echo json_encode(['error' => $error], JSON_PRETTY_PRINT);
  exit;
}

curl_close($ch);
header('Content-Type: application/json');
echo $response;
?>
import { useState } from 'react';

export default function StartScan() {
  const [result, setResult] = useState(null);
  const [error, setError] = useState(null);
  const start = async () => {
    setError(null);
    setResult(null);
    try {
      const res = await fetch('https://gtrack-api.wiremo.co/api/initiate-scan?wait=true&timeout=300', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-api-key': 'gtrk_demo_sample_key_here'
        },
        body: JSON.stringify({
          center: [51.5074, -0.1278],
          gridSize: 4,
          distance: 0.3,
          unit: 'kilometer',
          scanType: 'maps',
          keyword: 'hotel',
          placeId: 'ChIJ3S-JXmauEmsRUcIaWtf4MzE',
          customZoom: 18,
          language: 'es'
        })
      });

      const data = await res.json().catch(() => null);
      if (!res.ok) {
        throw new Error(data?.message || 'Request failed');
      }
      setResult(data);
    } catch (e) {
      setError(e.message);
    }
  };

  return (
    
{error &&
{error}
} {result &&
{JSON.stringify(result, null, 2)}
}
); }
import requests

url = 'https://gtrack-api.wiremo.co/api/initiate-scan'
params = {'wait': 'true', 'timeout': 300}
headers = {'x-api-key': 'gtrk_live_0202d7fcf814dd6f09d0feee', 'Content-Type': 'application/json'}
payload = {
  'center': [51.5074, -0.1278],
  'gridSize': 3,
  'distance': 300,
  'unit': 'kilometer',
  'scanType': 'both',
  'keyword': 'hotel',
  'placeId': 'ChIJ3S-JXmauEmsRUcIaWtf4MzE',
  'businessName': 'The London Hotel'
}
resp = requests.post(url, params=params, json=payload, headers=headers)
print(resp.json())
 [51.5074, -0.1278],
  'gridSize' => 4,
  'distance' => 0.3,
  'unit' => 'kilometer',
  'scanType' => 'maps',
  'keyword' => 'hotel',
  'placeId' => 'ChIJ3S-JXmauEmsRUcIaWtf4MzE',
  'customZoom' => 18,
  'language' => 'es'
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'Content-Type: application/json',
  'x-api-key: gtrk_demo_sample_key_here'
]);

$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
import { useState } from 'react';

function ScanWithPolling() {
  const [results, setResults] = useState(null);
  const [loading, setLoading] = useState(false);

  const startScan = async () => {
    setLoading(true);
    const response = await fetch(
      'https://gtrack-api.wiremo.co/api/initiate-scan?wait=true&timeout=300',
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-api-key': 'gtrk_demo_sample_key_here'
        },
        body: JSON.stringify({
          center: [51.5074, -0.1278],
          gridSize: 4,
          distance: 0.3,
          unit: 'kilometer',
          scanType: 'maps',
          keyword: 'hotel',
          placeId: 'ChIJ3S-JXmauEmsRUcIaWtf4MzE',
          customZoom: 18,
          language: 'es'
        })
      }
    );
    const data = await response.json();
    setResults(data);
    setLoading(false);
  };

  return (
    
{results &&
{JSON.stringify(results, null, 2)}
}
); }
Returns COMPLETED payload or a timeout envelope advising to poll by taskId.

POST Generate Grid Coordinates

/api/generate-grid

Generates grid coordinates without initiating a scan.

curl -X POST https://gtrack-api.wiremo.co/api/generate-grid \
  -H "x-api-key: gtrk_demo_sample_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "center": [28.0833107, -16.7223283],
    "gridSize": 3,
    "distance": 8,
    "unit": "kilometer"
  }'
import fetch from 'node-fetch';

const res = await fetch('https://gtrack-api.wiremo.co/api/generate-grid', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'gtrk_demo_sample_key_here'
  },
  body: JSON.stringify({
    center: [28.0833107, -16.7223283],
    gridSize: 3,
    distance: 8,
    unit: 'kilometer'
  })
});
console.log(await res.json());
import requests

url = 'https://gtrack-api.wiremo.co/api/generate-grid'
headers = {'x-api-key': 'gtrk_demo_sample_key_here', 'Content-Type': 'application/json'}
payload = {
  'center': [28.0833107, -16.7223283],
  'gridSize': 3,
  'distance': 8,
  'unit': 'kilometer'
}
resp = requests.post(url, json=payload, headers=headers)
print(resp.json())
 [40.7128, -74.0060],
  'gridSize' => 5,
  'distance' => 1.0,
  'unit' => 'kilometer'
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'Content-Type: application/json',
  'x-api-key: gtrk_demo_sample_key_here'
]);

$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
import { useState } from 'react';

function GenerateGrid() {
  const [grid, setGrid] = useState([]);

  const generateGrid = async () => {
    const response = await fetch('https://gtrack-api.wiremo.co/api/generate-grid', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'gtrk_demo_sample_key_here'
      },
      body: JSON.stringify({
        center: [40.7128, -74.0060],
        gridSize: 5,
        distance: 1.0,
        unit: 'kilometer'
      })
    });
    const data = await response.json();
    setGrid(data.coordinates);
  };

  return (
    
{grid.length > 0 &&

Generated {grid.length} coordinates

}
); }

GET Get Scan Status / Results

/api/fullstatus/scan/:taskId/status

Get the current status and results of a scan by task ID.

Errors: 404 not found/ownership, 403 forbidden.
curl -X GET https://gtrack-api.wiremo.co/api/fullstatus/scan/TASK_ID_HERE/status \
  -H "x-api-key: gtrk_demo_sample_key_here" \
  -H "Content-Type: application/json"
import fetch from 'node-fetch';

const taskId = 'TASK_ID_HERE';
const res = await fetch(`https://gtrack-api.wiremo.co/api/fullstatus/scan/${taskId}/status`, {
  method: 'GET',
  headers: {
    'x-api-key': 'gtrk_demo_sample_key_here',
    'Content-Type': 'application/json'
  }
});
console.log(await res.json());
import requests

task_id = 'TASK_ID_HERE'
url = f'https://gtrack-api.wiremo.co/api/fullstatus/scan/{task_id}/status'
headers = {'x-api-key': 'gtrk_demo_sample_key_here', 'Content-Type': 'application/json'}
resp = requests.get(url, headers=headers)
print(resp.json())
<?php
$taskId = 'TASK_ID_HERE';
$url = "https://gtrack-api.wiremo.co/api/fullstatus/scan/{$taskId}/status";
$headers = [
  'x-api-key: gtrk_demo_sample_key_here',
  'Content-Type: application/json'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>
import React, { useState, useEffect } from 'react';

function ScanStatus({ taskId }) {
  const [status, setStatus] = useState(null);

  useEffect(() => {
    const fetchStatus = async () => {
      const response = await fetch(`https://gtrack-api.wiremo.co/api/fullstatus/scan/${taskId}/status`, {
        headers: {
          'x-api-key': 'gtrk_demo_sample_key_here',
          'Content-Type': 'application/json'
        }
      });
      const data = await response.json();
      setStatus(data);
    };
    if (taskId) fetchStatus();
  }, [taskId]);

  return (
    
{status &&
{JSON.stringify(status, null, 2)}
}
); }

GET List All Scans

/api/scans

Retrieve all scans for the authenticated user.

curl -X GET https://gtrack-api.wiremo.co/api/scans \
  -H "x-api-key: gtrk_demo_sample_key_here" \
  -H "Content-Type: application/json"
import fetch from 'node-fetch';

const res = await fetch('https://gtrack-api.wiremo.co/api/scans', {
  method: 'GET',
  headers: {
    'x-api-key': 'gtrk_demo_sample_key_here',
    'Content-Type': 'application/json'
  }
});
console.log(await res.json());
import requests

url = 'https://gtrack-api.wiremo.co/api/scans'
headers = {'x-api-key': 'gtrk_demo_sample_key_here', 'Content-Type': 'application/json'}
resp = requests.get(url, headers=headers)
print(resp.json())
<?php
$url = 'https://gtrack-api.wiremo.co/api/scans';
$headers = [
  'x-api-key: gtrk_demo_sample_key_here',
  'Content-Type: application/json'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>
import React, { useState, useEffect } from 'react';

function ScanList() {
  const [scans, setScans] = useState([]);

  useEffect(() => {
    const fetchScans = async () => {
      const response = await fetch('https://gtrack-api.wiremo.co/api/scans', {
        headers: {
          'x-api-key': 'gtrk_demo_sample_key_here',
          'Content-Type': 'application/json'
        }
      });
      const data = await response.json();
      setScans(data);
    };
    fetchScans();
  }, []);

  return (
    
{scans.map(scan => (
{scan.taskId}
))}
); }

GET Get All Tracked Businesses

/api/tracked-businesses

Retrieve all tracked businesses for the authenticated user.

curl -X GET https://gtrack-api.wiremo.co/api/tracked-businesses \
  -H "x-api-key: gtrk_demo_sample_key_here" \
  -H "Content-Type: application/json"
import fetch from 'node-fetch';

const res = await fetch('https://gtrack-api.wiremo.co/api/tracked-businesses', {
  method: 'GET',
  headers: {
    'x-api-key': 'gtrk_demo_sample_key_here',
    'Content-Type': 'application/json'
  }
});
console.log(await res.json());
import requests

url = 'https://gtrack-api.wiremo.co/api/tracked-businesses'
headers = {'x-api-key': 'gtrk_demo_sample_key_here', 'Content-Type': 'application/json'}
resp = requests.get(url, headers=headers)
print(resp.json())
<?php
$url = 'https://gtrack-api.wiremo.co/api/tracked-businesses';
$headers = [
  'x-api-key: gtrk_demo_sample_key_here',
  'Content-Type: application/json'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>
import React, { useState, useEffect } from 'react';

function TrackedBusinessesList() {
  const [businesses, setBusinesses] = useState([]);

  useEffect(() => {
    const fetchBusinesses = async () => {
      const response = await fetch('https://gtrack-api.wiremo.co/api/tracked-businesses', {
        headers: {
          'x-api-key': 'gtrk_demo_sample_key_here',
          'Content-Type': 'application/json'
        }
      });
      const data = await response.json();
      setBusinesses(data);
    };
    fetchBusinesses();
  }, []);

  return (
    
{businesses.map(business => (
{business.businessName}
))}
); }

POST Add Tracked Business

/api/tracked-businesses

businesses:write

curl -X POST https://gtrack-api.wiremo.co/api/tracked-businesses \
  -H "x-api-key: gtrk_demo_sample_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "placeId": "ChIJ9X1uQniZagwR8nA2NqxFEb8",
    "businessName": "Dulce Vegan",
    "trackingParams": {"rating": true, "reviewCount": true, "position": false, "hours": false},
    "alertThresholds": {"ratingChange": 0.5, "reviewCountChange": 10},
    "alertFrequency": "daily",
    "alertEmail": "[email protected]"
  }'
import fetch from 'node-fetch';

const res = await fetch('https://gtrack-api.wiremo.co/api/tracked-businesses', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'gtrk_live_0202d7fcf814dd6f09d0feee'
  },
  body: JSON.stringify({
    placeId: 'ChIJ9X1uQniZagwR8nA2NqxFEb8',
    businessName: 'Dulce Vegan',
    trackingParams: { rating: true, reviewCount: true, position: false, hours: false },
    alertThresholds: { ratingChange: 0.5, reviewCountChange: 10 },
    alertFrequency: 'daily',
    alertEmail: '[email protected]'
  })
});
console.log(await res.json());
<?php
$ch = curl_init('https://gtrack-api.wiremo.co/api/tracked-businesses');

$payload = [
  'placeId' => 'ChIJ9X1uQniZagwR8nA2NqxFEb8',
  'businessName' => 'Dulce Vegan',
  'trackingParams' => [
    'rating' => true,
    'reviewCount' => true,
    'position' => false,
    'hours' => false
  ],
  'alertThresholds' => [
    'ratingChange' => 0.5,
    'reviewCountChange' => 10
  ],
  'alertFrequency' => 'daily',
  'alertEmail' => '[email protected]'
];

curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'x-api-key: gtrk_live_0202d7fcf814dd6f09d0feee'
  ],
  CURLOPT_POSTFIELDS => json_encode($payload)
]);

$response = curl_exec($ch);
if ($response === false) {
  http_response_code(500);
  echo 'cURL error: ' . curl_error($ch);
} else {
  header('Content-Type: application/json');
  echo $response;
}

curl_close($ch);
?>
import requests

url = 'https://gtrack-api.wiremo.co/api/tracked-businesses'
headers = {'x-api-key': 'gtrk_demo_sample_key_here', 'Content-Type': 'application/json'}
payload = {
  'placeId': 'ChIJ9X1uQniZagwR8nA2NqxFEb8',
  'businessName': 'Dulce Vegan',
  'trackingParams': {'rating': True, 'reviewCount': True, 'position': False, 'hours': False},
  'alertThresholds': {'ratingChange': 0.5, 'reviewCountChange': 10},
  'alertFrequency': 'daily',
  'alertEmail': '[email protected]'
}
resp = requests.post(url, json=payload, headers=headers)
print(resp.json())
import React, { useState } from 'react';

function AddTrackedBusiness() {
  const [result, setResult] = useState(null);
  const [loading, setLoading] = useState(false);

  const addBusiness = async () => {
    setLoading(true);
    const response = await fetch('https://gtrack-api.wiremo.co/api/tracked-businesses', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'gtrk_demo_sample_key_here'
      },
      body: JSON.stringify({
        placeId: 'ChIJ9X1uQniZagwR8nA2NqxFEb8',
        businessName: 'Dulce Vegan',
        trackingParams: { rating: true, reviewCount: true, position: false, hours: false },
        alertThresholds: { ratingChange: 0.5, reviewCountChange: 10 },
        alertFrequency: 'daily',
        alertEmail: '[email protected]'
      })
    });
    const data = await response.json();
    setResult(data);
    setLoading(false);
  };

  return (
    
{result &&
{JSON.stringify(result, null, 2)}
}
); }
Errors: plan limit reached, too many tracking params for plan.

GET List AI Reports

/reports-ai/reports/list

Retrieve all saved AI scan reports for the authenticated user.

curl -X GET https://gtrack-api.wiremo.co/reports-ai/reports/list \
  -H "x-api-key: gtrk_demo_sample_key_here" \
  -H "Content-Type: application/json"
import fetch from 'node-fetch';

const res = await fetch('https://gtrack-api.wiremo.co/reports-ai/reports/list', {
  method: 'GET',
  headers: {
    'x-api-key': 'gtrk_demo_sample_key_here',
    'Content-Type': 'application/json'
  }
});
console.log(await res.json());
import requests

url = 'https://gtrack-api.wiremo.co/reports-ai/reports/list'
headers = {'x-api-key': 'gtrk_demo_sample_key_here', 'Content-Type': 'application/json'}
resp = requests.get(url, headers=headers)
print(resp.json())
<?php
$url = 'https://gtrack-api.wiremo.co/reports-ai/reports/list';
$headers = [
  'x-api-key: gtrk_demo_sample_key_here',
  'Content-Type: application/json'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>
import React, { useState, useEffect } from 'react';

function AIReportsList() {
  const [reports, setReports] = useState([]);

  useEffect(() => {
    const fetchReports = async () => {
      const response = await fetch('https://gtrack-api.wiremo.co/reports-ai/reports/list', {
        headers: {
          'x-api-key': 'gtrk_demo_sample_key_here',
          'Content-Type': 'application/json'
        }
      });
      const data = await response.json();
      setReports(data);
    };
    fetchReports();
  }, []);

  return (
    
{reports.map(report => (
{report.title}
))}
); }

GET Get AI Report Details

/reports-ai/reports/:reportId

Get detailed data for a specific AI scan report.

curl -X GET https://gtrack-api.wiremo.co/reports-ai/reports/REPORT_ID_HERE \
  -H "x-api-key: gtrk_demo_sample_key_here" \
  -H "Content-Type: application/json"
import fetch from 'node-fetch';

const reportId = 'REPORT_ID_HERE';
const res = await fetch(`https://gtrack-api.wiremo.co/reports-ai/reports/${reportId}`, {
  method: 'GET',
  headers: {
    'x-api-key': 'gtrk_demo_sample_key_here',
    'Content-Type': 'application/json'
  }
});
console.log(await res.json());
import requests

report_id = 'REPORT_ID_HERE'
url = f'https://gtrack-api.wiremo.co/reports-ai/reports/{report_id}'
headers = {'x-api-key': 'gtrk_demo_sample_key_here', 'Content-Type': 'application/json'}
resp = requests.get(url, headers=headers)
print(resp.json())
<?php
$reportId = 'REPORT_ID_HERE';
$url = "https://gtrack-api.wiremo.co/reports-ai/reports/{$reportId}";
$headers = [
  'x-api-key: gtrk_demo_sample_key_here',
  'Content-Type: application/json'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>
import React, { useState, useEffect } from 'react';

function AIReportDetails({ reportId }) {
  const [report, setReport] = useState(null);

  useEffect(() => {
    const fetchReport = async () => {
      const response = await fetch(`https://gtrack-api.wiremo.co/reports-ai/reports/${reportId}`, {
        headers: {
          'x-api-key': 'gtrk_demo_sample_key_here',
          'Content-Type': 'application/json'
        }
      });
      const data = await response.json();
      setReport(data);
    };
    fetchReport();
  }, [reportId]);

  return (
    
{report &&
{report.title}
}
); }

DELETE Delete AI Report

/reports-ai/reports/:reportId

Delete a specific AI scan report permanently.

curl -X DELETE https://gtrack-api.wiremo.co/reports-ai/reports/REPORT_ID_HERE \
  -H "x-api-key: gtrk_demo_sample_key_here" \
  -H "Content-Type: application/json"
import fetch from 'node-fetch';

const reportId = 'REPORT_ID_HERE';
const res = await fetch(`https://gtrack-api.wiremo.co/reports-ai/reports/${reportId}`, {
  method: 'DELETE',
  headers: {
    'x-api-key': 'gtrk_demo_sample_key_here',
    'Content-Type': 'application/json'
  }
});
console.log(await res.json());
import requests

report_id = 'REPORT_ID_HERE'
url = f'https://gtrack-api.wiremo.co/reports-ai/reports/{report_id}'
headers = {'x-api-key': 'gtrk_demo_sample_key_here', 'Content-Type': 'application/json'}
resp = requests.delete(url, headers=headers)
print(resp.json())
<?php
$reportId = 'REPORT_ID_HERE';
$url = "https://gtrack-api.wiremo.co/reports-ai/reports/{$reportId}";
$headers = [
  'x-api-key: gtrk_demo_sample_key_here',
  'Content-Type: application/json'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>
import React from 'react';

function DeleteAIReport({ reportId, onDelete }) {
  const handleDelete = async () => {
    const response = await fetch(`https://gtrack-api.wiremo.co/reports-ai/reports/${reportId}`, {
      method: 'DELETE',
      headers: {
        'x-api-key': 'gtrk_demo_sample_key_here',
        'Content-Type': 'application/json'
      }
    });
    const result = await response.json();
    onDelete(result);
  };

  return (
    
  );
}

Credit Calculation

Scan TypeMultiplierFormula
Maps1xcoordinates × keywords × 1
Local2xcoordinates × keywords × 2
Examples: 9×1×maps=9 · 9×1×local=18

Common Error Codes

CodeDescriptionCommon Causes
400Bad RequestMissing/invalid params, insufficient credits
401UnauthorizedMissing API key, invalid format
403ForbiddenMissing scope, feature not in plan, plan limit reached
404Not FoundResource absent, wrong owner, scan not completed
500Internal Server ErrorScraper/DB/AI service error
429Too Many RequestsRate limits exceeded; see Retry-After

Retry-After Header

When you receive a 429 (Too Many Requests) response, the server includes a Retry-After header indicating when you can retry your request.

HeaderValueDescription
Retry-AfterSeconds (integer)Number of seconds to wait before retrying
Retry-AfterHTTP DateSpecific date/time when you can retry
Example Usage
Retry-After: 60 - Wait 60 seconds before retrying
Retry-After: Wed, 21 Oct 2015 07:28:00 GMT - Retry after this specific time

Best Practices

Security
  • Never expose API keys in client-side code
  • Rotate keys; use separate keys per env
  • Prefer IP restrictions
Performance
  • Use polling only when immediate results are needed
  • Cache results; paginate large lists
  • Generate grid once; reuse
Cost Optimization
  • Prefer maps (1x) unless local pack is required
  • Start with smaller grids; schedule scans
  • Check credits before large runs
Error Handling
  • Handle 400/403 for credits/scopes
  • Retry 5xx with backoff
  • Poll status if not using wait=true

Changelog

DateVersionChanges
2025-10-22v1.0Initial release: scan management, competitor tracking, AI reports
Need help?
Documentation 1.0 Last updated: 22 Oct 2025