Документ для заказчика (Пицца Венчур, КЦ Сыктывкар — интеграция из 1С по API YouDo). Формат: по слайдам, каждый шаг описан с трёх сторон — что делаете вы, что в этот момент делает YouDo, что видит исполнитель.
Сейчас по 35-му протоколу ФНС на каждую выплату исполнителю формируется отдельный документ «Задание», который исполнитель обязан подписать до начала работ. При еженедельных (и чаще) выплатах это значит: исполнитель подписывает документы на каждую выплату — операционно неподъёмно и ломает ваш процесс в 1С.
Новая механика: один рамочный договор на период + один документ «Задание» к нему. Исполнитель подписывает один раз за период, одной кнопкой. Все выплаты внутри периода создаются по API сразу готовыми к оплате — без каких-либо действий исполнителя, в том числе задним числом после окончания периода.
Требование ФНС при этом соблюдается: задание подписано до начала работ — просто теперь оно одно на весь период, а не на каждую выплату.
| Термин | Что это | Где встречается |
|---|---|---|
| Рамка / рамочный договор | Договор с самозанятым на период (неделя/две/месяц — по шаблону проекта). Подписывается исполнителем один раз | POST /frameworkagreements |
| Документ «Задание» | PDF-документ к рамке: период, условия, цена, объём услуг. Подписывается вместе с договором одной кнопкой | taskDocumentId в ответах API |
| Выплата (контракт) | Сущность оплаты: к ней привязан акт и сам платёж. Создаётся вами по API внутри рамки | POST /task/internal — ⚠️ в URL исторически слово task, но это именно выплата, не документ |
| Акт | Закрывающий документ по факту выполненных работ. Формируется по существующей механике, тут ничего не меняется | — |
| «Не подтверждено в срок» | Терминальный статус рамки, которую исполнитель не подписал вовремя. В интерфейсах может отображаться как «Срок истёк» | state: expired |
⚠️ Не путать: эндпоинт /task/internal создаёт выплату; документ «Задание» — это PDF при рамке; раздел «Задания» в кабинете исполнителя — это список его выплат. Три разные вещи, одно слово. В этом документе мы везде пишем «выплата» и «документ „Задание“», чтобы не смешивать.
ВЫ (1С) ──────── REST API ────────► YouDo
создать рамку, изменить условия,
создать выплату, узнать статусы,
скачать PDF
ВЫ (1С) ◄──────── вебхуки ───────── YouDo
«исполнитель подписал»,
«рамка не подписана в срок»
ВЫ (1С) ◄───────── ничего ───────── YouDo
мы НЕ ходим в вашу 1С, ничего из неё
не читаем и не пишем
Ключевое отличие от интеграции по Dodo IS: там YouDo опрашивает API Додо. Здесь наоборот — вся инициатива на вашей стороне. Данные о сменах, суммах, расчётах живут в вашей 1С; вы вызываете наши API тогда, когда вам нужно. Мы ваши суммы не пересчитываем и не корректируем.
В вашу сторону мы отправляем только вебхуки (HTTP-уведомления на ваш URL) о событиях с рамками — подписка настраивается один раз через POST /api/v1/webhook/Subscribe. Вебхуки — это ускорение, не единственный канал: те же статусы всегда можно забрать опросом GET-метода (слайд 9).
┌─────────────────────────────────────────────────┐
создали по API │ │
▼ ▼ │
┌────────────────┐ подписал до конца ┌──────────┐ период ┌─────────┐
│ readyToSign │ 1-го дня периода │ signed │ кончился │ ended │
│ (ждёт подписи) ├──────────────────────►│(действует├───────────►│(закончи-│
└───────┬────────┘ │ ) │ │ лась) │
│ не подписал в срок └──────────┘ └─────────┘
▼ Выплаты можно создавать в signed
┌────────────────┐ и в ended (задним числом).
│ expired │ терминальный статус.
│(не подтверждено│ Подписать нельзя. Выплаты в неё — нельзя.
│ в срок) │ Лечится созданием новой рамки.
└────────────────┘
Правила, которые стоит зафиксировать у себя:
start + срок из шаблона проекта) и не сдвигаются при подписании. Исполнитель подписал вечером 1-го числа рамку «с 1-го» — период остался «с 1-го», а не «со 2-го». Именно это позволяет рамкам идти встык.ended ≠ расторжение. Окончание периода — это просто окончание периода: договор не расторгается, уведомления о расторжении не отправляются, задним числом в него можно создавать выплаты.readyToSign — выплаты в её период создать нельзя (ошибка). Никакого «создастся и подождёт подписания».| Когда | Вы (1С) | YouDo | Исполнитель |
|---|---|---|---|
| ~29–30 июля | POST /frameworkagreements — рамка на август |
Генерирует PDF договора и задания, шлёт исполнителю SMS/TG со ссылкой | Получает ссылку |
| 30 июля – 1 августа | Ждёте вебхук / опрашиваете статус | — | Нажимает «Подписать» — одна кнопка на договор + задание |
| момент подписания | ◄ вебхук FrameworkAgreementAccept |
Фиксирует подпись | Больше в августе не делает ничего |
| весь август | POST /task/internal — выплаты по вашему графику (день-в-день, еженедельно — как удобно) |
Находит рамку по датам, создаёт выплату сразу «выполняется», дальше акты/оплата | Получает деньги, документы появляются в кабинете сами |
| ~29–30 августа | Рамка на сентябрь (августовская продолжает работать) | … | Подписывает сентябрьскую |
| начало сентября | Досоздаёте выплаты за август задним числом | Пропускает: попадание в августовскую рамку по датам — этого достаточно | — |
POST /api/v1/frameworkagreements
Тело запроса:
| Поле | Тип | Обяз. | Что это |
|---|---|---|---|
projectId |
int | да | Ваш проект в YouDo |
employeeId |
int | да | Исполнитель |
start |
date | да* | Дата начала периода. Конец = start + срок из шаблона проекта |
taskPrice |
decimal | нет | Цена в документе «Задание» |
taskTitle |
string | нет | Название задания |
taskDescription |
string | нет | Описание работ |
taskAddress |
string | нет | Адрес |
itemsCount |
decimal | нет | Плановый объём услуг |
itemsUnit |
string | нет | Единицы измерения объёма |
Не переданные условия задания подставляются из шаблона проекта. Исключение — itemsCount/itemsUnit: в шаблоне их нет, хотите объём в задании — передавайте явно. Имена полей совпадают с полями POST /task/internal, чтобы в 1С можно было переиспользовать маппинг.
Про срок периода: длина периода (term_days) настраивается в шаблоне вашего проекта на нашей стороне. Через API она не задаётся — это осознанное решение (меньше валидаций и краевых случаев). Хотите неделю вместо месяца или разные сроки на разных проектах — говорите нам, меняем в шаблоне. Вы и так приходите к нам при смене тарифов — это тот же процесс.
Ответ: frameworkAgreementId + taskDocumentId — id PDF-документа «Задание» (скачивание — слайд 12).
Что происходит у нас в фоне после ответа:
Ошибки создания:
| Код | Когда | Что делать |
|---|---|---|
| 400 «Период пересекается с существующей рамкой (Id: N)» | Новый период задевает уже существующую рамку исполнителя | Проверить даты; рамки должны идти встык, без нахлёста |
| стандартные 400/404 | Неверный исполнитель/проект и т.п. | Как в остальных методах API |
Пересечение с рамкой в статусе expired ошибкой не считается — протухшая рамка не блокирует создание новой на тот же период.
Опубликовали рамку, а условия поменялись (тариф, объём, адрес)? Пока исполнитель не подписал — условия можно заменить:
PUT /api/v1/frameworkagreements/{agreementId}/task
Тело: тот же набор полей условий (taskPrice, taskTitle, taskDescription, taskAddress, itemsCount, itemsUnit) — полная замена, не патч. Отсутствующие поля — из шаблона проекта.
Что делает YouDo: перегенерирует PDF задания, обновляет опубликованные данные. Ответ: актуальный taskDocumentId (id документа может смениться — сохраняйте новый).
Ошибки:
| Код | Когда |
|---|---|
| 400 | Рамка уже подписана / не подтверждена в срок / завершена / расторгнута — редактирование только до подписания |
| 404 | Рамка не найдена или из чужого проекта |
После подписания условия задания не меняются никогда. Расхождение плана с фактом закрывается актами — это штатная ситуация (слайд 15).
Окно подписания: от момента получения до конца первого дня периода включительно.
expired.Что видите вы в момент подписания: вебхук FrameworkAgreementAccept (существующий тип, уже знакомый интеграциям). С этого момента можно создавать выплаты в период рамки.
Что делает YouDo: фоновый процесс переводит рамку в статус «Не подтверждено в срок» (expired). Статус терминальный: подписать эту рамку уже невозможно, выплаты в неё создать нельзя.
Что получаете вы:
FrameworkAgreementExpired (новый тип; добавьте его в подписку через POST /api/v1/webhook/Subscribe):{
"frameworkAgreementId": 123,
"employeeId": 456,
"projectId": 789,
"state": "expired"
}
GET /api/v1/frameworkagreements/employees/{employeeId}/projects/{projectId}
В ответе по каждой рамке: agreementStartDate (начало периода), agreementEndDate (конец), даты подписания и state: readyToSign | signed | expired | ended | terminated, плюс taskDocumentId.
Что делаете вы: создаёте новую рамку обычным POST /frameworkagreements — на тот же период или сдвинутый. Исполнителю снова уходит ссылка, подписывает заново.
⚠️ Практическое следствие: пока висит expired и вы не пересоздали рамку — выплаты за эти дни провести нельзя. Рекомендуем в 1С обрабатывать вебхук FrameworkAgreementExpired как сигнал к немедленному пересозданию, а не разбирать раз в неделю: чем быстрее новая рамка подписана, тем меньше дней «зависает» (потом их можно закрыть задним числом — но только после подписания новой рамки, покрывающей эти даты... нет — см. FAQ, вопрос 4).
POST /api/v1/task/internal
(метод существующий — тот же, которым выплаты создаются сегодня; меняется только поведение для вашего проекта)
Ключевые поля (остальной контракт — без изменений):
| Поле | Обяз. | Роль в новой механике |
|---|---|---|
employeeId |
да | Исполнитель |
taskStarts |
да | Начало периода работ по этой выплате |
taskEnds |
да | Конец периода работ. По этим двум датам мы сами находим рамку — поля «id рамки» в запросе нет и не нужно |
| сумма, описание и пр. | как сейчас | Без изменений |
хидер Idempotency-Key |
рекомендуем | Защита от дублей при ретраях из 1С: повторный запрос с тем же ключом не создаст вторую выплату |
Что делает YouDo при получении запроса:
taskStarts..taskEnds. Рамка может быть действующей (signed) или уже завершённой (ended) — задним числом можно.Ошибки привязки (обе — 400 с внятным текстом):
| Ошибка | Причина | Что делать в 1С |
|---|---|---|
| «Нет подписанного рамочного договора, покрывающего период задания» | Даты не попадают ни в одну рамку, либо рамка есть, но readyToSign/expired |
Проверить статус рамки (GET / вебхуки); если не подписана — дождаться подписания или пересоздать; выплату повторить после |
| «Период задания пересекает границу рамочных договоров N и M — разделите на две выплаты» | Интервал работ лежит в двух рамках | Разбить платёж на две выплаты по границе рамок (слайд 11) |
Ошибка ничего не ломает и ничего не создаёт — просто повторяете запрос с исправленными датами. Прежний запрет «дата начала не может быть раньше текущего дня» в этом режиме не действует — backdated разрешён.
Пример. Рамки исполнителя: «1–31 июля» и «1–31 августа». Вы платите еженедельно и хотите закрыть неделю 28.07–03.08.
июльская рамка │ августовская рамка
──────────────────────│──────────────────────
28.07 ━━━━━━━━━━━┿━━━━━━━━ 03.08 ← одним запросом: 400, ошибка
28.07 ━━━━━━━━━━━┥ ← выплата №1: taskStarts=28.07, taskEnds=31.07
┝━━━━━━━━ 03.08 ← выплата №2: taskStarts=01.08, taskEnds=03.08
Почему так, а не «привяжем к какой-нибудь»: каждая выплата и её акт должны юридически лежать внутри конкретного договора. Выплата, размазанная по двум договорам, — это ровно то, к чему у ФНС появляются вопросы. Поэтому мы валидируем жёстко, а деление на две выплаты — ваша сторона (вы знаете, какая часть суммы к какой неделе относится, мы — нет).
Рекомендация для 1С: заложить деление по границе рамок прямо в генерацию платежей — граница всегда известна заранее (это даты рамок, которые вы сами и создали).
PDF-документов в механике два (на рамку): договор и документ «Задание». Акты — по существующей механике, без изменений.
Вам (по API):
| Что | Как |
|---|---|
| PDF договора / PDF задания | GET /api/v1/documents/{documentId} — существующий метод |
| Откуда взять id | taskDocumentId — из ответа создания/редактирования рамки и из GET /frameworkagreements/...; id договора — там же |
Вам (в кабинете компании): документ «Задание» появляется в общем разделе «Документы» автоматически, рядом с договором; также доступен из блока рамочных договоров в карточке исполнителя.
Исполнителю (в его кабинете):
Для проверок ФНС это значит: у исполнителя и у вас на руках одинаковый комплект — договор + задание на период + акты по фактическим выплатам.
У исполнителя может одновременно существовать несколько рамок: действующая + будущая (отправленная заранее). Отправка будущей не останавливает текущую. Ограничение одно: периоды не пересекаются (встык — можно и нужно).
Рекомендуемый регламент для 1С (на примере месячных периодов):
| День | Действие |
|---|---|
| ~за 2 дня до конца периода | POST /frameworkagreements на следующий период (start = первый день следующего периода) |
| сразу после | Исполнитель получает ссылку и подписывает будущую рамку заранее — текущая продолжает работать |
| до конца 1-го дня нового периода | Контроль: пришёл ли FrameworkAgreementAccept по новой рамке. Не пришёл — ждём FrameworkAgreementExpired и пересоздаём |
| весь период | Выплаты создаются с датами работ — попадание в нужную рамку автоматическое, думать не нужно |
Почему «за 2 дня», а не раньше/позже: раньше — исполнитель забудет про ссылку; позже — рискуете не успеть до дедлайна первого дня. Двое суток — практический баланс, но это ваш регламент, технических ограничений на «за сколько дней» нет.
Вы дёргаете нас:
| Задача | Метод | Комментарий |
|---|---|---|
| Создать рамку + задание | POST /api/v1/frameworkagreements |
+ условия задания в теле; ответ содержит taskDocumentId |
| Изменить условия до подписания | PUT /api/v1/frameworkagreements/{id}/task |
Полная замена условий; после подписания — 400 |
| Статусы рамок исполнителя | GET /api/v1/frameworkagreements/employees/{employeeId}/projects/{projectId} |
state, даты периода, дата подписания, taskDocumentId |
| Создать выплату | POST /api/v1/task/internal |
Обязательные taskStarts/taskEnds; рамка ищется по датам; Idempotency-Key |
| Скачать PDF (договор, задание) | GET /api/v1/documents/{documentId} |
Существующий метод |
| Подписаться на события | POST /api/v1/webhook/Subscribe |
Один раз при настройке |
Мы дёргаем вас (вебхуки на ваш URL):
| Событие | Тип | Когда | Ваша реакция |
|---|---|---|---|
| Исполнитель подписал рамку | FrameworkAgreementAccept (существующий) |
В момент подписания | Открыть создание выплат по периоду |
| Рамка не подписана в срок | FrameworkAgreementExpired (новый) |
После дедлайна первого дня | Создать новую рамку |
Авторизация, форматы ошибок, идемпотентность — как во всех остальных методах нашего API; отдельной авторизации для этой механики нет. Всё включается на уровне вашего проекта: для других ваших процессов и других клиентов YouDo поведение API не меняется.
1. Можно ли в одной рамке несколько документов «Задание» (например, рамка на квартал + задания помесячно)? Нет. Одна рамка = одно задание = одна подпись. Нужен другой шаг периодичности — делаем короче саму рамку (настройка шаблона).
2. Можно ли задать разный срок рамки для разных проектов? Да: срок — настройка шаблона per-проект. Один проект — две недели, другой — месяц. Меняется через нас.
3. Исполнитель подписал рамку в первый день вечером, а смена была утром — законно? Да, правило «подписать до конца первого дня включительно» согласовано юристами именно под это.
4. Рамка протухла (expired), мы пересоздали, исполнитель подписал новую. Можно ли заплатить за первые дни периода?
Выплата должна попадать в период подписанной рамки. Пересоздать рамку можно на тот же период — тогда после подписания новой рамки выплата за первые дни попадёт в неё. Если пересоздаёте со сдвинутым стартом — дни до старта новой рамки не покрыты ни одной подписанной рамкой, и выплату за них провести нельзя. Точная механика дедлайна подписания для пересозданной рамки (период которой уже начался) фиксируется в ТЗ — но практический вывод в любом случае один: пересоздавайте тем же периодом и добивайтесь подписания быстро.
5. Как понять, к какой рамке привязалась выплата?
Привязка детерминирована датами: рамка, чей период покрывает taskStarts..taskEnds. Периоды рамок не пересекаются, значит подходящая рамка всегда ровно одна (или ноль — тогда ошибка, выплата не создаётся).
6. Что будет, если отправить выплату до того, как исполнитель подписал будущую рамку?
Ошибка 400 «нет подписанного рамочного договора». Выплата не создаётся и не «зависает в ожидании» — повторите запрос после подписания (сигнал — вебхук FrameworkAgreementAccept).
7. Уведомляется ли исполнитель о каждой выплате? Выплаты приходят исполнителю без каких-либо действий с его стороны; документы появляются в кабинете автоматически. Никаких подписаний на выплату нет — в этом весь смысл механики.
8. Что происходит с договором по окончании периода? Придёт ли исполнителю «договор расторгнут»?
Нет. Окончание периода — не расторжение: статус становится ended, уведомления о расторжении не отправляются, задним числом в рамку можно платить.
9. Мы уже работаем по 35-му протоколу. Что произойдёт с текущими выплатами при переключении? Переключение — на уровне проекта, делаем мы. Уже созданные выплаты со своими по-контрактными заданиями доживают по старым правилам (протухание, оплата — всё работает). Новые рамки и выплаты после переключения идут по новой механике. Совмещать оба режима на одном проекте нельзя.
10. Есть ли пакетное создание (реестры) для этой механики?
Нет, в этой итерации — только поштучные вызовы API. При еженедельной пачке выплат — просто серия POST /task/internal (с Idempotency-Key на каждый).
11. Можно ли расторгнуть рамку досрочно (исполнитель уволился)? Существующая механика остановки договора сохраняется. Нюанс: по расторгнутой рамке выплаты блокируются — закройте долги по выплатам до расторжения.
YouDo:
readyToSign/signed/expired/ended по API; вебхуки Accept/Expired;Вы (1С):
Accept → открываем выплаты, Expired → пересоздаём рамку;Idempotency-Key на создании;Ваши исполнители: