How to Integrate Open-SEO with Other Tools: A Complete Integration Guide

Open-SEO exposes its core functionality through automatically routed HTTP endpoints, allowing any external system to programmatically access SEO data, rank tracking, audits, and billing via authenticated API calls.

Integrating Open-SEO with external tools unlocks powerful automation workflows—from CI pipelines that trigger SEO audits on every deploy to custom dashboards that pull real-time ranking data. As implemented in every-app/open-seo, the integration surface is built on TanStack React Start's createServerFn architecture, which transforms server functions into type-safe JSON RPC endpoints.

Core Integration Architecture

Understanding Open-SEO's layered architecture helps you choose the right integration approach for your use case.

Layer Purpose Key Source Files
HTTP Entry Point Cloudflare Workers fetch handler routes UI requests, OAuth flows, and chat endpoints src/server.ts
Authentication ensureUser middleware validates JWTs, Cloudflare Access headers, and project permissions src/middleware/ensureUser.ts
Server Functions createServerFn exports from src/serverFunctions/*.ts become HTTP endpoints src/serverFunctions/projects.ts
Routing TanStack Router's routeTree maps paths to RPC endpoints at /api/* src/routeTree.gen.ts
Data Layer Drizzle ORM provides type-safe database access for projects, audits, and tracking data src/db/schema.ts

According to the Open-SEO source code, every business operation you see in the UI has a corresponding server function that external tools can call directly.

Authentication Methods for External Integration

Before making API calls, you need valid credentials. Open-SEO supports three authentication patterns for programmatic access.

JWT / Cloudflare Access Token

The UI stores session state in an open-seo.session cookie containing a JWT. External tools can:

  • Extract and reuse this cookie for browser-automation scenarios
  • Generate their own JWT using the server's signing secret (for service accounts)

The token validation logic lives in src/middleware/ensureUser.ts, which parses the JWT, resolves the user's organization, and validates project-level access.

OAuth 2.0 / MCP Delegation

For third-party SaaS integrations, use the Open-SEO OAuth provider at /oauth/... endpoints to obtain access tokens on behalf of users. This enables scenarios where your application acts with the user's explicit permission without handling their primary credentials.

Project-Scoped API Keys

Long-lived tokens tied to specific projects can be created via the Projects API. The createProject function in src/serverFunctions/projects.ts returns a projectId that, combined with an organization-scoped JWT, enables fine-grained access control.

Integration Options Compared

Method Best For Implementation Complexity
Direct HTTP calls Server-side scripts, Python/Go/Java services, low-code platforms Low—standard REST patterns
TanStack React Start client TypeScript/React frontends already using Open-SEO components Minimal—automatic type safety
WebSocket agents Real-time chat features, streaming onboarding flows Medium—requires Agents SDK
OAuth/MCP delegation Third-party SaaS integrations, marketplace apps Higher—full OAuth flow required

Code Examples for Common Integration Scenarios

Node.js / TypeScript: Direct HTTP Integration

The most flexible approach for backend services. First obtain a JWT, then call any server function at its /api/ endpoint:

import fetch from 'node-fetch';

// Obtain JWT via client_credentials flow
async function getJwt(): Promise<string> {
  const resp = await fetch('https://your-open-seo.example.com/oauth/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      grant_type: 'client_credentials',
      client_id: process.env.OPEN_SEO_CLIENT_ID,
      client_secret: process.env.OPEN_SEO_CLIENT_SECRET,
    }),
  });
  const data = await resp.json();
  return data.access_token;
}

// Call createProject server function
async function createProject(name: string) {
  const token = await getJwt();

  const resp = await fetch(
    'https://your-open-seo.example.com/api/createProject',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${token}`,
      },
      body: JSON.stringify({ name, domain: 'example.com', market: 'US' }),
    },
  );

  if (!resp.ok) {
    const err = await resp.text();
    throw new Error(`Open-SEO error: ${resp.status} – ${err}`);
  }

  return await resp.json();
}

// Usage
createProject('Acme Corp')
  .then((proj) => console.log('Created project:', proj))
  .catch(console.error);

The createProject function is defined in src/serverFunctions/projects.ts and automatically exposed at POST /api/createProject.

React / TypeScript: Type-Safe Client Integration

For React applications already in the Open-SEO ecosystem, import server functions directly:

import { createProject } from '@/serverFunctions/projects';

async function onCreate() {
  const project = await createProject({
    name: 'New Startup',
    domain: 'startup.io',
    market: 'US',
  });
  console.log('Project created:', project);
}

The TanStack React Start client handles serialization, HTTP transport, and response typing automatically. The generated stub in src/routeTree.gen.ts ensures your calls stay synchronized with the server implementation.

Python: Using Requests Library

Python services can integrate without any Open-SEO-specific SDK:

import os
import requests

API_BASE = "https://your-open-seo.example.com"
TOKEN = os.getenv("OPEN_SEO_JWT")

def create_project(name, domain, market):
    url = f"{API_BASE}/api/createProject"
    payload = {"name": name, "domain": domain, "market": market}
    headers = {
        "Authorization": f"Bearer {TOKEN}",
        "Content-Type": "application/json"
    }
    r = requests.post(url, json=payload, headers=headers)
    r.raise_for_status()
    return r.json()

proj = create_project("Python SaaS", "python-saas.com", "US")
print("Created:", proj)

This pattern works with any language that can make HTTP requests and parse JSON responses.

Real-Time Chat: WebSocket Agents SDK

For conversational features like the Onboarding Chat or SAM assistant, connect to Durable Objects at /agents/*:

async function startOnboarding(projectId: string, token: string) {
  const ws = new WebSocket(
    `wss://your-open-seo.example.com/agents/ONBOARDING_CHAT/${projectId}`,
    {
      headers: { Authorization: `Bearer ${token}` },
    },
  );

  ws.onopen = () => ws.send(JSON.stringify({ type: 'START' }));
  ws.onmessage = (msg) => console.log('Chat:', msg.data);
}

The authorizeOnboardingChat function in src/server.ts enforces that the JWT belongs to the organization owning projectId, rejecting unauthorized connections with 401/403 status codes.

Required Environment Configuration

For full functionality, configure these environment variables in your Cloudflare Worker as defined in worker-configuration.d.ts:

Variable Purpose
DATAFORSEO_API_KEY Required for SEO data generation, rank tracking, and keyword research
OPENROUTER_API_KEY Powers AI-driven content and analysis features
JWT_SECRET Signs and verifies authentication tokens

The server validates DATAFORSEO_API_KEY presence in src/serverFunctions/config.ts before executing any SEO data operations.

Key Source Files for Integration Development

When building custom integrations, reference these files for authoritative implementation details:

  • src/serverFunctions/**/*.ts — Complete inventory of available API endpoints; each createServerFn export is callable via HTTP
  • src/middleware/ensureUser.ts — JWT parsing, organization resolution, and project authorization logic
  • src/server.ts — Entry point showing OAuth routing and /agents/* WebSocket upgrade handling
  • src/db/schema.ts — Database schema for direct querying or advanced reporting
  • src/server/lib/dataforseo/core.ts — External API integration patterns for SEO data providers

Summary

Integrating Open-SEO with external tools leverages its TanStack React Start foundation to expose type-safe, authenticated JSON RPC endpoints:

  • Any HTTP-capable system can call server functions at /api/<function-name> with a valid JWT
  • React/TypeScript frontends get automatic type safety through the TanStack client
  • Real-time features use WebSocket connections to Durable Objects with the same authentication middleware
  • OAuth delegation enables secure third-party SaaS integrations without credential sharing

The integration surface mirrors the UI exactly—every feature available to users can be accessed programmatically by authenticating through src/middleware/ensureUser.ts and calling the corresponding function from src/serverFunctions/.

Frequently Asked Questions

What authentication token do I need for Open-SEO API calls?

You need either a JWT from the open-seo.session cookie, a service account JWT signed with the server's secret, or an OAuth access token obtained through the /oauth/... endpoints. The ensureUser middleware in src/middleware/ensureUser.ts validates all three types and resolves your organization and project permissions.

Can I use Open-SEO server functions from languages other than TypeScript?

Yes. The server functions are standard HTTP endpoints accepting JSON POST requests and returning JSON responses. The Python example above demonstrates calling createProject from Python using the requests library. Any language with HTTP capabilities—Go, Java, Rust, or low-code platforms—can integrate directly.

How do I find the correct URL for a specific server function?

Check src/routeTree.gen.ts for the auto-generated routing table, which maps server functions to /api/* paths. The convention follows the function name: createProject in src/serverFunctions/projects.ts becomes POST /api/createProject. You can also inspect network requests in the Open-SEO UI to discover endpoint patterns.

What happens if I call an Open-SEO endpoint without proper authentication?

The ensureUser middleware returns HTTP 401 for missing or invalid JWTs, and HTTP 403 when your token lacks the required organization or project scope. For WebSocket connections to /agents/*, unauthorized upgrade requests are rejected before the Durable Object is instantiated.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →