# How the Grok Audit Service Tracks Usage and Client Billing in chenyme/grok2api

> Learn how the Grok audit service tracks usage and client billing in chenyme/grok2api using SQLite audit records and fixed-point USD ticks for accurate pricing.

- Repository: [Chenyme/grok2api](https://github.com/chenyme/grok2api)
- Tags: how-to-guide
- Published: 2026-08-09

---

**The Grok audit service tracks usage by persisting structured audit records with embedded attempt logs in SQLite, then calculates client billing using fixed-point USD ticks based on official pricing tables stored alongside each request.**

The chenyme/grok2api repository implements a comprehensive audit system that records every API request and its upstream attempts to enable precise usage tracking and client billing. This Grok audit service architecture separates concerns between persistence, domain logic for pricing, and application services to ensure accurate cost attribution even when pricing models change.

## Architecture of the Grok Audit Service

The implementation follows a three-layer architecture centered on the [`backend/internal/application/audit/service.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/application/audit/service.go) file, which exposes a thread-safe API for the HTTP transport layer.

### Persistence Layer (SQLite Repository)

The [`backend/internal/repository/audit.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/repository/audit.go) file manages an embedded SQLite database (`audit-service.db`). It stores `auditdomain.Record` objects that contain request identifiers, the client-key ID, model-route ID, HTTP status code, timestamps, input and output token counts, and a serialized list of `auditdomain.Attempt` objects. This repository handles low-level CRUD operations and query helpers used by the service layer.

### Domain Layer (Pricing and Models)

Located in [`backend/internal/domain/audit/pricing.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/domain/audit/pricing.go) and [`backend/internal/domain/audit/audit.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/domain/audit/audit.go), the domain layer defines the data structures and business rules. The `auditdomain.Record` struct holds the primary audit data, while `auditdomain.Attempt` captures individual upstream HTTP calls including stage names, start and end timestamps, upstream status codes, and truncated response bodies. The domain expresses monetary costs as `CostInUSDTicks`, where one USD equals 1,000,000 ticks, preventing floating-point rounding errors. The `ReconstructOfficialCost` function calculates costs by looking up the `OfficialPricingSource` pricing tables for the specific model version used.

### Application Service Layer

The [`backend/internal/application/audit/service.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/application/audit/service.go) file implements the `Service` struct, which provides the public methods consumed by HTTP handlers. These include `Create` and `CreateDurable` for inserting new records, `Record` for updating existing entries after retries or errors, `ListCursor` for paginating through audit history, and `Summary` for aggregating billing statistics. The service coalesces rapid-fire events and ensures thread-safe access to the underlying SQLite store.

## How the Grok Audit Service Tracks Usage

Usage tracking follows a lifecycle that captures request metadata, upstream attempts, and final cost calculations.

### 1. Request Initialization with Create

When the gateway receives a request, it invokes `auditService.Create` with a minimal `auditdomain.Record` containing the request ID, client-key ID, model-route ID, an initial HTTP 202 status code, and the creation timestamp. The service persists this row to SQLite and returns the generated database ID, which subsequent operations reference to append data to the same record.

### 2. Attempt Logging via Record Updates

Each upstream HTTP call—such as credential fetching or model inference—generates an `auditdomain.Attempt` object. The application layer calls `AddAttempt` (internally managed by the `Record` method) to append these attempts to the `Record.Attempts` slice. Each attempt captures the stage name (e.g., `credential` or `upstream_response`), precise start and end timestamps, the upstream HTTP status code, input and output token counts, and a truncated response body for debugging.

### 3. Token-Based Cost Calculation

After receiving the model response, the service calculates the monetary cost by invoking `auditdomain.ReconstructOfficialCost`. This function queries the `OfficialPricingSource` tables for the specific model version and multiplies the input and output token counts by the per-token price. The resulting `CostInUSDTicks` value is stored on the audit record, ensuring the exact pricing model version is preserved alongside the usage data for historical accuracy.

### 4. Billing Breakdown Persistence

The audit record stores a `PricingModel` identifier (e.g., `grok-build-0.1`) and a `PricingVersion` timestamp. This versioning allows the service to reconstruct historical billing statements even after official pricing changes. The domain also supports `EstimatedCostInUSDTicks` for preview modes, allowing clients to see potential costs before finalizing requests.

## How Client Billing Is Derived

The billing pipeline operates as a map-reduce query over the SQLite audit records.

### Filtering Audit Records

Administrators or client-facing APIs call `ListCursor` with a `ListFilter` specifying the client-key ID, date range, and request status. The service translates these parameters into SQL queries against the [`backend/internal/repository/audit.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/repository/audit.go) layer, returning only the rows belonging to the requested client.

### Aggregation and Summarization

The `Summary` method aggregates the filtered records to produce billing reports. It calculates the total request count, successful request count, total input and output token usage, and the sum of `CostInUSDTicks` across all matching records. This aggregation happens at the database level for efficiency, utilizing SQLite's `SUM` and `COUNT` functions.

### Currency Conversion and Display

Costs remain in `USDTicks` throughout the backend to maintain precision. The frontend or API consumers divide the tick value by 1,000,000 to display decimal USD amounts. This fixed-point approach ensures that financial calculations remain exact and free from floating-point artifacts common in monetary computations.

## Code Implementation Examples

### Creating an Audit Record

The following pattern from [`backend/internal/application/audit/service.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/application/audit/service.go) demonstrates initializing a request audit:

```go
func (s *Service) Create(ctx context.Context, rec auditdomain.Record) (uint64, error) {
    // Insert minimal record with status 202 (Accepted)
    rec.StatusCode = http.StatusAccepted
    rec.CreatedAt = time.Now().UTC()
    
    id, err := s.repo.Insert(ctx, rec)
    if err != nil {
        return 0, fmt.Errorf("failed to create audit record: %w", err)
    }
    return id, nil
}

```

### Logging an Upstream Attempt

When capturing telemetry from upstream providers, the service appends attempts to the existing record:

```go
func (s *Service) AddAttempt(ctx context.Context, recordID uint64, attempt auditdomain.Attempt) error {
    attempt.StartedAt = time.Now().UTC()
    
    // Capture token usage from model response
    attempt.InputTokens = resp.Usage.InputTokens
    attempt.OutputTokens = resp.Usage.OutputTokens
    attempt.UpstreamStatusCode = &resp.StatusCode
    
    return s.repo.AppendAttempt(ctx, recordID, attempt)
}

```

### Retrieving Client Billing via HTTP

The HTTP handler in [`backend/internal/transport/http/audit/handler.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/transport/http/audit/handler.go) exposes billing summaries:

```bash
curl -H "Authorization: Bearer <admin-token>" \
     "https://api.example.com/api/admin/v1/request-audits/summary?clientKeyId=42&period=30d"

```

Response structure:

```json
{
  "requests": 1245,
  "successfulRequests": 1198,
  "totalCostUSDTicks": 5873200,
  "totalInputTokens": 3210000,
  "totalOutputTokens": 1950000
}

```

## Summary

- **The Grok audit service** uses a three-tier architecture separating SQLite persistence, domain pricing logic, and application services.
- **Usage tracking** relies on `auditdomain.Record` and `auditdomain.Attempt` structures stored in `audit-service.db`, capturing every upstream HTTP call and token count.
- **Cost calculation** employs `ReconstructOfficialCost` and `OfficialPricingSource` to compute `CostInUSDTicks`, ensuring financial precision with fixed-point arithmetic.
- **Client billing** derives from the `Summary` and `ListCursor` methods in [`backend/internal/application/audit/service.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/application/audit/service.go), which aggregate filtered records by client-key and date range.
- **Versioned pricing** allows historical billing reconstruction because each record stores its specific `PricingModel` and `PricingVersion`.

## Frequently Asked Questions

### How does the Grok audit service store usage data?

The service stores usage data in an embedded SQLite database managed by [`backend/internal/repository/audit.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/repository/audit.go). Each row represents an `auditdomain.Record` containing request metadata, client identification, token counts, and a JSON array of `auditdomain.Attempt` objects that log every upstream interaction.

### What is a USDTick and why is it used for billing?

A `USDTick` is a fixed-point representation of US dollars where 1 USD equals 1,000,000 ticks. The [`backend/internal/domain/audit/pricing.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/domain/audit/pricing.go) file defines costs as `CostInUSDTicks` to avoid floating-point rounding errors in financial calculations, ensuring that client billing remains mathematically precise.

### How does the service handle pricing model changes?

The audit record stores the `PricingModel` identifier and `PricingVersion` timestamp alongside the `CostInUSDTicks`. Because the domain logic in [`backend/internal/domain/audit/pricing.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/domain/audit/pricing.go) preserves the historical pricing version with each record, the system can reconstruct accurate billing statements even after official pricing tables are updated.

### Which files contain the core audit logic?

The primary files are [`backend/internal/application/audit/service.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/application/audit/service.go) for the application service, [`backend/internal/domain/audit/pricing.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/domain/audit/pricing.go) for cost calculations, [`backend/internal/domain/audit/audit.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/domain/audit/audit.go) for data models, and [`backend/internal/repository/audit.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/repository/audit.go) for SQLite persistence. The HTTP API surface is exposed through [`backend/internal/transport/http/audit/handler.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/transport/http/audit/handler.go).