ACP Specification v1.0.0

Automotive Commerce Protocol — Normative specification defining the JSON envelope format for AI-generated automotive commerce data. This document describes the structure, constraints, and semantics of ACP envelopes. It does not describe the internal methods by which producers generate envelope contents.

Scope Boundary: This specification defines the data format — the shape of the envelope, field types, required vs optional semantics, and interchange rules. It intentionally does not define how AI agents detect intents, calculate scores, determine handoff triggers, or construct envelopes progressively. Those are implementation-specific concerns left to individual producers.

Out of Scope

The following topics are explicitly outside the scope of this specification and must not be inferred from the data format definitions herein:

  1. AI model training methodology — How producers train, fine-tune, or select models for conversation handling.
  2. Lead scoring algorithms — How lead.score and score_factors are calculated. The specification defines the output format only.
  3. Intent detection methods — How lead.intents[] are identified and confidence values are derived.
  4. Handoff trigger logic — What conditions cause a conversation.handoff to be initiated.
  5. CRM internal mapping logic — How receivers map ACP fields to their internal data structures.
  6. Dealer workflow design — How dealerships route, assign, or act on received envelopes.
  7. Conversation moderation policy — How producers filter, moderate, or restrict conversation content.
  8. Voice transcription methods — How audio is converted to text for voice agent types.
  9. Envelope construction sequencing — How producers progressively build envelope contents during a conversation.

Normative Language

The key words "must", "must not", "required", "shall", "shall not", "should", "should not", "recommended", "may", and "optional" in this document are to be interpreted as described in RFC 2119.

Keyword Meaning
MUST Absolute requirement. Non-compliance renders the implementation non-conformant.
MUST NOT Absolute prohibition.
SHOULD Recommended. Valid reasons may exist to ignore, but full implications must be understood.
SHOULD NOT Discouraged. Valid reasons may exist to allow, but full implications must be understood.
MAY Truly optional. Implementations may or may not include this behavior.

Content Type

Producers must set the HTTP Content-Type header to application/acp+json when transmitting envelopes. Receivers must accept application/acp+json and should also accept application/json for interoperability.

Number Precision

Monetary fields (vehicle_price, monthly_payment, trade_in_value, down_payment, estimated_value, payoff_amount) should be expressed as decimal values with exactly two fractional digits (e.g., 29995.00, not 29995 or 29995.999).

Percentage fields (apr, purchase_probability, confidence) should be expressed as decimal values with appropriate precision for the domain.

Receivers must not assume floating-point precision beyond standard IEEE-754 double-precision limits. Producers should not emit monetary values with more than two fractional digits.

Envelope Structure

An ACP envelope is a single JSON document with eight top-level objects. Seven are required for snapshot envelopes. Delta envelopes must contain only acp + events.

envelope.jsonJSON
{
  "acp": { },           // Protocol metadata — REQUIRED
  "source": { },        // Origin attribution — REQUIRED
  "dealership": { },    // Receiving dealer — REQUIRED
  "lead": { },          // Customer intelligence — REQUIRED
  "transaction": { },   // Deal state — REQUIRED
  "conversation": { },  // Transcript — REQUIRED
  "events": [ ],        // Behavioral stream — REQUIRED
  "ai_analysis": { }    // AI insights — OPTIONAL
}

Producers must not include additional top-level keys beyond these eight. Receivers must ignore unknown top-level keys without error.

Envelope Size Guidance

Producers should limit snapshot envelopes to 1MB uncompressed. If conversation transcripts exceed this limit, producers should truncate conversation.messages to the most recent messages and include a vendor-namespaced archival reference field (e.g., x_vendor.transcript_archive_url) pointing to the complete transcript.

Receivers must not reject envelopes solely based on size, but may return PAYLOAD_TOO_LARGE (HTTP 413) if the envelope exceeds their ingestion capacity. Receivers should document their maximum accepted payload size.

Delta envelopes are typically much smaller than snapshots — often under 10KB — as they contain only the changed fields and new events.

Field Ordering

JSON object key ordering is not semantically meaningful in ACP. Implementations must not depend on the order of keys within any object. Producers may emit keys in any order. Receivers must process envelopes identically regardless of key ordering. Array ordering is significant: events must be chronologically ordered, and vehicle_interests should be ordered by customer preference (most preferred first).

acp — Protocol Metadata REQUIRED

Identifies protocol version, envelope identity, and generation context. Uses additionalProperties: false — producers must not add vendor fields to this object.

