CRM
Developer Docs
Build integrations, extend the platform, and access the full API reference. Everything you need to build on top of CRM.
Mobile API Reference
Complete REST API for the CRM mobile app. Authentication, contacts, activities, support tickets, and more.
View Docs →Module Dev Guide
Build custom modules using CRM. Full guide covering the ORM, UI components, Smarty templates, and access control.
View Docs →Quickstart
Deploy CRM via Docker and build your first module in under 10 minutes. Step-by-step with full code examples.
View Docs →Swagger UI Explorer
Interactive API explorer — browse all endpoints, try requests live against the production API, and inspect response schemas.
Open Explorer →OpenAPI 3.0 Spec
Machine-readable YAML spec for the full mobile API. Import into Postman, Insomnia, or any OpenAPI-compatible tool.
Download YAML →Base URL
Production server for all API requests:
https://your-crm-domain.com/api/v1
Quick Reference
Common patterns you'll use across all integrations and module development.
Authentication
All API requests (except /login and /reset-password) require an access token.
# 1. Get your access token
curl -X POST https://your-crm-domain.com/api/v1/login \
-H "Content-Type: application/json" \
-d '{"login":"you@example.com","password":"yourpassword","device_name":"myapp"}'
# 2. Use it in subsequent requests (header or query param)
curl https://your-crm-domain.com/api/v1/common/app-state \
-H "access_token: YOUR_TOKEN_HERE"
DB Functions (Module Development)
Use only these DB helper functions — never use dbquery(), dbresult(), or dbfetch().
// Execute a write query
execsql("UPDATE polls SET votes = votes + 1 WHERE id = " . (int)$id);
// Read a single scalar value
$count = getsqlfield("SELECT COUNT(*) FROM polls WHERE id_company = " . TCompany::CurrentCompany()->ID());
// Read multiple rows
$rows = getsqlarray("SELECT id, title FROM polls WHERE active = 1 ORDER BY id DESC LIMIT 20");
foreach ($rows as $row) {
echo $row['title'];
}
// Insert and get new row ID
$newId = insertsql('polls', [
'title' => dbescape($title),
'id_company' => TCompany::CurrentCompany()->ID(),
'timeadded' => time(),
]);
// Escape user input
$safe = dbescape($_POST['title']);
Platform URL Pattern
https://your-crm-domain.com/index.php?m=<module>&d=<action>
# Examples
?m=customers&d=list # Contact pipeline (kanban)
?m=customerdetails&d=view&id= # Contact detail page
?m=organizations&d=list # Companies list
?m=polls&d=view # Your custom module
?m=polls-admin&d=admin # Your module's admin panel