← Workday.Money

API Workday.Money

Почасовой учёт заработка из вашей программы: проекты и ставки, запуск и остановка работы, завершение задачи с записью в отчёт.

Автор — Дмитрий Деулин, основатель Workday.Money. Вопросы: [email protected].

Договор в машиночитаемом виде — openapi.yaml, OpenAPI 3.1.

Основное

Величины Деньги — строка с двумя знаками («112.50») и поле currency рядом. Суммы разных валют не складываются: итоги приходят списком по валютам. Время — целые секунды, поля *_seconds. Даты работы — ГГГГ-ММ-ДД, моменты времени — ISO 8601 с Z.
Часовой пояс Обязателен для всех запросов, которые пишут: timezone (Europe/Kyiv) или utc_offset_minutes. Если пояс не передан и не сохранён у аккаунта — 400 timezone_required.
Ответы Успех — {"data": …, "warnings": […]}, отказ — {"error": {…}}. Поле warnings присутствует всегда.
Ограничения Запись задним числом недоступна. Записанный отрезок не изменяется и не удаляется. Время незавершённой задачи можно только уменьшить. Проект архивируется, но не удаляется.

Ключ

Выдаётся в приложении: меню → AI-агент и APIСоздать ключ. Показывается один раз. Ключей можно завести несколько и отзывать по отдельности. Передаётся заголовком Authorization.

curl https://api.workday.money/v1/me \
  -H "Authorization: Bearer wdm_live_ВАШ_КЛЮЧ"
{
  "data": {
    "account_id": "acc_9f2b7c1d4e0a",
    "email": "[email protected]",
    "plan": "free",
    "project_limit": 1,
    "projects_used": 1,
    "timezone_known": true,
    "scopes": ["work.read", "work.write", "projects.read", "projects.write"]
  },
  "warnings": []
}

Работа

post /v1/work/start Создаёт задачу и запускает отсчёт. Отсчёт идёт по часам сервера.
curl -X POST https://api.workday.money/v1/work/start \
  -H "Authorization: Bearer wdm_live_ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
        "project_id": "3Kq1xYt0aB",
        "title": "Разбор выгрузки",
        "limit_seconds": 7200,
        "timezone": "Europe/Kyiv"
      }'
{
  "data": {
    "task": {
      "id": "0c1b7f22-9a44-4f1e-8c2d-7b3a1e5d0f88",
      "project_id": "3Kq1xYt0aB",
      "title": "Разбор выгрузки",
      "state": "running",
      "earned": "0.00",
      "currency": "USD",
      "elapsed_seconds": 0,
      "limit_seconds": 7200,
      "started_at": "2026-08-12T08:41:02Z"
    }
  },
  "warnings": []
}

Повтор с тем же названием в том же проекте возвращает существующую задачу с предупреждением task_exists.

Поле on_running задаёт поведение, если другая задача уже идёт: allow (по умолчанию), pause_others, reject.

post /v1/work/pause Останавливает отсчёт без записи. Накопленное время остаётся у задачи.
curl -X POST https://api.workday.money/v1/work/pause \
  -H "Authorization: Bearer wdm_live_ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{"task_id": "0c1b7f22-9a44-4f1e-8c2d-7b3a1e5d0f88", "timezone": "Europe/Kyiv"}'

Остановить все задачи — {"all": true}.

post /v1/work/finish Записывает работу и удаляет задачу из незавершённых. Отменить нельзя.

Заголовок Idempotency-Key обязателен. Повтор с тем же ключом возвращает прежний ответ без повторной записи. Ключ хранится 90 дней.

curl -X POST https://api.workday.money/v1/work/finish \
  -H "Authorization: Bearer wdm_live_ВАШ_КЛЮЧ" \
  -H "Idempotency-Key: 2f1c9d5a-4b7e-4a0f-9c31-1e6f0a2b7c34" \
  -H "Content-Type: application/json" \
  -d '{"task_id": "0c1b7f22-9a44-4f1e-8c2d-7b3a1e5d0f88", "timezone": "Europe/Kyiv"}'
{
  "data": {
    "finished": {
      "task_id": "0c1b7f22-9a44-4f1e-8c2d-7b3a1e5d0f88",
      "project_id": "3Kq1xYt0aB",
      "earned": "45.00",
      "currency": "USD",
      "billable_seconds": 3600,
      "actual_seconds": 3720,
      "entries": [
        {
          "id": "0c1b7f22-9a44-4f1e-8c2d-7b3a1e5d0f88_2026-08-12",
          "work_date": "2026-08-12",
          "earned": "45.00",
          "currency": "USD",
          "billable_seconds": 3600,
          "actual_seconds": 3720
        }
      ]
    }
  },
  "warnings": []
}

