Base URLs & Authentication
Base URLs
• API URL:
https://gtrack-api.wiremo.co• MCP URL:
https://gtrack-mcp.wiremo.co/?key=gtrk_live_XXXXXXXXXXXXXXXXXAuthentication
All endpoints require an API key header:
x-api-key: gtrk_live_XXXXXXXXXXXXXXXXX
scans:write - contact support for this elevated permission.
Rate Limits
| Plan | Reads/Hour | Writes/Hour |
|---|---|---|
| Business | 2000 | 1000 |
| Pro | 5000 | 2000 |
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
| Parameter | Type | Required | Description |
|---|---|---|---|
| center | Array [lat, lng] | Optional | Center coordinate for grid generation |
| coordinates | Array of [lat, lng] | Optional | Manual coordinates (use either center OR coordinates) |
| gridSize | Integer | Required | Grid dimension (3-13, e.g., 3 = 3x3 = 9 points) |
| distance | Number | Required | Distance from center (0.1+ km/miles) |
| unit | String | Required | "kilometer" or "mile" |
| scanType | String | Optional | "maps" (1 credit) or "local" (2 credits), defaults to "maps" |
| keyword | String | Required | Search keyword |
| placeId | String | Required | Google Place ID |
| customZoom | Integer | Optional | Zoom level 1-20 (default: 13, maps only) |
| language | String | Optional | ISO 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 Type | Multiplier | Formula |
|---|---|---|
| Maps | 1x | coordinates × keywords × 1 |
| Local | 2x | coordinates × keywords × 2 |
Examples: 9×1×maps=9 · 9×1×local=18
Common Error Codes
| Code | Description | Common Causes |
|---|---|---|
| 400 | Bad Request | Missing/invalid params, insufficient credits |
| 401 | Unauthorized | Missing API key, invalid format |
| 403 | Forbidden | Missing scope, feature not in plan, plan limit reached |
| 404 | Not Found | Resource absent, wrong owner, scan not completed |
| 500 | Internal Server Error | Scraper/DB/AI service error |
| 429 | Too Many Requests | Rate 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.
| Header | Value | Description |
|---|---|---|
Retry-After | Seconds (integer) | Number of seconds to wait before retrying |
Retry-After | HTTP Date | Specific date/time when you can retry |
Example Usage
Retry-After: 60 - Wait 60 seconds before retryingRetry-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
| Date | Version | Changes |
|---|---|---|
| 2025-10-22 | v1.0 | Initial release: scan management, competitor tracking, AI reports |
Need help?
Email [email protected]
Documentation 1.0
Last updated: 22 Oct 2025