Privacy by design
How the customer's number stays locked down
On PrivHive, the contact's realPhoneNumber lives in a column the API never returns without an explicit ACL check. The default response for an agent is just the last four digits. Nothing leaks through the client — the masking happens server-side, before the JSON ever leaves the backend.
Server-side first
Every visibility check runs in PrivHive's backend before the response. Even if the frontend asks for the field, it returns empty or masked.
Multi-tenant isolation
Every query is automatically filtered by tenantId via Prisma middleware. Cross-tenant access is impossible from the API.
What goes into an ACL
- Specific user IDs (e.g. the account manager Maria)
- Whole roles (e.g. 'AGENT' grants visibility to every agent)
- Empty/null = only OWNER and ADMIN see the full number
- ACL changes are auditable and reversible
Bridged calls
- The agent clicks "call" — they never type a number.
- Twilio dials the agent's phone first (stored in a restricted column, never exposed cross-tenant).
- When the agent answers, Twilio dials the contact using the tenant's number as caller ID.
- The customer sees the company's number, not the agent's. Both legs are bridged with answerOnBridge.