Skip to main content
CitePilot logoCitePilot
Start
Developers

CitePilot Fleet API

Integrate citation monitoring into your agency stack. Fleet plan required β€” REST JSON API with workspace-scoped keys.

Base URL: https://getcitepilot.com/api/v1 Β· Fleet overview β†’

Authentication

Fleet plan required. Generate an API key in Dashboard β†’ Settings β†’ Fleet β†’ API Keys (one key per workspace).

Headers
Authorization: Bearer ck_live_xxxxxxxxxxxx
Content-Type: application/json

Alternative: X-API-Key: ck_live_… header. Session cookies work for browser testing with credentials included.

cURL
curl -s "https://getcitepilot.com/api/v1/workspaces" \
  -H "Authorization: Bearer ck_live_YOUR_KEY" \
  -H "Content-Type: application/json"
Node.js
const res = await fetch("https://getcitepilot.com/api/v1/workspaces", {
  headers: {
    Authorization: "Bearer ck_live_YOUR_KEY",
    "Content-Type": "application/json",
  },
});
const data = await res.json();
Python
import requests

r = requests.get(
    "https://getcitepilot.com/api/v1/workspaces",
    headers={
        "Authorization": "Bearer ck_live_YOUR_KEY",
        "Content-Type": "application/json",
    },
)
print(r.json())
  • β€’Keys are scoped to the workspace where they were created.
  • β€’The full secret is shown once at creation β€” store it in your secrets manager.
  • β€’Revoke compromised keys immediately from Fleet settings.

Workspaces

GET/workspaces

List workspaces

Returns all client workspaces for the authenticated Fleet account.

Example response

{
  "workspaces": [
    {
      "id": "ws_abc123",
      "domain": "client.com",
      "buyerQuestion": "Best CRM for agencies?",
      "citationScore": 62
    }
  ]
}
cURL
curl -s "https://getcitepilot.com/api/v1/workspaces" \
  -H "Authorization: Bearer ck_live_YOUR_KEY"
Node.js
const res = await fetch("https://getcitepilot.com/api/v1/workspaces", {
  headers: { Authorization: "Bearer ck_live_YOUR_KEY" },
});
Python
requests.get("https://getcitepilot.com/api/v1/workspaces", headers={"Authorization": "Bearer ck_live_YOUR_KEY"})

Prompts

GET/workspaces/{id}/prompts

List monitored prompts

Money prompts tracked for weekly rescans and citation audits.

cURL
curl -s "https://getcitepilot.com/api/v1/workspaces/ws_abc123/prompts" \
  -H "Authorization: Bearer ck_live_YOUR_KEY"
Node.js
await fetch("https://getcitepilot.com/api/v1/workspaces/ws_abc123/prompts", {
  headers: { Authorization: "Bearer ck_live_YOUR_KEY" },
});
Python
requests.get("https://getcitepilot.com/api/v1/workspaces/ws_abc123/prompts", headers=headers)
POST/workspaces/{id}/prompts

Add prompt(s)

Append one or more prompts to the monitored list (respects plan limits).

Request body

{ "prompt": "Best agency CRM for client reporting?" }
cURL
curl -s -X POST "https://getcitepilot.com/api/v1/workspaces/ws_abc123/prompts" \
  -H "Authorization: Bearer ck_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"Best agency CRM for client reporting?"}'