Field Type Req Description
version string MUST Semantic version. Pattern: ^\d+\.\d+\.\d+$. Producers must set to "1.0.0" for this specification.
protocol const "acp" MUST Protocol identifier. Must be "acp".
generated_at string (date-time) MUST ISO 8601 UTC timestamp of envelope generation.
envelope_id string MUST Globally unique idempotency key. Must match pattern ^acp_. Receivers must use this for deduplication. Receivers should retain processed envelope_id values for a minimum of 30 days to ensure reliable deduplication across retries and network failures.
parent_envelope_id string | null MAY For delta envelopes: references the most recent snapshot. When non-null, all other top-level objects must not be present.
acp objectJSON
{
  "acp": {
    "version": "1.0.0",
    "protocol": "acp",
    "generated_at": "2025-02-13T15:30:00Z",
    "envelope_id": "acp_1739456200_x8k2m9",
    "parent_envelope_id": null
  }
}

source — Origin Attribution REQUIRED

Identifies who generated this envelope, from what channel, and how the customer arrived. Extensible — vendors may add custom fields.

Field Type Req Description
provider string MUST Generating platform name.
agent_type string MUST "sales_chat", "sales_voice", "inbound_voice", "service_text", "service_voice"
channel string MUST "web_chat", "phone", "sms", "email", "voice"
session_id string MAY Unique session identifier for cross-channel linking.
device object MAY Device context: type, browser, os, ip.
utm object MAY Marketing attribution: source, medium, campaign, term, content.
page_url string MAY URL where the conversation was initiated.
referrer string MAY HTTP referrer URL.

dealership — Receiving Dealer REQUIRED

Identifies the dealership that should receive this envelope. Receivers must use id for routing.

Field Type Req Description
id string MUST Unique dealership identifier in the producer's system.
name string MUST Dealership display name.
crm_provider string MAY "salesforce", "vinsolutions", "dealersocket"
dms_provider string MAY "cdk", "reynolds", "tekion"
timezone string MAY IANA timezone. e.g. "America/New_York"

lead — Customer Intelligence REQUIRED

The core customer data object. Producers must include id and status. All other fields are optional but recommended for maximum CRM utility.

Field Type Req Description
id string MUST Unique lead identifier.
status string MUST "new", "qualified", "contacted", "converted", "lost"
contact object SHOULD Customer contact data.
vehicle_interests array SHOULD Vehicles discussed. Should be ordered by preference.
budget object MAY Customer budget parameters.
trade_in object MAY Trade-in vehicle details.
intents array SHOULD Detected purchase intents with confidence scores.
score integer (0–100) MAY Lead qualification score. Producer-defined algorithm.
score_factors array MAY Producer-supplied breakdown. See note below.
IP Boundary — score & score_factors: This specification defines the output format of scoring data only. The values in score and score_factors are produced by the generating platform's proprietary algorithms. This specification does not define how scores are calculated, what thresholds trigger status changes, or what weighting models are used. Producers may use any scoring methodology. The format exists so that CRM receivers can display and act on scores regardless of which producer generated them.

lead.contact

Field Type Description
first_name string Customer first name.
last_name string Customer last name.
email string Email address. Producers should validate format.
phone string Phone number. E.164 format recommended.
zip string ZIP or postal code.
address object Full address: street, city, state, zip, country.

lead.vehicle_interests[]

Field Type Description
year integer Model year.
make string Manufacturer.
model string Model name.
trim string Trim level.
condition string "new", "used", "certified"
color string Preferred exterior color.
stock_number string Dealership stock number.
vin string VIN if referencing a specific vehicle.
features array<string> Requested features.

lead.budget

Field Type Description
target_price number Customer's target purchase price.
max_price number Maximum willing to spend.
monthly_payment_target number Desired monthly payment.
down_payment number Down payment available.

lead.trade_in

Field Type Description
year integer Trade-in model year.
make string Manufacturer.
model string Model.
mileage integer Current mileage.
condition string "excellent", "good", "fair", "poor"
estimated_value number Customer's estimated value.
payoff_amount number Remaining loan balance.

lead.intents[]

Each item represents a detected purchase intent. The detection methodology is producer-defined; this specification defines only the output format.

Field Type Req Description
type string (enum) MUST Intent classification. See standard types below.
confidence number (0–1) MUST Detection confidence. Producer-defined scale.
detected_at date-time SHOULD When this intent was first detected.
source_message_id string MAY Message that triggered detection.

Standard Intent Types

VEHICLE_INQUIRY
TEST_DRIVE
PRICING
FINANCING
TRADE_IN
NEGOTIATION
READY_TO_BUY
OBJECTION_PRICE
OBJECTION_TIMING
OBJECTION_VEHICLE
SERVICE_REQUEST
GENERAL_QUESTION

