Eligible contacts
Queue size
Sent today
Replies today
Complaint rate
Hard bounce rate
AI drafts pending
Positive replies
Sales funnel
Primary metric: reply rate → qualification rate → revenue per 1,000 sends. Open rate is intentionally secondary.
Deliverability health
Recent activity
Last 24h
| Time | Event | Contact | Campaign | Status | |||
|---|---|---|---|---|---|---|---|
| No data available yet | |||||||
Field mapping — Website Redesign Leads
Validation result
Saved mapping profiles
Reusable field maps
| Profile | Preset | Fields | Last used | ||||
|---|---|---|---|---|---|---|---|
| No data available yet | |||||||
Total contacts
Eligible
Suppressed
Countries
| Business | Country | Stage | Eligibility | Last contacted | |||
|---|---|---|---|---|---|---|---|
| No data available yet | |||||||
No Website Campaign
Businesses without an official website. Soft, non-accusatory language.
Website Redesign Campaign
Approved audit findings only. Mobile / speed / enquiry flow.
Sending pace
Global limit · ~28,800 emails / 24h · ~3.47 days per 100K
| Campaign | Preset | Status | Sent | Delivered | Replies | Health | |
|---|---|---|---|---|---|---|---|
| No data available yet | |||||||
Campaign builder preview — Redesign · Batch 08
Launch checklist
Redesign Intro v3
Template + paragraph · 128 words · English/Hindi
No Website Intro v2
Soft opener · 96 words · 5 languages
Follow-up · 3 day
Short bump · reply-checked
Asset Manager
Image URL + destination link + preview
600px · alt: "Website redesign preview" · click tracking OFF
Links to codingmarble.com/portfolio
Broken image detected
Extracted facts
AI action guardrails
Portfolio: auto-approved list. Pricing: approval required. No SEO / revenue guarantees. No referral link in cold reply.
New
Interested
Qualified
Won this month
Kanban view — Qualified & later
Qualified (0)
Proposal (0)
Negotiation (0)
Won (0)
Auto-send settings
Knowledge base
Recent AI actions
| Time | Thread | Intent | Confidence | Action | Human edit | ||
|---|---|---|---|---|---|---|---|
| No data available yet | |||||||
SPF
DKIM
DMARC
Postmaster
Complaint & bounce trend (7 days)
Warning threshold 0.05% · pause 0.08% (before provider limit 0.10%)
Auto-pause history
Delivery rate
Human reply rate
Positive reply rate
Win rate
Preset comparison — No Website vs Redesign
Revenue attribution
Sender identities
Backend connection
Values save to localStorage. See Backend Guide tab for full integration steps.
1. Yeh file kaise use karein
Ye single-file dashboard hai. Download karke index.html kisi bhi browser me open kar do — sab UI kaam karega. Backend connect karne ke liye niche steps follow karo.
- File save karo
index.htmlnaam se. - Browser me double-click karke open karo (Chrome / Edge / Firefox).
- Settings tab me apna backend URL aur token daalo.
- Neeche diye JS snippets ko file me paste karke real API bind karo.
2. API base config
HTML ke <script> section me yeh function pehle se hai:
const API = {
base: () => localStorage.getItem('cm_api_base') || 'http://localhost:8000',
token: () => localStorage.getItem('cm_token') || '',
headers: () => ({
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + API.token()
}),
get: (path) => fetch(API.base()+path, {headers: API.headers()}).then(r => r.json()),
post: (path, body) => fetch(API.base()+path, {
method:'POST', headers: API.headers(), body: JSON.stringify(body)
}).then(r => r.json())
};
3. Backend endpoints jo yeh UI expect karti hai
GET /dashboard/summary
GET /deliverability/health
POST /imports (multipart file upload)
POST /imports/{id}/preview
POST /imports/{id}/mapping
POST /imports/{id}/validate
POST /imports/{id}/commit
GET /contacts?country=&eligibility=&stage=&page=
PATCH /contacts/{id}
POST /contacts/{id}/suppress
POST /campaigns
POST /campaigns/{id}/preview
POST /campaigns/{id}/test
POST /campaigns/{id}/launch
POST /campaigns/{id}/pause
POST /campaigns/{id}/resume
GET /inbox/threads
GET /inbox/threads/{id}
POST /inbox/threads/{id}/draft
POST /inbox/threads/{id}/approve
POST /inbox/threads/{id}/reply
GET /ai/settings
POST /ai/settings
POST /webhooks/email-provider
POST /webhooks/inbound-mail
POST /unsubscribe/{token}
4. Example — Dashboard live data
Overview tab ke numbers ko real API se replace karne ke liye niche wala code file ke script me daalo:
async function loadDashboard() {
const data = await API.get('/dashboard/summary');
document.querySelectorAll('#overview .card .num')[0].textContent = data.eligible;
document.querySelectorAll('#overview .card .num')[1].textContent = data.queue_size;
document.querySelectorAll('#overview .card .num')[2].textContent = data.sent_today;
document.querySelectorAll('#overview .card .num')[3].textContent = data.replies_today;
// etc.
}
loadDashboard();
setInterval(loadDashboard, 30000);
5. Example — Import upload
async function uploadImport(file, preset){
const fd = new FormData();
fd.append('file', file);
fd.append('preset', preset); // NO_WEBSITE | WEBSITE_REDESIGN
const r = await fetch(API.base()+'/imports', {
method:'POST',
headers:{'Authorization':'Bearer '+API.token()},
body: fd
});
return r.json();
}
6. Example — Launch campaign with checklist
async function launchCampaign(id){
const check = await API.post(`/campaigns/${id}/preflight`, {});
if(!check.passed){
alert('Blocked: '+check.blockers.map(b=>b.code).join(', '));
return;
}
const res = await API.post(`/campaigns/${id}/launch`, {});
showToast('Campaign launched: '+res.status);
}
7. Example — Inbox real-time
async function loadThreads(){
const {items} = await API.get('/inbox/threads?limit=50');
const list = document.querySelector('#inbox .pane:first-child');
list.innerHTML = '';
items.forEach(t => {
const el = document.createElement('div');
el.className = 'thread-item';
el.innerHTML = `<b>${t.contact_name}</b><p>${t.preview}</p>
<span class="pill ${t.intent==='UNSUBSCRIBE'?'error':'success'}">${t.intent}</span>`;
list.appendChild(el);
});
}
setInterval(loadThreads, 20000);
8. Example — AI draft approve
async function approveDraft(threadId, editedSubject, editedBody){
return API.post(`/inbox/threads/${threadId}/approve`, {
approved: true,
edited_subject: editedSubject,
edited_body: editedBody
});
}
9. CORS setup (backend side)
// FastAPI example from fastapi.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:5500","https://dash.codingmarble.com"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
10. Recommended enums (frontend + backend match)
CampaignPreset: NO_WEBSITE | WEBSITE_REDESIGN | SEO_SERVICE | APP_DEVELOPMENT | EXISTING_CLIENT_UPSELL
Eligibility: ELIGIBLE | NEEDS_REVIEW | SUPPRESSED | INVALID
Suppression: UNSUBSCRIBED | HARD_BOUNCE | COMPLAINT | MANUAL_BLOCK | COUNTRY_RESTRICTION | DATA_DELETION
LeadStage: IMPORTED | CONTACTED | DELIVERED | REPLIED | INTERESTED | QUALIFIED
| PROPOSAL_REQUIRED | PROPOSAL_SENT | NEGOTIATION | WON | LOST
| NOT_INTERESTED | UNSUBSCRIBED | INVALID
ThreadIntent: INTERESTED | PORTFOLIO | PRICING | REQUIREMENTS | OBJECTION
| NOT_NOW | NOT_INTERESTED | UNSUBSCRIBE | SUPPORT | LEGAL
| OUT_OF_SCOPE | AUTOMATED_REPLY | SECURITY_RISK
11. Recommended payloads
// Create campaign
POST /campaigns
{
"name": "Redesign · Batch 09",
"preset": "WEBSITE_REDESIGN",
"sender_identity_id": "sender_123",
"template_mode": "TEMPLATE_PLUS_PARAGRAPH",
"template_id": "tpl_44",
"contact_segment_id": "seg_88",
"schedule_at": null
}
// Preflight response
{
"passed": false,
"blockers": [
{"code":"SENDER_AUTH_MISSING","message":"DKIM not aligned"},
{"code":"BROKEN_LINK","message":"Image URL returns 404"}
],
"warnings": [
{"code":"FREQUENCY_CAP","message":"142 contacts contacted recently"}
]
}
// Suppression add (webhook trigger)
POST /webhooks/email-provider
{
"event": "bounce",
"type": "hard",
"message_id": "<msg-abc@codingmarble>",
"email": "info@oldsite.co.in"
}
12. Deployment tips
- Local test: file directly open karo browser me, ya
python3 -m http.server 5500chala do. - Production: Nginx par static host karo —
/var/www/dashboard/index.html. - Auth: initial login flow ke liye
/auth/loginadd karo backend me, JWT token localStorage me store karo. - HTTPS: Let's Encrypt cert lagao — mail providers webhook only HTTPS accept karte hain.
- Redis limiter: backend me global 20/min token bucket lagao — multiple workers ho to bhi total 20/min hi hona chahiye.
- Queue worker: RabbitMQ ya BullMQ / Celery use karo — har recipient ek separate job.
- Provider adapter: SES / Sendgrid / Postmark ke liye pluggable adapter banao, direct VPS SMTP se dur raho.
13. Build order (fastest path to production)
- Auth + sender identity setup + SPF/DKIM/DMARC
- Contacts table + shared suppression
- Import wizard + mapping profiles
- Campaign builder + preflight + Redis limiter
- Provider webhook (bounce / complaint) → suppression
- Inbox listener (Gmail push / IMAP IDLE)
- AI classifier + draft + approval queue
- Analytics + revenue attribution