A robust Node.js + Express API for contact identification and linking, built for the Bitespeed engineering challenge.
This backend service processes requests to identify, merge, and link user contacts by email and phone number, with all data managed in a Supabase PostgreSQL database and deployed on Render.
- Project Overview
- Features
- Tech Stack
- Getting Started
- Environment Variables
- Database Schema
- API Documentation
- Using the API with Postman
- Data Storage in Supabase
- Deployment
- Submission Details
- Notes
This backend exposes a REST API endpoint to:
- Identify users by email and/or phone number
- Link contacts as primary or secondary according to business logic
- Return all linked emails and phone numbers for a user
No frontend is included; this is a pure backend API intended for use with tools like Postman, curl, or integration into other services.
- POST
/identify: Main endpoint for contact identification and linking - Express.js: Minimal, fast Node.js backend
- Supabase PostgreSQL: Managed, scalable relational database
- Environment-based configuration: Secure, flexible deployment
- Production deployment: Hosted on Render for public access
- Node.js (v18+)
- Express.js
- pg (PostgreSQL client)
- dotenv (environment management)
- Supabase (PostgreSQL database as a service)
- Render (cloud deployment)
- Postman (for API testing and demonstration)
git clone https://github.com/SekharSunkara6/Bitespeed-Backend-Task.git
cd Bitespeed-Backend-Tasknpm installCreate a .env file in the project root:
PGUSER=your_supabase_pguser
PGPASSWORD=your_supabase_password
PGHOST=your_supabase_pooler_host
PGDATABASE=postgres
PGPORT=5432See Environment Variables for details.
npm run devServer will run at http://localhost:3000.
The app uses the following environment variables (required for both local and production):
| Key | Example Value | Description |
|---|---|---|
| PGUSER | your_supabase_pguser | Supabase pooler username |
| PGPASSWORD | your-supabase-password | Supabase database password |
| PGHOST | your_supabase_pooler_host | Supabase session pooler host |
| PGDATABASE | postgres | Database name (default: postgres) |
| PGPORT | 5432 | Database port (default: 5432) |
Note:
- Use the session pooler connection details from your Supabase dashboard for Render/cloud deployments.
- Never commit your real
.envfile to version control.
All contact data is stored in the contact table in Supabase.
| Column | Type | Description |
|---|---|---|
| id | integer | Primary key for each contact |
| phoneNumber | text | User’s phone number |
| text | User’s email address | |
| linkedId | integer | Points to primary contact (if this is secondary) |
| linkPrecedence | text | 'primary' or 'secondary' |
| createdAt | timestamp | Row creation time |
| updatedAt | timestamp | Last update time |
| deletedAt | timestamp | Deletion time (null if not deleted) |
- Primary contacts:
linkPrecedence = 'primary',linkedId = NULL - Secondary contacts:
linkPrecedence = 'secondary',linkedIdpoints to primary contact’sid
Below is a sample view of the contact table in Supabase:

Description:
Identify and link contacts by email and/or phone number.
Request Body:
{
"email": "mcfly@hillvalley.edu",
"phoneNumber": "123456"
}- At least one of
emailorphoneNumberis required.
Response:
{
"contact": {
"primaryContatctId": 1,
"emails": ["mcfly@hillvalley.edu"],
"phoneNumbers": ["123456"],
"secondaryContactIds": []
}
}Error Responses:
400 Bad Requestif both email and phone number are missing.500 Internal Server Errorfor unexpected issues.
You can test and interact with the API using Postman:
- Open Postman and create a new request.
- Set the request type to
POST. - Enter the request URL:
https://bitespeed-backend-task-mnst.onrender.com/identify - Go to the "Body" tab and select
rawandJSONas the format. - Paste your JSON payload, for example:
{ "email": "mcfly@hillvalley.edu", "phoneNumber": "123456" } - Click "Send".
- View the response in the lower section. You should see a JSON object with contact details.
Below is an example of a POST request to /identify in Postman:

You can also use the API with curl or any HTTP client.
- All contact data is securely stored in your Supabase PostgreSQL database, specifically in the
contacttable. Whenever a request is made to the/identifyendpoint, your backend reads from and writes to this table in Supabase. - You can view, query, and manage the data in the
contacttable directly from your Supabase dashboard. All new contacts, updates, and links created by your API logic are reflected in this table, ensuring your data is always up to date and accessible for future API calls.
The backend is deployed on Render for public access.
- Production URL:
https://bitespeed-backend-task-mnst.onrender.com/ - Health Check:
Visiting the root URL (/) returns:
Bitespeed Backend is running! - API Endpoint:
/identify(POST)
- Github Repository:
https://github.com/SekharSunkara6/Bitespeed-Backend-Task.git - Hosted Endpoint:
https://bitespeed-backend-task-mnst.onrender.com/
- This is a backend API only; no frontend is included.
- Use Postman, curl, or similar tools to interact with the API.
- All contact data is securely stored in Supabase and managed via the backend.
- For questions or issues, contact [sekharsunkara2002@gmail.com].
Replace the image URLs with your actual screenshot paths in the assets folder.
You’re all set for a clean, professional, and reviewer-friendly submission!