{"id":36296722,"url":"https://github.com/ufee/amoapi-v4","last_synced_at":"2026-02-20T13:00:54.776Z","repository":{"id":311234859,"uuid":"1020875668","full_name":"ufee/amoapi-v4","owner":"ufee","description":"amoCRM/Kommo API v4 PHP Client","archived":false,"fork":false,"pushed_at":"2025-10-16T09:58:06.000Z","size":100,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-11T14:21:01.766Z","etag":null,"topics":["amocrm","api","kommo","php"],"latest_commit_sha":null,"homepage":"https://amocrm.ru/developers/content/crm_platform/platform-abilities","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ufee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-16T14:24:38.000Z","updated_at":"2025-12-05T18:16:07.000Z","dependencies_parsed_at":"2025-09-18T16:11:23.224Z","dependency_job_id":"0d679b76-0933-4053-b159-febd0da21cd6","html_url":"https://github.com/ufee/amoapi-v4","commit_stats":null,"previous_names":["ufee/amoapi-v4"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/ufee/amoapi-v4","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ufee%2Famoapi-v4","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ufee%2Famoapi-v4/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ufee%2Famoapi-v4/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ufee%2Famoapi-v4/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ufee","download_url":"https://codeload.github.com/ufee/amoapi-v4/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ufee%2Famoapi-v4/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29651964,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T09:27:29.698Z","status":"ssl_error","status_checked_at":"2026-02-20T09:26:12.373Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amocrm","api","kommo","php"],"created_at":"2026-01-11T10:08:31.291Z","updated_at":"2026-02-20T13:00:54.762Z","avatar_url":"https://github.com/ufee.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🚀 amoCRM/Kommo PHP API (v4) Client\n\nПоддерживает OAuth 2.0, кэширование, пагинацию, события, автоматическое обновление токенов, обработку ошибок и работу с любыми сущностями (сделки, контакты, компании, задачи, заметки и др.).\n\n---\n\n## ✅ Возможности\n\n- ✅ Пддержка [amoCRM/Kommo API v4](https://www.amocrm.ru/developers/content/crm_platform/platform-abilities)\n- ✅ OAuth 2.0 с автообновлением токенов\n- ✅ Хранилище токенов: файлы, Redis, MongoDB + долгосрочные токены\n- ✅ Кэширование справочников в файлах и Redis: пользователи, поля, типы задач и т.д.\n- ✅ Постраничное извлечение сущностей через `foreach` и `do-while`\n- ✅ Обработка событий через `callbacks`: отладка, контроль\n- ✅ Ограничение частоты запросов\n- ✅ Поддержка массовых операций\n- ✅ Мультиаккаунтность\n\n---\n\n## 📦 Установка\n\n```bash\ncomposer require ufee/amoapi-v4\n```\n\n## ⚙️ Быстрый старт\n```php\n$api = \\Ufee\\AmoV4\\ApiClient::setInstance([...]);\n$leads = $api-\u003eleads()-\u003eget();\nforeach ($leads as $lead) {\n    echo $lead-\u003ename . \"\\n\";\n}\n```\n\n### Определение клиента  \n```php\n$api = \\Ufee\\AmoV4\\ApiClient::setInstance([\n    'domain'        =\u003e 'yourdomain',           // домен (без .amocrm.ru)\n    'client_id'     =\u003e '8a8135d4-31ca-47...', // ID интеграции\n    'client_secret' =\u003e 'zMZFNnho8FozhrDzxrbA9xuR9...',\n    'redirect_uri'  =\u003e 'https://yoursite.com/auth/callback',\n    'zone'          =\u003e 'ru', // или 'com' для Kommo\n]);\n```\n\n### Настройка параметров (опционально)  \n```php\n$api-\u003esetParam('query_delay', 0.15);   // задержка между запросами (сек)\n$api-\u003esetParam('query_retries', 3);    // кол-во попыток при ошибках 429\n$api-\u003esetParam('lang', 'ru');          // язык аккаунта\n```\n\n### Хранилище Oauth \nФайловое хранение OAuth-токенов  \nИспользуется по умолчанию: `/src/Temp/{domain}/{client_id}.json`  \n```php\n$api-\u003eoauth-\u003esetStorageFiles('/path/to/oauth/storage');\n```\n**Долгосрочный токен**  \n```php\n$api-\u003eoauth-\u003esetLongToken($long_token);\n```\n**Redis**  \nПоддерживается библиотека [phpredis](https://github.com/phpredis/phpredis)\n```php\n$redis = new \\Redis();\n$redis-\u003econnect('127.0.0.1');\n$redis-\u003esetOption(\\Redis::OPT_SERIALIZER, \\Redis::SERIALIZER_PHP); // или \\Redis::SERIALIZER_IGBINARY\n$redis-\u003eselect(4);\n\n$api-\u003eoauth-\u003esetStorageRedis($redis);\n```\n**Mongodb**  \nПоддерживается библиотека [mongo-php-library](https://github.com/mongodb/mongo-php-library)\n```php\n$mongo = new \\MongoDB\\Client('mongodb://127.0.0.1');\n$collection = $mongo-\u003eselectCollection('amo', 'oauth');\n\n$api-\u003eoauth-\u003esetStorageMongo($mongo);\n```\n\n### Кеширование данных  \nПоддерживается кеширование справочников и общих данных аккаунта  \nВремя жизни для кэша / по умолчанию\n```php\n$api-\u003ecache-\u003esetTtl([\n    'account'      =\u003e 60, // 3600\n    'users'        =\u003e 60, // 1800\n    'pipelines'    =\u003e 60, // 3600\n    'userGroups'   =\u003e 60, // 3600\n    'customFields' =\u003e 60, // 1800\n    'taskTypes'    =\u003e 60, // 3600\n    'eventTypes'   =\u003e 60  // 86400\n]);\n```\nФайловое хранение кэша\nИспользуется по умолчанию: `/src/Temp/{domain}/{client_id}.{key}.cache`  \n```php\n$api-\u003ecache-\u003esetStorageFiles('/path/to/cache/storage', [\n    'serialize'   =\u003e 'igbinary_serialize', // рекомендуется вместо serialize\n    'unserialize' =\u003e 'igbinary_unserialize' // рекомендуется вместо unserialize\n]);\n```\nОчистка кеша\n```php\n$api-\u003ecache-\u003eclear('account');\n$api-\u003ecache-\u003eclear('customFields');\n$api-\u003ecache-\u003eclear('taskTypes');\n```\n**Redis**  \nПоддерживается библиотека [phpredis](https://github.com/phpredis/phpredis)\n```php\n$redis = new \\Redis();\nredis-\u003econnect('127.0.0.1');\n$redis-\u003esetOption(\\Redis::OPT_SERIALIZER, \\Redis::SERIALIZER_PHP); // или \\Redis::SERIALIZER_IGBINARY\n$redis-\u003eselect(4);\n\n$api-\u003ecache-\u003esetStorageRedis($redis);\n```\n\n### 🔔 События (Callbacks)  \nМониторинг запросов, логирование, обработка ошибок, контроль  \n```php\n$api-\u003ecallbacks-\u003eon($event, function($payload) {\n   // подписка на события\n});\n```\n```php\n$api-\u003ecallbacks-\u003eoff($event, function($payload) {\n   // отписка от событий\n});\n```\nПоддерживаемые события  \nСобытия по query выполняются в последовательности, указанной ниже\n```php\n$api-\u003ecallbacks-\u003eoff('query.delay')-\u003eon('query.delay', function($query) {\n    // по умолчанию прописана логика задержек на основе $query-\u003einstance-\u003egetParam('query_delay')\n    // пауза между запросами вычисляется автоматически\n    sleep(1); // кастомная логика задержек между запросами\n});\n\n$api-\u003ecallbacks-\u003eon('query.request.before', function($query) {\n    // вызывается перед выполнением запроса\n    echo '['.$query-\u003emethod.'] '.$query-\u003egetUrl();\n});\n\n$api-\u003ecallbacks-\u003eon('query.response.code', function($code, $query) {\n    // вызывается после выполнения запроса\n    // поумолчанию присутствует обработка кодов:\n    // 429 - повторные попытки\n    // 401 - повторная попытка с переполучением токена из хранилища\n    // 502,504 - однократный повтор\n    // return false; прерывает дальнейшую логику обработки\n});\n\n$api-\u003ecallbacks-\u003eon('query.response.fail', function($query, $code) {\n    // вызывается после неудачного выполнения запроса\n    // все коды ответа кроме 200,204\n    if ($code === 0) {\n        echo 'Error: '.$query-\u003eresponse-\u003egetError().\"\\n\\n\";\n    } else {\n        echo \"Response:\\n\".$query-\u003eendDate().' - ['.$code.'] '.$query-\u003eresponse-\u003egetData().\"\\n\\n\";\n    }\n});\n\n$api-\u003ecallbacks-\u003eon('query.response.after', function($query, $code) {\n    // вызывается всегда после выполнения запроса\n    if ($code === 0) {\n        echo 'Error: '.$query-\u003eresponse-\u003egetError().\"\\n\\n\";\n    } else {\n        echo \"Response:\\n\".$query-\u003eendDate().' - ['.$code.'] '.$query-\u003eresponse-\u003egetData().\"\\n\\n\";\n    }\n});\n\n$api-\u003ecallbacks-\u003eon('oauth.token.fetch', function($oauth, $query, $response) {\n    // вызывается после извлечения токена\n});\n\n$api-\u003ecallbacks-\u003eon('oauth.token.refresh', function($oauth, $query, $response) {\n    // вызывается после обновления токена\n});\n\n$api-\u003ecallbacks-\u003eon('oauth.token.refresh.error', function($exc, $query = null, $response = null) {\n    // вызывается после неудачного обновления токена\n});\n```\n### 🔐 Первичное получение OAuth-токена \n```php\n$api-\u003eoauth-\u003efetchToken($code); // токен сохранится в выбранном storage\n```\n### Произвольные API запросы\n```php\n$query = $api-\u003equery('GET','/api/v4/leads/'.$lead_id);\n$query-\u003eexecute();\n$raw = $query-\u003eresponse-\u003evalidated();\nprint_r($raw); // object of lead\necho $raw-\u003ename;\n```\n### 📥 Работа с сущностями  \nПроизводится через сервисы:\n```php\n// получение экземпляра сервиса\n$service = $api-\u003eaccount();\n$api-\u003eusers();\n$api-\u003ecustomFields($entity_type);\n$api-\u003epipelines();\n$api-\u003epipelineStatuses($pipeline_id);\n$api-\u003eleads();\n$api-\u003econtacts();\n$api-\u003ecompanies();\n$api-\u003elinks();\n$api-\u003etasks();\n$api-\u003enotes($entity_type);\n$api-\u003eevents();\n$api-\u003ewidgets();\n$api-\u003ewebhooks();\n```\nУстановка параметров\n```php\n$service-\u003emaxPageRows($value);\n$service-\u003eorderBy($field, $direction = 'asc')\n$service-\u003ewith($values);\n$service-\u003esetQueryArg($key, $value);\n$service-\u003esetQueryArgs($args = []);\n\n```\nПолучение сущностей\n```php\n$model = $service-\u003efind($elem_id, $with = []);\n$collection = $service-\u003eget($with = null);\n$paginate = $service-\u003epaginate($with = null);\n$paginate = $service-\u003efilter($conditions, $with = []);\n$paginate = $service-\u003esearch($phrase, $with = []);\n\n```\nСоздание/обновление сущностей через сырые данные  \n$raw_data может быть объектом или массивом объектов  \nНа практике не применяется, так как действие производится через модель\n```php\n$raw_response = $service-\u003eadd($raw_data);\n$raw_response = $service-\u003eupdate($raw_data);\n```\n#### Модель сущности  \nПоля моделей динамические, реализованы через геттеры и сеттеры\n```php\n$model = $service-\u003ecreate(['field1' =\u003e 'value', 'field2' =\u003e 'value', ...]);\n// или \n$model = $service-\u003efind(123567);\n\n$model-\u003ename = 'Name';\n$model-\u003eprice = 100;\n$model-\u003esave(); // создание или обновление сущности под капотом\n$model-\u003etoArray(); \n```\n#### Коллекция сущностей  \n```php\n$models = $service-\u003ecreateCollection([\n    ['field1' =\u003e 'value', 'field2' =\u003e 'value', ...],\n    ['field1' =\u003e 'value', 'field2' =\u003e 'value', ...],\n]);\n// или \n$models = $service-\u003eget();\n\nforeach($models as $model) {\n    $model-\u003eattachTag('AmoV4');\n}\n$models-\u003esave(); // массовое создание или обновление сущностей под капотом\n$models-\u003etoArray(); \n```\n#### Получение сущностей по ID  \n```php\n$lead = $api-\u003eleads()-\u003efind(30013961);\n$contact = $api-\u003econtacts()-\u003efind(45968927);\n$company = $api-\u003ecompanies()-\u003efind(55968943);\n\n$leads = $api-\u003eleads()-\u003efind([30013961,30013962,30013963]);\n```\n#### Постраничное получение  \nОсуществляется на основании `_links-\u003enext-\u003ehref` из ответа  \n```php\n$paginate = $api-\u003eleads()-\u003epaginate();\n$paginate-\u003emaxPages(10); // максимальное кол-во страниц\n$paginate-\u003emaxRows(100); // максимальное кол-во сущностей на странице\n\ndo {\n    $leads = $paginate-\u003efetchPage();\n    echo \"\\nPage \".$paginate-\u003epage.\"\\n\";\n    print_r($leads); // collection\n} while(\n    $paginate-\u003enextPage();\n);\n\n// или так\nforeach($paginate as $page_num=\u003e$leads) {\n    echo \"\\nPage \".$page_num.\"\\n\";\n    print_r($leads); // collection\n}\n```\nВ некоторых случаях `_links-\u003enext-\u003ehref` отсутствует в ответе, но следующие страницы при этом существуют, в таком случае можно принудительно получить все страницы, как это делается в `$paginate-\u003efetchAll();`  \n```php\n$paginate-\u003emaxPages(10);\nwhile (\n    $paginate-\u003evalid() \u0026\u0026 ($leads = $paginate-\u003efetchPage()) \u0026\u0026 $leads-\u003ecount()\n) {\n    echo \"\\nPage \".$paginate-\u003epage.\"\\n\";\n    print_r($leads); // collection\n    $paginate-\u003esetPageNum($paginate-\u003epage+1);\n}\n\n// или так\n$leads = $paginate-\u003efetchAll($max_pages);\n```\n#### Фильтрация сущностей\n```php\n$paginate = $api-\u003eleads()-\u003efilter([\n    'price' =\u003e ['from' =\u003e 0, 'to' =\u003e 100500]\n]);\nforeach($paginate as $page_num=\u003e$leads) {\n    echo \"\\nPage \".$page_num.\"\\n\";\n    print_r($leads); // collection\n}\n```\n#### Поиск сущностей\n```php\n$leads = $service-\u003esearchByCustomField(string $query, string $field, int $page_limit = 0, array $with = []);\n$contacts = $service-\u003esearchByPhone(string $phone, int $page_limit = 0, array $with = []);\n$contacts = $service-\u003esearchByEmail(string $email, int $page_limit = 0, array $with = []);\n$companies = $service-\u003esearchByName(string $name, int $page_limit = 0, array $with = []);\n\n$paginate = $leads-\u003esearch('query', ['source_id','source']);\n```\n#### Аккаунт\n```php\n$account = $api-\u003eaccount()-\u003eget();\n// или\n$account = $api-\u003eaccount;\n// или из кеша\n$account = $api-\u003ecache-\u003eaccount();\n\n// модель аккаунта\necho $account-\u003eid;\necho $account-\u003ename;\n\n$userGroups = $account-\u003euserGroups; // collection\n$taskTypes = $account-\u003etaskTypes; // collection\n\n// или из кеша\n$userGroups = $api-\u003ecache-\u003euserGroups();\n$taskTypes = $api-\u003ecache-\u003etaskTypes();\n$eventTypes = $api-\u003ecache-\u003eeventTypes($lang = null); // текущий язык по умолчанию\n\n// очистка кеша\n$api-\u003ecache-\u003eclear('account');\n```\n#### Пользователи аккаунта\n```php\n$users = $api-\u003eusers()-\u003eget();\n// или из кеша\n$users = $api-\u003ecache-\u003eusers();\n// пользователь по id\n$user = $api-\u003ecache-\u003euser(128737);\n```\n#### Воронки сделок\n```php\n$pipelines = $api-\u003epipelines()-\u003eget();\n$pipeline = $api-\u003epipelines()-\u003efind($pipeline_id);\n// или из кеша\n$pipelines = $api-\u003ecache-\u003epipelines();\n$pipeline = $api-\u003ecache-\u003epipeline($pipeline_id);\n// или новая воронка\n$pipeline = $api-\u003epipelines()-\u003ecreate(['name' =\u003e 'Рекламации']);\n\n$pipeline-\u003esort = 20;\n$pipeline-\u003eis_main = false;\n$pipeline-\u003eis_unsorted_on = false;\n$pipeline-\u003e_embedded = [];\n$pipeline-\u003esave();\n\n// этапы воронки\n$statuses = $pipeline-\u003estatuses(); // collection\n// удаление воронки\n$pipeline-\u003edelete();\n```\n#### Этапы воронок\n```php\n$statuses = $api-\u003epipelineStatuses($pipeline_id)-\u003ewith(['descriptions'])-\u003eget();\n$status = $api-\u003epipelineStatuses($pipeline_id)-\u003efind($status_id, ['descriptions']);\n// или новый этап\n$status = $api-\u003epipelineStatuses($pipeline_id)-\u003ecreate(['name' =\u003e 'Договор подписан']);\n\n$status-\u003esort = 50;\n$status-\u003esave();\n\n// удаление этапа\n$status-\u003edelete();\n```\n#### Кастомные поля аккаунта\n```php\n$service = $api-\u003ecustomFields('contacts');\n$service = $api-\u003ecustomFields('catalogs', $catalog_id);\n$service-\u003emaxPageRows(10);\n$service-\u003eorderBy('sort', 'desc');\n\n// получение коллекции\n$cfields = $service-\u003eget();\n// или из кеша\n$cfields = $api-\u003ecache-\u003ecustomFields('contacts');\n$cfields = $api-\u003ecache-\u003ecustomFields('catalogs', $catalog_id);\n```\nСоздание поля\n```php\n$service = $api-\u003ecustomFields('contacts');\n$cf = $service-\u003ecreate(['name' =\u003e 'Варианты оплаты']);\n$cf-\u003etype = 'multiselect';\n$cf-\u003eenums = [\n    ['value' =\u003e 'Онлайн', 'sort' =\u003e 0],\n    ['value' =\u003e 'При получении', 'sort' =\u003e 1],\n    ['value' =\u003e 'СБП', 'sort' =\u003e 2]\n];\n$cf-\u003esave();\n```\n#### Кастомные поля сущности\n```php\n$lead = $api-\u003eleads()-\u003efind($lead_id);\n\n$cf = $lead-\u003ecf('Варианты оплаты');\n$cf-\u003ereset();\n$cf-\u003esetValues(['Онлайн','При получении']);\n$cf-\u003esetEnums([845234,945431]);\n$values = $cf-\u003egetValues();\n\n// поле по названию\n$cf = $lead-\u003ecf('Город');\n// поле по id\n$cf = $lead-\u003ecf(3745829);\n\n$cf-\u003esetValue('Москва');\n$cf-\u003esetEnum(546710);\n$value = $cf-\u003egetValue();\n\n$field = $cf-\u003efield;\n$enum_values = $field-\u003egetEnums();\n$enum_ids = $field-\u003egetEnumIds();\n$values = $field-\u003egetValues();\n$bool = $field-\u003ehasEnum(568345);\n$bool = $field-\u003ehasValue('Чебоксары');\n\n$cf = $lead-\u003ecf()-\u003ebyName('Город');\n$cf = $lead-\u003ecf()-\u003ebyId(3745829);\n$cf = $lead-\u003ecf()-\u003ebyCode('PHONE');\n$cf = $lead-\u003ecf()-\u003ebyType('radiobutton');\n\n$cfields = $lead-\u003ecf()-\u003eall();\nforeach($cfs as $cf) {\n    print_r($cf-\u003egetValue());\n    echo \"\\n\";\n}\n```\n#### Сделки\n```php\n$leads = $api-\u003eleads()-\u003eget();\n$leads = $api-\u003eleads;\n$leads = $api-\u003eleads()-\u003ewith(['source_id','source']))-\u003eget();\n$leads = $api-\u003eleads()-\u003esearchByCustomField('Москва', 'Город', 1); // 1 page (250 rows max)\n$leads = $api-\u003eleads()-\u003esearchByName('Разработка ПО', 1, ['source_id','source']); // 1 page with source\n\n$paginate = $api-\u003eleads()\n                -\u003eorderBy('updated_at', 'desc')\n                -\u003ewith(['source_id','source','loss_reason'])\n                -\u003epaginate();\n\n$paginate = $api-\u003eleads()-\u003efilter($conditions = [],  $with = []);\n$paginate = $api-\u003eleads()-\u003esearch('VIP');\n\n$lead = $api-\u003eleads()-\u003efind($lead_id);\n$lead = $api-\u003eleads()-\u003efind($lead_ids, ['source_id','source']);\n$lead = $api-\u003eleads()-\u003ecreate(['name' =\u003e 'Новая сделка']);\n\n$lead-\u003eprice = 100;\n$lead-\u003estatus_id = 21776227;\n$lead-\u003ecf('Приоритет')-\u003esetValue('Высокий'); // set value name by cf name\n$lead-\u003ecf(123678)-\u003esetEnum(83565); // set enum id by cf id\n\n$lead-\u003eattachTag('Tag1');\n$lead-\u003eattachTag(['name' =\u003e 'Цветной', 'color' =\u003e 'FF8F92']);\n$lead-\u003edetachTag('Tag3');\n$tags = $lead-\u003egetTags();\n\n// replace all existing tags\n$lead-\u003esetTags($tags); // ids or names\n$lead-\u003eresetTags(); // replace with none\n\n$paginate = $lead-\u003egetTasks($filter = []);\n$tasks = $lead-\u003egetTasks($filter = [])-\u003efetchAll();\n$task = $lead-\u003efindTask($task_id);\n$task = $lead-\u003ecreateTask($type = 1);\n\n$paginate = $lead-\u003egetNotes($filter = []);\n$notes = $lead-\u003egetNotes($filter = [])-\u003efetchAll();\n$note = $lead-\u003efindTask($task_id);\n$note = $lead-\u003ecreateNote($type = 'common');\n\n```\n\n#### Виджеты\n```php\n$paginate = $api-\u003ewidgets()-\u003epaginate();\n$paginate-\u003emaxRows(100)-\u003emaxPages(10);\n\n// пагинация на основе next link\nforeach($paginate as $page_num=\u003e$widgets) {\n    echo \"\\nPage \".$page_num.\" loaded \".$widgets-\u003ecount().\"\\n\\n\";\n    print_r($widgets); // collection\n}\n// принудительная пагинация на основании наличия данных\nwhile (\n    $paginate-\u003evalid() \u0026\u0026 ($widgets = $paginate-\u003efetchPage()) \u0026\u0026 $widgets-\u003ecount()\n) {\n    echo \"\\nPage \".$paginate-\u003epage.\" loaded \".$widgets-\u003ecount().\"\\n\\n\";\n    $paginate-\u003esetPageNum($paginate-\u003epage+1);\n}\n\n// получение всех страниц в виде одной коллекции\n$widgets = $api-\u003ewidgets()-\u003eget();\n$widgets = $api-\u003ewidgets()-\u003epaginate()-\u003efetchAll($max_pages);\n\n$widget = $widgets-\u003ewhere('id', 972)-\u003efirst();\n// или получение отдельным запросом по коду\n$widget = $api-\u003ewidgets()-\u003efind('amo_asterisk');\n\n// установка виджета, возвращает модель\n$installed = $api-\u003ewidgets()-\u003einstall('amo_asterisk', $settings);\n// или через модель\n$installed = $widget-\u003einstall([\n    'login' =\u003e 'example',\n    'password' =\u003e 'eXaMp1E',\n    'phones' =\u003e [\n        1234 =\u003e '8927047',\n        5678 =\u003e '8906000',\n    ],\n    'script_path'=\u003e 'https://site.ru/'\n]);\n\n// удаление установки виджета\n$bool = $api-\u003ewidgets()-\u003euninstall('amo_asterisk');\n// или через модель\n$bool = $widget-\u003euninstall();\n```\n\n#### Вебхуки\n```php\n// получение всех вебхуков\n$webhooks = $this-\u003ecrm-\u003ewebhooks()-\u003eget();\n// или конкретных по url\n$webhooks = $this-\u003ecrm-\u003ewebhooks()-\u003eget($some_url);\n\nforeach($webhooks as $webhook) {\n    // отписка\n    $webhook-\u003eunsubscribe();\n}\n// подписка на вебхук\n$webhook = $this-\u003ecrm-\u003ewebhooks()-\u003esubscribe($some_url, ['note_lead','note_contact','...']);\n// отписка\n$result = $this-\u003ecrm-\u003ewebhooks()-\u003eunsubscribe($some_url);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fufee%2Famoapi-v4","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fufee%2Famoapi-v4","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fufee%2Famoapi-v4/lists"}