Записывается по одному отрезку на каждый календарный день работы. Если к проекту подключена таблица и строка в неё не записана, в warnings приходит sheet_not_written с перечнем entry_ids; повторная отправка строки не выполняется.

post /v1/work/{task_id}/trim Задаёт итоговое время незавершённой задачи.
curl -X POST https://api.workday.money/v1/work/0c1b7f22…/trim \
  -H "Authorization: Bearer wdm_live_ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{"remaining_seconds": 1800}'

Значение должно быть меньше текущего: увеличение недоступно (409 trim_not_downward). Задача должна быть остановлена (409 task_running).

patch /v1/work/{task_id} Лимит оплачиваемого времени и отметка «без оплаты».
curl -X PATCH https://api.workday.money/v1/work/0c1b7f22… \
  -H "Authorization: Bearer wdm_live_ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{"limit_seconds": 0, "unpaid": true}'

Время сверх лимита записывается, но не оплачивается. limit_seconds: 0 снимает лимит. При unpaid время учитывается, стоимость равна нулю.

get /v1/work Незавершённые задачи: идущие, приостановленные, заведённые.

Фильтры: state=running|paused|all, project_id.

Проекты

get /v1/projects Список проектов.

Фильтр state=active|archived|all, по умолчанию active.

post /v1/projects Заводит проект.
curl -X POST https://api.workday.money/v1/projects \
  -H "Authorization: Bearer wdm_live_ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "Acme — интеграция",
        "rate": "45.00",
        "currency": "USD",
        "report": { "period": "month" },
        "timezone": "Europe/Kyiv"
      }'

Повтор с тем же названием возвращает существующий проект с предупреждением project_exists.

patch /v1/projects/{project_id} Название, ставка, валюта, вид отчётности, архив.

Новая ставка применяется к работе, записанной после изменения; стоимость записанных отрезков не меняется. Архивирование и возврат — поле state. Удаление проекта через API недоступно: DELETE отвечает 405.

Отчёты

get /v1/today Итоги дня по проектам и валютам.

Параметры: date, timezone.

get /v1/report Записанная работа за период.
curl "https://api.workday.money/v1/report?from=2026-08-01&to=2026-08-12&project_id=3Kq1xYt0aB" \
  -H "Authorization: Bearer wdm_live_ВАШ_КЛЮЧ"

Постранично: limit до 1000, следующая страница — по next_cursor из ответа.

Ошибки

Разбирайте отказы по полю code. Поле message — пояснение на английском, может изменяться. retryable показывает, имеет ли смысл повтор.

{
  "error": {
    "code": "plan_limit",
    "message": "Project limit reached for this plan",
    "details": { "plan": "free", "project_limit": 1, "projects_used": 1 },
    "retryable": false,
    "doc": "https://workday.money/api/errors#plan_limit",
    "request_id": "req_01J8ZK7QB2V8Y"
  }
}
HTTPcodeУсловие
400timezone_requiredПишущий запрос без пояса, у аккаунта пояс не сохранён
400unknown_fieldПоле, не описанное в v1
400idempotency_key_requiredЗавершение без заголовка Idempotency-Key
401key_unknownКлюч не распознан
403plan_limitДостигнут предел числа проектов
404task_not_foundНезавершённой задачи с таким идентификатором нет
405method_not_allowedМетод не поддерживается для этого пути
409trim_not_downwardЗапрошено увеличение времени
409state_conflictСостояние изменено другим клиентом
429rate_limitedПревышена частота запросов

Не входит в v1

Помощник вместо кода

Тот же учёт доступен ИИ-ассистенту напрямую, командами на естественном языке: подключение AI-агента по MCP.

Договор: openapi.yaml. Вопросы: [email protected].