# How the Billing Credit Feature Mapping Operates in OpenSEO

> Discover how OpenSEO maps billing credit features to DataForSEO API requests using path matching. Get precise accounting for keyword research, domain overview, and more.

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

---

**OpenSEO automatically maps every DataForSEO API request to a billing credit feature using path-based pattern matching in [`src/shared/billing-credit-features.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing-credit-features.ts), enabling precise usage-credit accounting across keyword research, domain overview, backlinks, site audit, and other SEO services.**

OpenSEO is an open-source SEO platform that integrates with the DataForSEO API to provide comprehensive search analytics. A critical component of its architecture is the **billing credit feature mapping system**, which translates raw API paths into categorized credit consumption events. This ensures customers are charged accurately based on which SEO capabilities they actually use.

## Credit Feature Types in OpenSEO

The foundation of the mapping system is a strict type definition enumerating every billable capability. In [`src/shared/billing-credit-features.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing-credit-features.ts), the `CreditFeature` union type defines all possible credit-consuming features:

- `keyword_research`
- `domain_overview`
- `backlinks`
- `site_audit`
- `rank_tracking`
- `ai_citations`
- `local_seo`

This union guarantees type safety throughout the billing pipeline and prevents misclassification of API calls.

## How the Path-to-Feature Mapper Works

The core mapping logic resides in the exported function `mapDataforseoPathToCreditFeature`. This function receives a DataForSEO response path as an array of strings and applies a deterministic classification algorithm.

### Path Normalization

Before classification, the function ensures consistent formatting:

```typescript
// Lines 35-36 in billing-credit-features.ts
const normalizedPath = path[0] === "v3" ? path : ["v3", ...path];

```

This guarantees all paths start with `"v3"` regardless of how the API client constructed them.

### Module-Based Feature Assignment

The second element of the normalized path—the `module`—drives feature assignment via a comprehensive `switch` statement (lines 38-72):

| Module | Feature Assignment | Conditions |
|--------|-------------------|------------|
| `on_page` | `site_audit` | Always |
| `backlinks` | `backlinks` | Always |
| `serp` | `keyword_research` or `local_seo` | `local_seo` for specific Google sub-paths |
| `ai_optimization` | `ai_citations` or `ai_prompt_responses` | `ai_citations` for `llm_mentions` sub-path |
| `business_data` | `local_seo` | Always |
| `keywords_data` | `keyword_research` | Always |
| `dataforseo_labs` | `domain_overview` or `keyword_research` | `domain_overview` for paths starting with `domain_`, `ranked_keywords`, or `relevant_pages` |

Any unrecognized module falls back to `site_audit`, providing defensive default behavior.

### Practical Mapping Example

```typescript
import { mapDataforseoPathToCreditFeature } from "@/shared/billing-credit-features";

// DataForSEO returns a path for domain-rank overview
const path = ["v3", "dataforseo_labs", "google", "domain_rank_overview", "live"];
const feature = mapDataforseoPathToCreditFeature(path);
// feature === "domain_overview"

```

## Default Integration in the DataForSEO Client

When calling the DataForSEO API, OpenSEO's client automatically applies this mapping when no explicit credit feature is provided. In [`src/server/lib/dataforseo/client.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseo/client.ts) (lines 190-202), the `trackDataforseoCost` helper implements this fallback:

```typescript
// Inside trackDataforseoCost – credit feature inferred when not supplied
await trackDataforseoCost({
  customer,
  customerId: billingCustomer.id,
  billing: response.billing,
  monthlyRemaining,
  // No creditFeature supplied → mapper runs internally
});

```

This design ensures backward compatibility: existing code continues to function while new calls can optionally specify `creditFeature` for override scenarios.

## Billing Constants and Credit Conversion

Supporting the mapper are constants and utilities defined in [`src/shared/billing.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing.ts):

- `AUTUMN_SEO_DATA_BALANCE_FEATURE_ID` (`usage_credits`) — shared pool for plan-included credits
- `AUTUMN_SEO_DATA_TOPUP_BALANCE_FEATURE_ID` (`topup_credits`) — pool for purchased top-up credits
- `AUTUMN_SEO_DATA_CREDITS_PER_USD = 1000` — conversion rate for USD reporting

Helper functions `roundUsdForBilling` and `applyBillingMarkupUsd` normalize monetary values for customer-facing displays and invoice generation.

## Key Implementation Files

- **[`src/shared/billing-credit-features.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing-credit-features.ts)** — `CreditFeature` type definition, feature labels, and `mapDataforseoPathToCreditFeature` implementation
- **[`src/shared/billing.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing.ts)** — billing route constants, plan identifiers, balance feature IDs, and USD conversion utilities
- **[`src/server/lib/dataforseo/client.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseo/client.ts)** — DataForSEO client integration with automatic mapper fallback

## Summary

- OpenSEO's **billing credit feature mapping** converts DataForSEO API paths into categorized credit consumption events using deterministic pattern matching.
- The `mapDataforseoPathToCreditFeature` function in [`src/shared/billing-credit-features.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing-credit-features.ts) normalizes paths and applies module-based classification with sensible fallbacks.
- The **DataForSEO client** automatically invokes this mapper when `creditFeature` is omitted, ensuring accurate billing without manual intervention.
- **Type-safe credit features** prevent misclassification, while **billing constants** in [`src/shared/billing.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing.ts) handle currency conversion and balance tracking.

## Frequently Asked Questions

### What happens if DataForSEO adds a new API module?

OpenSEO's mapper includes a **default case** that assigns `site_audit` to any unrecognized module. This ensures the system continues functioning while logging the unknown module for engineering review. Updates to [`src/shared/billing-credit-features.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/billing-credit-features.ts) can then add proper classification.

### Can I override the automatic credit feature detection?

Yes. The `trackDataforseoCost` function accepts an optional `creditFeature` parameter. When provided, this value bypasses the automatic mapper entirely, allowing manual classification for edge cases or custom integrations.

### How does OpenSEO calculate the USD cost of a DataForSEO call?

The billing system uses `AUTUMN_SEO_DATA_CREDITS_PER_USD = 1000` to convert credit consumption to USD values. The `roundUsdForBilling` function applies standard rounding, and `applyBillingMarkupUsd` adds any configured markup before displaying costs to customers.

### Where are credit balances stored and checked?

Credit balances are associated with the feature IDs `usage_credits` (plan-included) and `topup_credits` (purchased). The billing layer queries these balances before executing DataForSEO calls and deducts consumed credits post-request based on the feature classification determined by the mapper.