Skip to main content

ACORD XML Protocol

All Safeco Auto communication uses ACORD XML transmitted over HTTPS. Internally, the XML is represented as JSON (converted by SafecoV3XmlConverterService) so all mapping and manipulation happens in JS objects.

Transaction Types

TransactionType ValueSub-TransactionPurpose
RC1RateCall1Plain rate call (establish quote, get UUIDs)
RC1 + CCRateCall1com.safeco_ReconcileCCPrior insurance verification (CLUE)
RC1 + ADDRateCall1com.safeco_ReconcileADDAdditional driver discovery
RC2RateCall2com.safeco_ReconcileADDFinal rating with MVR/CLUE ordering and driver reconciliation
RC3RateCall3com.safeco_BindBind policy with payment

ACORD Envelope Structure

ACORD
├── SignonRq
│ ├── SignonPswd → CustId → CustLoginId (agent login)
│ └── ClientApp → Org, Name, Version
└── InsuranceSvcRq
├── RqUID (unique request ID)
└── PersAutoPolicyQuoteInqRq
├── com__safeco_TransactionType
├── com__safeco_SubTransactionType (optional)
├── TransactionRequestDt
├── InsuredOrPrincipal (named insured)
├── PersPolicy
│ ├── ContractTerm (EffectiveDt, ExpirationDt, DurationPeriod)
│ ├── QuoteInfo (CompanysQuoteNumber, com.safeco_CompanyURL)
│ └── PaymentOption (for RC3 bind)
├── PersAutoLineBusiness
│ ├── LOBCd: "AUTOP"
│ ├── PersDriver[] (drivers with IDs, DOB, license, relation)
│ ├── PersVeh[] (vehicles with VIN, year, make, model, garaging)
│ ├── Coverage[] (coverages with codes and limits)
│ └── Discount[] (discount codes and amounts)
├── Location[] (garaging addresses)
└── CreditScoreInfo (IBS consent)

Entity References

Safeco assigns internal IDs to drivers, vehicles, and locations on the first RC1 call. These IDs must be preserved across all subsequent calls.

carrier_quote_sessions.metadata.entityRefs = {
drivers: { driver_1: "safeco-id-abc", driver_2: "safeco-id-def" },
vehicles: { vehicle_1: "safeco-id-123", vehicle_2: "safeco-id-456" },
locations: { location_1: "safeco-id-loc1" }
}

Entity refs are extracted after each RC1 call via extractQuoteSessionFromResponse() and merged with existing refs. New refs overwrite by key; existing refs are preserved.

Source: libs/apis/carriers/safeco/src/v3/application/utils/safeco-session.extractor.ts

Full Rate Flow (4 Steps)

RC1 + CC (Prior Insurance Verification)

Runs a CLUE report to verify prior insurance history. The sub-transaction com.safeco_ReconcileCC triggers Safeco to order a Comprehensive Claims (CC) report.

Response codes (com__safeco_CLUEOrderResult):

CodeMeaning
CClean — no prior claims
HHits — prior claims found
NNo hit — no record found
EError ordering report
999System error

RC1 + ADD (Additional Driver Discovery)

Discovers undisclosed household drivers. Safeco returns DriverCandidate entries that must be reconciled in RC2.

For RC2, discovered drivers are injected with:

  • com__safeco_DriverCandidateType: 'N' (not adding)
  • com__safeco_AddAction: 'N' (decline to add)

RC2 (Final Rating)

Before sending RC2, the service validates ~14 required fields:

FieldValidation
TransactionTypeMust be RateCall2
EsignYNMust be present
PaperlessBillingYNMust be present
AgentEmailAddressMust be present
NIPRIdMust be present
ContractNumber / RqUIDMust be present
Insured name + DOBMust be present
AddressMust be present
CreditScoreInfo (IBS)Must be present
LOBCdMust be AUTOP
EffectiveDtMust be present
DriversCount > 0
VehiclesCount > 0

MVR response codes (com__safeco_MVROrderResult):

CodeMeaning
CClean record
HHits — violations found
NNo record found
EError ordering report
999System error

RC3 (Bind)

RC3 preparation:

  1. Clone RC2 quote data
  2. Set TransactionType = 'RateCall3', SubTransactionType = 'com.safeco_Bind'
  3. Remove MsgStatus (response-only field)
  4. Add PaymentOption to PersPolicy with Hydra instrument and plan details

Response Parsing

All rate responses are parsed through parseRateResponse():

Extracted DataACORD Path
StatusACORD.Status.StatusCd (0 = success)
Message statusPersAutoPolicyQuoteInqRs.MsgStatus.MsgStatusCd
Extended errorsMsgStatus.ExtendedStatus[].ExtendedStatusDesc
Quote numberPersAutoPolicyQuoteInqRs.RqUID
Policy numberPersAutoPolicyQuoteInqRs.PolicyNumber
FullTermAmtSum of PersVeh[].FullTermAmt.Amt
Policy termPersPolicy.ContractTerm.DurationPeriod.NumUnits
CoveragesPersAutoLineBusiness.Coverage[]
DiscountsPersAutoLineBusiness.Discount[]
Payment plansPersPolicy.PaymentOption[]
Safeco URLcom.safeco_CompanyURL

API Client

Implementation: libs/apis/carriers/safeco/src/v3/infrastructure/api/safeco-v3-api.client.ts

ConfigEnv Variable
RC1/RC2 endpointSAFECO_RC1_RC2_URL
RC3 (bind) endpointSAFECO_RC3_URL
Attribution IDSAFECO_RC1_RC2_ATTRIBUTION_ID
TimeoutSAFECO_API_TIMEOUT (default 30s)

Auth: Bearer token from SafecoV3AuthService → Switchboard OAuth (SwitchboardTokenManagerService).

Headers: Authorization, Content-Type: application/xml, Accept: application/xml, x-partner-attribution-id.

Retry: On 401, clears cached token and retries once.

Logging: Request/response XML and JSON logged to logs/api/ with timestamps.

Field Mapper

SafecoV3FieldMapperService converts GHCMS session data into the ACORD XML structure:

Session DataACORD Target
Applicant name, DOB, SSNInsuredOrPrincipal
Drivers (license, relation)PersDriver[]
Vehicles (VIN, year, make, model)PersVeh[]
Garaging addressesLocation[]
Prior policy infoPriorPolicy on PersAutoLineBusiness
Coverages (BI, PD, UM, PIP)Coverage[]
Policy info (effective date, term)PersPolicy.ContractTerm
Agent NPNNIPRId
E-sign acceptancecom__safeco_EsignYN
Excluded driverscom__safeco_ExcludedDriverInputs

Source: libs/apis/carriers/safeco/src/v3/infrastructure/mapping/safeco-v3-field-mapper.service.ts