Documentation contents
Campaigns
Reusable crawl configurations and their schedule.
List the campaigns of a project
GET
/v1/projects/{project}/campaigns
Reusable crawl configurations and their schedule, newest first.
- Required scopes
- projects:read
- Rate-limit cost
- 1 unit(s)
Parameters
-
projectpath · string (uuid) · required -
cursorquery · string · optionalOpaque cursor from `meta.next_cursor`. It is bound to the request that issued it; reusing it with other filters returns `400 pagination.invalid_cursor`.
-
limitquery · integer · optionalItems per page, 1 to 100 (default 25).
Responses
-
200OK. -
400Malformed request, such as an invalid pagination cursor (`pagination.invalid_cursor`). -
422Invalid query or body values (`validation_failed`), with `errors` by field. -
401Missing, invalid or expired token, or a member who left the team. -
403The plan does not include the API (`api.not_in_plan`) or this verb (`api.write_not_in_plan`), or the token lacks a scope (`token.missing_scope`). -
404No such resource for the token's team. Resources of another team answer 404 as well, never 403. -
429The plan rate limit is exhausted for one window.
cURL
curl "https://api.nessflow.com/v1/projects/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57/campaigns" \
-H "Authorization: Bearer $NESSFLOW_TOKEN"
PHP
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.nessflow.com/v1/']);
$response = $client->request('GET', 'projects/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57/campaigns', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NESSFLOW_TOKEN'),
],
]);
$data = json_decode((string) $response->getBody(), true);
JavaScript
const response = await fetch('https://api.nessflow.com/v1/projects/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57/campaigns', {
headers: {
Authorization: `Bearer ${process.env.NESSFLOW_TOKEN}`,
},
});
const data = await response.json();
Python
import os
import requests
response = requests.get(
"https://api.nessflow.com/v1/projects/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57/campaigns",
headers={
"Authorization": f"Bearer {os.environ['NESSFLOW_TOKEN']}",
},
timeout=30,
)
response.raise_for_status()
data = response.json()
Response example
{
"data": [
{
"id": "0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57",
"project_id": "0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57",
"name": "Exemple",
"start_url": "https://exemple.fr/",
"max_depth": 42,
"max_urls": 42,
"javascript_rendering": true,
"pagespeed": true,
"check_external_links": true,
"check_ai_reachability": true,
"check_accessibility": true,
"protected_site": true,
"schedule": {
"frequency": "manual",
"day": "string",
"time": "string",
"paused": true,
"next_run_at": "string"
},
"created_at": "2026-10-01T09:30:00Z"
}
],
"meta": {
"limit": 100,
"has_more": true,
"next_cursor": "string"
}
}
Create a campaign
POST
/v1/projects/{project}/campaigns
Same validation and plan bounds as the product (URL budget, JavaScript rendering, schedule frequencies). Unknown fields are refused, never ignored.
- Required scopes
- projects:write
- Rate-limit cost
- 1 unit(s)
- Idempotency-Key
- Idempotency-Key accepted
Parameters
-
projectpath · string (uuid) · required
Request body
-
namestring · required -
start_urlstring · required -
max_depthinteger · required -
max_urlsinteger · required -
javascript_renderingboolean · optional -
pagespeedboolean · optional -
check_external_linksboolean · optional -
check_ai_reachabilityboolean · optional -
check_accessibilityboolean · optional -
check_accessibility_renderedboolean · optional -
include_patternsstring | null · optional -
exclude_patternsstring | null · optional -
issue_exclusion_patternsstring | null · optional -
timeoutinteger | null · optional -
retriesinteger | null · optional -
duplication_thresholdnumber | null · optional -
regression_thresholdstring · optionalValues (off, warning, error)
-
protected_siteboolean · optional -
http_userstring | null · optional -
http_passwordstring | null · optional -
notifyboolean · optional -
scheduleobject · optional
Responses
-
201OK. -
400Malformed request, such as an invalid pagination cursor (`pagination.invalid_cursor`). -
401Missing, invalid or expired token, or a member who left the team. -
403The plan does not include the API (`api.not_in_plan`) or this verb (`api.write_not_in_plan`), or the token lacks a scope (`token.missing_scope`). -
404No such resource for the token's team. Resources of another team answer 404 as well, never 403. -
409The request conflicts with the current state (a crawl already running, an idempotency key in use, a project not ready). -
422Invalid query or body values (`validation_failed`), with `errors` by field. -
429The plan rate limit is exhausted for one window.
cURL
curl -X POST "https://api.nessflow.com/v1/projects/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57/campaigns" \
-H "Authorization: Bearer $NESSFLOW_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"name":"Exemple","start_url":"https://exemple.fr/","max_depth":42,"max_urls":42,"javascript_rendering":true,"pagespeed":true,"check_external_links":true,"check_ai_reachability":true,"check_accessibility":true,"check_accessibility_rendered":true,"include_patterns":"string","exclude_patterns":"string","issue_exclusion_patterns":"string","timeout":42,"retries":42,"duplication_threshold":0.5,"regression_threshold":"off","protected_site":true,"http_user":"string","http_password":"string","notify":true,"schedule":{"frequency":"manual","day":"string","time":"string"}}'
PHP
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.nessflow.com/v1/']);
$response = $client->request('POST', 'projects/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57/campaigns', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NESSFLOW_TOKEN'),
'Idempotency-Key' => bin2hex(random_bytes(16)),
],
'json' => [
'name' => 'Exemple',
'start_url' => 'https://exemple.fr/',
'max_depth' => 42,
'max_urls' => 42,
'javascript_rendering' => true,
'pagespeed' => true,
'check_external_links' => true,
'check_ai_reachability' => true,
'check_accessibility' => true,
'check_accessibility_rendered' => true,
'include_patterns' => 'string',
'exclude_patterns' => 'string',
'issue_exclusion_patterns' => 'string',
'timeout' => 42,
'retries' => 42,
'duplication_threshold' => 0.5,
'regression_threshold' => 'off',
'protected_site' => true,
'http_user' => 'string',
'http_password' => 'string',
'notify' => true,
'schedule' => [
'frequency' => 'manual',
'day' => 'string',
'time' => 'string',
],
],
]);
$data = json_decode((string) $response->getBody(), true);
JavaScript
const response = await fetch('https://api.nessflow.com/v1/projects/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57/campaigns', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NESSFLOW_TOKEN}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"name": "Exemple",
"start_url": "https://exemple.fr/",
"max_depth": 42,
"max_urls": 42,
"javascript_rendering": true,
"pagespeed": true,
"check_external_links": true,
"check_ai_reachability": true,
"check_accessibility": true,
"check_accessibility_rendered": true,
"include_patterns": "string",
"exclude_patterns": "string",
"issue_exclusion_patterns": "string",
"timeout": 42,
"retries": 42,
"duplication_threshold": 0.5,
"regression_threshold": "off",
"protected_site": true,
"http_user": "string",
"http_password": "string",
"notify": true,
"schedule": {
"frequency": "manual",
"day": "string",
"time": "string"
}
}),
});
const data = await response.json();
Python
import os
import uuid
import requests
response = requests.post(
"https://api.nessflow.com/v1/projects/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57/campaigns",
headers={
"Authorization": f"Bearer {os.environ['NESSFLOW_TOKEN']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"name": "Exemple",
"start_url": "https://exemple.fr/",
"max_depth": 42,
"max_urls": 42,
"javascript_rendering": True,
"pagespeed": True,
"check_external_links": True,
"check_ai_reachability": True,
"check_accessibility": True,
"check_accessibility_rendered": True,
"include_patterns": "string",
"exclude_patterns": "string",
"issue_exclusion_patterns": "string",
"timeout": 42,
"retries": 42,
"duplication_threshold": 0.5,
"regression_threshold": "off",
"protected_site": True,
"http_user": "string",
"http_password": "string",
"notify": True,
"schedule": {
"frequency": "manual",
"day": "string",
"time": "string",
},
},
timeout=30,
)
response.raise_for_status()
data = response.json()
Response example
{
"data": {
"id": "0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57",
"project_id": "0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57",
"name": "Exemple",
"start_url": "https://exemple.fr/",
"max_depth": 42,
"max_urls": 42,
"javascript_rendering": true,
"pagespeed": true,
"check_external_links": true,
"check_ai_reachability": true,
"check_accessibility": true,
"protected_site": true,
"schedule": {
"frequency": "manual",
"day": "string",
"time": "string",
"paused": true,
"next_run_at": "string"
},
"created_at": "2026-10-01T09:30:00Z"
}
}
Get a campaign
GET
/v1/campaigns/{campaign}
A crawl configuration and its schedule. HTTP credentials are never returned.
- Required scopes
- projects:read
- Rate-limit cost
- 1 unit(s)
Parameters
-
campaignpath · string (uuid) · required
Responses
-
200OK. -
401Missing, invalid or expired token, or a member who left the team. -
403The plan does not include the API (`api.not_in_plan`) or this verb (`api.write_not_in_plan`), or the token lacks a scope (`token.missing_scope`). -
404No such resource for the token's team. Resources of another team answer 404 as well, never 403. -
429The plan rate limit is exhausted for one window.
cURL
curl "https://api.nessflow.com/v1/campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57" \
-H "Authorization: Bearer $NESSFLOW_TOKEN"
PHP
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.nessflow.com/v1/']);
$response = $client->request('GET', 'campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NESSFLOW_TOKEN'),
],
]);
$data = json_decode((string) $response->getBody(), true);
JavaScript
const response = await fetch('https://api.nessflow.com/v1/campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57', {
headers: {
Authorization: `Bearer ${process.env.NESSFLOW_TOKEN}`,
},
});
const data = await response.json();
Python
import os
import requests
response = requests.get(
"https://api.nessflow.com/v1/campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57",
headers={
"Authorization": f"Bearer {os.environ['NESSFLOW_TOKEN']}",
},
timeout=30,
)
response.raise_for_status()
data = response.json()
Response example
{
"data": {
"id": "0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57",
"project_id": "0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57",
"name": "Exemple",
"start_url": "https://exemple.fr/",
"max_depth": 42,
"max_urls": 42,
"javascript_rendering": true,
"pagespeed": true,
"check_external_links": true,
"check_ai_reachability": true,
"check_accessibility": true,
"protected_site": true,
"schedule": {
"frequency": "manual",
"day": "string",
"time": "string",
"paused": true,
"next_run_at": "string"
},
"created_at": "2026-10-01T09:30:00Z"
}
}
Update a campaign
PATCH
/v1/campaigns/{campaign}
Partial update: absent fields keep their value. The HTTP password stays unchanged when absent.
- Required scopes
- projects:write
- Rate-limit cost
- 1 unit(s)
Parameters
-
campaignpath · string (uuid) · required
Request body
-
namestring · optional -
start_urlstring · optional -
max_depthinteger · optional -
max_urlsinteger · optional -
javascript_renderingboolean · optional -
pagespeedboolean · optional -
check_external_linksboolean · optional -
check_ai_reachabilityboolean · optional -
check_accessibilityboolean · optional -
check_accessibility_renderedboolean · optional -
include_patternsstring | null · optional -
exclude_patternsstring | null · optional -
issue_exclusion_patternsstring | null · optional -
timeoutinteger | null · optional -
retriesinteger | null · optional -
duplication_thresholdnumber | null · optional -
regression_thresholdstring · optionalValues (off, warning, error)
-
protected_siteboolean · optional -
http_userstring | null · optional -
http_passwordstring | null · optional -
notifyboolean · optional -
scheduleobject · optional
Responses
-
200OK. -
401Missing, invalid or expired token, or a member who left the team. -
403The plan does not include the API (`api.not_in_plan`) or this verb (`api.write_not_in_plan`), or the token lacks a scope (`token.missing_scope`). -
404No such resource for the token's team. Resources of another team answer 404 as well, never 403. -
422Invalid query or body values (`validation_failed`), with `errors` by field. -
429The plan rate limit is exhausted for one window.
cURL
curl -X PATCH "https://api.nessflow.com/v1/campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57" \
-H "Authorization: Bearer $NESSFLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Exemple","start_url":"https://exemple.fr/","max_depth":42,"max_urls":42,"javascript_rendering":true,"pagespeed":true,"check_external_links":true,"check_ai_reachability":true,"check_accessibility":true,"check_accessibility_rendered":true,"include_patterns":"string","exclude_patterns":"string","issue_exclusion_patterns":"string","timeout":42,"retries":42,"duplication_threshold":0.5,"regression_threshold":"off","protected_site":true,"http_user":"string","http_password":"string","notify":true,"schedule":{"frequency":"manual","day":"string","time":"string"}}'
PHP
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.nessflow.com/v1/']);
$response = $client->request('PATCH', 'campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NESSFLOW_TOKEN'),
],
'json' => [
'name' => 'Exemple',
'start_url' => 'https://exemple.fr/',
'max_depth' => 42,
'max_urls' => 42,
'javascript_rendering' => true,
'pagespeed' => true,
'check_external_links' => true,
'check_ai_reachability' => true,
'check_accessibility' => true,
'check_accessibility_rendered' => true,
'include_patterns' => 'string',
'exclude_patterns' => 'string',
'issue_exclusion_patterns' => 'string',
'timeout' => 42,
'retries' => 42,
'duplication_threshold' => 0.5,
'regression_threshold' => 'off',
'protected_site' => true,
'http_user' => 'string',
'http_password' => 'string',
'notify' => true,
'schedule' => [
'frequency' => 'manual',
'day' => 'string',
'time' => 'string',
],
],
]);
$data = json_decode((string) $response->getBody(), true);
JavaScript
const response = await fetch('https://api.nessflow.com/v1/campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.NESSFLOW_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Exemple",
"start_url": "https://exemple.fr/",
"max_depth": 42,
"max_urls": 42,
"javascript_rendering": true,
"pagespeed": true,
"check_external_links": true,
"check_ai_reachability": true,
"check_accessibility": true,
"check_accessibility_rendered": true,
"include_patterns": "string",
"exclude_patterns": "string",
"issue_exclusion_patterns": "string",
"timeout": 42,
"retries": 42,
"duplication_threshold": 0.5,
"regression_threshold": "off",
"protected_site": true,
"http_user": "string",
"http_password": "string",
"notify": true,
"schedule": {
"frequency": "manual",
"day": "string",
"time": "string"
}
}),
});
const data = await response.json();
Python
import os
import requests
response = requests.patch(
"https://api.nessflow.com/v1/campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57",
headers={
"Authorization": f"Bearer {os.environ['NESSFLOW_TOKEN']}",
},
json={
"name": "Exemple",
"start_url": "https://exemple.fr/",
"max_depth": 42,
"max_urls": 42,
"javascript_rendering": True,
"pagespeed": True,
"check_external_links": True,
"check_ai_reachability": True,
"check_accessibility": True,
"check_accessibility_rendered": True,
"include_patterns": "string",
"exclude_patterns": "string",
"issue_exclusion_patterns": "string",
"timeout": 42,
"retries": 42,
"duplication_threshold": 0.5,
"regression_threshold": "off",
"protected_site": True,
"http_user": "string",
"http_password": "string",
"notify": True,
"schedule": {
"frequency": "manual",
"day": "string",
"time": "string",
},
},
timeout=30,
)
response.raise_for_status()
data = response.json()
Response example
{
"data": {
"id": "0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57",
"project_id": "0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57",
"name": "Exemple",
"start_url": "https://exemple.fr/",
"max_depth": 42,
"max_urls": 42,
"javascript_rendering": true,
"pagespeed": true,
"check_external_links": true,
"check_ai_reachability": true,
"check_accessibility": true,
"protected_site": true,
"schedule": {
"frequency": "manual",
"day": "string",
"time": "string",
"paused": true,
"next_run_at": "string"
},
"created_at": "2026-10-01T09:30:00Z"
}
}
Delete a campaign
DELETE
/v1/campaigns/{campaign}
Deletes the campaign and its crawls. A running crawl of the campaign is stopped first.
- Required scopes
- projects:write
- Rate-limit cost
- 1 unit(s)
Parameters
-
campaignpath · string (uuid) · required
Responses
-
204Deleted. -
401Missing, invalid or expired token, or a member who left the team. -
403The plan does not include the API (`api.not_in_plan`) or this verb (`api.write_not_in_plan`), or the token lacks a scope (`token.missing_scope`). -
404No such resource for the token's team. Resources of another team answer 404 as well, never 403. -
429The plan rate limit is exhausted for one window.
cURL
curl -X DELETE "https://api.nessflow.com/v1/campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57" \
-H "Authorization: Bearer $NESSFLOW_TOKEN"
PHP
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.nessflow.com/v1/']);
$response = $client->request('DELETE', 'campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57', [
'headers' => [
'Authorization' => 'Bearer '.getenv('NESSFLOW_TOKEN'),
],
]);
JavaScript
const response = await fetch('https://api.nessflow.com/v1/campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.NESSFLOW_TOKEN}`,
},
});
Python
import os
import requests
response = requests.delete(
"https://api.nessflow.com/v1/campaigns/0190f5a2-7c4e-7b1a-9d3e-2f6b8c1a4e57",
headers={
"Authorization": f"Bearer {os.environ['NESSFLOW_TOKEN']}",
},
timeout=30,
)
response.raise_for_status()
Response example
No response body.