API documentation

    This guide explains how to call SEOforGPT over HTTP. Use an API key for servers and scripts, or a login session token when calling from the browser.

    Sign inAfter signing in, open the user menu (top right) and choose API Keys to create and manage keys.

    Overview

    Public API v1 is the HTTP surface for scripts, CI jobs, internal tools, and agents that need to list projects, run visibility workflows, fetch reports, generate content, or manage API keys.

    Every request is scoped to the authenticated user and respects plan access, quota, and per-route rate limits. For server-side use, prefer an API key. For browser or app-originated calls, use a logged-in session JWT.

    https://www.seoforgpt.io/api/v1

    Use this when

    You want a stable HTTP API for automation, background jobs, CLI tools, or agent workflows.

    Success envelope

    Successful responses use { data, meta }.meta.billingincludes plan and quota hints.

    OpenAPI file (optional)

    If you use tools that import OpenAPI (for example code generators or API clients), you can open openapi.json in a new tab. It lists the same routes as this page in JSON form. Cloud tools that must fetch the file from the public internet (for example some Custom GPT setups) should use https://www.seoforgpt.io/openapi.json. If you are new to APIs, you can skip OpenAPI and follow the sections below. This page is the main guide.

    Get an API key

    Sign in. Then open the user menu (top right) and choose API Keys to create a key. Keys are shown only once when you create them. You can have up to 10 keys.

    Sign in to manage keys

    Claude: For chat tools instead of raw HTTP, use the hosted MCP connector at /mcp (OAuth). That gives the assistant the same product actions as the app, not the REST shape documented here.

    ChatGPT / OpenAI: If your product supports a remote MCP URL, it is the same /mcp endpoint. OpenAI rolls out MCP on different plans and surfaces, so check their docs. If you only have HTTP actions, add a Custom GPT Action (or equivalent). Point it at the publicly reachable schema URL https://www.seoforgpt.io/openapi.json so ChatGPT can fetch the spec from the internet. On this site you can preview openapi.json in a new tab. Use Bearer with a user API key (sgpt_…). We do not ship a separate OpenAI-only MCP. More help: Developers, ChatGPT and OpenAI (MCP docs).

    Authentication

    Send a bearer token in the request header. Use an API key for scripts and server-side automation. Use a JWT when calling from a signed-in browser session or when creating, listing, or deleting API keys.

    Header

    Authorization: Bearer <your_api_key_or_jwt>
    • API keys look like sgpt_... and are the right choice for CI, cron, and agents.
    • JWTs come from a logged-in user session and are required for/keysmanagement.

    Quickstart

    If you only need one reliable flow, use this order: list projects, choose a project, run a visibility workflow, then fetch the report.

    1. 1. List projects

      Start with GET /projects and choose the project you want to work with.

    2. 2. Run visibility

      Use POST /analyze/project for the project's saved prompts, or POST /analyze/custom for ad-hoc prompts and brands.

    3. 3. Fetch the report

      Use GET /reports/:id with the returned data.id or GET /reports/latest if you only need the most recent report for a project.

    Visibility workflows

    These routes run the same brand visibility workflows used inside the app. They are the core API for recurring monitoring and one-off visibility experiments.

    All visibility routes consume visibility quota. Use the returned data.id with a report route. For async runs, poll until the returned status is terminal.

    POST /analyze/project (recommended)

    Use this when you want the project's saved prompts from SEOforGPT. Body: projectId only. Returns 202 while multi-provider jobs run, or 200 when the report is already complete.

    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

    Use this for ad-hoc prompt sets or a brand that is different from the one saved in the app. Body: projectId, brand, prompts (strings or { prompt } objects), plus optional competitors. Max 20 prompts. Returns HTTP 200 with a report id of type visibility_analysis_api.

    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. Still supported, but new integrations should prefer the explicit routes above. It accepts testId, projectId + brand + prompts, projectId + brand + crawlRecordId, or just projectId.

    Reports

    Report routes let you fetch either the latest report for a project or a specific report by id. Visibility reports support three views: raw, summary, and full.

    • raw returns normalized low-level rows.
    • summary is the default compact report.
    • full returns the richer dashboard-style report with trends, sources, and gaps.

    GET /reports/latest

    Use this when you do not want to track a report id yourself. Query params: required projectId, optional source=main|custom, optional view=raw|summary|full.

    curl --request GET \
      --url "https://www.seoforgpt.io/api/v1/reports/latest?projectId=<uuid>&source=main&view=full" \
      --header "Authorization: Bearer $SEOFORGPT_TOKEN"

    GET /reports/:id

    Fetch a specific report id. The returned data.type is visibility_analysis, visibility_analysis_api, or generated_content. Visibility reports accept the same view query param.

    curl --request GET \
      --url "https://www.seoforgpt.io/api/v1/reports/REPORT_ID_FROM_PREVIOUS_STEP?view=full" \
      --header "Authorization: Bearer $SEOFORGPT_TOKEN"

    After 202 from /analyze/project, poll this route until data.status is terminal.

    Content generation

    Use POST /generate-content when you want SEOforGPT to create a draft from project context. This route consumes content quota and returns a report id you can fetch later.

    POST /generate-content

    Body: projectId, platform (blog, linkedin, thread), topic, plus optional metadata and promptType.

    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"}'
    • The response includes data.id for GET /reports/:id.
    • It also returns context_quality and context_message so you know whether the draft used completed website analysis.

    Readiness & prompt helpers

    These routes are useful when you want website-readiness output or prompt suggestions in automation. They are real public API routes even though they are more advanced than the main visibility/content flows.

    POST /readiness

    Runs the same website-readiness workflow as the app. Body: required projectId, optional forceRerun, optional url override. Response includes data.id, data.cached, and data.result.

    curl --request POST \
      --url https://www.seoforgpt.io/api/v1/readiness \
      --header "Authorization: Bearer $SEOFORGPT_TOKEN" \
      --header "Content-Type: application/json" \
      --data '{"projectId":"<uuid>","forceRerun":false}'

    POST /suggest-prompts

    Generates prompt suggestions from an existing crawl. Body: required crawlRecordId, optional projectId, optional brand, optional competitors. Response includes prompt_count and may include a saved test id in report_url.

    curl --request POST \
      --url https://www.seoforgpt.io/api/v1/suggest-prompts \
      --header "Authorization: Bearer $SEOFORGPT_TOKEN" \
      --header "Content-Type: application/json" \
      --data '{"crawlRecordId":"<uuid>","projectId":"<uuid>"}'

    API keys

    Key-management routes require a JWT from a logged-in user session, not an API key. The actual secret key value is returned only once at creation time.

    POST /keys

    Create an API key. Body: optional name and optional expires_at. Returns HTTP 201 with data.key.

    curl --request POST \
      --url https://www.seoforgpt.io/api/v1/keys \
      --header "Authorization: Bearer $SEOFORGPT_TOKEN" \
      --header "Content-Type: application/json" \
      --data '{"name":"CI automation","expires_at":"2026-06-01T00:00:00.000Z"}'

    GET /keys

    List your API keys with prefix, name, created time, last-used time, and expiry.

    DELETE /keys/:id

    Delete one API key owned by the authenticated user.

    Errors & limits

    API-owned errors return a predictable envelope. Rate-limited responses also include retry headers such as Retry-After and X-RateLimit-*.

    {
      "error": {
        "code": "BILLING_REQUIRED",
        "message": "content quota exceeded",
        "details": {
          "remaining": 0
        },
        "request_id": "0d2c2e3d-5f04-43e2-a8fb-f5d0b92e7ab1"
      }
    }
    • 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