API documentation
Public API v1 for scripts, CI, and tools. Use an API key or session token to list projects, run analyses, and generate content.
Overview
Use this API from scripts, CI, or cron. Send an API key in the header; every call is tied to your account and your plan limits.
Typical first run: GET /projects to list workspaces and copy a projectId, then POST /analyze/project with that id, then GET /reports/<id> until the run finishes.
https://www.seoforgpt.io/api/v1Get an API key
Sign in, then go to Settings → API keys to create a key. Keys are shown only once at creation. You can have up to 10 keys.
Sign in to manage keysUsing Claude or Cursor? See the MCP server guide to use SEOforGPT as tools in chat.
Authentication
Send your API key or session token in the request header. Key management endpoints (create/list/delete keys) require a JWT from a logged-in session, not an API key.
Header:
Authorization: Bearer <your_api_key_or_jwt>
Use an API key (e.g. sgpt_...) for scripts and CI; use a JWT for server or browser calls with a logged-in session.
Brand visibility (analyze)
Project analyze — You send only projectId. The server uses the same prompt list you set up in the SEOforGPT app. Best for monitoring and cron jobs.
Custom analyze — You send projectId, brand, and your own prompts (max 30). Does not change the app's saved prompts or "latest test" in the UI—good for one-off experiments.
Both count against visibility quota. Successful JSON is wrapped as { data, meta } — use data.id for reports; meta includes billing hints.
/analyze/custom waits for completion and returns HTTP 200 with data.id when done. /analyze/project may return 202 while tests run.
POST /analyze/project (recommended)
Body: projectId only. Server picks the latest saved test with prompts and runs the standard multi-provider flow (may return 202 while jobs finish).
curl --request POST \
--url https://www.seoforgpt.io/api/v1/analyze/project \
--header "Authorization: Bearer $SEOFORGPT_TOKEN" \
--header "Content-Type: application/json" \
--data '{"projectId":"<uuid>"}'POST /analyze/custom
Body: projectId, brand, prompts (strings or { prompt } objects); optional competitors (array of strings, optional). Same validation as Edge Function api-test-brand-visibility (max 30 prompts). Response: HTTP 200, data.id, data.type: visibility_analysis_api, data.report_url.
curl --request POST \
--url https://www.seoforgpt.io/api/v1/analyze/custom \
--header "Authorization: Bearer $SEOFORGPT_TOKEN" \
--header "Content-Type: application/json" \
--data '{"projectId":"<uuid>","brand":"YourBrand","prompts":["query 1","query 2"]}'POST /analyze
Legacy dispatcher: testId; projectId + brand + prompts (same as custom, API-only storage); projectId only (same as /analyze/project); or crawlRecordId (deprecated).
GET /reports/:id
data.type is visibility_analysis (saved tests), visibility_analysis_api (custom), or generated_content. Poll GET /reports/<data.id> after 202 from project analyze until data.status is no longer in-progress (e.g. completed or failed).
curl --request GET \ --url https://www.seoforgpt.io/api/v1/reports/REPORT_ID_FROM_PREVIOUS_STEP \ --header "Authorization: Bearer $SEOFORGPT_TOKEN"
Visibility reports expose results (normalized rows); generated content exposes content, status, etc.
Other endpoints
GET /projects
Returns the authenticated user's projects.
curl --request GET \ --url https://www.seoforgpt.io/api/v1/projects \ --header "Authorization: Bearer $SEOFORGPT_TOKEN"
POST /generate-content
Body (passed through to generate-content): projectId, platform (blog | linkedin | thread), topic; optional metadata (object), promptType (string). Response: data.id for GET /reports/:id (type: generated_content).
curl --request POST \
--url https://www.seoforgpt.io/api/v1/generate-content \
--header "Authorization: Bearer $SEOFORGPT_TOKEN" \
--header "Content-Type: application/json" \
--data '{"projectId":"<uuid>","platform":"blog","topic":"How to measure AI search visibility"}'POST /keys
Create an API key. Requires JWT. Body: optional name, optional expires_at (ISO string).
GET /keys
List your API keys (prefix, name, created, last used). Requires JWT.
DELETE /keys/:id
Delete one API key. Requires JWT.
Errors & limits
Errors return a JSON envelope with code, message, and optional details. Rate limits and quotas apply per user.
- 400 — Invalid input
- 401 — Missing or invalid token
- 402 — Billing or quota gate
- 404 — Resource not found
- 409 — Conflict (e.g. API key limit reached)
- 429 — Rate limit exceeded
- 500 — Server error