Skip to main content

Quick setup

  1. Obtain your API key from Surnex.
  2. Send requests to the base URL from the live API:
    • https://api.surnex.io
  3. Use the OpenAPI contract to test operations interactively and discover service coverage.

Surnex-first execution model

  • New integrations should use the provider-agnostic execution surface first:
    • GET /v1/providers
    • GET /v1/providers/{provider}/catalog
    • GET /v1/providers/{provider}/capabilities
    • POST /v1/executions
    • GET /v1/executions/{id}
    • GET /v1/executions/{id}/results
  • DataForSEO remains available and fully supported through compatibility routes:
    • GET /v1/dataforseo/catalog
    • POST /v1/dataforseo/executions
    • GET /v1/dataforseo/executions/{id}
    • GET /v1/dataforseo/executions/{id}/results

Current implementation status

  • Canonical /v1/providers and /v1/executions* surfaces are the first-party Surnex API contract.
  • dataforseo is the currently active upstream provider and remains as a compatibility-backed path for existing integrations.
  • Provider extension work is next: additional providers should be added through packages/provider-core adapter implementations.
  • Next in roadmap:
    • provider onboarding metadata and policy controls in /v1/providers/{provider}/capabilities,
    • project/tenant capabilities for future Surnex UI and sharing features,
    • and stronger multi-provider operational controls.

Marketing site publishing integration

The marketing website setup now has its own page: Core pieces:
  • SEO/LLM-first static pages and blog routes at https://surnex.io
  • Content ingest contract: POST /v1/webhooks/marketing/blog
  • Vercel deployment settings and environment mapping are documented in one place

DataForSEO coverage workflow

  • Catalog all known services:
    • GET /v1/dataforseo/catalog
  • All service responses now include category for deterministic UI grouping.
  • Filter catalog views by category with ?category=<slug> (for example: ?category=serp).
  • Group services by discovery source:
    • GET /v1/dataforseo/catalog?group_by=discovery_source&discover=false
    • Group key order: static, discovered, mixed
  • Discover live endpoints for one service:
    • GET /v1/dataforseo/catalog?service=<service>&discover=true
  • Browse a service-scoped operations index (paginated and filterable):
    • GET /v1/dataforseo/catalog/services/{service}
  • /v1/dataforseo/catalog/services/{service} returns operation rows; use GET /v1/dataforseo/catalog/services/{service}/templates for template rows with path_variables and execution hints.
  • Group a service-scoped operation index:
    • GET /v1/dataforseo/catalog/services/{service}?group_by=mode|method
    • GET /v1/dataforseo/catalog/services/{service}?group_by=discovery_source
  • Scope template discovery and execution scaffolding for one service:
    • GET /v1/dataforseo/catalog/services/{service}/templates
  • group_by=discovery_source keys are static, discovered
  • Group the global flat operation index by method, mode, or service:
    • group_by=service keys are alphabetical
    • group_by=method keys are GET, POST
    • group_by=mode keys are live, task_post, task_get, tasks_ready, tasks_fixed
    • group_by=discovery_source keys are static, discovered
    • GET /v1/dataforseo/catalog/operations?group_by=service|mode|method|discovery_source
  • Discover all service endpoints at once:
    • GET /v1/dataforseo/catalog?discover=true
  • Bootstrap everything at startup (manifest + operation counts):
    • GET /v1/dataforseo/catalog/bootstrap
  • Get deterministic category buckets for UI sections:
    • GET /v1/dataforseo/catalog/categories
  • Get services for a single category with pagination/filtering:
    • GET /v1/dataforseo/catalog/categories/{category}
  • Build your UI service catalog quickly from capability summaries: GET /v1/dataforseo/catalog/capabilities
  • Filter capability results with method and mode: GET /v1/dataforseo/catalog/capabilities?method=GET&mode=live
  • Focus capabilities for one service: GET /v1/dataforseo/catalog/capabilities?service=serp
  • Get operation templates (path variables + execution hints) for UI builders:
    • GET /v1/dataforseo/catalog/templates
  • Filter and group operation templates for onboarding surfaces:
    • GET /v1/dataforseo/catalog/templates?group_by=service&method=POST
  • Service-scoped templates are the same shape with URL-level scoping:
    • GET /v1/dataforseo/catalog/services/{service}/templates?discover=false&group_by=mode&method=POST
  • Group capability output by service: GET /v1/dataforseo/catalog/capabilities?group_by=service
  • Paginate capabilities list for large catalogs:
    • GET /v1/dataforseo/catalog/capabilities?limit=25&offset=25
  • Group capability output with group_by=service (alphabetical) or group_by=discovery_source (static, discovered, mixed)
  • Refresh discovery cache when needed:
    • GET /v1/dataforseo/catalog?discover=true&refresh_discovery=true
  • Filter by source:
    • GET /v1/dataforseo/catalog?discover=true&discovery_source=discovered
  • Refresh discovery in catalog queries when you need latest DataForSEO paths:
    • GET /v1/dataforseo/catalog?discover=true&refresh_discovery=true
    • GET /v1/dataforseo/catalog/summary?discover=true&refresh_discovery=true
    • GET /v1/dataforseo/catalog/operations?discover=true&refresh_discovery=true
  • Search catalog services and operations:
    • GET /v1/dataforseo/catalog?search=google_trends
  • Get compact coverage summary:
    • GET /v1/dataforseo/catalog/summary
  • Get discovered-only summary:
    • GET /v1/dataforseo/catalog/summary?discover=true&discovery_source=discovered
  • Filter summary coverage by search:
    • GET /v1/dataforseo/catalog/summary?search=backlinks
  • Browse discoverable operations directly:
    • GET /v1/dataforseo/catalog/operations
  • Discoverable operations with filters:
    • GET /v1/dataforseo/catalog/operations?service=serp&method=POST&mode=live
  • Paginate operation catalogs for UI loaders:
    • GET /v1/dataforseo/catalog/operations?service=serp&limit=25&offset=50
  • Sort operation list by fields (service, operation_path, method, mode, discovery_source) and ordering:
    • GET /v1/dataforseo/catalog/operations?sort=service&order=desc
  • Sorts are stable for equal primary values using a deterministic secondary order (service, operation_path, method) so paginated clients can resume safely.
  • Catalog responses include:
    • discovery_source per service (static, discovered, mixed)
    • discovery_source per operation (static, discovered)
  • discovery_context on catalog/summary/operations responses:
    • source (cache, provider, mixed, or none)
    • discovered_at timestamp and cache metadata
    • cache_hit and provider_calls
  • Execute a provider operation:
  • POST /v1/executions
  • Execute any provider endpoint path directly (including newly introduced or undocumented paths):
    • POST /v1/dataforseo/executions
  • Use catalog templates for safer onboarding (operation_template + path_variables) so clients avoid manual string interpolation:
    • POST /v1/dataforseo/executions
  • Read execution status and results:
    • GET /v1/executions/{id}
    • GET /v1/executions/{id}/results
  • Compatibility reads for existing integrations:
    • GET /v1/dataforseo/executions/{id}
    • GET /v1/dataforseo/executions/{id}/results
