# Projected billing approval rates

`GET /v2/reports/projected-billing/approval-rates`

Core API v2, Reports.

Returns the approval rate your own renewals achieved in each bucket of the projected billing report — Rebill #1 to #4+ and Recycle #1 to #4+ — with the period it was measured over and the number of attempts behind each rate. The rates are measured over the 90 days before your request, from the renewals first charged in that time: each renewal's first attempt counts toward its rebill bucket, and each retry made for it so far toward its recycle bucket. An attempt counts as approved when it was authorized, and as declined when a retry followed it or it came back with a decline of any type, including a payment that could not be authorized against its payment method at all. Free renewals are not counted, and neither is an attempt still awaiting its outcome or one that failed without a decline. The rates cover your whole account, whatever a projection filters on, and are computed when you request them. Pass them as `rebillProjections` and `recycleProjections` to project at the rates your renewals actually achieve.

**Authentication:** Send `Authorization: Bearer <token>`. To authenticate, generate a Secret API Key from your ODUS Dashboard and include it in the `Authorization` header as follows: `Authorization: Bearer <YOUR_SECRET_API_KEY>`

## Responses

### `200`

OK

Type: object (ProjectedBillingApprovalRatesDTO).

- `periodStart` (string (date-time), required): Start of the period the rates were measured over: 90 days before `periodEnd`. Example: `2026-07-26T09:30:00.000Z`.
- `periodEnd` (string (date-time), required): End of the period the rates were measured over: the moment of your request. Example: `2026-10-24T09:30:00.000Z`.
- `rebill` (array of object, required): Your approval rate for each rebill bucket, in the order `rebillProjections` takes them: Rebill #1, #2, #3 and #4+. A rebill is a renewal's first attempt, and Rebill #1 is a subscription's first renewal.
  - `bucket` (number, required): The bucket: `1`, `2` or `3`, or `4` for the fourth attempt and every later one. The same numbering as the `attemptBucket` filter of the projected billing report. Example: `1`.
  - `attempts` (number, required): Number of attempts in this bucket made for the renewals first charged during the period. An attempt still awaiting its outcome is not counted yet. Example: `240`.
  - `approved` (number, required): Number of those attempts that were approved. Example: `204`.
  - `approvalRate` (number, required, nullable): `approved` as a percentage of `attempts`, rounded to two decimals. `null` when the bucket has no attempts in the period, so there is no rate to measure. Example: `85`.
- `recycle` (array of object, required): Your approval rate for each recycle bucket, in the order `recycleProjections` takes them: Recycle #1, #2, #3 and #4+. A recycle is a retry of a declined renewal, and Recycle #1 is its first retry.
  - `bucket` (number, required): The bucket: `1`, `2` or `3`, or `4` for the fourth attempt and every later one. The same numbering as the `attemptBucket` filter of the projected billing report. Example: `1`.
  - `attempts` (number, required): Number of attempts in this bucket made for the renewals first charged during the period. An attempt still awaiting its outcome is not counted yet. Example: `240`.
  - `approved` (number, required): Number of those attempts that were approved. Example: `204`.
  - `approvalRate` (number, required, nullable): `approved` as a percentage of `attempts`, rounded to two decimals. `null` when the bucket has no attempts in the period, so there is no rate to measure. Example: `85`.

### `202`

The merchant is entitled but its environment is not provisioned yet. Provisioning has been kicked off (exactly once) and is in progress; retry the request — it succeeds once the environment is ready. Returned only for identity-token (dashboard) requests bound to a merchant, not for secret-key API calls; any such endpoint can return it while provisioning is underway.

Type: object (ProvisioningInProgress).

- `status` (string, required): Signals the merchant environment is still being provisioned. One of `provisioning`.
- `merchantAccountId` (string, required): The merchant account whose environment is being provisioned. Example: `dAI3aa87ROOeupeBCjNSKCOBOisBCYjB`.

### Errors

- `401`: No API key was supplied, or the key is not valid. `type` is `authentication_error`.
- `403`: The API key is valid but lacks the permission this operation requires. `type` is `permission_error`.
- `429`: Too many requests. A limit applies per operation; requests to other operations are unaffected. `type` is `rate_limit_error`. Use the `Retry-After-global` header to know when to retry.
- `500`: The request could not be completed because of an unexpected error. `type` is `api_error`.
- `503`: The request could not be served right now: the API is temporarily at capacity, or a dependency needed to authorize the request is unavailable — the auth service that verifies credentials, or the entitlement lookup behind it. `type` is `api_error`. It is raised before the operation runs, so the request had no effect, and unlike a plain 500 the condition is transient: retry with backoff.
- `504`: The request exceeded the processing time limit and was abandoned. `type` is `api_error` and `code` is `timeout` — unlike a plain 500 the request may still have taken effect, so retry with the same idempotency key rather than blindly.

Every error response has the same body: see [Errors](https://docs.odus.com/docs/guides/api-features/errors.md).

---

Generated from the Core API v2 OpenAPI document, https://api.odus.com/openapi.v2.json. Interactive page: https://docs.odus.com/docs/api/core/v2/reporting-controller-get-projected-billing-approval-rates
