Done-for-you AI lead automation, from first click to booked client. Book a discovery call
Voice Agent Engineering

A Supabase Leads Table That Avoids Duplicate Records

Watch LF32 on YouTube ↗ Browse the Backend & Infrastructure playlist ↗

A lead may arrive through a form, a missed call and a follow-up call. If each event creates a new row, your team sees several records for one person and loses the conversation history. Prevent duplicates at the database layer, where simultaneous requests cannot race past a UI check.

Choose a key that represents identity

Decide what makes two records the same lead in your business. A normalized phone number may work for a simple inbound workflow, while an external CRM ID or a combination of tenant and contact ID may be safer. Avoid treating a name as a unique key. Two people can share a name, and one person may use different numbers.

Enforce the rule in Postgres

Create a unique constraint on the chosen key, with any tenant scope included if the same contact can exist for different businesses. PostgreSQL’s constraint documentation explains how unique and foreign-key constraints enforce rules when rows are written. Then use an upsert so a repeat event updates the existing lead or returns its ID rather than creating a second record.

Keep events separate from the lead

Store each call, form submission or message as its own event linked to the lead. That preserves history without copying the contact into a fresh row each time. Include a provider event ID and a unique constraint for event processing, so webhook retries do not add the same call twice.

Secure the Data API

If a browser accesses a Supabase table, review grants and Row Level Security together. Supabase is making explicit grants mandatory for new tables in the public schema, with the change applying to existing projects on October 30, 2026. Without the required grant, the Data API cannot reach a table; RLS then limits which rows an allowed role can access. See the Supabase rollout notice for details. Supabase’s data security guide says to keep secret and service-role keys server-side because they bypass RLS. Add tests for permitted and denied reads and writes before exposing the table.

The data model should reflect how your team identifies a lead, not a guess copied from an example. Test concurrent submissions, changed phone numbers and two tenants with the same contact before you rely on deduplication.

Continue with the LeadOro AI Phone Agent Stack series for the related walkthrough.

Don't Want to Build This Yourself?

This series shows you exactly how the AI phone and messaging stack goes together, piece by piece. If you'd rather have it built, tuned, and maintained for you, that's what LeadOro does.

TK
Taiye Kotiku

Founder of LeadOro. Builds and narrates the AI Phone Agent Stack series on the channel, documenting the real integration work most demos skip.