Producers should use standard types where applicable. Vendors may define additional types prefixed with their namespace: "x-vendorname:custom_intent". Receivers must not reject envelopes containing unknown intent types.

lead.score & lead.score_factors[]

Field Type Description
factor string Human-readable factor name. Producer-defined.
points integer Points added (positive) or deducted (negative).
category string "contact", "intent", "engagement", "qualification", "negative"

transaction — Deal State REQUIRED

Models the commerce lifecycle. Producers must include id, stage, and last_updated.

Field Type Req Description
id string MUST Unique transaction identifier.
stage string (enum) MUST Current lifecycle stage.
last_updated date-time MUST When transaction state last changed.
offer_history array MAY Chronological offer revisions.
finance_terms object MAY Financing details.
appointment object MAY Scheduled interaction.
delivery object MAY Delivery confirmation.

Transaction Stages

inquiry
qualified
negotiation
finance
appointment
sold
delivered
closed_lost
Non-linear progression: Receivers must not assume stages follow a linear path. Stages may be skipped (inquiry → sold), reversed (negotiation → qualified), or terminated from any point (→ closed_lost). The closed_lost stage is terminal — producers must create a new transaction if the customer re-engages.

transaction.offer_history[]

Uses additionalProperties: false. Vendors must not add custom fields.

Field Type Req Description
revision integer MUST Revision number (starts at 1).
timestamp date-time MUST When this offer was made.
status string MUST "pending", "accepted", "rejected", "countered", "expired"
vehicle_price number MAY Offered vehicle price.
trade_in_value number MAY Trade-in valuation offered.
monthly_payment number MAY Monthly payment quoted.
notes string MAY Agent notes about this offer.

transaction.finance_terms

Field Type Description
type string "finance", "lease", "cash"
term_months integer Loan or lease term in months.
apr number Annual percentage rate.
down_payment number Down payment amount.
monthly_payment number Calculated monthly payment.
credit_tier string Customer's credit classification.

transaction.appointment

Field Type Description
type string "test_drive", "sales_visit", "delivery", "service"
scheduled_at date-time Appointment date and time.
status string "scheduled", "confirmed", "completed", "cancelled", "no_show"
assigned_to string Assigned sales rep name.

transaction.delivery

Field Type Description
status string "pending", "in_transit", "delivered"
scheduled_at date-time Scheduled delivery date.
delivered_at date-time Actual delivery timestamp.
vin string VIN of the delivered vehicle.

conversation — Transcript REQUIRED

Producers must include id and started_at. Including messages is recommended.

Field Type Req Description
id string MUST Unique conversation identifier.
started_at date-time MUST Conversation start timestamp.
ended_at date-time MAY End timestamp. Null if active.
duration_seconds integer MAY Total conversation duration.
message_count integer SHOULD Total messages exchanged.
messages array SHOULD Full transcript.
handoff object MAY AI-to-human escalation record.
sentiment string MAY "positive", "neutral", "negative", "mixed"
topics array<string> MAY Topics discussed.

conversation.messages[]

Messages must be chronologically ordered. Producers must not alter message content after generation.

Field Type Req Description
id string MUST Unique message identifier.
role string (enum) MUST "user" (customer), "assistant" (AI), "system"
content string MUST Message text content.
timestamp date-time MUST When the message was sent.
metadata object MAY Message-level metadata. Vendor-extensible.

conversation.handoff

Records that a handoff was initiated and why. The decision logic for triggering handoffs is producer-defined; this object captures the outcome only.

Field Type Description
requested boolean Whether a handoff was triggered.
reason string "customer_request", "emotional", "price_authority", "complexity", "complaint", "deal_ready"
priority string "urgent", "high", "normal", "low"
summary string Human-readable summary enabling seamless continuation.
triggered_at date-time When handoff was initiated.

events — Behavioral Stream REQUIRED

Chronological array of typed behavioral events. Producers must preserve chronological order. Receivers must not reorder events.

Field Type Req Description
type string MUST Event classification.
timestamp date-time MUST When the event occurred.
data object MAY Event-specific payload. Schema varies by type.

Standard Event Types (18)

conversation_started
conversation_ended
message_sent
message_received
intent_detected
contact_extracted
vehicle_interest_added
score_updated
stage_changed
offer_made
offer_responded
appointment_scheduled
appointment_confirmed
handoff_triggered
handoff_completed
trade_in_discussed
financing_discussed
objection_detected

