Audit events (Orizon RGA)
Audit events carry the outcome of a payer audit in Brazil. When Orizon returns an RGA (Relatório de Glosa e Auditoria) for a provider's guide, RCM parses the SOAP report, classifies each executed item, and emits one event per item with the business action already derived.
These are the events to consume if your ERP needs to reflect what the payer accepted, adjusted, or removed from a submitted guide.
Unlike the document events, RGA audit events are consumed today over the pull API (POST /rcm/v1/integration/events/pull + /ack), not over push webhooks. See Consumption model before you wire anything up.
Event catalog
There are four types — one per audit_classification:
| Event | audit_classification | What the payer decided |
|---|---|---|
CHARGE_AUDIT_ACCEPTED | ACCEPTED | The item was accepted as submitted. Value and quantity are unchanged. |
CHARGE_AUDIT_UPDATED | UPDATED | The item was accepted with an adjustment — value and/or quantity differ from what was submitted. |
CHARGE_AUDIT_DELETED | DELETED | The item was removed entirely (agreed_value = 0). |
CHARGE_AUDIT_PENDING | PENDING | No actionable decision yet. Do not apply changes — see CHARGE_AUDIT_PENDING. |
All four use entity_type: charge_audit_item, and entity_id is the id of the audited item.
CHARGE_AUDIT_* events are emitted only when the orizon.rga.classification.enabled feature flag is true. It defaults to false. With the flag off, the RGA is still received and persisted — items get audit_classification = NULL — and zero CHARGE_AUDIT_* events are produced.
This is the number one reason integrators report "the events never arrive". Confirm the flag is enabled for your environment with the Integrations team before debugging your consumer.
Where the data comes from
A single RGA produces one ORIZON_RGA_RECEIVED event (the raw parsed report, entity_type: orizon_audit_report) plus N CHARGE_AUDIT_* events — one per executed item. All of them share the same correlation_id.
ORIZON_RGA_RECEIVED carries the report as received, with no classification: its items[] deliberately omit audit_classification, so a consumer that prefers to apply its own interpretation can work from the raw data. The CHARGE_AUDIT_* events are the pre-interpreted view of the same items.
Consume one or the other for a given item — consuming both means processing the same audit decision twice.
Classification
item_status and audit_classification are two different things, and confusing them is the most common integration bug:
item_statusis the auditor's raw decision, mapped from<rga:statusItem>:QUESTIONED(2),JUSTIFIED(3),APPROVED(6).audit_classificationis the business action RCM derives by combiningitem_statuswith the submitted vs. agreed values and quantities. This is what the event type reflects.
An item_status of APPROVED does not mean "accept as submitted" — an approved item whose agreed value is zero was deleted, and one whose agreed value differs was adjusted.
Mapping table
item_status | Condition (value and quantity) | audit_classification | Event |
|---|---|---|---|
APPROVED | agreed_value = 0 AND agreed_quantity = 0 (or absent) | DELETED | CHARGE_AUDIT_DELETED |
APPROVED | agreed_value ≠ submitted_value OR agreed_quantity ≠ submitted_quantity | UPDATED | CHARGE_AUDIT_UPDATED |
APPROVED | agreed_value = submitted_value AND agreed_quantity = submitted_quantity | ACCEPTED | CHARGE_AUDIT_ACCEPTED |
APPROVED | agreed_value or submitted_value is null | PENDING | CHARGE_AUDIT_PENDING |
QUESTIONED / JUSTIFIED | any values | PENDING | CHARGE_AUDIT_PENDING |
(statusItem absent) | any values | ACCEPTED | CHARGE_AUDIT_ACCEPTED |
Rows are evaluated top to bottom — the first match wins.
Three details worth internalizing:
- Quantities are optional in the RGA. When a quantity is not reported (
null) it is not used as a criterion.DELETEDtolerates an absent quantity —agreed_value = 0with no quantity reported is an effective removal.UPDATEDonly asserts a quantity change when both quantities are reported and differ. - Upward adjustments also classify as
UPDATED. The condition is a literal inequality, soagreed_value > submitted_valuelands inUPDATEDjust like a reduction does. Don't assume an adjustment is always downward. - Quantity-only adjustments are
UPDATED, notACCEPTED. Ifagreed_value = submitted_valuebut the quantities differ, the item was adjusted.
Unmapped providers
If the RGA arrives for a provider RCM cannot resolve to a known slug, its items are persisted with audit_classification = PENDING but no event is emitted at all — neither ORIZON_RGA_RECEIVED nor CHARGE_AUDIT_*, because there is no owner to deliver them to. Silence on a guide you know Orizon audited is a signal to check the provider mapping.
CHARGE_AUDIT_UPDATED
The item was accepted with an adjustment. Compare agreed_value / agreed_quantity against submitted_value / submitted_quantity to know what changed; denial_number carries the glosa id when the payer issued one.
Header
| Header | Value |
|---|---|
X-RCM-Event-Type | CHARGE_AUDIT_UPDATED |
Payload
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"event_type": "CHARGE_AUDIT_UPDATED",
"entity_type": "charge_audit_item",
"entity_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"payload": {
"correlation_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"sequence": 2,
"provider_guide_number": "9001",
"procedure_code": "1000000002",
"procedure_description": "HONORARIO MEDICO",
"execution_date": "2026-04-22",
"item_status": "APPROVED",
"notes": "AJUSTE DE VALOR CONFORME CONTRATO",
"denial_number": "GL-1234",
"submitted_quantity": 5,
"submitted_value": 200.0,
"adjusted_quantity": 0,
"adjusted_value": 50.0,
"agreed_quantity": 5,
"agreed_value": 150.0,
"ans_registry": "005811",
"audit_classification": "UPDATED",
"cbos_description": "MEDICO"
},
"metadata": {
"source": "orizon-rga",
"rga_report_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"s3_url": "s3://osigu-rcm-orizon/rga/2026/05/10/f47ac10b.xml"
},
"created_at": "2026-05-10T14:23:01.123-03:00"
}
Here the payer agreed to 150.00 of the 200.00 submitted, keeping the quantity at 5 — a value-only reduction of 50.00, which is what adjusted_value reports.
CHARGE_AUDIT_ACCEPTED
The item was accepted exactly as submitted: agreed_value = submitted_value and agreed_quantity = submitted_quantity. Nothing to reconcile — record the audit outcome and move on.
Header
| Header | Value |
|---|---|
X-RCM-Event-Type | CHARGE_AUDIT_ACCEPTED |
Payload
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"event_type": "CHARGE_AUDIT_ACCEPTED",
"entity_type": "charge_audit_item",
"entity_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"payload": {
"correlation_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"sequence": 1,
"provider_guide_number": "9001",
"procedure_code": "1000000001",
"procedure_description": "DIARIA HOSPITALAR ACEITA INTEGRAL",
"execution_date": "2026-04-22",
"item_status": "APPROVED",
"notes": "ITEM ACEITO SEM GLOSA",
"submitted_quantity": 1,
"submitted_value": 500.0,
"adjusted_quantity": 0,
"adjusted_value": 500.0,
"agreed_quantity": 1,
"agreed_value": 500.0,
"ans_registry": "005811",
"audit_classification": "ACCEPTED",
"cbos_description": "MEDICO"
},
"metadata": {
"source": "orizon-rga",
"rga_report_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"s3_url": "s3://osigu-rcm-orizon/rga/2026/05/10/f47ac10b.xml"
},
"created_at": "2026-05-10T14:23:01.089-03:00"
}
denial_number is absent because no glosa was issued — like every field, it is omitted when null.
CHARGE_AUDIT_DELETED
The item was removed from the guide: agreed_value = 0, with agreed_quantity either 0 or not reported. The provider will not be paid for this line.
Header
| Header | Value |
|---|---|
X-RCM-Event-Type | CHARGE_AUDIT_DELETED |
Payload
{
"id": "d4e5f6a7-b8c9-0123-def1-234567890123",
"event_type": "CHARGE_AUDIT_DELETED",
"entity_type": "charge_audit_item",
"entity_id": "e5f6a7b8-c901-2345-ef12-345678901234",
"payload": {
"correlation_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"sequence": 3,
"provider_guide_number": "9001",
"procedure_code": "1000000003",
"procedure_description": "MATERIAL DESCARTAVEL",
"execution_date": "2026-04-23",
"item_status": "APPROVED",
"notes": "ITEM GLOSADO INTEGRALMENTE",
"denial_number": "GL-1235",
"submitted_quantity": 2,
"submitted_value": 80.0,
"adjusted_quantity": 2,
"adjusted_value": 80.0,
"agreed_quantity": 0,
"agreed_value": 0.0,
"ans_registry": "005811",
"audit_classification": "DELETED",
"cbos_description": "MEDICO"
},
"metadata": {
"source": "orizon-rga",
"rga_report_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"s3_url": "s3://osigu-rcm-orizon/rga/2026/05/10/f47ac10b.xml"
},
"created_at": "2026-05-10T14:23:01.201-03:00"
}
CHARGE_AUDIT_PENDING
The auditor has not reached an actionable decision for this item — either the raw status is QUESTIONED/JUSTIFIED, or the values needed to classify it came back null.
PENDING is not a decision. Your ERP must not adjust or remove the charge on this event. Record it as awaiting resolution and wait for a later RGA that carries a terminal classification for the same (correlation_id, sequence).
Header
| Header | Value |
|---|---|
X-RCM-Event-Type | CHARGE_AUDIT_PENDING |
Payload
{
"id": "f6a7b8c9-0123-4567-f123-456789012345",
"event_type": "CHARGE_AUDIT_PENDING",
"entity_type": "charge_audit_item",
"entity_id": "a7b8c901-2345-6789-1234-567890123456",
"payload": {
"correlation_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"sequence": 4,
"provider_guide_number": "9001",
"procedure_code": "1000000004",
"procedure_description": "EXAME LABORATORIAL",
"execution_date": "2026-04-23",
"item_status": "QUESTIONED",
"notes": "AGUARDANDO JUSTIFICATIVA DO PRESTADOR",
"denial_number": "GL-1236",
"submitted_quantity": 1,
"submitted_value": 120.0,
"ans_registry": "005811",
"audit_classification": "PENDING",
"cbos_description": "MEDICO"
},
"metadata": {
"source": "orizon-rga",
"rga_report_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"s3_url": "s3://osigu-rcm-orizon/rga/2026/05/10/f47ac10b.xml"
},
"created_at": "2026-05-10T14:23:01.264-03:00"
}
The agreed and adjusted fields are absent — the auditor has not settled them yet.
Field reference
All four events share the same flat payload of 18 fields. Only audit_classification (and, indirectly, which fields are populated) varies.
| Path | Type | Optional | Description |
|---|---|---|---|
payload.correlation_id | string (UUID) | No | Groups every event produced from the same RGA. Together with sequence, it is your dedupe key. |
payload.sequence | integer | No | 1-based position of the item within the guide. |
payload.provider_guide_number | string | No | Provider's guide number (<rga:numeroGuiaPrestador>). |
payload.procedure_code | string | No | Medical procedure code. |
payload.procedure_description | string | No | Procedure description as reported by the payer. |
payload.execution_date | string (date) | No | When the procedure was performed (YYYY-MM-DD). |
payload.item_status | string | Yes | Auditor's raw decision: QUESTIONED, JUSTIFIED or APPROVED. Absent when <rga:statusItem> was not reported. Not the business action — see Classification. |
payload.notes | string | Yes | Free-text note from the auditor (<rga:apontamento>). |
payload.denial_number | string | Yes | Glosa id (<rga:numeroGlosa>). Present when the payer issued a denial. |
payload.submitted_quantity | integer | Yes | Quantity presented by the provider. Quantities are optional in the RGA. |
payload.submitted_value | number | Yes | Value presented by the provider. |
payload.adjusted_quantity | integer | Yes | Pre-agreement adjusted quantity. |
payload.adjusted_value | number | Yes | Pre-agreement adjusted value. |
payload.agreed_quantity | integer | Yes | Final agreed quantity, post-audit. |
payload.agreed_value | number | Yes | Final agreed value, post-audit. This is what the provider gets paid. |
payload.ans_registry | string | No | ANS registry of the payer (Brazilian regulator id). Denormalized from the report header. |
payload.audit_classification | string | No | Derived business action: ACCEPTED, UPDATED, DELETED or PENDING. Mirrors the event type. |
payload.cbos_description | string | Yes | CBOS — the physician's specialty (<rga:CBOS>). |
Fields with a null value are omitted from the JSON. In particular, an item still under audit typically arrives without its agreed/adjusted fields.
metadata carries the report's provenance:
| Path | Type | Description |
|---|---|---|
metadata.source | string | Always orizon-rga. |
metadata.rga_report_id | string (UUID) | Internal id of the audit report the item belongs to. |
metadata.s3_url | string | Location of the original encrypted XML. |
Idempotency and correlation
Delivery is at-least-once — the same event can arrive more than once, and a duplicate correlation_id (from an Orizon retry of the same RGA) is accepted by design. Dedupe on:
id— the envelope's event id, for exact redeliveries of the same event.(correlation_id, sequence)— identifies one item within one guide, and survives a full re-send of the RGA.
There is no ordering guarantee across events, so do not assume sequence 1 arrives before sequence 2.
Consumption model
RGA audit events are produced into RCM's integration outbox. The intended way to consume them is the pull API, where your ERP polls RCM instead of RCM pushing to you:
| Endpoint | Purpose |
|---|---|
POST /rcm/v1/integration/events/pull | Claims up to max_batch_size pending events (default 10, capped server-side at 50). A JSON body is required — send {} to accept the defaults. Claimed events are invisible to further pulls for 300 seconds. |
POST /rcm/v1/integration/events/ack | Confirms processed events: event_ids (1–100), plus success and optional error_message. Returns 204 No Content. |
GET /rcm/v1/integration/events/stats | Pending count, age of the oldest event, and a recommended poll interval. Use it to monitor lag. |
Authentication is OAuth2 client credentials, using the same read permission as the account endpoints. Tenant isolation is derived from the token — you only ever receive your own provider's events, and you never send provider_slug in the request.
Every request field on these endpoints is snake_case: max_batch_size, event_ids, error_message. A camelCase field name is silently ignored, not rejected — so {"maxBatchSize": 25} is accepted and quietly falls back to the default of 10, and an ack sent as {"eventIds": [...]} fails validation with 400 because event_ids arrives empty. If your acknowledgements are returning 400 while your pulls appear to work, this is why.
Acknowledge before the visibility window closes. A positive acknowledgement (success: true) is idempotent — acknowledging the same event twice is safe. A negative acknowledgement (success: false) is not: each one consumes a retry attempt. An event that is never acknowledged becomes visible again after 300 seconds and is redelivered; once it exhausts its retry attempts it moves to ERROR, and there is no endpoint to request redelivery — recovering it requires OSIGU support.
Note when reading stats and pull: pending_count, total_pending and has_more count events in PENDING and IN_PROGRESS. Immediately after a pull they still include the batch you just claimed, so they overstate what is actually waiting.
In this model the envelope's event id field is id (not event_id), and the X-RCM-* headers described in Webhook events → Common headers do not apply — those are a property of push delivery.
subscribed_event_types is an open list — RCM matches the configured strings against the event type without a closed catalog, so adding CHARGE_AUDIT_ACCEPTED, CHARGE_AUDIT_UPDATED, CHARGE_AUDIT_DELETED or CHARGE_AUDIT_PENDING to a webhook subscription is technically accepted.
That said, RGA-by-webhook is not a validated end-to-end path today: these events were designed for, and are exercised in production through, the pull API. If you need push delivery for audit events, coordinate with the Integrations team before building against it.
Next steps
- Payload reference — envelope and all payload fields in one place.
- Webhook events — delivery model for the document events.
- Charges — the billable lines an audit decision applies to.