# Is OpenSEO Suitable for Automated SEO Checks? A Technical Deep Dive

> Discover if OpenSEO is suitable for automated SEO checks. This technical deep dive explores its server-function-first architecture for seamless CI/CD integration and unattended audits.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: deep-dive
- Published: 2026-08-06

---

**OpenSEO is architected as a server-function-first platform that exposes typed server functions—such as `startAudit`, `getAuditStatus`, and `getAuditResults`—enabling fully automated SEO checks from CI pipelines, scheduled jobs, or any HTTP client without requiring UI interaction.**

OpenSEO (available at `every-app/open-seo`) is built specifically for headless automation. Its core SEO operations are exposed through secure HTTP endpoints generated from TypeScript functions, making it possible to trigger comprehensive site audits, poll for completion, and retrieve structured reports entirely via code. If you are evaluating whether open-seo can power your automated SEO checks, the answer lies in its workflow engine, durable background processing, and strict input validation.

## Server-Function-First Architecture

Unlike traditional SEO tools that require browser automation or manual UI interaction, OpenSEO exposes functionality through **typed server functions** wrapped with `createServerFn` from **@tanstack/react-start**. These functions automatically generate secure HTTP endpoints while maintaining end-to-end type safety.

The primary API surface resides in [`src/serverFunctions/audit.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/audit.ts), which exports four key operations:

- **`startAudit`** – Initiates a new site audit with configurable parameters.
- **`getAuditStatus`** – Returns the current progress percentage and phase.
- **`getAuditResults`** – Retrieves the completed report in JSON, CSV, or HTML format.
- **`deleteAudit`** – Removes historical audit data to manage storage.

Because these functions use **Zod schemas** defined in [`src/types/schemas/audit.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/audit.ts) for input validation, they reject malformed requests automatically—critical for unattended automation where input drift could otherwise cause silent failures.

## The Audit Workflow Engine

