Replicant California Property Integration
Response To Aman
Suggested reply:
Thanks. We will treat Twilio as a placeholder in the API notes and use our Telnyx voice gateway on the Riff side.
Our review approves the two-endpoint shape for the California property-management line. Riff will call
POST /riff/identifyat call start while the greeting plays, use a 2-second timeout, and continue as an unknown caller if Replicant is unavailable. At the end of intake, Riff will callPOST /riff/maintenance-ticketswith the same stable call id for idempotency and durable retries.We have the HMAC secret installed locally as
Replicant_RIFF_WEBHOOK_SECRET; we will keep it out of git and use it only for signed Replicant requests. The main API clarification we recommend before implementation ispermission_to_enter: a boolean is too lossy forno,conditional, andunknown, so either make it an enum or preserve conditional access inentry_notes. SMS consent design looks correct: Riff should not promise text updates unlesssms_consentis already true or the caller agrees to receive the opt-in text.
Local Configuration
Replicant_RIFF_WEBHOOK_SECRET has been added to the local .env file for the Replicant HMAC signing flow.
Do not commit the value. .env is ignored by git. Production deployment needs the same variable set on whichever node runs the California property flow.
The mixed-case spelling is intentional. Implementation code should read the exact Replicant_RIFF_WEBHOOK_SECRET key.
| Variable | Use |
|---|---|
Replicant_RIFF_WEBHOOK_SECRET | New shared HMAC secret for Replicant identify and maintenance-tickets requests. |
RIFF_DIALED_ROUTING_TABLE_JSON | Live override for mapping the California number to the intended flow. |
RIFF_REPLICANTPM_VOICE_RESULTS_URL | Older post-call Replicant voice-results export. This is not the new two-endpoint ticket API. |
RIFF_REPLICANTPM_TOKEN | Older bearer-style post-call export token. Do not confuse with HMAC signing. |
Recommended Runtime Behavior
At call start:
- Normalize
caller_phoneandcalled_numberto E.164. - Fire
POST /riff/identifywhile the greeting audio plays. - Sign the exact JSON request body with
Replicant_RIFF_WEBHOOK_SECRET. - Budget 2 seconds.
- Store organization, tenant, units, and SMS consent in session slots if matched.
| Identify result | Flow behavior |
|---|---|
| Tenant with one active unit | Confirm the unit briefly, then collect issue details. Do not ask for name, phone, address, or unit from scratch. |
| Tenant with multiple units | Ask which property/unit has the issue, then store the selected unit_id. |
| No match, timeout, 5xx, or 404 | Continue as an unknown caller and collect name, address, unit, and issue details verbally. Alert on 404 because that means the called number is not registered in Replicant. |
At intake completion:
- Build a
maintenance-ticketspayload from slots. - Use a stable carrier-neutral call id for the API field currently named
call_sid. - Submit immediately if possible.
- On timeout or 5xx, persist a durable retry job with the same call id for up to 24 hours.
- On 4xx, do not retry; log and alert because that is a contract or payload bug.
Slot Mapping
| Riff slot/source | Replicant field |
|---|---|
| stable Telnyx/Riff call id | call_sid |
| identify response | organization_id, tenant_user_id, unit_id |
| inbound caller | caller_phone |
| unknown caller fallback | caller_name, stated_address |
| issue summary | title, description |
| issue category | category |
| urgency/severity slots | severity_hint |
| access permission | permission_to_enter, entry_notes |
| post-call artifact | transcript_url when safe to expose |
| SMS consent question | request_sms_optin |
SMS Consent Rule
Replicant owns consent server-side.
If identify returns sms_consent: true, Riff may say the caller will receive text updates.
If sms_consent: false, Riff should ask whether the caller wants a text to opt in. Only set request_sms_optin: true when the caller agrees. Riff should not promise ongoing text updates before the opt-in is completed.
Current Repo Gaps
riff/postcall/replicantpm_adapter.pyis the older post-call export to/api/v1/ai/voice/results/. It does not implement the new HMACidentifyplusmaintenance-ticketscontract.flows/property_trouble_ticket.yamlcurrently performs its own caller verification and collects property/address/unit information. The Replicant version should skip those fields whenidentifyreturns a tenant and unit.flows/_routing.yamlcurrently maps+15102160079toplumbing_intakeas a temporary domain-tree demo. Before a live Replicant test, route the California number to the property/Replicant flow throughRIFF_DIALED_ROUTING_TABLE_JSONor by updating the routing table.- A durable retry queue is required for ticket POST failures. A best-effort post-call hook is not enough.
- The API field name
call_sidis Twilio-shaped. Since Riff uses Telnyx, implementation should treat it as a stable carrier-neutral call id unless Replicant renames it tocall_id.
Implementation Checklist
- Add a Replicant HMAC client with deterministic compact JSON body signing.
- Add tests for signature generation and no secret logging.
- Add a call-start identify hook with a 2-second timeout and fallback behavior.
- Store identify result in session slots for flow branching.
- Add multi-unit selection behavior.
- Map property intake slots to the
maintenance-ticketspayload. - Add durable retry for timeout/5xx responses with the same call id.
- Add 4xx alerting without retry.
- Update California number routing for the live property flow.
- Run simulator/L1 checks for matched tenant, multi-unit tenant, unknown caller, identify timeout, and ticket retry.