> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# RCS billing and metering model: what an RCS message costs, when the charge lands, and how to read it back

> RCS bills per message at carrier acceptance (submitted), never again on later delivered or read receipts, and refunds terminal failures through the shared DLR refund arm. The billing_category tier you declare at agent creation rides along on every submission, unreachable recipients never enter RCS billing, sends that ride the platform agent during approval are zero-rated, and usage records, the CDR export, and the spend series read the same ledger back.

# RCS billing and metering model

RCS is billed per message against your prepaid wallet, on the same
trigger-and-refund rules as the rest of the messaging channels. This page
is the money view of RCS: what a message costs, when the debit lands, the
two billing tiers you declare for an agent, which sends never enter
billing at all, and how to reconcile RCS spend after the fact. The brand
and agent approval lifecycle lives on
[RCS brand and bot approval lifecycle](https://docs.orbit.devotel.io/concepts/rcs-brand-lifecycle.md);
reach detection and SMS fallback live on
[RCS capability check and SMS fallback](https://docs.orbit.devotel.io/concepts/rcs-fallback-and-capability.md).

## What you pay for on RCS

RCS charges **per message, at `submitted`** — the moment the RCS provider
accepts the handoff. The debit lands at send time, before delivery
completes, so your wallet reflects the spend the moment the send goes to
the wire. This is the same rule SMS, MMS, email, and push follow; the
per-channel billing rules note in the
[billing API reference](https://docs.orbit.devotel.io/api-reference/billing.md) and the
[Channel charge trigger model](https://docs.orbit.devotel.io/concepts/channel-charge-trigger-model.md)
state it for every channel in one table.

Three consequences follow from the trigger:

* **No double-bill on delivery or read.** A later DLR `delivered` or
  `read` receipt updates the message row's status and fans out to your
  webhooks, but it never posts a second charge. One submitted message is
  exactly one debit.
* **Terminal failure refunds.** When the provider reports a terminal
  failure — `failed`, `undelivered`, or `rejected` — the shared DLR
  pipeline's [refund arm](https://docs.orbit.devotel.io/concepts/dlr-provider-webhook-fleet.md#the-refund-arm)
  credits the charge back to your wallet as part of the same hand-off
  that commits the status. A `sent` or `delivered` receipt never reaches
  the refund arm.
* **Pre-submit rejections are free.** If the provider refuses the
  handoff before accepting it (an unapproved agent, a rejected payload),
  no charge ever posts.

## Conversational vs Non\_Conversational billing category

RBM (Rich Business Messaging) pricing splits agent traffic into two
tiers, and you declare the tier per agent at creation with the
`billing_category` field: `Conversational` or `Non_Conversational`. The
same field is accepted on the combined setup call and on agent updates,
and RBM is moving toward making the declaration mandatory, so set it
explicitly rather than leaving it unset.

Operationally, the two tiers classify how the agent is used:

* **`Conversational`** marks an agent whose traffic is part of
  user-initiated conversations — the subscriber messages the agent
  first, or replies inside an open conversation window.
* **`Non_Conversational`** marks agent-initiated traffic outside a
  conversation window — alerts, one-time codes, notifications, and
  scheduled updates the subscriber did not prompt.

Carriers price the two tiers differently, and the declaration is
expected to match how the agent actually behaves; it is part of the
agent's directory submission, not a per-message switch. Two things Orbit
deliberately does not do:

* **Orbit does not set RBM prices.** The per-message price that lands in
  your wallet is the resolved rate for your plan and volume, the same way
  every other channel resolves rates (see
  [pricing and rate resolution](https://docs.orbit.devotel.io/concepts/pricing-rate-resolution.md) and
  the [pricing page](https://orbit.devotel.io/pricing) for your rate
  card). This page defines when and what Orbit meters, not the carrier
  rate tables behind the tiers.
* **Orbit does not re-classify your traffic.** The value you send is
  stored on the agent record and passed through verbatim on every
  submission and resubmission. Pick the tier that matches the agent's
  real traffic pattern when you create it, and update the agent if the
  pattern changes.

## Capability check before you pay

RCS only bills recipients who can actually receive RCS. Before a send
dispatches, the reach scan checks whether the destination can render
RCS; a recipient without an RCS-capable device or client never produces
an RCS submission and never enters RCS billing. See
[RCS capability check and SMS fallback](https://docs.orbit.devotel.io/concepts/rcs-fallback-and-capability.md)
for the probe contract and the codes a not-capable send reports.

When a send falls back to SMS, you are billed for the leg that actually
submitted. If the RCS leg was accepted and later failed terminally
before the fallback fired, the RCS charge is refunded by the refund arm
and the SMS leg is charged as SMS at its own per-segment rate — you pay
for what reached the wire, per channel. The ordered-chain rules,
including which leg a charge belongs to, live on
[Cross-channel fallback](https://docs.orbit.devotel.io/concepts/cross-channel-fallback.md). Combined
with the pre-submit-rejection rule above, the practical summary is: an
unreachable recipient costs you nothing on RCS, and a recipient who
lands on SMS costs you exactly one SMS.

## Test mode

Two zero-rated lanes exist while you are evaluating RCS:

* **The platform agent during approval.** Your production asset is a
  Google-approved agent, and approval takes days. While your agent
  application is pending, the platform's approved demo agent carries
  your verification sends, and traffic on that shared lane writes
  zero-cost, test-stamped ledger rows rather than debiting your wallet —
  the same shared-asset posture described on
  [The channel test-account model](https://docs.orbit.devotel.io/concepts/channel-test-account-model.md).
  Once your agent is approved, the shared lane ends and sends bill
  normally.
* **Simulated test mode.** Sends made with a `dv_test_sk_*` key (or inside
  the sandbox) are persisted and receipted by a simulated provider but
  never dispatched, and post no charge; the rows are stamped as test so
  they stay out of production spend. See
  [Sandbox, test mode, and the provisioning model](https://docs.orbit.devotel.io/concepts/provisioning-and-test-mode.md)
  and the [Sandbox model](https://docs.orbit.devotel.io/concepts/sandbox-model.md) for the boundary.

In both lanes the usage row is written anyway, so cost analytics stay
complete; the row simply carries a zero amount and a test marker.

## Reading your RCS spend back

Three surfaces read the same ledger back, at three granularities:

* **Usage records** are the row-level feed: one record per RCS message
  with `units`, the persisted `price` and `currency`, the terminal
  status, and timestamps. RCS bills per message, so an RCS row reports
  `units` of 1 (unlike multipart SMS, which reports its segment count).
  Filter the feed on `channels=rcs` and sum `units × price` per currency
  to reconcile against wallet debits; the reconciliation walk is on
  [Usage records: the per-record billing feed](https://docs.orbit.devotel.io/concepts/usage-records-model.md).
* **The CDR export** returns every finished message — RCS included —
  with its billed units and terminal status, for workbook-side
  reconciliation against the usage feed. See
  [CDR export](https://docs.orbit.devotel.io/api-reference/cdr-export.md).
* **The spend series** (`GET /api/v1/billing/spend-series`) gives the
  per-day aggregate your dashboard chart renders, RCS rolled into the
  messaging total. Aggregates can legitimately differ in rounding from
  a row-level sum; for any dispute, the row-level ledger is the source
  of truth (see
  [Channel cost rollup vs the billing ledger model](https://docs.orbit.devotel.io/concepts/cost-channel-rollup-model.md)).

Refunds on terminal failure appear as credits on the wallet ledger, so
a period's net RCS spend is submitted debits minus refund-arm credits —
reconcile both sides, not just the debits.

## Cross-references

* [RCS brand and bot approval lifecycle](https://docs.orbit.devotel.io/concepts/rcs-brand-lifecycle.md) — the approval states an agent moves through before it bills as your asset.
* [Send your first RCS message](https://docs.orbit.devotel.io/guides/first-rcs-message-send.md) — the ordered how-to from approved brand to first live send.
* [RCS capability check and SMS fallback](https://docs.orbit.devotel.io/concepts/rcs-fallback-and-capability.md) — the reach probe and the fallback codes a not-capable send reports.
* [Channel charge trigger model](https://docs.orbit.devotel.io/concepts/channel-charge-trigger-model.md) — the per-channel trigger and refund table, RCS row included.
* [The DLR pipeline's refund arm](https://docs.orbit.devotel.io/concepts/dlr-provider-webhook-fleet.md#the-refund-arm) — where terminal-failure credits come from.
* [How billing meters your usage](https://docs.orbit.devotel.io/concepts/billing-and-wallet.md) — the prepaid wallet map every channel's charges land in.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.