Automated SEO checks in OpenSEO follow a deterministic five-phase pipeline orchestrated by [`src/server/workflows/siteAuditWorkflowPhases.ts`](https://github.com/every-app/open-seo/blob/main/src/server/workflows/siteAuditWorkflowPhases.ts). This workflow engine handles the entire lifecycle from discovery to reporting:

1. **URL Discovery** – The `discoverUrls` function in [`src/server/lib/audit/discovery.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/audit/discovery.ts) parses [`robots.txt`](https://github.com/every-app/open-seo/blob/main/robots.txt), filters same-origin URLs, and generates the crawl queue.
2. **Parallel Crawling** – Fetches raw HTML and metadata from discovered pages concurrently.
3. **Lighthouse Execution** – Runs Google Lighthouse scoring via [`src/server/lib/audit/lighthouse.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/audit/lighthouse.ts) for each crawled page.
4. **Issue Collection** – Aggregates SEO warnings, bot challenges, and broken links using the issue registry in [`src/shared/audit-issues.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/audit-issues.ts).
5. **Durable Storage** – Persists results to the audit repository at [`src/server/features/audit/repositories/AuditRepository.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/audit/repositories/AuditRepository.ts).

The workflow executes asynchronously with state stored in a durable KV store, allowing long-running audits to survive server restarts and enabling safe polling from CI pipelines.

## Safety Controls for Automation

OpenSEO implements safeguards specifically designed for automated usage. The platform enforces **billing limits** and **plan tiers** through logic in [`src/shared/billing-credit-features.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing-credit-features.ts), preventing runaway automation from exhausting quotas or incurring unexpected costs. Each `startAudit` call validates available credits before allocating crawl resources.

Additionally, the Zod schemas in [`src/types/schemas/audit.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/audit.ts) enforce strict payload shapes, ensuring that automated scripts cannot accidentally trigger invalid audit configurations that would waste resources.

## Integration Examples

You can invoke OpenSEO's automated SEO checks from any environment capable of making HTTP requests, or directly import the functions if you are already using TanStack React Start.

### HTTP Client Implementation

For external scripts or CI pipelines, target the auto-generated endpoints:

```typescript
import fetch from "node-fetch";

async function runAutomatedAudit() {
  // Start the audit
  const startResponse = await fetch("https://your-openseo-instance.com/api/startAudit", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      startUrl: "https://example.com",
      maxPages: 100,
      lighthouseStrategy: "desktop"
    })
  });
  
  const { auditId } = await startResponse.json();
  
  // Poll until completion
  while (true) {
    const statusRes = await fetch("https://your-openseo-instance.com/api/getAuditStatus", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ auditId })
    });
    
    const { status, progress } = await statusRes.json();
    console.log(`Progress: ${progress}%`);
    
    if (status === "complete") break;
    await new Promise(r => setTimeout(r, 5000));
  }
  
  // Retrieve results
  const resultsRes = await fetch("https://your-openseo-instance.com/api/getAuditResults", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ auditId })
  });
  
  const report = await resultsRes.json();
  return report;
}

```

### Direct TanStack Integration

If your automation runs within a TanStack React Start application, import the functions directly for optimal type safety:

```typescript
import { startAudit, getAuditStatus, getAuditResults } from "@/serverFunctions/audit";

async function performAudit() {
  const { auditId } = await startAudit({ 
    startUrl: "https://example.com", 
    maxPages: 50 
  });
  
  let status = await getAuditStatus({ auditId });
  while (status !== "complete") {
    await new Promise(r => setTimeout(r, 3000));
    status = (await getAuditStatus({ auditId })).status;
  }
  
  const report = await getAuditResults({ auditId });
  return report;
}

```

## Summary

- **Server-function architecture** in [`src/serverFunctions/audit.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/audit.ts) enables headless automation without UI dependencies.
- **Workflow engine** at [`src/server/workflows/siteAuditWorkflowPhases.ts`](https://github.com/every-app/open-seo/blob/main/src/server/workflows/siteAuditWorkflowPhases.ts) orchestrates discovery, crawling, Lighthouse scoring, and issue collection.
- **Type-safe APIs** use Zod validation from [`src/types/schemas/audit.ts`](https://github.com/every-app/open-seo/blob/main/src/types/schemas/audit.ts) to prevent automation errors.
- **Billing safeguards** in [`src/shared/billing-credit-features.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing-credit-features.ts) enforce quota limits during automated execution.
- **Flexible integration** supports both HTTP clients and direct function imports for CI/CD and scheduled job scenarios.

## Frequently Asked Questions

### Can OpenSEO run audits without the web interface?

Yes. The platform exposes `startAudit`, `getAuditStatus`, and `getAuditResults` as server functions that generate HTTP endpoints via `createServerFn`. You can invoke these from any HTTP client, curl scripts, or directly import them in a TanStack React Start application, completely bypassing the React-based UI.

### How does OpenSEO prevent automated audits from exceeding quota limits?

The system enforces billing limits and plan tiers through [`src/shared/billing-credit-features.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing-credit-features.ts). Each audit checks available credits before execution, ensuring automated scripts cannot trigger runaway costs. If the `maxPages` parameter exceeds your remaining quota, the function returns a validation error before starting the crawl.

### What data format does the audit workflow return?

The `getAuditResults` function returns structured data including raw HTML snapshots, Lighthouse performance scores, and SEO-specific issues defined in [`src/shared/audit-issues.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/audit-issues.ts). Results can be retrieved as JSON for programmatic processing, CSV for spreadsheet analysis, or rendered HTML for human review, making them compatible with downstream automation tools.

### Is the audit workflow suitable for CI/CD integration?

Yes. The workflow engine runs asynchronously with progress tracked in a durable KV store, allowing you to poll `getAuditStatus` until completion without maintaining a persistent connection. This pattern fits naturally into CI/CD pipelines where you might run `startAudit` during a build phase, poll for completion in a test stage, and fail the pipeline if `getAuditResults` returns critical SEO errors.