---
title: "Operate an API integration"
url: "https://stylome.io/api/docs/operations"
---

> [Documentation index](https://stylome.io/llms.txt) · [API overview](https://stylome.io/api/docs)

# Operate an API integration

Use `https://stylome.io` as the base URL. The [OpenAPI schema](https://stylome.io/api/openapi.json) defines complete response types for all six endpoints. The read endpoints below do not submit text to the detector.

## Read limits and prepaid balance

`GET /api/v1/limits` requires Bearer authentication with `account:read`. It does not consume the scoring request window.

```bash
curl --fail-with-body https://stylome.io/api/v1/limits \
  --header "Authorization: Bearer $STYLOME_API_KEY"
```

The result has `object: "api_limits"`, `measured_at`, `rate_limit_scope: "account"`, `window_seconds`, `request_limit`, `remaining_requests`, `resets_at`, `rate_limit_exempt`, `request_timeout_seconds`, `idempotency_lifetime_seconds`, `idempotency_supported`, `retention_mode`, and `prepaid`. Operator-exempt keys can have null request-limit and reset fields; ordinary integrations must not assume an exemption.

`prepaid` contains `currency`, `balance_usd`, `reserved_usd`, `available_usd`, `billing_review_required`, `topup_min_usd`, and `topup_max_usd`. Monetary values are decimal strings. Available credit accounts for reservations; the request window and credit balance are separate constraints.

## Read usage

`GET /api/v1/usage` requires Bearer authentication with `usage:read`.

| Query parameter | Rule |
| --- | --- |
| `start` | Inclusive timezone-aware timestamp; defaults to seven days before `end` |
| `end` | Exclusive timezone-aware timestamp; defaults to now |
| `group_by` | `day` (default), `model`, or `key` |
| `model` | Optional model ID; retired IDs are accepted for historical usage |
| `key` | Optional 16-character lowercase hexadecimal public key ID; never send a secret |

Use a start before end, no future end, and a range of at most 90 days. A report with too many groups returns `422`; narrow the range or add a filter.

```bash
curl --fail-with-body --get https://stylome.io/api/v1/usage \
  --header "Authorization: Bearer $STYLOME_API_KEY" \
  --data-urlencode 'group_by=model'
```

The response has `object: "api_usage"`, `start`, `end`, `measured_at`, `group_by`, `totals`, `data`, and `description`. Totals and each bucket report `requests`, `successes`, `failures`, `pending`, `billed_characters`, `cost_usd`, and `unpriced_requests`; buckets also have `value`. Reports use operation start time and exclude idempotent replays and failures before ledger creation. Historical unpriced operations have no inferred charge.

## Check service status

`GET /api/v1/status` is public. It returns `object: "api_status"`, `status` (`operational` or `degraded`), `checked_at`, `database` (`reachable` or `unavailable`), `inference` (`configured` or `unconfigured`), and `description`. Operational responses use `200`; degraded responses use `503`. The check can be cached internally for 15 seconds. It checks database reachability and configuration presence; it does not run inference or guarantee model availability.

## Rate limits and deadlines

Ordinary accounts share a fixed 120-request, 60-second scoring window across all their keys. Scoring attempts count after authentication and text validation, including failures and idempotent replays. An exhausted window returns `429` with `Retry-After` in seconds.

`RateLimit-Policy` describes the window and quota. `RateLimit` gives the remaining count and time to reset. Compatibility headers are `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` (Unix seconds). `X-RateLimit-Exempt: true` appears for an operator-exempt key.

Scoring admission and inference have a 110-second deadline. Allow 150 seconds in your client for transport and finalization. Each worker admits eight developer scoring calls. Use bounded exponential backoff with jitter for retryable failures, and honor `Retry-After`.

## Idempotency and safe retries

For a standard-retention key, send a project-wide, case-sensitive opaque `Idempotency-Key` of 1–255 characters. Use a new value for each logical scoring operation. A completed result replays for 24 hours when normalized text, model, and operating point match. Changing those inputs with the same key returns `409 idempotency_conflict`. A pending operation returns `409 idempotency_in_progress` with `Retry-After`.

A successful replay returns `X-Idempotent-Replayed: true` and the original `X-Operation-ID`. It consumes the request-rate window but adds no charge. `X-Request-ID` identifies the current HTTP attempt. Zero-content keys reject idempotency headers with `400 idempotency_not_supported`.

A network failure can happen after processing and charging. Preserve the idempotency key for safe standard-retention retries. Do not automatically repeat a scoring POST without an idempotency key. With zero-content keys, the service cannot replay a response; a repeated successful scoring call is another paid operation.

## Errors and response headers

Developer API errors use the JSON envelope below. The names and types shown are a schema description, not a recorded service response:

```text
error: {
  code: string,
  message: string,
  request_id: string,
  retryable: boolean,
  param: string | null,
  fields: [{loc: (string | integer)[], msg: string, type: string}] | null
}
```

| HTTP status | Action |
| --- | --- |
| `400` | Correct an invalid option or unsupported idempotency header |
| `401` / `403` | Check credential, scope, or billing-review status |
| `402` | Add prepaid API credit |
| `404` | Check the requested resource or path |
| `409` | Distinguish a conflicting request from an in-progress operation |
| `422` | Correct validation, text length, model, or usage range |
| `429` | Wait for `Retry-After` |
| `500` / `502` / `503` / `504` | Check `retryable`; follow safe-retry rules |

Every API attempt returns `X-Request-ID`. Scoring returns `X-Operation-ID` once an operation is identified. `X-Stylome-Data-Retention` is `none` for zero-content scoring or `standard` for retained scoring. Scoring responses use `Cache-Control: no-store`. Keep request IDs for support and redact keys, submitted text, and private receipt capabilities from logs.
