- Audit date: 2026-07-17
- Documentation baseline:
ab124d9e25df - Backend baseline:
81686b34e5bc(origin/master) - Raw backend surface: 60 operations
- Published public surface: 42 operations
| Classification | Operations | Published |
|---|---|---|
| Public | 42 | 42 |
| Internal | 10 | 0 |
| Needs decision | 8 | 0 |
| Total | 60 | 42 |
Seven of the needs decision operations are the Waiting List group. The available production Business User receives 403 for both collection reads, so they remain unpublished until a positive production contract can be verified with an authorized fixture.
The engineering ratio is therefore 42 of 60. The approved public denominator is currently 42, and all 42 approved operations are published. This does not imply that all 60 registered routes are approved public APIs.
- Auth
P+U+L: Partner token, Business User token, and active Location license checks are required. Controllers may apply additional access checks. - Test
I: a route-name integration test exists at the backend baseline. - Test
N: no route-name or controller integration test was found. - Live: positive production behavior was verified during the 2026-07-15 contract audit or the 2026-07-16 canonical URL check.
- Route: only route reachability, validation behavior, or a non-positive response was verified in production.
- Source: controller, request, transformer, service, and/or UI consumer was inspected at the backend baseline.
All canonical routes below are relative to https://api.alteg.io/api/v2.
| Method | Canonical route | Backend route name | Controller | OpenAPI operation ID | Auth | Test | Evidence |
|---|---|---|---|---|---|---|---|
| GET | /locations/{location_id}/products | api_v2.company.goods.list | GoodsController::action_list | list_products | P+U+L | I | Live |
| GET | /locations/{location_id}/products/{product_id} | api_v2.company.good.read | GoodsController::action_read | get_product | P+U+L | I | Live |
| GET | /locations/{location_id}/products/{product_id}/storage_amounts | api_v2.company.good.storage_amounts.list | GoodStorageAmountsController::action_list | list_product_storage_amounts | P+U+L | I | Live |
| GET | /locations/{location_id}/products/autocomplete | api_v2.company.goods.autocomplete | GoodsAutocompleteController | autocomplete_products | P+U+L | I | Live |
| GET | /locations/{location_id}/units | api_v2.company.units.list | UnitsController::action_list | list_product_units | P+U+L | I | Live |
| GET | /locations/{location_id}/attendance_product_items/{attendance_product_item_id} | api_v2.company.attendance_good_item.read | AttendanceGoodItemsController::action_read | get_attendance_product_item | P+U+L | I | Route + Source; no safe positive fixture |
| GET | /locations/{location_id}/product_categories | api_v2.company.good_categories.list | GoodCategoriesController::action_list | list_product_categories | P+U+L | I | Live |
| GET | /locations/{location_id}/product_categories/{product_category_id} | api_v2.company.good_category.read | GoodCategoriesController::action_read | get_product_category | P+U+L | I | Live |
| GET | /locations/{location_id}/service_categories | api_v2.company.service_categories.list | ServiceCategoriesController::action_list | list_service_categories | P+U+L | I | Live |
| GET | /locations/{location_id}/services/{service_id} | api_v2.company.service.read | ServiceReadController | get_service | P+U+L | I | Live |
| GET | /locations/{location_id}/services | api_v2.company.services.list | ServicesListController | list_services | P+U+L | I | Live |
| GET | /locations/{location_id}/attendance_services | api_v2.company.attendance_services.list | AttendanceServicesController::action_list | list_attendance_services | P+U+L | I | Live |
| GET | /locations/{location_id}/composite_services/{service_id}/attendance_services | api_v2.company.composite_service.attendance_services_list | CompositeServiceAttendanceServicesListController | list_composite_service_attendance_services | P+U+L | I | Live |
| GET | /locations/{location_id}/attendance_service_suggestions | api_v2.company.attendance_service_suggestions.list | AttendanceServiceSuggestionsController::action_list | list_attendance_service_suggestions | P+U+L | N | Live |
| GET | /locations/{location_id}/resource_occupations | api_v2.company.resource_occupations.list | ResourceOccupationsListController | list_resource_occupations | P+U+L | I | Live |
| GET | /locations/{location_id}/custom_fields | api_v2.company.custom_fields.list | CustomFieldsController::action_list | list_custom_fields | P+U+L | I | Live |
| GET | /locations/{location_id}/team_members | api_v2.company.staff.list | StaffController::action_list | list_team_members | P+U+L | I | Live |
| GET | /locations/{location_id}/appointments | api_v2.company.records.list | RecordsListController | list_appointments | P+U+L | N | Live |
| GET | /locations/{location_id}/attendances/{attendance_id}/appointments | api_v2.company.attendance.records.list | AttendanceRecordsController::action_list | list_attendance_appointments | P+U+L | N | Live with record_ and visit_ identifiers |
| DELETE | /locations/{location_id}/appointments/{appointment_id} | api_v2.company.record.delete | RecordDeleteController | delete_appointment | P+U+L | I | Route + Source |
| POST | /locations/{location_id}/timetable/appointments/delete | api_v2.company.timetable.record.delete | TimetableRecordDeleteController | delete_timetable_appointment | P+U+L | N | Route + Source |
| GET | /locations/{location_id}/attendance/clients/{client_id} | api_v2.company.attendance.client.read | AttendanceClientsController::action_read | get_attendance_booking_user | P+U+L | N | Live |
| GET | /locations/{location_id}/clients/{client_id}/attendances_statistic | api_v2.company.client.attendances_statistic.read | SalonAttendancesStatisticController | get_booking_user_location_attendance_statistics | P+U+L | I | Live |
| GET | /locations/{location_id}/clients/{client_id}/chain_attendances_statistic/{chain_id} | api_v2.company.client.chain_attendances_statistic.read | ChainAttendancesStatisticController | get_booking_user_chain_attendance_statistics | P+U+L | I | Live |
| POST | /locations/{location_id}/events | api_v2.company.activities.create | ActivityController::action_create | create_event | P+U+L | I | Live |
| GET | /locations/{location_id}/events | api_v2.company.activities.list | ActivityController::action_list | list_events | P+U+L | N | Live |
| GET | /locations/{location_id}/events/{event_id} | api_v2.company.activities.read | ActivityController::action_read | get_event | P+U+L | I | Live |
| PUT | /locations/{location_id}/events/{event_id} | api_v2.company.activities.update | ActivityController::action_update | update_event | P+U+L | I | Live |
| DELETE | /locations/{location_id}/events/{event_id} | api_v2.company.activities.delete | ActivityController::action_delete | delete_event | P+U+L | I | Live |
| POST | /locations/{location_id}/events/{event_id}/appointments | api_v2.company.activities.records.create | ActivityRecordCreateController | create_event_appointment | P+U+L | I | Validation + Source |
| PUT | /locations/{location_id}/events/{event_id}/appointments/{appointment_id} | api_v2.company.activities.records.update | ActivityRecordUpdateController | update_event_appointment | P+U+L | I | Validation + Source |
| PATCH | /locations/{location_id}/events/{event_id}/appointments/{appointment_id} | api_v2.company.activities.records.reschedule | ActivityRecordRescheduleController | reschedule_event_appointment | P+U+L | N | Validation + Source |
| GET | /locations/{company_id}/tags | api_v2.company.tags.list | TagsController::action_list | list_tags | P+U+L | I | Live; /companies response identical |
| GET | /locations/{company_id}/tags/{tag_id} | api_v2.company.tags.read | TagsController::action_read | get_tag | P+U+L | I | Live |
| POST | /locations/{company_id}/tags | api_v2.company.tags.create | TagsController::action_create | create_tag | P+U+L | I | Live |
| PUT | /locations/{company_id}/tags/{tag_id} | api_v2.company.tags.update | TagsController::action_update | update_tag | P+U+L | I | Live |
| DELETE | /locations/{company_id}/tags/{tag_id} | api_v2.company.tags.delete | TagsController::action_delete | delete_tag | P+U+L | I | Live |
| GET | /locations/{company_id}/positions | api_v2.company.positions.list | PositionsController::action_list | list_positions | P+U+L | I | Live; /companies response identical |
| GET | /locations/{company_id}/positions/{position_id} | api_v2.company.positions.read | PositionsController::action_read | get_position | P+U+L | I | Live |
| POST | /locations/{company_id}/positions | api_v2.company.positions.create | PositionsController::action_create | create_position | P+U+L | I | Live |
| PUT | /locations/{company_id}/positions/{position_id} | api_v2.company.positions.update | PositionsController::action_update | update_position | P+U+L | I | Live |
| DELETE | /locations/{company_id}/positions/{position_id} | api_v2.company.positions.delete | PositionsController::action_delete | delete_position | P+U+L | I | Live |
The literal company_id parameter remains in Tags and Positions for SDK compatibility. It identifies a Location. The middleware also accepts the legacy /companies/{company_id} path alias.
| Method | Canonical route | Backend route name | Controller | Known consumer | Test | Classification and evidence |
|---|---|---|---|---|---|---|
| GET | /locations/{location_id}/attendance_services/autocomplete | api_v2.company.attendance_services.autocomplete | AttendanceServicesAutocompleteController | serviceAutocompleteApi | N | Needs decision; Source; backend marks route for deletion |
| POST | /locations/{location_id}/attendance/appointments | api_v2.company.attendance.records.update | AttendanceController | Backoffice attendance editor | I | Internal; UI-state mutation |
| GET | /locations/{location_id}/attendance/field_pins | api_v2.company.attendance.field_pin.list | UserAttendanceFieldPinsController::action_list | attendancePinItemsApi | I | Internal; per-user UI state |
| POST | /locations/{location_id}/attendance/field_pins | api_v2.company.attendance.field_pin.pin | UserAttendanceFieldPinsController::action_pin | attendancePinItemsApi | I | Internal; per-user UI state |
| DELETE | /locations/{location_id}/attendance/field_pins/{slug} | api_v2.company.attendance.field_pin.unpin | UserAttendanceFieldPinsController::action_unpin | attendancePinItemsApi | I | Internal; per-user UI state |
| PUT | /locations/{location_id}/attendance/payment_method_pins | api_v2.company.attendance.payment_method_pins.update | UserAttendancePaymentMethodPinsController::action_update | attendancePinPaymentMethodsApi | I | Internal; per-user UI state |
| GET | /locations/{location_id}/attendance/payment_method_pins | api_v2.company.attendance.payment_method_pins.list | UserAttendancePaymentMethodPinsController::action_list | attendancePinPaymentMethodsApi | I | Internal; per-user UI state |
| POST | /locations/{location_id}/comers/{client_id}/vehicles | api_v2.company.comer.vehicles.create | ComerInfoVehiclesController::action_create | comerApiV2, client and visit modals | N | Internal; backoffice-specific profile state |
| PATCH | /locations/{location_id}/comers/{comer_id}/vehicles | api_v2.company.comer.vehicles.update | ComerInfoVehiclesController::action_update | comerApiV2, client and visit modals | N | Internal; backoffice-specific profile state |
| GET | /locations/{location_id}/comers/{client_id}/vehicles | api_v2.company.comer.vehicles.list | ComerInfoVehiclesController::action_list | comerApiV2, client and visit modals | N | Internal; backoffice-specific profile state |
| DELETE | /locations/{location_id}/comers/{comer_id}/vehicles | api_v2.company.comer.vehicles.delete | ComerInfoVehiclesController::action_delete | comerApiV2, client and visit modals | N | Internal; backoffice-specific profile state |
| GET | /locations/{location_id}/waiting_list | api_v2.company.waiting_list.search | SearchWaitingListEntryController | Backoffice WaitingListApi | I | Needs decision; production 403; unregistered draft get_waiting_list_v2 exists |
| GET | /locations/{location_id}/waiting_list/count | api_v2.company.waiting_list.count | CountWaitingListEntryController | Backoffice Waiting List widget | I | Needs decision; production 403; no OpenAPI draft |
| POST | /locations/{location_id}/waiting_list | api_v2.company.waiting_list.create | CreateWaitingListEntryController | Backoffice WaitingListApi | I | Needs decision; unsafe without controlled Booking User; unregistered draft exists |
| GET | /locations/{location_id}/waiting_list/{waiting_list_entry_id} | api_v2.company.waiting_list.read | ReadWaitingListEntryController | Backoffice Waiting List editor | I | Needs decision; no safe positive fixture |
| PUT | /locations/{location_id}/waiting_list/{waiting_list_entry_id} | api_v2.company.waiting_list.update | UpdateWaitingListEntryController | Backoffice WaitingListApi | I | Needs decision; unsafe without controlled Booking User; unregistered draft exists |
| POST | /locations/{location_id}/waiting_list/{waiting_list_entry_id}/finish | api_v2.company.waiting_list.finish | FinishWaitingListEntryController | Backoffice WaitingListApi | I | Needs decision; notification/workflow safety unverified |
| DELETE | /locations/{location_id}/waiting_list/{waiting_list_entry_id} | api_v2.company.waiting_list.delete | DeleteWaitingListEntryController | Backoffice WaitingListApi | I | Needs decision; cleanup route source-verified; unregistered draft exists |
- Authenticated Tags list: canonical
/locationsand compatibility/companiesboth returned200with identical response bodies. - Authenticated Positions list: canonical
/locationsand compatibility/companiesboth returned200with identical response bodies. - Waiting List list and count: the only managed Location returned
403for both operations. No Waiting List write was attempted. - Attendance Appointments: positive
200collection responses were verified with bothrecord_{appointment_id}andvisit_{visit_id}identifiers. An invalid identifier returned422, and a missing attendance group returned404. - Attendance Booking User: positive
200item responses were verified for several Booking User profiles without retaining personal data. The base response returned theclientresource type and an emptymetaarray. - Product Units returned
200with 38 JSON:APIunitresources. - Attendance Services returned
200; a composite Service fixture was then used to verify its component Attendance Services with another200. - Resource Occupations, Attendance Service Suggestions, and Appointment Custom Fields returned
200with deterministic empty collections for safe fixtures. - Booking User Location and Chain attendance statistics returned
200item responses with the expected JSON:API resource types and deposit relationship. - No production data was created, updated, deleted, or included in this file.
Waiting List coverage requires a Business User and Location with positive read access. Publishing list and count then requires observed 200 shapes and a passing read-only Arazzo workflow. Its remaining five operations additionally require a controlled Booking User, notification safety, and guaranteed cleanup.
The other remaining read candidate requires a decision on the autocomplete route that the backend marks for deletion.