LLM Mentions calls are policy-enforced. If a request targets llm_mentions operations, the following are enforced:
  • platform: "chat_gpt"
  • location_code: 2840
  • language_code: "en"
  • targets.length <= 10
  • limit <= 1000
  • offset <= 9000

Required headers

  • x-api-key: your Surnex API key
  • Content-Type: application/json

Web app auth flow

For local development, copy apps/app/.env.example to apps/app/.env.local and set:
VITE_API_BASE_URL=http://localhost:3001
Session cookies are required and sent with cross-origin credentials:
  • Cookie name: surnex_session
  • Session requests include credentials: 'include' and carry x-request-id.
Run the SPA locally with:
pnpm --filter @surnex/app dev
  • Frontend application: https://app.surnex.io
  • Session endpoints:
    • POST /v1/auth/signup
    • POST /v1/auth/signin
    • POST /v1/auth/signout
    • GET /v1/auth/me
  • Project endpoints:
    • GET /v1/projects
    • POST /v1/projects
    • GET /v1/projects/{projectId}
  • Cookies are required for app sessions using surnex_session and request-origin app.surnex.io.

Observability contract

  • All API responses include an x-request-id header.
  • Error responses include error.request_id, which must match x-request-id exactly.
  • Include this value in support tickets and logs when reporting incidents.
  • Usage rollups are provider-aware:
    • GET /v1/usage returns the filtered rollup in totals plus per-provider rollups in providers.

Base responses

All primary API health and metadata routes are publicly exposed:
  • GET /health
  • GET /ready
  • GET /.well-known/openapi.json
  • GET /llms.txt
Snapshots are created with POST /v1/geo/snapshots and checked via GET /v1/geo/snapshots/{id} and GET /v1/geo/snapshots/{id}/results.

Canonical execution payload pattern

Use this shape as a baseline for direct execution requests:
{
  "provider": "dataforseo",
  "service": "serp",
  "method": "POST",
  "mode": "live",
  "operation_template": "/serp/{se}/{type}/live",
  "path_variables": {
    "se": "google",
    "type": "organic"
  },
  "request_body": {
    "keyword": "example"
  },
  "request_query": {
    "api_key": "optional"
  },
  "expected_part_name": "serp_google_organic_live"
}
provider can be omitted in current releases and defaults to dataforseo. Notes:
  • Use operation_path when you already know exact path.
  • Use operation_template + path_variables for onboarding with minimal risk of formatting errors.
  • Only include one of operation_path or operation_template.

Error contract reference

All API failures use a stable envelope and include the matching request_id:
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request",
    "request_id": "a13e…"
  }
}
Most commonly observed codes:
  • VALIDATION_ERROR: schema/parameter/body validation failure.
  • UNAUTHORIZED: missing/invalid credentials.
  • NOT_FOUND: resource not found.
  • PROVIDER_ERROR: upstream provider unavailable or returned error.
  • INTERNAL_ERROR: unexpected service exception.
Use error.request_id in support tickets and include the corresponding x-request-id response header.