Prepare once. Reuse later.
Saved contact lists and phone-based deduplication, preserving existing names.
From a saved audience to a message with each customer’s name.
WhatsApp, email, tickets and team follow-up, in one workspace.
One license per company. Features depend on your purchased plan; integrations require provider accounts and setup. Contact support for more than 20 users.

Choose your audience, address each customer by name, and share an offer with an image or video and a link button. Keep the follow-up moving with your team in one workspace.
Upload Excel or CSV. Create a list or merge contacts into an existing one, checking duplicates by phone number.
Up to 1,000 contacts per list. Saving does not send messages or change contact consent.
Illustrative preview. Meta and 360dialog media and buttons follow your approved template. Local image and video buttons require experimental buttons; local PDFs are sent separately from buttons.
Review your audience and consent before starting. Follow campaign status, refresh delivery status where available, and export the results.
New campaigns continue with the interface closed or PIN locked while the computer and CRM service run. Provider acceptance does not confirm delivery or reading; group status does not confirm delivery to every member.
Saved contact lists and phone-based deduplication, preserving existing names.
Formatted text, emoji, links, images, video and PDF, personalized by recipient name.
Clear task ownership and project stages, with optional reminders and manager alerts.

As your business grows, so do the details. Give your team the context they need for every follow-up, connecting customers, sales, delivery and results.
Explore the journey below. One customer, with context carried from the first opportunity through to results.
Review candidates and Mindy Priority rankings, then turn a good fit into an opportunity your team can follow.
Conversations, opportunities, documents and next steps, so every follow-up starts with the full context.
Financial transactions, receivables and quotations give you a clearer view of collections and spending.
Review sales, marketing and financial performance to see where action is needed and where there is room to grow.
From attracting customers and starting conversations to sales, delivery and results. Explore each module; available features depend on your plan and permissions.
Customer and contact records, opportunities, sales follow-up, follow-up radar and opportunity scouting. Quotations are available with Finance.
Explore plansSaved WhatsApp lists with duplicate checks, personalised campaigns, images, video and PDFs. Link buttons through the local Mindy connection, plus email, Google Ads and Salla with the relevant setup. New licenses include Customers and Sales.
Explore plansTransactions, receivables, collections, expenses, budgets, quotations and Al-Ostaz integration. Accounting invoice issuance is not included within CRM.
Explore plansTask assignment, acceptance and returns, project stage templates and team handoffs, with appointments, documents and permissions.
Explore plansDashboards, indicators and reports to help you understand performance and set priorities.
Explore plansOnce you reach an agreement, assign tasks and track project stages. Keep the customer record and next step in view throughout the handoff.
Features depend on enabled modules. External provider subscriptions and fees are separate from your CRM plan.

