Skip to main content

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.

Consumption model

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:

Eventaudit_classificationWhat the payer decided
CHARGE_AUDIT_ACCEPTEDACCEPTEDThe item was accepted as submitted. Value and quantity are unchanged.
CHARGE_AUDIT_UPDATEDUPDATEDThe item was accepted with an adjustment — value and/or quantity differ from what was submitted.
CHARGE_AUDIT_DELETEDDELETEDThe item was removed entirely (agreed_value = 0).
CHARGE_AUDIT_PENDINGPENDINGNo 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.

Nothing arrives unless the classification flag is on

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_status is the auditor's raw decision, mapped from <rga:statusItem>: QUESTIONED (2), JUSTIFIED (3), APPROVED (6).
  • audit_classification is the business action RCM derives by combining item_status with 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_statusCondition (value and quantity)audit_classificationEvent
APPROVEDagreed_value = 0 AND agreed_quantity = 0 (or absent)DELETEDCHARGE_AUDIT_DELETED
APPROVEDagreed_value ≠ submitted_value OR agreed_quantity ≠ submitted_quantityUPDATEDCHARGE_AUDIT_UPDATED
APPROVEDagreed_value = submitted_value AND agreed_quantity = submitted_quantityACCEPTEDCHARGE_AUDIT_ACCEPTED
APPROVEDagreed_value or submitted_value is nullPENDINGCHARGE_AUDIT_PENDING
QUESTIONED / JUSTIFIEDany valuesPENDINGCHARGE_AUDIT_PENDING
(statusItem absent)any valuesACCEPTEDCHARGE_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. DELETED tolerates an absent quantity — agreed_value = 0 with no quantity reported is an effective removal. UPDATED only asserts a quantity change when both quantities are reported and differ.
  • Upward adjustments also classify as UPDATED. The condition is a literal inequality, so agreed_value > submitted_value lands in UPDATED just like a reduction does. Don't assume an adjustment is always downward.
  • Quantity-only adjustments are UPDATED, not ACCEPTED. If agreed_value = submitted_value but 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.

HeaderValue
X-RCM-Event-TypeCHARGE_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

HeaderValue
X-RCM-Event-TypeCHARGE_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

HeaderValue
X-RCM-Event-TypeCHARGE_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.

Do not apply changes on PENDING

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

HeaderValue
X-RCM-Event-TypeCHARGE_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.

PathTypeOptionalDescription
payload.correlation_idstring (UUID)NoGroups every event produced from the same RGA. Together with sequence, it is your dedupe key.
payload.sequenceintegerNo1-based position of the item within the guide.
payload.provider_guide_numberstringNoProvider's guide number (<rga:numeroGuiaPrestador>).
payload.procedure_codestringNoMedical procedure code.
payload.procedure_descriptionstringNoProcedure description as reported by the payer.
payload.execution_datestring (date)NoWhen the procedure was performed (YYYY-MM-DD).
payload.item_statusstringYesAuditor's raw decision: QUESTIONED, JUSTIFIED or APPROVED. Absent when <rga:statusItem> was not reported. Not the business action — see Classification.
payload.notesstringYesFree-text note from the auditor (<rga:apontamento>).
payload.denial_numberstringYesGlosa id (<rga:numeroGlosa>). Present when the payer issued a denial.
payload.submitted_quantityintegerYesQuantity presented by the provider. Quantities are optional in the RGA.
payload.submitted_valuenumberYesValue presented by the provider.
payload.adjusted_quantityintegerYesPre-agreement adjusted quantity.
payload.adjusted_valuenumberYesPre-agreement adjusted value.
payload.agreed_quantityintegerYesFinal agreed quantity, post-audit.
payload.agreed_valuenumberYesFinal agreed value, post-audit. This is what the provider gets paid.
payload.ans_registrystringNoANS registry of the payer (Brazilian regulator id). Denormalized from the report header.
payload.audit_classificationstringNoDerived business action: ACCEPTED, UPDATED, DELETED or PENDING. Mirrors the event type.
payload.cbos_descriptionstringYesCBOS — 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:

PathTypeDescription
metadata.sourcestringAlways orizon-rga.
metadata.rga_report_idstring (UUID)Internal id of the audit report the item belongs to.
metadata.s3_urlstringLocation 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:

EndpointPurpose
POST /rcm/v1/integration/events/pullClaims 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/ackConfirms processed events: event_ids (1–100), plus success and optional error_message. Returns 204 No Content.
GET /rcm/v1/integration/events/statsPending 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.

Request field names are snake_case

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.

About receiving these over webhooks

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