# Metrics and usage reporting

:::note[In short]

The SDK sends two kinds of usage data, and neither carries coordinates. Aggregate metrics counters are on by default and turn off with `OctetConfig.telemetryEnabled = false`. The daily usage record, one per device per UTC day, is always on, because Octet counts active devices.

:::

## Metrics counters

When `telemetryEnabled` is on (the default), the SDK reports counters to `{activationServerUrl}/v1/metrics`, indexed by your license: how many proofs were generated, uploaded, or could not be produced, by coarse level and region type. The counters are buffered in an encrypted file in the app's private storage and uploaded once a day, plus a best-effort flush when the app enters the background.

A metrics report contains no coordinates and no proof contents. Octet turns on additional counters through remote configuration, and they are on for all licenses. They include region codes, for example the ISO 3166 code of each region your app checks (`US` or `US-NY`) with the verdict, and the code a background proof resolved to. See [Data collection](/docs/mobile/concepts/data-collection/#usage-counters) for the full list.

| Sent | Not sent |
|---|---|
| Counts of proofs generated / uploaded / not produced, by coarse level and region type, and region codes with per-proof events (see [Usage counters](/docs/mobile/concepts/data-collection/#usage-counters)) | Coordinates or proof contents |
| SDK version, platform, OS version, app id | Any identifier that resolves to a person |
| A pseudonymous device fingerprint (a one-way SHA-256 hash of the install UUID and a platform device identifier) | The install UUID or the platform identifier itself |

### Turning metrics off

Set `OctetConfig.telemetryEnabled = false`. That disables the metrics upload and deletes any buffered report. It does not affect the daily usage record.

## Daily usage record

New in 3.0. To count active devices, the SDK sends one usage record per device per UTC day:

1. The app generates its first proof of the UTC day.
2. The SDK queues a single `device_active` record. This needs no network, and the proof is already complete.
3. The SDK sends the record with the next background heartbeat. Later proofs that day send nothing more.

**What it contains.** The operation name, a timestamp and a record ID. The record ID is a one-way SHA-256 hash of the device's opaque activation fingerprint and the date, so it changes every day and lets the server ignore duplicates. The device is counted from the activation credentials the SDK already holds. The record carries no location, no coordinates, no proof data, no user or account identity, and no new device identifier.

**It never affects a proof.** The record is written after the proof exists. A failed send is retried on later heartbeats, and a record that could not be sent within 30 days is dropped. A sandbox session sends nothing.

**It is always on.** Reporting cannot be switched off. `OctetConfig.creditServiceUrl` defaults to `https://credits.octetproof.com` (`OctetConfig.defaultCreditServiceUrl` on iOS, `OctetConfig.DEFAULT_CREDIT_SERVICE_URL` on Android). Set it only to point a test build at another environment. Setting it to `nil` / `null` does not disable reporting.

In a [gateway mode](/docs/mobile/concepts/gateway-routing/), the record goes through your gateway under `/v1/credits/...`.

## Where to go next

- [Data collection](/docs/mobile/concepts/data-collection/): how to declare this data in the App Store and Play Console.
- [License & Activation](/docs/mobile/concepts/license-activation/): how the SDK reaches the backend.