Producers should use standard types where applicable. Custom event types must be namespaced: "x-vendorname:event_name". Receivers must not reject envelopes containing unknown event types.

ai_analysis — AI Insights OPTIONAL

Producer-generated analysis. Entirely optional and fully extensible. The contents are producer-defined outputs — this specification defines suggested field names but does not mandate how analysis values are computed.

Field Type Description
purchase_probability number (0–1) Estimated probability of purchase. Producer-defined model.
recommended_actions array<string> Suggested next steps.
objections array<string> Detected objections.
engagement_level string "high", "medium", "low"
summary string Natural language summary for sales teams.

Snapshots & Deltas

ACP envelopes are full state snapshots by default. Receivers must replace stored state entirely — no merge logic is required or expected.

Delta envelopes may be generated to represent partial updates between snapshots. A delta envelope contains only acp + events and references a parent snapshot via parent_envelope_id. When parent_envelope_id is non-null, all other top-level objects must not be present.

This specification does not define when or how frequently producers generate delta envelopes — that is an implementation decision. Producers must send a full snapshot envelope at the conclusion of the interaction, regardless of how many delta envelopes were previously transmitted.

Delta Conflict Resolution

If a delta envelope references a parent_envelope_id that the receiver has not previously ingested, the receiver must reject the envelope with error code UNKNOWN_PARENT_ENVELOPE (HTTP 422). The producer should respond by retransmitting the parent snapshot before retrying the delta.

If deltas arrive out of chronological order (determined by acp.generated_at), receivers should process them in timestamp order. If reordering is not feasible, receivers may reject out-of-order deltas with error code OUT_OF_ORDER_DELTA and request a fresh snapshot.

Producers must not assume delta delivery is guaranteed. The final snapshot at conversation conclusion serves as the authoritative record and must be independently valid without reference to any prior deltas.

Extensibility

ACP uses a two-tier additionalProperties strategy:

Object additionalProperties Rationale
acp false Protocol-controlled. Vendors must not add fields.
source, dealership, lead, transaction, conversation true Vendors may add namespaced fields.
offer_history[], finance_terms, appointment, delivery false Protocol-controlled sub-objects.
ai_analysis true Fully open. Vendors define their own analysis.

When adding custom fields, vendors should prefix with their namespace to avoid collisions: "x-vendorname:field_name". Receivers must ignore unknown fields without error.

Validation

Producers should validate envelopes against the official JSON Schema before transmission. Receivers must validate on receipt and reject non-conformant envelopes with error code INVALID_SCHEMA.

Versioning Policy

ACP follows Semantic Versioning 2.0.0. The version string in acp.version consists of MAJOR.MINOR.PATCH.

Component Change Type Compatibility Example
MAJOR Breaking structural change Not backward compatible. Receivers must not assume interoperability between major versions. 1.0.0 → 2.0.0
MINOR New optional fields or event types Backward compatible. Existing v1.0 receivers must continue to function. 1.0.0 → 1.1.0
PATCH Clarification, typo fix, documentation No schema change. Fully compatible. 1.0.0 → 1.0.1

The v1.0.0 schema is frozen upon publication. New optional fields may be introduced in minor versions. Required fields must not be added in minor versions — only in major versions.

Backward Compatibility

Forward Compatibility (Receiver Side)

Receivers must be forward-compatible within a major version. This means:

  • Receivers must ignore unknown fields without error.
  • Receivers must ignore unknown event types without error.
  • Receivers must ignore unknown intent types without error.
  • Receivers must not reject envelopes containing fields added in a later minor version.

Backward Compatibility (Producer Side)

Producers targeting a specific version must produce envelopes valid against that version's schema. Producers may include fields from a later minor version, but must not depend on receivers understanding them.

Deprecation Policy

  • Fields must not be removed in minor versions. Removal requires a major version increment.
  • Deprecated fields must be documented for at least one full minor version cycle before removal.
  • Migration guides must accompany any major version release.

Version Negotiation

Producers should include the X-ACP-Version HTTP header. Receivers should check acp.version and respond with VERSION_MISMATCH if the major version is unsupported.

Conformance Requirements

A system is ACP-conformant if it meets one or both of the following profiles:

ACP Producer Conformance

A conformant producer must:

  1. Produce envelopes that validate against the official JSON Schema for the declared version.
  2. Include all required fields in snapshot envelopes.
  3. Generate globally unique envelope_id values matching pattern ^acp_.
  4. Preserve chronological order in events arrays.
  5. Send a full snapshot envelope at the conclusion of an interaction if delta envelopes were transmitted.
  6. Set Content-Type: application/acp+json when transmitting envelopes.

