{"openapi":"3.0.3","info":{"title":"TheCRM Public API","version":"1.0.0","description":"Публичный API TheCRM для интеграций. Аутентификация: заголовок Authorization: Bearer <ключ центра>. Организация определяется из ключа. Ключи: tcrm_live_… — боевые (реальные данные); tcrm_test_… — песочница (детерминированные фикстуры, запись ничего не создаёт). Лимиты: 120 запросов/мин на ключ; заголовки X-RateLimit-Limit/Remaining/Reset на каждом ответе, Retry-After при 429. Идемпотентность: у записывающих вызовов поддерживается заголовок Idempotency-Key (TTL 24 часа; повтор ключа с другим телом → 409). Вебхуки: таймаут доставки 10 секунд — отвечайте 2xx сразу, обработку выполняйте асинхронно. Документация: https://thecrm.uz/developers"},"servers":[{"url":"https://thecrm.uz/api"}],"security":[{"ApiKey":[]}],"components":{"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer","description":"Ключ центра: tcrm_live_… (боевой) или tcrm_test_… (песочница)"}},"schemas":{"Balance":{"type":"object","properties":{"studentId":{"type":"string"},"name":{"type":"string"},"earned":{"type":"integer"},"held":{"type":"integer"},"available":{"type":"integer"}}},"Gift":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"costCoins":{"type":"integer"}}},"Redemption":{"type":"object","properties":{"id":{"type":"string"},"giftName":{"type":"string"},"costCoins":{"type":"integer"},"status":{"type":"string","enum":["REQUESTED","APPROVED","REJECTED"]},"requestedAt":{"type":"string","format":"date-time"}}},"RedeemResult":{"type":"object","properties":{"ok":{"type":"boolean"},"id":{"type":"string"},"status":{"type":"string","enum":["REQUESTED","APPROVED","REJECTED"]},"giftName":{"type":"string"},"costCoins":{"type":"integer"},"requestedAt":{"type":"string","format":"date-time"}}},"Student":{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"phone":{"type":"string","nullable":true},"status":{"type":"string","enum":["TRIAL","ACTIVE","PAUSED","GRADUATED","CHURNED"]},"enrolledAt":{"type":"string","format":"date-time"}}},"Lead":{"type":"object","properties":{"id":{"type":"string"},"fullName":{"type":"string"},"phone":{"type":"string","nullable":true},"source":{"type":"string"},"stage":{"type":"string","enum":["NEW","CONTACTED","DEFERRED","TRIAL","CONVERTED","LOST"]},"createdAt":{"type":"string","format":"date-time"}}},"Payment":{"type":"object","properties":{"id":{"type":"string"},"studentId":{"type":"string","nullable":true},"amount":{"type":"integer"},"status":{"type":"string","enum":["PENDING","COMPLETED","FAILED","REFUNDED"]},"paidAt":{"type":"string","format":"date-time","nullable":true}}},"Error":{"type":"object","description":"Единый формат ошибки. Машиночитаемый код — в message.","properties":{"statusCode":{"type":"integer"},"message":{"type":"string","example":"not_enough_coins"},"error":{"type":"string"}}}}},"tags":[{"name":"Геймификация"},{"name":"Ученики"},{"name":"Лиды"},{"name":"Оплаты"}],"paths":{"/v1/gamification/students/{studentId}/balance":{"get":{"tags":["Геймификация"],"summary":"Баланс коинов ученика","parameters":[{"name":"studentId","in":"path","required":true,"description":"ID ученика","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Баланс","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Balance"}}}},"401":{"description":"Ключ не передан или недействителен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"У ключа нет нужного права (scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Ресурс не найден в вашем центре","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Превышен лимит запросов. Заголовки Retry-After и X-RateLimit-*","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/gamification/gifts":{"get":{"tags":["Геймификация"],"summary":"Каталог подарков","responses":{"200":{"description":"Список подарков","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Gift"}}}}},"401":{"description":"Ключ не передан или недействителен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"У ключа нет нужного права (scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Ресурс не найден в вашем центре","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Превышен лимит запросов. Заголовки Retry-After и X-RateLimit-*","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/gamification/students/{studentId}/redemptions":{"get":{"tags":["Геймификация"],"summary":"История обменов (cursor-пагинация)","parameters":[{"name":"studentId","in":"path","required":true,"description":"ID ученика","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"description":"Размер страницы 1–100 (по умолчанию 50)","schema":{"type":"integer"}},{"name":"cursor","in":"query","required":false,"description":"Курсор следующей страницы (nextCursor из ответа)","schema":{"type":"string"}}],"responses":{"200":{"description":"Страница заявок","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Redemption"}},"nextCursor":{"type":"string","nullable":true}}}}}},"401":{"description":"Ключ не передан или недействителен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"У ключа нет нужного права (scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Ресурс не найден в вашем центре","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Превышен лимит запросов. Заголовки Retry-After и X-RateLimit-*","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/gamification/students/{studentId}/redeem":{"post":{"tags":["Геймификация"],"summary":"Обмен коинов на подарок","security":[{"ApiKey":[]}],"parameters":[{"name":"studentId","in":"path","required":true,"description":"ID ученика","schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Ключ идемпотентности: повтор с тем же значением вернёт тот же ответ, не создавая вторую заявку","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["giftId"],"properties":{"giftId":{"type":"string","format":"uuid"}}}}}},"responses":{"201":{"description":"Заявка создана","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedeemResult"}}}},"400":{"description":"Нарушено бизнес-правило: not_enough_coins / request_already_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Ключ не передан или недействителен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"У ключа нет нужного права (scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Ресурс не найден в вашем центре","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Idempotency-Key повторно использован с другим телом (idempotency_key_reused_with_different_body)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Превышен лимит запросов. Заголовки Retry-After и X-RateLimit-*","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/students":{"get":{"tags":["Ученики"],"summary":"Список учеников","parameters":[{"name":"limit","in":"query","required":false,"description":"Размер страницы 1–100 (по умолчанию 50)","schema":{"type":"integer"}},{"name":"cursor","in":"query","required":false,"description":"Курсор следующей страницы (nextCursor из ответа)","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Фильтр по статусу","schema":{"type":"string"}}],"responses":{"200":{"description":"Страница учеников","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Student"}},"nextCursor":{"type":"string","nullable":true}}}}}},"401":{"description":"Ключ не передан или недействителен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"У ключа нет нужного права (scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Ресурс не найден в вашем центре","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Превышен лимит запросов. Заголовки Retry-After и X-RateLimit-*","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/students/{id}":{"get":{"tags":["Ученики"],"summary":"Ученик по ID","parameters":[{"name":"id","in":"path","required":true,"description":"ID ученика","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ученик","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Student"}}}},"401":{"description":"Ключ не передан или недействителен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"У ключа нет нужного права (scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Ресурс не найден в вашем центре","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Превышен лимит запросов. Заголовки Retry-After и X-RateLimit-*","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/leads":{"get":{"tags":["Лиды"],"summary":"Список лидов","parameters":[{"name":"limit","in":"query","required":false,"description":"Размер страницы 1–100 (по умолчанию 50)","schema":{"type":"integer"}},{"name":"cursor","in":"query","required":false,"description":"Курсор следующей страницы (nextCursor из ответа)","schema":{"type":"string"}},{"name":"stage","in":"query","required":false,"description":"Фильтр по стадии","schema":{"type":"string"}}],"responses":{"200":{"description":"Страница лидов","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}},"nextCursor":{"type":"string","nullable":true}}}}}},"401":{"description":"Ключ не передан или недействителен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"У ключа нет нужного права (scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Ресурс не найден в вашем центре","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Превышен лимит запросов. Заголовки Retry-After и X-RateLimit-*","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/payments":{"get":{"tags":["Оплаты"],"summary":"Список оплат (чтение)","parameters":[{"name":"limit","in":"query","required":false,"description":"Размер страницы 1–100 (по умолчанию 50)","schema":{"type":"integer"}},{"name":"cursor","in":"query","required":false,"description":"Курсор следующей страницы (nextCursor из ответа)","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Фильтр по статусу","schema":{"type":"string"}}],"responses":{"200":{"description":"Страница оплат","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Payment"}},"nextCursor":{"type":"string","nullable":true}}}}}},"401":{"description":"Ключ не передан или недействителен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"У ключа нет нужного права (scope)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Ресурс не найден в вашем центре","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Превышен лимит запросов. Заголовки Retry-After и X-RateLimit-*","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}