amoCRM Integration with Mobile Application
amoCRM (now kommo.com on the international market)—a CRM focused on sales funnel and messenger integration. REST API is modern, with OAuth 2.0, cursor-based pagination, and webhooks. One distinctive feature—authorization is tied to the account subdomain, which must be considered when building OAuth flow in mobile app.
OAuth 2.0 and Multi-account
amoCRM uses Authorization Code Flow with a quirk: base URL depends on the account subdomain ({subdomain}.amocrm.ru). When developing mobile app for multiple accounts, store the subdomain alongside tokens.
Code-to-token exchange:
POST https://{subdomain}.amocrm.ru/oauth2/access_token
{
"client_id": "...",
"client_secret": "...",
"grant_type": "authorization_code",
"code": "...",
"redirect_uri": "..."
}
access_token lives 24 hours, refresh_token — 3 months. amoCRM invalidates refresh_token with each use and issues a new one—must save fresh token after every refresh. If you skip this and try using old token—authorization fails, user must log in again.
Working with Leads and Deals
Lead list with cursor pagination:
suspend fun getLeads(cursor: String? = null): LeadsResponse {
return api.getLeads(
withQuery = mapOf(
"contacts" to listOf("contacts"),
"catalog_elements" to listOf("catalog_elements")
),
cursor = cursor,
limit = 50
)
}
amoCRM returns _links.next.href with ready-made next page URL including cursor. No need to build URL manually—use it directly.
Creating a lead linked to contact—two requests: POST /api/v4/leads → POST /api/v4/leads/{id}/link with contacts array. Or use embedded creation: pass _embedded.contacts in lead body—amoCRM creates and links in one request.
Webhooks and Events
amoCRM webhook sends POST to specified URL with x-www-form-urlencoded body (not JSON). Server-side parsing:
// Node.js
app.post('/webhook/amo', express.urlencoded({ extended: true }), (req, res) => {
const event = req.body;
// event.leads.update[0].id - ID of changed deal
// event.leads.status_change[0].status_id - new status
res.sendStatus(200);
});
amoCRM waits for 200 OK within 10 seconds, otherwise considers delivery failed and retries. Don't do long operations in webhook handler—accept, queue, return 200.
Event subscriptions: leads (leads), deals (contacts), tasks (tasks), incoming calls—each type configured separately in amoCRM integration settings.
Telephony and Calls
amoCRM registers calls via POST /api/v4/calls:
{
"direction": "outbound",
"duration": 125,
"source": "MyApplication",
"link": "https://...",
"phone": "+79001234567",
"call_result": "Successful",
"call_status": 4,
"responsible_user_id": 123456,
"created_by": 123456
}
call_status: 1 — left message, 2 — will call back, 3 — missed call, 4 — talked. After call from mobile app—record automatically created in amoCRM linked to contact by phone.
Timeline
Basic integration (leads, contacts, deals, OAuth) with pagination: 1-2 weeks. Webhooks, call logging, push notifications: plus 3-5 days. Cost calculated individually.







