# How OpenSEO Handles Error Codes and Billing Classification

> Discover how OpenSEO manages error codes and classifies billing failures. Learn about its Zod-validated schema and DataForSEO billing classifiers for efficient error resolution.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: internals
- Published: 2026-09-01

---

**OpenSEO centralizes error handling in a Zod-validated schema at [`src/shared/error-codes.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/error-codes.ts) and classifies DataForSEO billing failures using specialized classifiers in [`src/server/lib/dataforseoBillingClassification.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseoBillingClassification.ts), converting external HTTP 402 responses into distinct internal codes like `BACKLINKS_BILLING_ISSUE` and `AI_SEARCH_BILLING_ISSUE`.**

OpenSEO, from the repository every-app/open-seo, implements a type-safe error architecture that distinguishes between system failures and user-facing billing issues. Understanding how OpenSEO handles error codes and billing classification reveals a robust approach to managing external API degradation and payment-related failures. The system combines a closed-set error enumeration with per-API billing classifiers to ensure accurate error routing and monitoring.

## Centralized Error Code Management with Zod

The foundation of OpenSEO's error handling lies in [`src/shared/error-codes.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/error-codes.ts), which defines a strict, closed-set of error identifiers using **Zod** validation. This approach ensures that every error passed through the system conforms to a predefined schema, enabling type-safe error handling across both client and server boundaries.

### The Error Code Schema

The `errorCodeSchema` uses Zod's enum validation to establish the canonical set of valid errors. This schema is exported as a TypeScript type called `ErrorCode` for use throughout the application:

```typescript
export const errorCodeSchema = z.enum([
  "UNAUTHENTICATED",
  "AUTH_CONFIG_MISSING",
  "PAYMENT_REQUIRED",
  "INSUFFICIENT_CREDITS",
  "FORBIDDEN",
  "NOT_FOUND",
  "AUDIT_CAPACITY_REACHED",
  "AUDIT_PAGE_LIMIT_EXCEEDED",
  "AUDIT_ALREADY_RUNNING",
  "VALIDATION_ERROR",
  "CRAWL_TARGET_BLOCKED",
  "BACKLINKS_BILLING_ISSUE",
  "AI_SEARCH_BILLING_ISSUE",
  "DATAFORSEO_AUTH_FAILED",
  "RATE_LIMITED",
  "UPSTREAM_UNAVAILABLE",
  "CONFLICT",
  "INTERNAL_ERROR",
] as const);

```

### Filtering Non-Reportable Errors

Not all errors warrant monitoring service alerts. OpenSEO maintains a set of **non-reportable error codes** (such as authentication failures or insufficient credits) that should not clutter error-tracking dashboards. The helper function `shouldCaptureAppErrorCode` implements this filtering logic:

```typescript
export function shouldCaptureAppErrorCode(
  code: ErrorCode | null | undefined,
): boolean {
  return code == null || !NON_REPORTABLE_ERROR_CODES.has(code);
}

```

When this function returns `false`, the error is excluded from external capture services while still being available for user-facing error display.

## Billing Classification for DataForSEO Integrations

When interacting with external DataForSEO APIs, OpenSEO must translate ambiguous HTTP responses—particularly **HTTP 402 status codes**—into actionable internal error codes. The module [`src/server/lib/dataforseoBillingClassification.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseoBillingClassification.ts) provides a factory function that creates specialized classifiers for different API sections.

### The Billing Classifier Factory

The `createDataforseoBillingClassifier` function generates type-safe classifiers that inspect response status codes and message content for billing-related signals. It looks for specific **billing status codes** (the HTTP 402 family) and **billing signals** (keywords like "insufficient funds" or "balance is too low"):

```typescript
export function createDataforseoBillingClassifier(config: {
  pathPrefix: string;
  billingIssueCode: ErrorCode;
  billingIssueMessage: string;
}): DataforseoBillingClassifier {
  return (status, details, path) => {
    if (!path.includes(config.pathPrefix)) return null;

    const text = details.toLowerCase();
    const matchesBillingStatus = status != null && BILLING_STATUS_CODES.has(status);
    const matchesBillingText = BILLING_SIGNALS.some((signal) => text.includes(signal));

    if (matchesBillingStatus || matchesBillingText) {
      return new AppError(config.billingIssueCode, config.billingIssueMessage);
    }
    return null;
  };
}

```

### Per-API Billing Implementations

Each DataForSEO API section (Backlinks, AI Search, etc.) instantiates its own classifier with specific configuration. In [`src/server/lib/dataforseo/backlinks.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseo/backlinks.ts), the classifier targets the `/backlinks` path prefix:

