Projects
Create a project
POST
/api/v1/projects
Plan limits apply (project count, minimum intervals). The first uptime, technical and DNS checks start automatically. If intervals.pagesMinutes is omitted while page crawling is on, your plan’s minimum is used.
- API key access
- Read and write
- Project permission
- None — acts on your own account
- Success
- 201 — Created
Request body
JSON, with Content-Type: application/json.
| Field | Type | Notes |
|---|---|---|
name required |
string | max 120 chars |
domain required |
string | |
trackingStatus |
"active" | "inactive" | default "active" |
phases |
object | |
phases.pages |
boolean | default true |
intervals |
object | |
intervals.uptimeMinutes |
integer | |
intervals.pagesMinutes |
integer | |
intervals.technicalMinutes |
integer | |
healthCheck |
object | |
healthCheck.verifyHeader |
boolean | |
healthCheck.headerName |
string | max 200 chars |
healthCheck.headerValueIncludes |
string | max 500 chars |
healthCheck.verifyContent |
boolean | |
healthCheck.contentIncludes |
string | max 2000 chars |
Example request
Replace tk_live_YOUR_KEY with your API key.
curl -X POST 'https://trackerv2.marketingplanet.global/api/v1/projects' \
-H 'Authorization: Bearer tk_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{
"name": "Acme Retail",
"domain": "acmeretail.com",
"intervals": {
"uptimeMinutes": 5
},
"healthCheck": {
"verifyContent": true,
"contentIncludes": "Add to cart"
}
}'
const response = await fetch('https://trackerv2.marketingplanet.global/api/v1/projects', {
method: 'POST',
headers: {
Authorization: 'Bearer tk_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Acme Retail",
"domain": "acmeretail.com",
"intervals": {
"uptimeMinutes": 5
},
"healthCheck": {
"verifyContent": true,
"contentIncludes": "Add to cart"
}
}),
});
const result = await response.json();
if (!response.ok) throw new Error(`${result.error.code}: ${result.error.message}`);
console.log(result.data);
import requests
response = requests.post(
"https://trackerv2.marketingplanet.global/api/v1/projects",
headers={"Authorization": "Bearer tk_live_YOUR_KEY"},
json={
"name": "Acme Retail",
"domain": "acmeretail.com",
"intervals": {
"uptimeMinutes": 5,
},
"healthCheck": {
"verifyContent": True,
"contentIncludes": "Add to cart",
},
},
)
result = response.json()
if not response.ok:
raise RuntimeError(f"{result['error']['code']}: {result['error']['message']}")
print(result["data"])
Example response
{
"data": {
"id": "6650a4c2e1b3d5f7a9c1e301",
"name": "Acme Retail",
"domain": "acmeretail.com",
"role": "owner",
"trackingStatus": "active",
"phases": {
"uptime": true,
"technical": true,
"sitemap": true,
"pages": true,
"robots": true,
"llm": false,
"udp": false,
"dns": true,
"domainExpiry": true,
"ports": true
},
"intervals": {
"uptimeMinutes": 5,
"pagesMinutes": 1440,
"technicalMinutes": 1440,
"dnsMinutes": 60
},
"uptime": {
"scheme": "https",
"port": null,
"timeoutSeconds": 30,
"alertRepeatMinutes": 60,
"lastStatus": "success",
"lastCheckedAt": "2026-10-06T09:25:12.000Z"
},
"healthCheck": {
"verifyHeader": false,
"headerName": "",
"headerValueIncludes": "",
"verifyContent": true,
"contentIncludes": "Add to cart"
},
"sitemap": {
"url": "https://acmeretail.com/sitemap.xml",
"status": "ok",
"lastCheckedAt": "2026-10-06T03:00:41.000Z",
"pagesFound": 128
},
"robotsUrl": null,
"llmUrl": null,
"domainExpiry": {
"status": "ok",
"daysLeft": 212,
"lastCheckedAt": "2026-10-05T03:00:00.000Z"
},
"technicalLastCheckedAt": "2026-10-06T03:00:45.000Z",
"cms": "wordpress",
"createdAt": "2026-05-24T10:12:00.000Z",
"updatedAt": "2026-10-06T09:25:12.000Z"
}
}
Response fields
| Field | Type | Notes |
|---|---|---|
data |
object | |
data.id |
string | |
data.name |
string | |
data.domain |
string | |
data.role |
"owner" | "member" | |
data.trackingStatus |
"active" | "inactive" | "paused-by-plan" | |
data.phases |
object | Which monitors are on. |
data.phases.uptime |
boolean | |
data.phases.technical |
boolean | |
data.phases.sitemap |
boolean | |
data.phases.pages |
boolean | |
data.phases.robots |
boolean | |
data.phases.llm |
boolean | |
data.phases.udp |
boolean | |
data.phases.dns |
boolean | |
data.phases.domainExpiry |
boolean | |
data.phases.ports |
boolean | |
data.intervals |
object | Minutes. Plan minimums apply. null when that monitor has no schedule yet. |
data.intervals.uptimeMinutes |
integer or null | |
data.intervals.pagesMinutes |
integer or null | |
data.intervals.technicalMinutes |
integer or null | |
data.intervals.dnsMinutes |
integer or null | |
data.uptime |
object | |
data.uptime.scheme |
"https" | "http" | |
data.uptime.port |
integer or null | |
data.uptime.timeoutSeconds |
integer | |
data.uptime.alertRepeatMinutes |
integer | |
data.uptime.lastStatus |
string or null | |
data.uptime.lastCheckedAt |
string (date-time) or null | |
data.healthCheck |
object | |
data.healthCheck.verifyHeader |
boolean | |
data.healthCheck.headerName |
string | max 200 chars |
data.healthCheck.headerValueIncludes |
string | max 500 chars |
data.healthCheck.verifyContent |
boolean | |
data.healthCheck.contentIncludes |
string | max 2000 chars |
data.sitemap |
object | |
data.sitemap.url |
string or null | |
data.sitemap.status |
string or null | |
data.sitemap.lastCheckedAt |
string (date-time) or null | |
data.sitemap.pagesFound |
integer | |
data.robotsUrl |
string or null | |
data.llmUrl |
string or null | |
data.domainExpiry |
object | |
data.domainExpiry.status |
string or null | |
data.domainExpiry.daysLeft |
integer or null | |
data.domainExpiry.lastCheckedAt |
string (date-time) or null | |
data.technicalLastCheckedAt |
string (date-time) or null | |
data.cms |
string or null | |
data.createdAt |
string (date-time) | |
data.updatedAt |
string (date-time) |
Errors
Besides the errors any request can return (bad or missing key, plan, scope, rate limit), this endpoint can return:
| Status | error.code | Meaning |
|---|---|---|
| 400 | invalid-request | A parameter or body field is missing or invalid; error.message says which. |
| 403 | plan-required | Start a trial or choose a plan before adding projects. |
| 403 | max-projects | Your plan’s project limit is reached; error.maxProjects gives the limit. |
| 403 | forbidden | The account is restricted: reads still work, but changes that add or modify projects, pages or monitors are blocked (error.accountStatus is restricted). |
| 409 | conflict | You already have a project for that domain. |
Errors always look like { "error": { "code": "…", "message": "…" } }. See Errors & limits.