Node.js
await fetch("https://getcitepilot.com/api/v1/workspaces/ws_abc123/prompts", {
  method: "POST",
  headers: {
    Authorization: "Bearer ck_live_YOUR_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ prompt: "Best agency CRM for client reporting?" }),
});
Python
requests.post(
    "https://getcitepilot.com/api/v1/workspaces/ws_abc123/prompts",
    headers=headers,
    json={"prompt": "Best agency CRM for client reporting?"},
)
POST/workspaces/{id}/prompts/import

Bulk CSV import

Replace monitored prompts from CSV (`prompt` column or one prompt per line). Multipart file upload or raw CSV body.

cURL
curl -s -X POST "https://getcitepilot.com/api/v1/workspaces/ws_abc123/prompts/import" \
  -H "Authorization: Bearer ck_live_YOUR_KEY" \
  -F "file=@prompts.csv"
Node.js
const form = new FormData();
form.append("file", file);
await fetch("https://getcitepilot.com/api/v1/workspaces/ws_abc123/prompts/import", {
  method: "POST",
  headers: { Authorization: "Bearer ck_live_YOUR_KEY" },
  body: form,
});
Python
requests.post(
    "https://getcitepilot.com/api/v1/workspaces/ws_abc123/prompts/import",
    headers={"Authorization": "Bearer ck_live_YOUR_KEY"},
    files={"file": open("prompts.csv", "rb")},
)

Audits

GET/workspaces/{id}/audits

List audit history

Recent citation audits for a workspace. Optional `?limit=20` (max 50).

cURL
curl -s "https://getcitepilot.com/api/v1/workspaces/ws_abc123/audits?limit=10" \
  -H "Authorization: Bearer ck_live_YOUR_KEY"
Node.js
await fetch("https://getcitepilot.com/api/v1/workspaces/ws_abc123/audits?limit=10", {
  headers: { Authorization: "Bearer ck_live_YOUR_KEY" },
});
Python
requests.get("https://getcitepilot.com/api/v1/workspaces/ws_abc123/audits", headers=headers, params={"limit": 10})
POST/workspaces/{id}/audits

Trigger a new audit

Runs a live citation audit against all monitored prompts. Limited to 10 triggers/hour (see Rate limits).

cURL
curl -s -X POST "https://getcitepilot.com/api/v1/workspaces/ws_abc123/audits" \
  -H "Authorization: Bearer ck_live_YOUR_KEY"
Node.js
await fetch("https://getcitepilot.com/api/v1/workspaces/ws_abc123/audits", {
  method: "POST",
  headers: { Authorization: "Bearer ck_live_YOUR_KEY" },
});
Python
requests.post("https://getcitepilot.com/api/v1/workspaces/ws_abc123/audits", headers=headers)
GET/audits/{auditId}/results

Get audit results

Full prompt-level results, platform coverage, gaps, and site signals for one audit run.

cURL
curl -s "https://getcitepilot.com/api/v1/audits/audit_xyz/results" \
  -H "Authorization: Bearer ck_live_YOUR_KEY"
Node.js
await fetch("https://getcitepilot.com/api/v1/audits/audit_xyz/results", {
  headers: { Authorization: "Bearer ck_live_YOUR_KEY" },
});
Python
requests.get("https://getcitepilot.com/api/v1/audits/audit_xyz/results", headers=headers)

Reports

GET/reports/{workspaceId}

Proof report JSON

Stakeholder-ready proof report data: citation summary, platform rows, prompt results, benchmark, and recommended actions.

Example response

{
  "schemaVersion": 1,
  "workspaceId": "ws_abc123",
  "summary": { "citationScore": 62, "promptsTracked": 8 },
  "promptRows": [],
  "topActions": ["Publish comparison page for …"]
}
cURL
curl -s "https://getcitepilot.com/api/v1/reports/ws_abc123" \
  -H "Authorization: Bearer ck_live_YOUR_KEY"
Node.js
await fetch("https://getcitepilot.com/api/v1/reports/ws_abc123", {
  headers: { Authorization: "Bearer ck_live_YOUR_KEY" },
});
Python
requests.get("https://getcitepilot.com/api/v1/reports/ws_abc123", headers=headers)

Webhooks

Fleet plan β€” register webhook endpoints in Dashboard β†’ Settings β†’ Integrations. CitePilot POSTs flat, Zapier-friendly JSON when citations change or audits complete.

Verify signatures with your signing secret (set when adding the endpoint). Reject requests when the signature does not match.

cURL
# Raw body bytes must match what you verify
BODY='{"event":"citation.change_detected",...}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "YOUR_SECRET" | awk '{print "sha256="$2}')

curl -X POST https://hooks.example.com/citepilot \
  -H "Content-Type: application/json" \
  -H "X-CitePilot-Signature: $SIG" \
  -d "$BODY"
Node.js
import crypto from "crypto";

function verify(secret: string, rawBody: string, header: string | null) {
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  return header === expected;
}
Python
import hmac, hashlib

def verify(secret: str, raw_body: bytes, header: str | None) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return header == expected
  • β€’citation.change_detected β€” prompt gained or lost citation coverage
  • β€’audit.completed β€” scan finished with score and citation rate
  • β€’Flat field names (workspace_domain, prompt, delta) β€” no nested objects
  • β€’X-CitePilot-Signature: sha256=HMAC-SHA256(secret, raw body)
  • β€’Works with Zapier Catch Hook and Make.com Custom webhook
Error shape
{
  "event": "citation.change_detected",
  "workspace_domain": "brightlayer.io",
  "workspace_id": "abc123",
  "prompt": "best CRM for agencies",
  "platform": "chatgpt",
  "change": "gained",
  "citation_rate_before": 0.50,
  "citation_rate_after": 0.58,
  "delta": "+8%",
  "timestamp": "2026-06-14T08:00:00Z",
  "report_url": "https://getcitepilot.com/dashboard/geo-audit?workspace=abc123"
}

Rate limits

  • β€’Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
  • β€’Minute-level headers: X-RateLimit-Limit-Minute, X-RateLimit-Remaining-Minute
  • β€’429 responses include code RATE_LIMIT or AUDIT_LIMIT with resetAt timestamp
ScopeLimit
Fleet API (all endpoints)100 requests/min
Fleet API (all endpoints)1000 requests/hour
POST /workspaces/{id}/audits10 triggers/hour

Errors

All errors return JSON with a consistent shape:

CodeHTTPDescription
UNAUTHORIZED401Missing or invalid API key / session
FLEET_REQUIRED403Active Fleet subscription required
WORKSPACE_SCOPE403Key scoped to a different workspace
NOT_FOUND404Workspace, audit, or report not found
VALIDATION_ERROR400Invalid request body or missing fields
PROMPT_LIMIT_EXCEEDED429Monitored prompt cap reached
RATE_LIMIT429Fleet API rate limit exceeded
AUDIT_LIMIT429Audit trigger limit exceeded (10/hour)
KEY_LIMIT400Maximum API keys for this workspace
INTERNAL_ERROR500Unexpected server error
Error shape
{
  "error": "Prompt limit exceeded for your plan",
  "code": "PROMPT_LIMIT_EXCEEDED",
  "status": 429
}