```typescript
const classifyBacklinksError = createDataforseoBillingClassifier({
  pathPrefix: "/backlinks",
  billingIssueCode: "BACKLINKS_BILLING_ISSUE",
  billingIssueMessage: "Your DataForSEO balance is too low for Backlinks requests.",
});

```

Similarly, [`src/server/lib/dataforseo/ai.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseo/ai.ts) configures classification for AI Search endpoints:

```typescript
const classifyAiSearchError = createDataforseoBillingClassifier({
  pathPrefix: "/ai-search",
  billingIssueCode: "AI_SEARCH_BILLING_ISSUE",
  billingIssueMessage: "Your DataForSEO balance is too low for AI Search requests.",
});

```

When a DataForSEO request fails, the corresponding classifier runs first. If it detects a billing problem, it returns an `AppError` with the appropriate internal error code. The generic error-handling middleware in [`src/middleware/errorHandling.ts`](https://github.com/every-app/open-seo/blob/main/src/middleware/errorHandling.ts) then translates these codes to user-visible messages or redirects to the billing UI.

## Credit to USD Conversion and Billing Logic

Beyond error classification, OpenSEO manages usage-based billing through [`src/shared/billing.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing.ts). This module defines the credit-to-currency conversion rate and applies platform markup for hosted deployments:

```typescript
export const AUTUMN_SEO_DATA_CREDITS_PER_USD = 1000;

export function roundUsdForBilling(value: number) {
  return Math.round(value * 100000) / 100000;
}

export function autumnSeoDataCreditsToUsd(credits: number) {
  return credits / AUTUMN_SEO_DATA_CREDITS_PER_USD;
}

/** Apply the platform markup before billing the hosted customer */
export function applyBillingMarkupUsd(rawUsd: number) {
  return roundUsdForBilling(rawUsd * SEO_DATA_COST_MARKUP);
}

```

These utilities ensure that cost displays match actual charge amounts, while self-hosted deployments can skip the markup step entirely.

## Summary

- OpenSEO defines a strict error code enumeration in [`src/shared/error-codes.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/error-codes.ts) using Zod validation to ensure type safety across the application.
- The `shouldCaptureAppErrorCode` function filters non-reportable errors (authentication, insufficient credits) to prevent noise in error tracking services.
- Billing classification uses factory functions in [`src/server/lib/dataforseoBillingClassification.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseoBillingClassification.ts) to detect HTTP 402 responses and specific keywords like "insufficient funds" from DataForSEO APIs.
- Distinct error codes (`BACKLINKS_BILLING_ISSUE`, `AI_SEARCH_BILLING_ISSUE`) allow the middleware in [`src/middleware/errorHandling.ts`](https://github.com/every-app/open-seo/blob/main/src/middleware/errorHandling.ts) to route users to appropriate billing UI flows.
- Credit-to-USD conversion utilities in [`src/shared/billing.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing.ts) handle platform markup calculations for accurate billing displays.

## Frequently Asked Questions

### What is the complete list of error codes defined in OpenSEO?

The `errorCodeSchema` in [`src/shared/error-codes.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/error-codes.ts) defines 18 distinct error codes including `UNAUTHENTICATED`, `PAYMENT_REQUIRED`, `INSUFFICIENT_CREDITS`, `AUDIT_CAPACITY_REACHED`, `BACKLINKS_BILLING_ISSUE`, `AI_SEARCH_BILLING_ISSUE`, and `UPSTREAM_UNAVAILABLE`. These cover authentication failures, resource limits, billing issues, and upstream service unavailability.

### How does OpenSEO prevent billing-related errors from cluttering error tracking dashboards?

The `shouldCaptureAppErrorCode` function checks incoming error codes against the `NON_REPORTABLE_ERROR_CODES` set. When errors like `UNAUTHENTICATED` or `INSUFFICIENT_CREDITS` occur, the function returns `false`, preventing them from being sent to external monitoring services while still allowing user-facing error display.

### What triggers the BACKLINKS_BILLING_ISSUE error code?

This error occurs when the DataForSEO Backlinks API returns an HTTP 402 status code or response text containing keywords like "insufficient funds" or "balance is too low". The `classifyBacklinksError` function in [`src/server/lib/dataforseo/backlinks.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseo/backlinks.ts) detects these signals and converts them to the internal `BACKLINKS_BILLING_ISSUE` code.

### How does OpenSEO convert usage credits to billing amounts?

The [`src/shared/billing.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing.ts) module defines `AUTUMN_SEO_DATA_CREDITS_PER_USD` (1000 credits per USD) and provides `autumnSeoDataCreditsToUsd` for conversion. For hosted deployments, `applyBillingMarkupUsd` multiplies the raw cost by the platform markup factor before rounding to five decimal places for precise billing.