Use it individually on Windows or on a Windows team server, with staff signing in through their browsers using their own accounts and permissions.
Documentation · User and server guides →On your computer or server, with backup and export tools.
Individual accounts with permissions that match each team member’s responsibilities.
Team use requires a running server and network setup. Remote access needs VPN or HTTPS configuration; managed hosting is not included.
Integrations depend on enabled modules and require provider accounts and permissions.
Complete includes every module. Or start with the base and add what you need. Each license covers one company and 20 active users, including admin.
From your first customer to your latest report. Sales, Marketing, Finance, Operations and Analytics, in one license.
Add to my installationFor your existing license. We check module prerequisites before checkout.
Details and purchase →
Add to my installationFor your existing license. We check module prerequisites before checkout.
Details and purchase →
Add to my installationFor your existing license. We check module prerequisites before checkout.
Details and purchase →For your existing license. We check module prerequisites before checkout.
Details and purchase →
Add to my installationFor your existing license. We check module prerequisites before checkout.
Details and purchase →
New licenseThe base for your new license. Add the modules you need.
Details and purchase →
START HEREDownload Mindy CRM and add your first customer.
Start a 14-day trial after online trial activation.
Choose a guide to read here or open it separately. User and server guides are available in English and Arabic.
Mindy CRM 1.0.0 Beta
فتح الدليل منفصلًا ↗من استوديو الرسائل: ربط مباشر مع Meta عبر WhatsApp Cloud API، أو عبر 360dialog، باستخدام حسابك وقوالبك المعتمدة ومتغيرات الرسالة والوسائط والأزرار. الربط المحلي بالـQR مشمول لمستخدمي الموديول، وUltraMsg خيار إضافي. تُطبق متطلبات إعداد WhatsApp Business ورسوم Meta والمزود؛ لا يتجاوز الربط مراجعة الشركة أو قيود الحساب. تستمر الحملات الجديدة عند إغلاق الواجهة ما دام الجهاز وخدمة CRM يعملان. قبول المزود ليس تأكيدًا للتسليم أو القراءة.
Mindy CRM 1.0.0 Beta
فتح الدليل منفصلًا ↗Mindy CRM 1.0.0 Beta
Open standalone guide ↗Message Studio supports direct Meta WhatsApp Cloud API or 360dialog with your account and approved templates, message variables, media and template buttons. Local QR pairing is included for module users; UltraMsg is optional. WhatsApp Business setup, Meta requirements and fees, and any provider fees apply. Connecting does not bypass business review or account restrictions. New campaigns continue with the interface closed while the computer and CRM service run. Provider acceptance does not confirm delivery or reading.
Mindy CRM 1.0.0 Beta
Open standalone guide ↗اربط نموذج الدعم في موقع شركتك بصندوق التذاكر داخل CRM. هذا API لتذاكر شركتك؛ التواصل مع دعم Mindy يعمل من «دعم البرنامج» بالترخيص ولا يستخدم هذا المفتاح.
Mindy CRM 1.0.0 Beta · API v1
| Method | Path | الوظيفة |
|---|---|---|
GET | /api/integrations/tickets/health | فحص الاتصال والمفتاح دون إنشاء تذكرة |
POST | /api/integrations/tickets | إنشاء تذكرة |
GET | /api/integrations/tickets/{id} | قراءة التذكرة والردود العامة |
POST | /api/integrations/tickets/{id}/messages | إرسال رد عام |
Authorization: Bearer مطلوب في جميع المسارات. لطلبات POST: استخدم Content-Type: application/json، وOrigin يساوي عنوان CRM المعتمد تمامًا بدون شرطة أخيرة (وليس عنوان موقعك)، وIdempotency-Key بطول 8–100 حرف. استخدم معرّفًا جديدًا لكل عملية ونفس المعرّف والمحتوى عند إعادة المحاولة.
الإنشاء: subject مطلوب حتى 180 حرفًا، message مطلوب حتى 8000، reporter_name مطلوب حتى 190، reporter_email اختياري حتى 190. priority اختياري: low / normal / high / urgent. الرد يحتاج message فقط مع ترويسات POST نفسها.
curl --fail-with-body "$MINDY_CRM_URL/api/integrations/tickets/health" \
-H "Authorization: Bearer $MINDY_TICKET_KEY" \
-H "Origin: $MINDY_CRM_URL"{"ok":true,"service":"mindy-company-tickets","api_version":1,"write_enabled":true}هذا المسار متاح ضمن Mindy CRM 1.0.0 Beta. في الحزم القديمة قد يرجع 404. write_enabled:false تعني أن الاتصال يعمل لكن كتابة التذاكر متوقفة بسبب انتهاء التجربة.
curl --fail-with-body "$MINDY_CRM_URL/api/integrations/tickets" \
-H "Authorization: Bearer $MINDY_TICKET_KEY" \
-H "Origin: $MINDY_CRM_URL" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: website-test-001" \
--data '{"subject":"Order help","message":"Please help with my order.","reporter_name":"Customer","reporter_email":"customer@example.com","priority":"normal"}' {"id":123,"duplicate":false}الاستجابة الناجحة HTTP 200. إعادة الطلب نفسه ترجع id نفسه وduplicate:true. قراءة التذكرة ترجع subject وstatus وpriority وreporter_name وreporter_email وmessages؛ كل رسالة تحتوي id وauthor وbody وcreated_at. الرد الناجح يرجع {"ok":true}. الحالات: open / in_progress / waiting / closed. الملاحظات الداخلية والتذاكر الداخلية لا تظهر عبر API.
| 400 | تحقق من الحقول وحدودها أو عنوان السيرفر. |
|---|---|
| 401 | مفتاح مفقود أو غير صالح أو ملغى. |
| 402 | انتهت التجربة؛ كتابة الطلبات متوقفة. |
| 403 | HTTPS أو Origin غير مطابق، أو خدمة التذاكر غير مفعّلة. |
| 404 | المسار غير موجود، أو التذكرة خارج الشركة أو داخلية. |
| 409 | إعادة استخدام المعرّف لمحتوى مختلف أو الرد على تذكرة مغلقة. |
| 413 / 415 | الطلب أكبر من 40,000 بايت أو ليس JSON. |
| 429 | طلبات كثيرة؛ انتظر وقلّل وتيرة المحاولات. |
حدود المعدّل: 120 طلبًا/دقيقة للمفتاح و180 طلبًا/دقيقة لعنوان IP. لأخطاء DNS أو TLS أو المهلة راجع الوصول والشهادة من خادم الموقع؛ لا تعطّل فحص TLS. لا تضع المفاتيح في السجلات أو رسائل الخطأ أو التذاكر.
PHP 8+ مع cURL. احفظه خارج مجلد الويب العام واستدعه من خادم موقعك بعد تطبيق صلاحيات العميل وCSRF وحدود الطلبات. المثال مكتبة اتصال؛ لا ينشئ نموذجًا عامًا أو يحفظ ملكية التذاكر نيابة عن موقعك.
تنزيل مثال PHP<?php
declare(strict_types=1);
/** Save outside public web root. PHP 8+ with cURL.
* Environment: MINDY_CRM_URL=https://crm.example.com and MINDY_TICKET_KEY=mdt_...
* Call only from your authenticated backend. Before read/reply, check that the
* current website customer owns the ticket ID in YOUR database. Never trust a
* ticket ID supplied by a browser without an ownership check. Add CSRF checks
* and rate limits to your website form. Do not put this key in browser code.
*/
function mindyTicketRequest(string $method, string $path, ?array $body=null, string $requestId=''): array {
$base=rtrim((string)getenv('MINDY_CRM_URL'),'/');
$token=(string)getenv('MINDY_TICKET_KEY');
if(!preg_match('~^https://[a-z0-9.-]+(?::[0-9]+)?$~i',$base) || !str_starts_with($token,'mdt_'))
throw new RuntimeException('Configure the CRM HTTPS origin and ticket key on the server.');
if(!preg_match('~^/api/integrations/tickets(?:/health|/[1-9][0-9]*(?:/messages)?)?$~D',$path))
throw new InvalidArgumentException('Unsupported ticket endpoint.');
if(!in_array($method,['GET','POST'],true))throw new InvalidArgumentException('Use GET or POST.');
$headers=['Accept: application/json','Authorization: Bearer '.$token,'Origin: '.$base];
if($method==='POST'){
if(strlen($requestId)<8||strlen($requestId)>100||preg_match('/[\r\n]/',$requestId))
throw new InvalidArgumentException('Provide a stable 8–100 character idempotency ID.');
$headers[]='Content-Type: application/json';$headers[]='Idempotency-Key: '.$requestId;
}
$ch=curl_init($base.$path);$response='';
curl_setopt_array($ch,[CURLOPT_CUSTOMREQUEST=>$method,CURLOPT_CONNECTTIMEOUT=>8,CURLOPT_TIMEOUT=>25,
CURLOPT_FOLLOWLOCATION=>false,CURLOPT_PROTOCOLS=>CURLPROTO_HTTPS,
CURLOPT_SSL_VERIFYPEER=>true,CURLOPT_SSL_VERIFYHOST=>2,CURLOPT_HTTPHEADER=>$headers,
CURLOPT_WRITEFUNCTION=>static function($ch,$chunk)use(&$response){if(strlen($response)+strlen($chunk)>2097152)return 0;$response.=$chunk;return strlen($chunk);}]);
if($method==='POST')curl_setopt($ch,CURLOPT_POSTFIELDS,json_encode($body,JSON_UNESCAPED_UNICODE|JSON_THROW_ON_ERROR));
$ok=curl_exec($ch);$status=(int)curl_getinfo($ch,CURLINFO_RESPONSE_CODE);curl_close($ch);
if($ok===false)throw new RuntimeException('CRM network/TLS failure; verify DNS, HTTPS trust and reachability.');
$data=json_decode($response,true);
if($status<200||$status>=300||!is_array($data))throw new RuntimeException('CRM returned HTTP '.$status.'. Check the API troubleshooting guide.');
return $data;
}
// Safe connection check (does not create a ticket):
// $health=mindyTicketRequest('GET','/api/integrations/tickets/health');
// Create once: persist a request ID in your website DB BEFORE the first attempt.
// $created=mindyTicketRequest('POST','/api/integrations/tickets',[
// 'subject'=>'Order help','message'=>'Please help with my order.',
// 'reporter_name'=>'Customer name','reporter_email'=>'customer@example.com',
// 'priority'=>'normal'], $persistedRequestId);
// Save $created['id'] against the authenticated customer in YOUR database.
// After checking ownership locally:
// $detail=mindyTicketRequest('GET','/api/integrations/tickets/'.$ownedTicketId);
// $reply=mindyTicketRequest('POST','/api/integrations/tickets/'.$ownedTicketId.'/messages',
// ['message'=>'Customer reply'], $persistedReplyRequestId);
// Retry a failed operation with the SAME request ID and identical body.
// Notes marked internal in CRM are never returned through this API.
Connect your website support form to company tickets in CRM. This API handles your company tickets; Program support contacts Mindy using your license and does not use this key.
Mindy CRM 1.0.0 Beta · API v1
| Method | Path | Purpose |
|---|---|---|
GET | /api/integrations/tickets/health | Check connection and key without creating a ticket |
POST | /api/integrations/tickets | Create a ticket |
GET | /api/integrations/tickets/{id} | Read ticket and public replies |
POST | /api/integrations/tickets/{id}/messages | Send a public reply |
Authorization: Bearer is required on all routes. For POST, use Content-Type: application/json, Origin exactly equal to the approved CRM origin without a trailing slash (not your website origin), and an 8–100 character Idempotency-Key. Use a new ID per operation and reuse it with the identical body when retrying.
Create: subject is required, up to 180 characters; message required, up to 8000; reporter_name required, up to 190; reporter_email optional, up to 190. Optional priority: low / normal / high / urgent. Replies need message and the same POST headers.
curl --fail-with-body "$MINDY_CRM_URL/api/integrations/tickets/health" \
-H "Authorization: Bearer $MINDY_TICKET_KEY" \
-H "Origin: $MINDY_CRM_URL"{"ok":true,"service":"mindy-company-tickets","api_version":1,"write_enabled":true}This check is included in Mindy CRM 1.0.0 Beta. Older packages may return 404. write_enabled:false means the connection works but ticket writes are unavailable due to trial expiry.
curl --fail-with-body "$MINDY_CRM_URL/api/integrations/tickets" \
-H "Authorization: Bearer $MINDY_TICKET_KEY" \
-H "Origin: $MINDY_CRM_URL" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: website-test-001" \
--data '{"subject":"Order help","message":"Please help with my order.","reporter_name":"Customer","reporter_email":"customer@example.com","priority":"normal"}' {"id":123,"duplicate":false}Successful responses use HTTP 200. Retrying the same request returns the same id and duplicate:true. Reading a ticket returns subject, status, priority, reporter_name, reporter_email and messages; each message includes id, author, body and created_at. A successful reply returns {"ok":true}. Statuses: open / in_progress / waiting / closed. Internal notes and internal tickets are excluded from the API.
| 400 | Check fields, limits and the server origin. |
|---|---|
| 401 | Missing, invalid or revoked key. |
| 402 | Trial expired; writes are unavailable. |
| 403 | HTTPS/origin mismatch, cross-site request, or ticket module unavailable. |
| 404 | Unknown route, ticket outside the company, or an internal ticket. |
| 409 | Idempotency ID reused with different content, or reply to a closed ticket. |
| 413 / 415 | Body exceeds 40,000 bytes or is not JSON. |
| 429 | Rate limit; wait and reduce request frequency. |
Rate limits: 120 requests/minute per key and 180 per IP. For DNS, TLS or timeout failures, check reachability and certificate trust from the website server; never disable TLS verification. Keep keys out of logs, errors and tickets.
PHP 8+ with cURL. Save outside the public web root and call from your backend after customer authorization, CSRF and rate-limit checks. This connection helper does not create a public form or store ticket ownership for your site.
Download PHP example<?php
declare(strict_types=1);
/** Save outside public web root. PHP 8+ with cURL.
* Environment: MINDY_CRM_URL=https://crm.example.com and MINDY_TICKET_KEY=mdt_...
* Call only from your authenticated backend. Before read/reply, check that the
* current website customer owns the ticket ID in YOUR database. Never trust a
* ticket ID supplied by a browser without an ownership check. Add CSRF checks
* and rate limits to your website form. Do not put this key in browser code.
*/
function mindyTicketRequest(string $method, string $path, ?array $body=null, string $requestId=''): array {
$base=rtrim((string)getenv('MINDY_CRM_URL'),'/');
$token=(string)getenv('MINDY_TICKET_KEY');
if(!preg_match('~^https://[a-z0-9.-]+(?::[0-9]+)?$~i',$base) || !str_starts_with($token,'mdt_'))
throw new RuntimeException('Configure the CRM HTTPS origin and ticket key on the server.');
if(!preg_match('~^/api/integrations/tickets(?:/health|/[1-9][0-9]*(?:/messages)?)?$~D',$path))
throw new InvalidArgumentException('Unsupported ticket endpoint.');
if(!in_array($method,['GET','POST'],true))throw new InvalidArgumentException('Use GET or POST.');
$headers=['Accept: application/json','Authorization: Bearer '.$token,'Origin: '.$base];
if($method==='POST'){
if(strlen($requestId)<8||strlen($requestId)>100||preg_match('/[\r\n]/',$requestId))
throw new InvalidArgumentException('Provide a stable 8–100 character idempotency ID.');
$headers[]='Content-Type: application/json';$headers[]='Idempotency-Key: '.$requestId;
}
$ch=curl_init($base.$path);$response='';
curl_setopt_array($ch,[CURLOPT_CUSTOMREQUEST=>$method,CURLOPT_CONNECTTIMEOUT=>8,CURLOPT_TIMEOUT=>25,
CURLOPT_FOLLOWLOCATION=>false,CURLOPT_PROTOCOLS=>CURLPROTO_HTTPS,
CURLOPT_SSL_VERIFYPEER=>true,CURLOPT_SSL_VERIFYHOST=>2,CURLOPT_HTTPHEADER=>$headers,
CURLOPT_WRITEFUNCTION=>static function($ch,$chunk)use(&$response){if(strlen($response)+strlen($chunk)>2097152)return 0;$response.=$chunk;return strlen($chunk);}]);
if($method==='POST')curl_setopt($ch,CURLOPT_POSTFIELDS,json_encode($body,JSON_UNESCAPED_UNICODE|JSON_THROW_ON_ERROR));
$ok=curl_exec($ch);$status=(int)curl_getinfo($ch,CURLINFO_RESPONSE_CODE);curl_close($ch);
if($ok===false)throw new RuntimeException('CRM network/TLS failure; verify DNS, HTTPS trust and reachability.');
$data=json_decode($response,true);
if($status<200||$status>=300||!is_array($data))throw new RuntimeException('CRM returned HTTP '.$status.'. Check the API troubleshooting guide.');
return $data;
}
// Safe connection check (does not create a ticket):
// $health=mindyTicketRequest('GET','/api/integrations/tickets/health');
// Create once: persist a request ID in your website DB BEFORE the first attempt.
// $created=mindyTicketRequest('POST','/api/integrations/tickets',[
// 'subject'=>'Order help','message'=>'Please help with my order.',
// 'reporter_name'=>'Customer name','reporter_email'=>'customer@example.com',
// 'priority'=>'normal'], $persistedRequestId);
// Save $created['id'] against the authenticated customer in YOUR database.
// After checking ownership locally:
// $detail=mindyTicketRequest('GET','/api/integrations/tickets/'.$ownedTicketId);
// $reply=mindyTicketRequest('POST','/api/integrations/tickets/'.$ownedTicketId.'/messages',
// ['message'=>'Customer reply'], $persistedReplyRequestId);
// Retry a failed operation with the SAME request ID and identical body.
// Notes marked internal in CRM are never returned through this API.
Message Studio supports direct Meta WhatsApp Cloud API or 360dialog using your account and approved templates. Local QR pairing is included for Communication and Marketing users on their computer or server; UltraMsg is optional. Official connections require WhatsApp Business account setup and credentials. Meta requirements and fees, plus any provider fees, apply; connecting does not bypass business review or account restrictions.
Yes. Upload Excel or CSV to create a list or merge contacts into an existing list, with duplicates checked by international phone number. Lists persist after closing the interface. Up to 1,000 contacts per list; confirm consent before sending.
Yes. Meta and 360dialog use approved templates, with text variables, image, video or PDF headers and template buttons as supported by the template. Local image and video link buttons require experimental buttons to be enabled; local PDFs are sent separately from buttons. New campaigns continue with the interface closed or PIN locked while your computer and CRM service run. Provider acceptance does not confirm delivery or reading.
Buy from the Mindy store on this website. Once payment is verified, a code is requested from the license server and displayed in your order. Enter it in the CRM Product Center.
Purchased module licenses are perpetual. New purchases include three months of updates from activation and ticket support for local use, with an initial response within three business days. Server use includes updates only, without technical support. Renewal is optional.
Activation, updates and external integrations require internet access. Individual use stores data locally; team members need a connection to the server.
In team mode, CRM is installed on one Windows server. Employees sign in through their browsers. Network and HTTPS setup are required for secure access.
The upgrade process preserves the database. Keep a backup, select the previous installation during setup and do not delete its data folder.