ACP Receiver Conformance

A conformant receiver must:

  1. Accept application/acp+json content type.
  2. Validate received envelopes against the JSON Schema.
  3. Deduplicate by envelope_id, returning success (not error) for duplicates.
  4. Distinguish snapshot vs delta envelopes via parent_envelope_id.
  5. Replace stored state on snapshot receipt (not merge).
  6. Ignore unknown fields, event types, and intent types without error.
  7. Respond with standardized error codes (see Error Codes).
Compliance claim: Systems meeting the requirements above may describe themselves as "ACP v1.0 Conformant (Producer)", "ACP v1.0 Conformant (Receiver)", or "ACP v1.0 Conformant (Producer + Receiver)".

Security Considerations

Personally Identifiable Information (PII)

ACP envelopes may contain PII including names, email addresses, phone numbers, physical addresses, and conversation transcripts. Implementations must handle PII in accordance with applicable regulations (CCPA, GDPR, TCPA, state privacy laws). Producers should document what PII categories their envelopes contain.

Encryption in Transit

ACP envelopes must be transmitted over TLS 1.2 or higher. Unencrypted HTTP transmission is a conformance violation. Producers and receivers should enforce HTTPS-only endpoints.

Authentication & Access Control

Receivers must authenticate the source of incoming envelopes. Bearer tokens, mutual TLS, or API key authentication are all acceptable. Receivers should verify that the source.provider value matches the authenticated identity. Unauthorized sources must be rejected with UNAUTHORIZED_SOURCE.

Replay Attack Prevention

The envelope_id field serves as an idempotency key. Receivers must track processed envelope IDs and reject replayed envelopes. Receivers should also validate generated_at timestamps — envelopes more than 24 hours old should be flagged for review. This prevents captured envelopes from being re-submitted by malicious actors.

Envelope Integrity

Producers should include an X-ACP-Signature HTTP header containing an HMAC-SHA256 signature of the envelope body. Receivers should verify this signature when present. A future version of this specification may make envelope signing required.

Data Minimization

Producers should include only data relevant to the receiving dealership's legitimate business purpose. Conversation transcripts should not include system prompts, internal reasoning traces, or model configuration details. Producers must not include data from other customers' conversations in an envelope.

Rate Limiting

Receivers should implement rate limiting to mitigate denial-of-service attacks and resource exhaustion from misconfigured producers. Receivers must respond with RATE_LIMITED (HTTP 429) and include a Retry-After header indicating the number of seconds before the producer may retry.

Producers must respect 429 responses and implement exponential backoff with jitter. A producer that continues to transmit after receiving a 429 response may be permanently blocked by the receiver.

Error Codes

Receivers must use the following standardized error codes in HTTP responses. Error responses must include a JSON body conforming to the canonical error structure:

Error Response FormatREQUIRED
{
  "error": {
    "code": "INVALID_SCHEMA",
    "message": "Envelope does not conform to ACP v1.0.0 schema",
    "details": [
      {
        "field": "lead.score",
        "issue": "Value 150 exceeds maximum of 100"
      }
    ]
  }
}

The error.code field must match one of the codes below. The error.message field should be a human-readable explanation. The error.details array is optional and may contain field-level validation errors or contextual information.

Code HTTP Description
INVALID_SCHEMA 400 Envelope failed JSON Schema validation. Response should include validation error details.
VERSION_MISMATCH 400 The acp.version major version is not supported by this receiver.
DUPLICATE_ENVELOPE 200 This envelope_id has already been processed. Must return 200, not an error status.
ENVELOPE_CONFLICT 409 A delta envelope references a parent_envelope_id that does not exist in the receiver's store.
UNKNOWN_PARENT_ENVELOPE 422 A delta envelope references a parent_envelope_id that the receiver has never ingested. Producer should retransmit the parent snapshot.
OUT_OF_ORDER_DELTA 422 A delta envelope arrived with a generated_at timestamp earlier than the most recent processed delta. Producer should send a fresh snapshot.
PAYLOAD_TOO_LARGE 413 Envelope exceeds the receiver's maximum accepted payload size. Producer should truncate conversation.messages and retry.
UNAUTHORIZED_SOURCE 401 Authentication failed or source.provider does not match authenticated identity.
DEALER_NOT_FOUND 404 The dealership.id does not map to a known dealer in the receiver's system.
RATE_LIMITED 429 Too many envelopes. Producers should implement exponential backoff.
INTERNAL_ERROR 500 Receiver encountered an unexpected error. Producers should retry with backoff.