Більшість бізнес-сутностей мають життєвий цикл: замовлення (нове → оплачене → відправлене → доставлене / скасоване), стаття (чернетка → на модерації → опублікована), заявка, платіж. API має відображати цей цикл явно.
1. Поле стану - перелічення з документованими значеннями:
{ "id": 42, "state": "paid", "paid_at": "2026-10-04T07:15:00Z" }
Не набір булевих прапорців (is_paid, is_shipped, is_cancelled) - вони допускають неможливі комбінації.
2. Стан змінюють не напряму, а через дії:
PATCH /orders/42 {"state": "shipped"} # погано: обходить правила
POST /orders/42/ship {"tracking": "UA123"} # добре: явний перехід з даними
Google AIP-216 радить робити поле стану лише для читання (output only) і змінювати його власними методами. Тоді:
- кожен перехід має свої параметри (трек-номер при відправці, причина при скасуванні);
- свої права (скасувати може клієнт, відправити - лише склад);
- свої побічні ефекти (лист, повернення коштів) - у явному місці коду.
3. Недопустимий перехід - явна помилка:
POST /orders/42/cancel
409 Conflict
{ "type": "/problems/invalid-state-transition", "title": "Замовлення вже відправлено", "current_state": "shipped" }
4. Клієнт має знати, що дозволено зараз:
{ "state": "paid", "allowed_actions": ["ship", "refund"] }
Інтерфейс показує кнопки за цим списком - логіку переходів не дублюють на клієнтах.
5. Історія переходів - окремий ресурс (GET /orders/42/events): хто, коли, з якого стану в який. Потрібна для підтримки, аудиту й спорів.
6. Конкурентні переходи: два запити «скасувати» й «відправити» одночасно. На сервері - перевірка поточного стану атомарно (UPDATE ... WHERE state = 'paid' чи блокування рядка), а в API - оптимістичне блокування через If-Match/версію.
7. Нові стани - зміна, що може зламати клієнтів: клієнт з switch по відомих станах не знає, що робити з новим. Документуйте, що перелік може розширюватися, і вимагайте від клієнтів обробки невідомих значень.
На бекенді Laravel це зручно оформити енумом стану з методом canTransitionTo() або пакетом станів (spatie/laravel-model-states), а дії - окремими класами-actions, на які спираються контролери.