Using RushCRM
Getting started
New company? Create an account at https://crm.codenbrand.com/app/register. We review each sign-up and email you when your workspace is switched on, usually within one working day. Until then, logging in shows "waiting for approval".
Log in at https://crm.codenbrand.com/app/login with your email and password (team members get theirs from their admin). If you're the admin setting up a new company, do these three things first:
- Add your team. Settings → Team → Add person. Each salesperson gets their own login.
- Shape your pipeline. Settings → Stages and sources. Rename stages to match how you sell, for example add "Site visit done".
- Bring in leads. Import a spreadsheet (Settings → Import and export), or connect your website forms (see Getting leads in).
After that, the daily routine is simple: open Follow-ups, call the people listed there, and log what happened on each lead.
Who can see what
| Role | Sees | Can |
|---|---|---|
| Sales rep | Only leads assigned to them | Add leads, call, log activity, move stages, set follow-ups |
| Admin | Every lead in their company | Everything a rep can, plus reassign and delete leads, manage the team, stages, sources, imports, API keys and reports |
| Super admin (RushCRM) | Usage numbers for each company: lead and user counts, logins. Never leads, contacts or notes | Approve or decline sign-ups, create and pause companies |
Each company's data is completely separate and private. Nobody in one company can see another company's leads, and the RushCRM team can't open your workspace either.
Adding leads
Go to Leads → Add lead. Fill in whatever you have: a name, a phone number or an email is enough. Your own custom fields appear on the same form. Click More details for company, city, deal value and how interested they are.
- Assign to: choose a person, or "Assign automatically" to give it to the next person in turn. Leads a sales rep adds are always theirs.
- Next follow-up: set when someone should call. The quick buttons (In 2 hours, Tomorrow 11 am…) fill it in for you.
- Duplicates: if the phone number or email already exists, RushCRM warns you and links to the existing lead. Phone numbers match even when written differently, so "+91 98200 12345" and "098200-12345" count as the same.
The leads list has quick views at the top: Follow-up today, Overdue, Not contacted and Unassigned. Search works on name, phone, email, company and the text in custom fields. Fields your admin marks as filters appear under More filters.
Filter by date and campaign: the date menu shows leads that came in, were won, were lost or were last contacted Today, This week, This month, Last month, or between dates you choose. The campaign menu lists every campaign your leads came from. Save this view keeps any combination (for example "Cardiology, Facebook ads, this month") as a button above the list; admins can share a view with the whole team.
Working a lead
Open any lead to see everything about it on one screen.
- Call, WhatsApp, Email: one tap opens your phone's dialer, WhatsApp chat or email app. RushCRM then gets the "Log what happened" box ready.
- Log what happened: choose Call, WhatsApp, Email or Note. For calls, pick the outcome (Connected, No answer, Busy, Asked to call back…), write a line, and set the next follow-up in the same step.
- History: every call, note, stage change and enquiry, newest first, with who did it and when.
- Stage: click a stage to move the lead. Choosing Lost asks for a reason, which feeds the reports. Won closes any open follow-ups.
- Owner: admins can reassign a lead. Its open follow-ups move with it, and the new owner is notified.
- Who handled it: the Owner box shows who the lead was first assigned to, who last contacted them, how many calls were made, and everyone who has worked on it, even after it was reassigned. The same columns are in the Excel export.
Follow-ups
The Follow-ups page is each person's to-do list: Overdue (shown in red, call these first), Today and Next 7 days. Each row has Call, WhatsApp and Log result buttons. Done marks it finished without writing anything. Admins can switch between team members.
Leads that arrive from your website or the API automatically get a "first call" follow-up within the hour.
Pipeline board
A column for each stage, with the number of leads and the total deal value. On a computer, drag a card to another column. On a phone, use the Move to… menu on each card. Won and Lost columns show the last 30 days.
Reports
Choose a period (last 7, 30 or 90 days, this month, last month or this year) to see:
- New leads, leads won and their value, and the win rate
- How many new leads were contacted within an hour, and the average time to first contact
- Which sources bring the most leads, and which turn into sales
- Each team member's new leads, calls, connected calls, wins and overdue follow-ups
- Why leads were lost
Settings (admins)
- Team: add people, set a new password for someone, or switch an account off (their leads stay).
- Custom fields: add the details your business collects, such as Pin Code, Age or Course (see Custom fields).
- Stages and sources: rename, recolour, reorder, add or delete stages. Manage lead sources and the reasons for losing.
- Who gets new leads: share new leads in turn between chosen people, or leave them unassigned for an admin to give out.
- API and website forms: create keys to connect your website and other tools. The page also has two ready-to-copy forms: a standard one (first name, last name, phone, email and a message) and one that includes all your custom fields, with a link to add more.
Custom fields
Every lead has the same standard fields: first name, last name, full name, phone, email, company and city. Anything else your business needs, add yourself under Settings → Custom fields. Each company has its own fields; nobody else sees them.
- Click Add field and give it a name, for example Pin Code.
- RushCRM makes its key from the name:
pin_code. This is the exact name your website forms, the API and CSV files use. You can change it before saving. - Choose the type: short or long text, number, date, date and time, dropdown, multiple choice, yes/no, email, phone or website link.
- Tick what you need: Required, Column in the leads list (up to 3), Filter, and for dates, Add a follow-up for this date (for example an appointment date puts a reminder in the owner's follow-ups).
The field then shows on Add lead and Edit lead, on the lead page, in the import column list and in exports. Dropdown, yes/no and multiple-choice fields also get their own chart in Reports.
Once leads have a value in a field, its key and type are locked so forms that use them keep working. You can still rename the label, change options, or delete the field.
Import and export
Import: save your spreadsheet as CSV (Excel: File → Save As → CSV; Google Sheets: File → Download → CSV), then upload it under Settings → Import and export. Choose what each column should be saved as; columns named exactly like a field (for example first_name, "Phone" or "Pin Code") are selected for you. Then choose who gets the leads, and import. Rows with problems are listed with the reason. Up to 5,000 rows per file. Download a sample file.
Export (admins): on the Leads page, set the filters you want (for example This month with all stages), then click Export and choose Excel (.xlsx) or CSV. The file has exactly the leads on screen, in the same order, with every column: stage and status (open, won or lost), owner, who it was first assigned to, who last contacted them, how many calls were made, everyone who worked on it, source, campaign, deal value in rupees, lost reason, dates, and all your custom fields. The Excel file has a frozen header row with filters and real dates and amounts.
Notifications and passwords
- Notifications (bell icon) shows new leads assigned to you and repeat enquiries from people you're already talking to.
- Email alerts: turn new-lead emails on or off under My profile.
- Forgot your password? Use the link on the login page and you'll get an email with a reset link that works for one hour. Admins can also set a new password for anyone in their team.
- Login code (OTP): after 2 wrong passwords in a row, the password alone is no longer enough. We email a 6-digit code to the account's address, and the person enters it to log in. A code works for 20 minutes, and a new one can be asked for every 2 minutes (up to 5 an hour), with a countdown on the button.
- Locked account: 5 wrong codes lock the account for 6 hours, and the person gets an email about it. To get in sooner, reset the password with "Forgot your password?", or ask an admin to click Unlock next to their name under Settings → Team.
Getting leads in from your website
Any form on any website can send its submissions to RushCRM. Each one becomes a lead within a second, is given to the next salesperson in turn, and gets a first-call follow-up.
Your RushCRM must be online (for example at https://crm.yourdomain.com) for a live website to reach it. A copy running only on your own computer (localhost) can't receive leads from the internet.
Pick one way:
| Your form | Best way | Key to use |
|---|---|---|
Has a PHP process file (form posts to contact.php, send.php…) | PHP form handler (cURL) | Secret key |
| A new form, or one that only needs to save the lead | Plain HTML form | Website form key |
| An existing form you don't want to change | One script tag | Website form key |
| WordPress | WordPress options | Either |
Create a key: log in as an admin, go to Settings → API and website forms, enter a name (for example your website's name) and choose the type:
- Secret key (
rk_live_…): full access. Use it only in server code such as PHP. Never put it in HTML or JavaScript. - Website form key (
rk_form_…): can only add leads, so it's safe in a web page.
Copy the key straight away. It's shown only once. If one is ever exposed, revoke it and make a new one.
PHP form handler (cURL)
Use this when your form posts to a PHP file. Paste this function once, at the top of that file or in a shared file you include. It is built so it can never break your form: if RushCRM is slow, offline, or the key is wrong, the function gives up within a few seconds, writes the reason to your server's error log, and your own code carries on (emails, thank-you page and so on).
<?php
/**
* Send a lead to RushCRM.
* Never stops your script: no exceptions, no exit, at most ~5 seconds.
* Returns the lead's ID, or null if it wasn't sent.
*/
if (!function_exists('rushcrm_send_lead')) {
function rushcrm_send_lead(array $lead): ?int
{
$url = 'https://crm.codenbrand.com/api/v1/leads';
$key = 'rk_live_PASTE_YOUR_SECRET_KEY'; // keep this on the server only
try {
if (!function_exists('curl_init')) {
error_log('RushCRM lead not sent: the PHP cURL extension is not installed.');
return null;
}
$json = json_encode($lead, JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE | JSON_PARTIAL_OUTPUT_ON_ERROR);
$ch = curl_init($url);
if ($ch === false) {
return null;
}
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $key,
'Content-Type: application/json',
'Accept: application/json',
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 3, // give up quickly if RushCRM can't be reached
CURLOPT_TIMEOUT => 5, // never make the visitor wait long
CURLOPT_NOSIGNAL => true,
]);
$body = curl_exec($ch);
$status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
// 201 = new lead. 200 = same phone/email already existed; the enquiry was added to that lead.
if ($status === 201 || $status === 200) {
$data = json_decode((string) $body, true);
return isset($data['data']['id']) ? (int) $data['data']['id'] : null;
}
error_log('RushCRM lead not sent (' . $status . '): ' . ($error ?: substr((string) $body, 0, 500)));
} catch (\Throwable $e) {
error_log('RushCRM lead not sent: ' . $e->getMessage());
}
return null;
}
}Then, after your own checks, send the lead. The keys on the left must be RushCRM's exact keys (see Field names); the right-hand side is whatever your form uses:
rushcrm_send_lead([
'first_name' => $_POST['first_name'] ?? '',
'last_name' => $_POST['last_name'] ?? '',
// or, if your form has a single name box: 'full_name' => $_POST['name'] ?? '',
'phone' => $_POST['phone'] ?? '',
'email' => $_POST['email'] ?? '',
'company' => $_POST['company'] ?? '',
'source' => 'Website',
'campaign' => 'Contact page', // which form this is
'notes' => $_POST['message'] ?? '',
// Your custom fields, using the keys from Settings > Custom fields:
'pin_code' => $_POST['pin_code'] ?? '',
'service' => $_POST['service'] ?? '',
]);
// Your existing code carries on here whatever happened above:
// send the email, show the thank-you page, etc.To keep track of which ad brought the visitor, pass campaign details along if your page has them, for example 'utm_source' => $_GET['utm_source'] ?? ''.
warnings.Plain HTML form
The form sends straight to RushCRM, which then sends the visitor to your thank-you page. Each input's name must be a RushCRM key.
<form action="https://crm.codenbrand.com/api/v1/forms/leads" method="post">
<input type="hidden" name="form_key" value="rk_form_YOUR_FORM_KEY">
<input type="hidden" name="source" value="Website">
<input type="hidden" name="campaign" value="Contact page">
<input type="hidden" name="redirect" value="https://yourdomain.com/thank-you">
<input name="first_name" placeholder="First name" required>
<input name="last_name" placeholder="Last name">
<input name="phone" placeholder="Phone" required>
<input name="email" type="email" placeholder="Email">
<input name="pin_code" placeholder="Pin code"> <!-- a custom field -->
<textarea name="notes" placeholder="How can we help?"></textarea>
<!-- Spam trap: keep it hidden. Bots fill it in, people don't. -->
<input name="_hp" style="display:none" tabindex="-1" autocomplete="off">
<button>Send</button>
</form>Add to an existing form (JavaScript)
Keeps your current form exactly as it is, including any emails it sends you, and also sends a copy to RushCRM. Paste before </body> on pages with forms:
<script>
document.querySelectorAll('form').forEach(function (form) {
form.addEventListener('submit', function () {
var data = new FormData(form);
data.append('form_key', 'rk_form_YOUR_FORM_KEY');
data.append('source', 'Website');
data.append('campaign', form.getAttribute('data-crm') || document.title);
var q = new URLSearchParams(location.search);
['utm_source', 'utm_medium', 'utm_campaign'].forEach(function (k) {
if (q.get(k)) data.append(k, q.get(k));
});
navigator.sendBeacon('https://crm.codenbrand.com/api/v1/forms/leads', data);
});
});
</script>The script sends every input under its name, so name your inputs with RushCRM's keys: first_name, last_name or full_name, phone, email, notes and your custom field keys. Inputs with other names are kept under "Other details sent" on the lead.
To name a form, add data-crm="Pricing page" to its <form> tag. To skip a form, such as a newsletter box without a phone field, give it a different selector or remove it from the list.
WordPress
- Contact Form 7, WPForms, Gravity Forms, Fluent Forms: use the JavaScript snippet (add it with a plugin like "WPCode", or in your theme footer). Give each form field RushCRM's key as its name, for example
[text* full_name],[tel* phone]and[email email]in Contact Form 7. - Elementor Pro forms: edit the form → Actions After Submit → add Webhook → Webhook URL:
https://crm.codenbrand.com/api/v1/forms/leads?form_key=rk_form_YOUR_FORM_KEY. Under the webhook, turn on Advanced Data, and set each field's ID (Advanced tab) to a RushCRM key:full_name,phone,email, and so on. - Your own PHP in functions.php: use the PHP function inside your form plugin's "after submit" hook.
Field names (keys)
RushCRM only accepts its exact keys: lowercase, with _ between words. Nothing is guessed, so Name, mobile or your-name are not matched to a field. This keeps every lead clean and predictable.
| Key | What to send |
|---|---|
first_name * | Text. Send this, or full_name. |
last_name | Text, optional. |
full_name * | Text. Filled in from first_name + last_name when not sent. |
phone * | 10 to 15 digits. Send phone or email (or both). |
email * | An email address. |
company | Text, optional. |
city | Text, optional. |
source | Where the lead came from, e.g. Website, Facebook ads. |
campaign | The ad or offer, e.g. diwali-offer. |
notes | Their message or requirement. Saved on the lead's history. |
stage | A stage name, e.g. New. Default: the first stage. |
owner_email | Give the lead to this team member instead of the next in turn. |
temperature | hot, warm or cold. |
deal_value | A number in rupees, e.g. 45000. |
follow_up_at | When to call them, e.g. 2026-10-12 11:00. |
* Nothing is mandatory, but send at least a name (full_name, or first_name and last_name) and a phone or email so your team can reach the lead.
Custom fields use the key shown next to each field in Settings → Custom fields, for example pin_code or date_of_birth. Send them at the top level like the standard keys, or inside a custom_fields object. Values that fit the field's type are tidied (for example dates become YYYY-MM-DD, so they can be filtered and create follow-ups). Anything else is saved exactly as sent:
| Type | Send |
|---|---|
| Short text | Any text, up to 500 characters |
| Long text | Any text, up to 5,000 characters |
| Number | A number, e.g. 42 or 1250.50 |
| Date | YYYY-MM-DD or DD-MM-YYYY, e.g. 2026-10-12 |
| Date and time | YYYY-MM-DD HH:MM, e.g. 2026-10-12 16:30 |
| Dropdown (pick one) | One of the options, exactly as listed |
| Multiple choice | Options separated by commas, or a JSON list |
| Yes / no | yes or no (also true/false, 1/0) |
| An email address | |
| Phone | A phone number |
| Website link | A web address, e.g. example.com/page |
A key that matches nothing (a typo like pin_cde) doesn't stop the lead: it's saved, the value is kept under "Other details sent" on the lead page, and the API reply lists it in warnings so you can fix the form.
Leads are never rejected for their content. Every value is stored as it comes, and every field can be empty. When a value can't be used for a CRM feature (a date that isn't a date, a temperature other than hot, warm or cold, a deal value that isn't a number), the lead is still saved, the value is kept, and the reply lists it under warnings.notes. The same note appears in the lead's history so your team can check it. Only a completely empty request is refused.
REST API reference
Basics
- Base address:
https://crm.codenbrand.com/api/v1 - Sign in: send a secret key in every request:
Authorization: Bearer rk_live_…. If your host strips that header, useX-Api-Key: rk_live_…instead. - Format: send JSON (
Content-Type: application/json). Form-encoded bodies also work. All replies are JSON. - Scope: a key belongs to one company and only sees that company's data.
- Dates come back in ISO 8601 with the timezone, e.g.
2026-10-12T11:00:00+05:30. - The
v1in the address won't change in ways that break your code. Bigger changes would come asv2.
Check that a key works:
curl https://crm.codenbrand.com/api/v1/me \
-H "Authorization: Bearer rk_live_YOUR_KEY"Endpoints
| Method | Path | What it does |
|---|---|---|
| GET | /me | Which company the key belongs to |
| GET | /leads | List and search leads |
| POST | /leads | Add a lead (or add an enquiry to an existing one) |
| GET | /leads/{id} | One lead; add ?include=activities for its history |
| PATCH | /leads/{id} | Update fields, stage or owner |
| DELETE | /leads/{id} | Delete a lead |
| GET | /leads/{id}/activities | A lead's history |
| POST | /leads/{id}/activities | Log a call, note, WhatsApp or email |
| POST | /leads/{id}/follow-ups | Set a follow-up |
| GET | /tasks | List follow-ups |
| POST | /tasks/{id}/complete | Mark a follow-up done |
| GET | /fields | Every key this company accepts: standard and custom fields, with types and options |
| GET | /stages, /sources, /users, /lost-reasons | Lists you need when building an integration |
| POST | /forms/leads | Website form endpoint (form or secret key; open to other domains) |
Leads
Add a lead
curl -X POST https://crm.codenbrand.com/api/v1/leads \
-H "Authorization: Bearer rk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Priya",
"last_name": "Sharma",
"phone": "+91 98200 12345",
"email": "priya@example.com",
"source": "Google Ads",
"campaign": "diwali-offer",
"notes": "Wants a 2BHK near the station",
"pin_code": "400053",
"budget": 5000000
}'Here pin_code and budget are custom fields this company added. Reply 201 Created for a new lead. If the phone or email already exists, the reply is 200 with "duplicate": true, and the enquiry is added to that lead's history instead:
{
"data": {
"id": 1042,
"first_name": "Priya",
"last_name": "Sharma",
"full_name": "Priya Sharma",
"phone": "+91 98200 12345",
"email": "priya@example.com",
"company": null,
"city": null,
"source": "Google Ads",
"campaign": "diwali-offer",
"stage": { "id": 7, "name": "New", "status": "open" },
"owner": { "id": 3, "name": "Rahul Mehta", "email": "rahul@example.com" },
"temperature": null,
"deal_value": null,
"lost_reason": null,
"next_follow_up_at": "2026-10-09T15:01:00+05:30",
"last_activity_at": null,
"won_at": null,
"lost_at": null,
"custom_fields": { "pin_code": "400053", "budget": 5000000, "property_type": null },
"unmatched_fields": null,
"created_at": "2026-10-09T14:01:16+05:30",
"updated_at": "2026-10-09T14:01:16+05:30",
"url": "https://crm.yourdomain.com/app/leads/1042"
},
"duplicate": false
}List and search
GET /leads accepts: q (name, email, phone or custom field text), cf[key] for a custom field (a dropdown or yes/no value, text it contains, or cf[age][min]=50 / cf[appointment_date][max]=2026-10-31 for numbers and dates), phone, email, status (open, won, lost), stage_id, owner_id, source_id, updated_since (a date: only leads changed after it), page, per_page (up to 100).
curl "https://crm.codenbrand.com/api/v1/leads?status=open&per_page=50" \
-H "Authorization: Bearer rk_live_YOUR_KEY"Lists come back as {"data": [...], "meta": {"page": 1, "per_page": 50, "total": 182, "pages": 4}}.
Update a lead
Send only what changes. Moving to a lost stage needs a lost_reason (by name) or lost_reason_id.
curl -X PATCH https://crm.codenbrand.com/api/v1/leads/1042 \
-H "Authorization: Bearer rk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"stage": "Interested", "temperature": "hot", "deal_value": 4500000, "owner_email": "rahul@example.com"}'Fields you can change: first_name, last_name, full_name, any custom field key (send null or "" to clear it), phone, email, company, city, campaign, source, temperature, deal_value, stage or stage_id, owner_email or owner_id (null to unassign).
History and follow-ups
Log a call or note
curl -X POST https://crm.codenbrand.com/api/v1/leads/1042/activities \
-H "Authorization: Bearer rk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"type": "call", "outcome": "connected", "body": "Interested, site visit on Sunday"}'type: call, note, whatsapp or email. For calls, outcome is one of connected, no_answer, busy, callback, switched_off, wrong_number. Other types need a body.
Set a follow-up
curl -X POST https://crm.codenbrand.com/api/v1/leads/1042/follow-ups \
-H "Authorization: Bearer rk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"due_at": "2026-10-12T11:00:00+05:30", "title": "Confirm site visit"}'GET /tasks lists follow-ups. Filters: status (open or done), due (today or overdue), assigned_to, lead_id. Mark one done with POST /tasks/{id}/complete.
Errors and limits
Adding a lead never fails because of its content. Errors are about the request itself (key, method, an update to a stage that doesn't exist) and look like this:
{
"error": {
"code": "validation_failed",
"message": "Some fields need fixing.",
"fields": { "stage": "No stage with that id or name. See GET /api/v1/stages." }
}
}| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_json | The body isn't valid JSON |
| 401 | unauthorized | Key missing, wrong, revoked, or the company is paused |
| 403 | forbidden | A website form key was used on an endpoint that needs a secret key |
| 404 | not_found | No such lead or endpoint (or it belongs to another company) |
| 405 | method_not_allowed | Wrong method, e.g. GET instead of POST |
| 422 | empty_request | Adding a lead with nothing in it. Any other lead is saved as sent |
| 422 | validation_failed | An update asked for something impossible, such as a stage that doesn't exist; see fields |
| 429 | rate_limited | More than 120 requests in a minute with one key; wait and retry |
| 500 | server_error | Something went wrong on the RushCRM side |
Common questions
- A lead came in twice from the same person. Will I see two leads?
- No. When the phone number or email matches an existing lead, RushCRM adds the new enquiry to that lead's history and tells its owner.
- Who gets leads from my website?
- The next person in turn among the people ticked under Settings → Stages and sources → Who gets new leads. To send a form's leads to one person, include
owner_email. - My form submits, but no lead appears.
- Check that RushCRM is online (not on localhost), that the key hasn't been revoked, and that the field names match RushCRM's keys exactly (anything else lands under "Other details sent"). With the PHP method, the reason is written to your server's error log.
- Can a salesperson see other people's leads?
- No. Sales reps only see leads assigned to them. Admins see everything in their company.
- I forgot my password.
- Use "Forgot your password?" on the login page, or ask your admin to set a new one under Settings → Team.