# Zapazime Mobile App API Documentation
## Overview
This document provides comprehensive API documentation for the Zapazime mobile application designed for B2C (Business-to-Consumer) clients. The mobile app allows users to discover venues, make bookings, manage reservations, and handle payments through a seamless mobile experience.
**Base URL:** `https://api.zapazime.bg`
**API Version:** v1.24.0
**Content-Type:** `application/json`
> **Current-contract rule:** Only endpoints in the functional sections below and in the Pages & Endpoints Reference are supported mobile integration operations. Older changelog entries are historical and may describe retired proposals; they must not be used as an endpoint catalog.
**Related Documentation:**
- [Mobile App Pages & Endpoints Reference](./MOBILE_APP_PAGES_ENDPOINTS_REFERENCE.md) - Complete mapping of mobile app screens to required API endpoints for implementation
- [Notification Inventory](/NOTIFICATION_INVENTORY.md) - Complete inventory of all system notifications, recipients, and trigger conditions
---
## Changelog
### Version 1.24.0 (September 16, 2026)
- Hardened ESTI/RegiX readiness and diagnostics:
- `GET /api/esti/configuration` reports RegiX as configured only when the accommodation UIN, HTTPS endpoint, consumer OID, certificate path/password and certificate file are present.
- `GET /api/esti/regix/test-connection` now loads the configured WSDL and returns success only when `SendInfoForAccomodationRegister` is advertised; it does not submit guest data.
- RegiX operational logs use a non-sensitive request ID and no longer log guest payloads or raw SOAP messages.
- ESTI exports remain restricted to stays whose checkout is completed.
- Manual CSV generation enforces the official 19-column order, semicolon delimiter, UTF-8 BOM, ESTI date/decimal formats, mandatory identity fields, field lengths and `NEW`/`UPD`/`DEL` codes. Booking CSV endpoints also require a completed stay checkout.
### Version 1.23.0 (September 16, 2026)
- Security hardening of company-admin mutation endpoints:
- `POST /api/company-admin/bookings/{booking}/check-out` now runs the atomic `CheckOutService` workflow (stay row lock, folio/balance validation with override reasons, room-assignment closure, key return, room marked dirty, housekeeping task creation). Bookings without an active stay record fall back to a guarded transactional status update.
- `GET`/`PUT /api/company-admin/housekeeping/tasks*` moved from `company.portal` to the `housekeeping.tasks` capability and are scoped to the canonical active company resolved via `BillingCompany` (not the legacy `users.company_id`).
- `POST /api/company-admin/bookings/{booking}/cancel` moved from `company.portal` to the `booking.manage` capability.
- `POST`/`PUT /api/company-admin/clients*` moved from `company.portal` to `company.manage_bookings`; `PUT /api/company-admin/clients/{client}` is now validated (`name`, `email`, `phone`, `address`) instead of mass-assigning the raw request body.
- Inventory, product, service, and package create/update mutations (`POST /inventory`, `POST .../update-stock`, `POST`/`PUT /products`, `POST /services`, `POST`/`PUT /packages`) moved from `company.portal` to `company.manage_workspaces`.
### Version 1.22.0 (September 13, 2026)
- Fixed company-admin contract mismatches reported by the mobile team:
- Inventory: `GET /api/company-admin/inventory` now eager-loads the canonical `inventories` relation (was `inventory_locations`). `POST /api/company-admin/inventory` accepts the Amenity schema (`name`, `sku`, `category`, `unit`, `cost_per_unit`, `description`, `supplier`, `supplier_contact`, `lead_time_days`, `is_perishable`, `expiration_date`, `active`) plus optional initial stock fields (`initial_quantity`, `minimum_threshold`, `maximum_capacity`, `reorder_quantity`, `venue_id`, `venue_object_id`, `location`) which create an `AmenityInventory` record. `total_stock` is removed.
- `POST /api/company-admin/inventory/inventory/{inventory}/update-stock` body is `{ "quantity": <int> }` mapped to `current_quantity` on `AmenityInventory`, with company-ownership enforcement.
- Products: `POST`/`PUT /api/company-admin/products` now use the Product model schema (`name`, `description`, `price`, `sale_price`, `cost`, `quantity`, `product_type`, `currency`, `vat_class_id`, `image`, `is_active`, `stock_management`, `sku`). The unsupported `category` field was removed; `PUT` is now validated instead of mass-assigning the raw request.
- Packages: `POST`/`PUT /api/company-admin/packages` share one canonical schema (`name`, `description`, `type`, `total_price`, `original_price`, `percentage_discount`, `duration_nights`, `duration_minutes`, `max_guests`, `currency`, `vat_class_id`, `is_active`, `is_featured`, `sort_order`, `features`, `includes`, `excludes`, `image_path`, `gallery`, `available_from`, `available_until`, `availability_days`, `advance_booking_days`, `terms_conditions`). Legacy `price`/`category`/`duration` fields were removed.
- Documents: `POST /api/company-admin/documents` now writes the encrypted `Document` model (`document_type`, `encrypted_file_path`, `encrypted_file_name`, `encrypted_file_type`, `file_size`, `encrypted_description`, `encrypted_tags`, `access_level`, `is_public`, `expires_at`, `created_by`) storing files on the private `secure` disk. `DELETE` removes the decrypted file from the `secure` disk and remains behind the `company.manage_workspaces` capability.
- Added housekeeping task endpoints for company admins:
- `GET /api/company-admin/housekeeping/tasks` - List housekeeping tasks (filters: `status`, `venue_id`, `assigned_to`)
- `PUT /api/company-admin/housekeeping/tasks/{task}` - Update a housekeeping task (status transitions set `completed_at` automatically)
### Version 1.21.0 (September 11, 2026)
- Added department-based access scoping for company employees: each employee can belong to multiple departments, and each department grants a set of `company-admin.{resource}.{action}` permission patterns.
- Effective access is now the intersection of subscription plan entitlements, role permissions, and department permissions; owner/admin/company_manager roles remain unrestricted.
- The auth `access` context now includes a `departments` array (id, name, slug) and returns `capabilities` filtered through the department layer.
### Version 1.20.0 (September 10, 2026)
- Added public deal listing/detail endpoints for website and mobile presentation.
- Added company-admin deal catalog, CRUD, image upload, and publish-toggle endpoints.
- Confirmed and documented the public popular-destinations and recommended-venues endpoints for the mobile home screen, with validated filters and limits.
- Expanded the mobile screen reference with initial-screen composition, public and admin Deals flows, POS flow notes, and one screen per non-Filament settings group.
### Version 1.19.0 (September 10, 2026)
- Expanded the company-admin settings API to cover every tab in the non-Filament settings screen.
- Added dedicated profile, logo, regional, venue, ESTI, and cancellation operations.
- Added validated read/write access for booking, financial, notification, discount, POS, policy, and PWA settings; stored secrets are never returned.
### Version 1.18.0 (September 10, 2026)
- Added bearer-token endpoints for the native Point of Sale module: catalog, paginated order history, order detail, and order creation.
- Kept native POS operations separate from myPOS online payments, myPOS cash-register integration, and company fiscal-device operations.
- Added company isolation, POS-settings enforcement, inventory updates, and room-folio posting to the mobile POS contract.
### Version 1.17.0 (September 8, 2026)
- Added the company fiscal-device integration API for Windows and Android cashier devices.
- Corrected company-admin authentication to use `/api/auth/login` and `/api/auth/register/b2b`.
- Corrected location preference paths to `/api/user/location/status` and `/api/user/location/preferences`.
- Marked web-only receipt and invoice downloads as unavailable to bearer-token mobile clients.
- Removed unsupported company-admin facilities, role-management, front-desk, housekeeping, template, policy, report, subscription, and settlement operations from the active pages reference.
### Version 1.16.0 (September 2, 2026)
**Documented Existing Operations:**
- Added B2B registration, role switching, role-aware navigation, and authentication-level 2FA endpoints.
- Added location recommendation and nearby-venue endpoints.
- Added venue translation CRUD, bulk, copy, status, import/export, search, and analytics endpoints.
- All endpoints in this release are documented from the currently registered Laravel routes and controller validation rules.
<details>
<summary>Archived pre-v1.16 changelog (historical; endpoints here are not part of the current contract)</summary>
### Version 1.15.0 (August 11, 2026)
**New Endpoints - Company Admin Messaging:**
**Messaging System:**
- `GET /api/company-admin/messaging/conversations` - List all conversations for the authenticated user
- Returns conversations with participants and last message
- Filters by company and user participation
- Ordered by most recently updated
- `GET /api/company-admin/messaging/conversations/{conversation}` - Get conversation details with messages
- Returns conversation with all participants and message history
- Messages include sender information and read status
- Only accessible to conversation participants
- `POST /api/company-admin/messaging/conversations` - Create new conversation
- Supports both private (1-on-1) and group conversations
- Requires conversation type and array of participant user IDs
- Group conversations require a name
- Creator is automatically added as admin participant
- `POST /api/company-admin/messaging/conversations/{conversation}/send` - Send message to conversation
- Supports text messages, file attachments, and location sharing
- Accepts multipart/form-data for file uploads (max 10MB)
- Supports message types: text, image, file, audio, video, location
- Automatically marks message as read for sender
- Updates conversation timestamp
- `POST /api/company-admin/messaging/conversations/{conversation}/read` - Mark conversation as read
- Updates last_read_at timestamp for authenticated user
- Used for tracking read status and unread counts
- `POST /api/company-admin/messaging/conversations/{conversation}/participants` - Add participant to conversation
- Only accessible to conversation admins
- Requires user_id of participant to add
- New participants are added as non-admin by default
- `DELETE /api/company-admin/messaging/conversations/{conversation}/participants/{user}` - Remove participant from conversation
- Accessible to conversation admins or the participant themselves
- Removes user from conversation and all message access
- `DELETE /api/company-admin/messaging/conversations/{conversation}` - Delete conversation
- Only accessible to conversation admins
- Soft deletes conversation (preserves data in database)
- Removes access for all participants
**API Documentation:**
- Updated API version to v1.15.0
- Added comprehensive messaging endpoints to company admin API
- Enhanced send message endpoint to support file uploads (images, videos, audio, documents)
- Added location sharing support via Google Maps URLs
- Included participant management functionality
- Added conversation read status tracking
- Updated openapi.yaml with all new messaging endpoints
- All endpoints require authentication and proper company capability checks
### Version 1.14.0 (August 8, 2026)
**New Endpoints - Company Registration:**
**Complete Company Registration:**
- `POST /api/company/complete-registration` - Complete company registration with all required data
- Creates company, workspace, owner user, venue, and venue objects in a single transaction
- Accepts company information (name, description, email, phone, address, city, country, postal_code, trade_register_number, vat_number, currency, locale, timezone, available_reservation_types)
- Accepts owner information (name, email, phone, password, password_confirmation)
- Accepts venue information (name, description, venue_type, booking_type, category, address, city, country, phone, email, capacity, opening_hours)
- Accepts optional venue objects array (name, description, type_id, capacity, price, is_active)
- Returns complete registration data including company, user, workspace, venue, and venue objects
- All data is validated and created in a database transaction for data integrity
**Venue Creation:**
- `POST /api/company/venues` - Create a new venue for authenticated company
- Accepts venue details including booking_type and category (required fields)
- Supports location_id, place_id, country_id for geographic data
- Returns created venue with id, name, booking_type, and category
- Validates user company association before creation
**Venue Objects Creation:**
- `POST /api/company/venue-objects` - Create multiple venue objects for a venue
- Accepts venue_id and array of venue objects
- Each venue object can have name, description, type_id, capacity, price, is_active
- Validates venue ownership before creation
- Returns created venue objects with ids and names
**API Documentation:**
- Updated API version to v1.14.0
- Added comprehensive documentation for company registration endpoints
- Included request/response examples and parameter descriptions
- Documented booking_type and category requirements for venue creation
### Version 1.13.0 (August 6, 2026)
**New Endpoints - Location Search Criteria:**
**Location Search Filters:**
- `GET /api/locations/search-criteria` - Get all available search criteria for locations page filters
- Returns comprehensive filter options organized by booking type (spots, rentals, services)
- Includes location & dates filters, price & budget options, property & features, rating & reviews
- Supports dynamic extensibility for adding new filter criteria
- Localized support for multiple languages
- Returns structured JSON with field types, labels, options, and icons
- Common filters include sort options and view options (grid, list, map)
**API Documentation:**
- Updated API version to v1.13.0
- Added comprehensive documentation for search criteria endpoint
- Included request/response examples and parameter descriptions
- Documented filter structure for each booking type
### Version 1.12.0 (August 5, 2026)
**Enhancements - Fiscal Receipts Management:**
**Company Admin Fiscal Receipts:**
- Added fiscal receipts management to company admin panel (non-Filament based)
- `GET /company-admin/fiscal-receipts` - List fiscal receipts with filters
- `GET /company-admin/fiscal-receipts/{fiscalReceipt}` - View fiscal receipt details
- `GET /company-admin/fiscal-receipts/{fiscalReceipt}/download` - Download fiscal receipt as PDF
- `POST /company-admin/fiscal-receipts/{fiscalReceipt}/reprint` - Reprint fiscal receipt via fiscal device
- Added fiscal receipts views with comprehensive filtering options
- Filter by status (printed, failed, cancelled), date range, and booking ID
- Display receipt details including fiscal numbers, amounts, VAT information, and items data
- Support for downloading PDF receipts and reprinting via fiscal device
**Mobile App API Fiscal Receipts:**
- Added fiscal receipts endpoint to mobile app API
- `GET /api/venues/{venueId}/fiscal-receipts` - Get fiscal receipts for a specific venue
- Supports pagination and filtering by status and date range
- Returns receipt data including fiscal numbers, amounts, payment methods, and booking information
- Properly scoped to venue for data security
**API Documentation:**
- Updated API version to v1.12.0
- Added comprehensive documentation for fiscal receipts endpoints
- Included request/response examples and parameter descriptions
### Version 1.11.0 (August 5, 2026)
**Enhancements - Venue Gallery, House Rules, and SEO:**
**Venue API Updates:**
- Enhanced `GET /api/venues/{id}` endpoint to include comprehensive venue data:
- Added `name_cyrillic` field for Cyrillic venue names
- Added `house_rules_translated` field with translated house rules
- Added `gallery_images` array with image metadata (url, alt, title)
- Added `seo` object with meta_title, meta_keywords, meta_description, og_title, og_description
- Added `website` and `business_type` fields
**Web Venue Page Updates:**
- Added SEO meta tags to venue pages for better search engine optimization
- Meta description, keywords, and title tags
- Open Graph tags for social media sharing
- Enhanced house rules section to use translated rules
- Gallery images already displayed with enhanced metadata
**Image Processing Enhancements:**
- Implemented automatic image compression for files larger than 5MB
- Images compressed to max 1920x1080 resolution
- JPEG quality set to 85%, PNG maximum compression
- WebP support with 85% quality
- Increased gallery image limit from 10 to 40 images per venue
- Maintains image quality while reducing file size for better performance
**API Documentation:**
- Updated venue endpoint documentation with new fields
- Added examples for SEO metadata and gallery image structure
### Version 1.10.0 (August 5, 2026)
**Bug Fixes - Missing Company Admin API Endpoints:**
**Venue Objects Management:**
- `PUT /api/company-admin/venue-objects/{object}` - Update specific venue object
- Accepts venue_id, name, type, capacity, description, bedrooms, bathrooms, price, currency, booking_time_unit, is_available, is_active, images
- Validates company access before allowing updates
- Returns updated venue object data
**Enhancements:**
- Added missing PUT endpoint for venue objects update
- Ensured all company-admin venue-operations routes are documented and available
- Fixed OpenAPI specification to include all implemented endpoints
### Version 1.9.0 (August 5, 2026)
**New Endpoints - Complete Mobile App Coverage:**
**Company Admin Authentication:**
- `POST /api/company-admin/auth/register` - Register new company admin user
- `POST /api/company-admin/auth/login` - Authenticate company admin user
**Venue Facilities Management:**
- `GET /api/company-admin/venues/{venue}/facilities` - Get venue facilities
- `POST /api/company-admin/venues/{venue}/facilities` - Add facility to venue
- `DELETE /api/company-admin/venues/{venue}/facilities/{facility}` - Remove facility from venue
**Role Permissions Management:**
- `GET /api/company-admin/roles` - List all roles with permissions
- `POST /api/company-admin/roles` - Create new role
- `GET /api/company-admin/roles/{role}` - Get role details
- `PUT /api/company-admin/roles/{role}` - Update role and permissions
- `DELETE /api/company-admin/roles/{role}` - Delete role
**Front Desk Operations:**
- `GET /api/company-admin/front-desk/dashboard` - Get front desk dashboard with arrivals/departures
- `GET /api/company-admin/front-desk/check-in-queue` - Get pending check-ins
- `GET /api/company-admin/front-desk/check-out-queue` - Get pending check-outs
- `GET /api/company-admin/front-desk/room-status` - Get real-time room status
**Housekeeping Management:**
- `GET /api/company-admin/housekeeping/dashboard` - Get housekeeping dashboard
- `GET /api/company-admin/housekeeping/tasks` - Get housekeeping tasks
- `POST /api/company-admin/housekeeping/tasks` - Create housekeeping task
- `PUT /api/company-admin/housekeeping/tasks/{task}` - Update housekeeping task
- `POST /api/company-admin/housekeeping/approve` - Approve room condition after cleaning
**Message Templates:**
- `GET /api/company-admin/message-templates` - List message templates
- `POST /api/company-admin/message-templates` - Create message template
- `GET /api/company-admin/message-templates/{template}` - Get template details
- `PUT /api/company-admin/message-templates/{template}` - Update template
- `DELETE /api/company-admin/message-templates/{template}` - Delete template
**Advanced Settings:**
- `GET /api/company-admin/cancellation-policies` - List cancellation policies
- `POST /api/company-admin/cancellation-policies` - Create cancellation policy
- `PUT /api/company-admin/cancellation-policies/{policy}` - Update policy
- `DELETE /api/company-admin/cancellation-policies/{policy}` - Delete policy
- `GET /api/company-admin/notification-settings` - Get admin notification preferences
- `PUT /api/company-admin/notification-settings` - Update admin notification preferences
**Financial Reports:**
- `GET /api/company-admin/financial-reports` - Get financial reports with revenue, expenses, profit
**B2B Features:**
- `GET /api/company-admin/b2b-invoices` - List B2B invoices
- `POST /api/company-admin/b2b-invoices` - Create B2B invoice
- `GET /api/company-admin/subscriptions` - List subscriptions
- `POST /api/company-admin/subscriptions` - Create subscription
- `PUT /api/company-admin/subscriptions/{subscription}` - Update subscription
- `DELETE /api/company-admin/subscriptions/{subscription}` - Cancel subscription
- `GET /api/company-admin/settlements` - List settlements
- `POST /api/company-admin/settlements` - Create settlement
**Enhancements:**
- Complete coverage for all mobile app pages including front desk, housekeeping, and B2B features
- Added comprehensive role-based access control endpoints
- Enhanced operational management capabilities for mobile admin app
- Financial reporting for business intelligence
### Version 1.8.0 (August 5, 2026)
**Enhancements - Form and API Alignment:**
**Security Settings:**
- Updated security settings to use notification_preferences JSON column structure
- Fixed notification preferences access pattern from direct properties to JSON column
- Updated SecurityController to properly handle notification_preferences as JSON object
- Changed notification fields to: email_notifications, sms_notifications, push_notifications (removed login_alerts)
**Company Admin Booking API:**
- Updated POST /api/company-admin/bookings endpoint to match actual form implementation
- Changed required fields from venue_object_id (singular) to venue_objects (array)
- Added support for guests_count, booking_category, services, packages, products, notes fields
- Fixed booking_type enum from ['spot', 'rentals', 'services'] to ['spots', 'rentals', 'services']
- Removed total_amount from required fields (calculated by backend)
**Company Admin Client API:**
- Updated POST /api/company-admin/clients endpoint to match actual form implementation
- Changed required fields to include email and phone
- Added support for city, country, vat_number optional fields
- Enhanced client creation to support complete address information
**Bug Fixes:**
- Fixed notification preferences storage in database schema alignment
- Corrected API documentation to reflect actual backend implementation
- Ensured non-Filament forms match API endpoint payloads and response objects
### Version 1.7.0 (August 5, 2026)
**New Endpoints - Push Notification System:**
**Device Token Management:**
- `POST /api/user/device-tokens/register` - Register device token for push notifications
- Accepts token, device_type (ios/android/web), device_name, app_version, os_version
- Updates existing token if already registered
- Returns device token ID and type
- `POST /api/user/device-tokens/unregister` - Unregister device token
- Accepts token to unregister
- Deactivates the device token for the user
- `GET /api/user/device-tokens` - Get all device tokens for the user
- Returns list of registered devices with their details and status
**Push Notification Support:**
- Updated all transactional notifications to support push notifications
- Added push channel to BookingConfirmedNotification
- Added push channel to PaymentSuccessNotification
- Added push channel to BonusPointsEarnedNotification
- Push notifications respect user notification preferences
- Notifications sent via Firebase Cloud Messaging (FCM)
**Enhancements:**
- Added PushNotificationService for FCM integration
- Added DeviceToken model for managing push notification tokens
- Updated NotificationSettingsHelper to support push notification preferences
- Added FCM configuration to services config
- Registered custom push notification channel in AppServiceProvider
### Version 1.6.0 (August 4, 2026)
**New Endpoints - Complete Mobile API Implementation:**
**Authentication:**
- `POST /api/auth/apple` - Authenticate user with Apple ID token
- Accepts `id_token` and optional `device_name`
- Creates or updates user account based on Apple ID
- Returns user data and authentication token
**Bonus Points:**
- `GET /api/bonus-points` - Get bonus points overview and balance
- Returns current balance, tier information, expiring points
- Includes total earned/spent statistics
- `GET /api/bonus-points/statistics` - Get detailed bonus points statistics
- Returns monthly earnings, expiring points, expired points
- Provides historical data analysis
- `GET /api/bonus-points/transactions` - Get bonus points transaction history
- Supports filtering by transaction type (earned/spent/all)
- Paginated results with booking details
- `POST /api/bonus-points/spend` - Spend bonus points
- Validates sufficient balance before spending
- Returns updated balance after transaction
**User Transactions:**
- `GET /api/user/transactions` - Get user payment transactions
- Filterable by status (all/pending/completed/failed)
- Paginated results with booking and payment method details
- `GET /api/user/transactions/{id}` - Get single transaction details
- Includes full transaction metadata and invoice information
- Shows booking details and payment method
**Reviews:**
- `PUT /api/user/reviews/{id}` - Update existing review
- Allows updating rating, title, comment, and sub-ratings
- Validates ownership of review
- `DELETE /api/user/reviews/{id}` - Delete a review
- Soft delete with validation of ownership
**Notifications:**
- `DELETE /api/user/notifications/{id}` - Delete a notification
- Permanently removes notification from user's list
**Notification Preferences:**
- `GET /api/user/notification-preferences/summary` - Get notification preferences summary
- Returns comprehensive settings overview
- Includes quiet hours, category preferences, and enablement status
- `POST /api/user/notification-preferences/quiet-hours` - Set quiet hours for notifications
- Configure time range for quiet hours
- Enable/disable quiet hours functionality
- `POST /api/user/notification-preferences/toggle-all` - Toggle all notifications on/off
- Bulk enable/disable all notification channels
- `POST /api/user/notification-preferences/reset` - Reset notification preferences to defaults
- Restores default notification settings
- `POST /api/user/notification-preferences/test` - Send test notification
- Sends a test notification to verify notification system
**Security:**
- `GET /api/user/security/settings` - Get security settings
- Returns 2FA status, verification status, password change date
- Includes recent login history
- `PUT /api/user/security/settings` - Update security settings
- Enable/disable 2FA
- Manage security preferences
- `POST /api/user/security/2fa/enable` - Enable two-factor authentication
- Sends verification code to user's email
- `POST /api/user/security/2fa/disable` - Disable two-factor authentication
- Disables 2FA for the user account
**Location:**
- `GET /api/user/location/status` - Get location status
- Returns location services enablement status
- Shows last known location and update timestamp
- `PUT /api/user/location/preferences` - Update location preferences
- Enable/disable location services
- Manage location tracking preferences
**Feedback:**
- `GET /api/user/feedback` - Get user feedback history
- Returns paginated list of submitted feedback
- Shows status and category of each feedback
- `POST /api/user/feedback` - Submit feedback
- Accepts category (bug/feature/general), subject, message
- Optional rating for overall experience
- Returns feedback ID and status
**Documents:**
- `GET /api/documents` - Get accessible documents
- Returns public documents and user-accessible documents
- Includes company-specific documents
- Paginated results with document metadata
**Enhancements:**
- Added comprehensive error handling and validation for all new endpoints
- Implemented proper authentication checks using Sanctum tokens
- Added pagination support for list endpoints
- Included proper HTTP status codes and error responses
- Implemented consistent response structure across all endpoints
### Version 1.5.0 (August 4, 2026)
**New Endpoints - Popular Destinations & Recommended Venues:**
- **Popular Destinations**: Added `GET /api/venues/popular-destinations` endpoint to retrieve popular destinations (locations with is_main = true)
- Supports optional `booking_type` parameter to filter by booking type
- Returns destination details with venue count and sample venues (max 5 per destination)
- Includes location images and venue images for all sample venues
- **Recommended Venues**: Added `GET /api/venues/recommended` endpoint to retrieve recommended venues (venues with is_featured = true)
- Supports optional `booking_type` parameter to filter by booking type
- Supports optional `location_id` parameter to filter by location
- Supports optional `limit` parameter (default: 10, max: 20)
- Returns complete venue details with images, pricing, and ratings
- Sorted by rating (desc) and creation date (desc)
**Response Structure Updates:**
- Popular destinations include `image_url`, `venue_count`, and sample `venues` with full image data
- Recommended venues include complete venue information with `image_url`, `gallery_images`, `lowest_price`, `average_rating`, and `total_reviews`
### Version 1.4.0 (August 4, 2026)
**Enhancements - Venue Images:**
- **Venue Images in All Endpoints**: Added venue images (`image_url` and `gallery_images`) to all API endpoints that return venue data
- **Public Venue API**: Updated `GET /api/venues`, `GET /api/venues/{id}`, `GET /api/venues/search`, `POST /api/venues/{id}/availability`, `GET /api/venues/{venue_id}/objects`, `GET /api/venues/{venue_id}/spots` to include venue images
- **Company Admin API**: Updated `GET /api/company-admin/venues`, `GET /api/company-admin/venue-objects`, `GET /api/company-admin/bookings/{booking}`, `GET /api/company-admin/gantt-chart/venue-occupation`, `POST /api/company-admin/qr-codes/scan`, `GET /api/company-admin/bookings/lookup/{uniqueBookingId}` to include venue images
- **Location Services API**: Updated `POST /nearby` and venue recommendation endpoints to include venue images
- **Venue Object Images**: Enhanced venue object responses to include their own `images` array along with parent venue images
- **Venue Spot Images**: Added venue information (including images) to venue spot responses
**Response Structure Updates:**
- All venue responses now include `image_url` (string, nullable) - the primary venue image URL
- All venue responses now include `gallery_images` (array) - collection of all venue gallery images with metadata
- Venue object responses include both object-specific `images` and parent venue `image_url`/`gallery_images`
- Venue spot responses include parent venue information with images
### Version 1.3.0 (August 4, 2026)
**New Features - Developer Portal:**
- **Developer Portal Launch**: Introduced a dedicated developer portal at `/developer` for API access management
- **Developer Registration**: Developers can register for API access through `/developer/register`
- **API Key Management**: Each developer receives unique API key and secret upon registration
- **Developer Dashboard**: Access to dashboard at `/developer/dashboard` for managing API credentials
- **Developer Authentication**: Separate authentication system for developers using `auth:developer` guard
- **Developer Model**: New `Developer` model with dedicated database table for developer accounts
**Enhancements:**
- Added developer-specific authentication with email verification
- Implemented API key and secret generation for secure API access
- Created developer profile management functionality
- Added translations for developer portal in all 11 supported languages
### Version 1.2.0 (August 4, 2026)
**New Endpoints Added - Company Admin API:**
**Dashboard & Settings:**
- `GET /api/company-admin/dashboard/stats` - Retrieve dashboard statistics (clients, users, bookings, revenue, tasks)
- `GET /api/company-admin/settings` - Get company settings
- `PUT /api/company-admin/settings` - Update company settings
**Venues:**
- `GET /api/company-admin/venues` - List all venues
- `POST /api/company-admin/venues` - Create new venue
- `PUT /api/company-admin/venues/{venue}` - Update venue
- `DELETE /api/company-admin/venues/{venue}` - Delete venue
**Bookings:**
- `GET /api/company-admin/bookings` - List bookings with filters (status, date range)
- `GET /api/company-admin/bookings/{booking}` - Get booking details
- `POST /api/company-admin/bookings` - Create new booking
- `PUT /api/company-admin/bookings/{booking}` - Update booking
- `POST /api/company-admin/bookings/{booking}/check-in` - Check in booking
- `POST /api/company-admin/bookings/{booking}/check-out` - Check out booking
- `POST /api/company-admin/bookings/{booking}/cancel` - Cancel booking
- `GET /api/company-admin/bookings/lookup/{uniqueBookingId}` - Lookup booking by unique ID
**Clients:**
- `GET /api/company-admin/clients` - List clients with search
- `GET /api/company-admin/clients/{client}` - Get client details
- `POST /api/company-admin/clients` - Create new client
- `PUT /api/company-admin/clients/{client}` - Update client
**Users & Employees:**
- `GET /api/company-admin/users` - List users with roles
- `POST /api/company-admin/users` - Create new user
- `PUT /api/company-admin/users/{user}` - Update user
- `DELETE /api/company-admin/users/{user}` - Delete user
- `GET /api/company-admin/employees` - List employees
- `POST /api/company-admin/employees` - Create new employee
- `PUT /api/company-admin/employees/{user}` - Update employee
**Venue Objects & Gantt Chart:**
- `GET /api/company-admin/venue-objects` - List venue objects
- `POST /api/company-admin/venue-objects` - Create venue object
- `GET /api/company-admin/gantt-chart/venue-occupation` - Get venue objects occupation for Gantt chart
**Inventory:**
- `GET /api/company-admin/inventory` - List inventory items
- `POST /api/company-admin/inventory` - Create inventory item
- `POST /api/company-admin/inventory/inventory/{inventory}/update-stock` - Update inventory stock
**Products, Services & Packages:**
- `GET /api/company-admin/products` - List products
- `POST /api/company-admin/products` - Create product
- `PUT /api/company-admin/products/{product}` - Update product
- `DELETE /api/company-admin/products/{product}` - Delete product
- `GET /api/company-admin/services` - List services
- `POST /api/company-admin/services` - Create service
- `GET /api/company-admin/packages` - List packages
- `POST /api/company-admin/packages` - Create package
- `PUT /api/company-admin/packages/{package}` - Update package
- `DELETE /api/company-admin/packages/{package}` - Delete package
**Invoices:**
- `GET /api/company-admin/invoices` - List invoices
- `GET /api/company-admin/invoices/{invoice}` - Get invoice details
- `POST /api/company-admin/invoices` - Create invoice
- `PUT /api/company-admin/invoices/{invoice}` - Update invoice
- `PUT /api/company-admin/invoices/{invoice}/mark-paid` - Mark invoice as paid
- `DELETE /api/company-admin/invoices/{invoice}` - Delete invoice
**Transactions/Payments:**
- `GET /api/company-admin/transactions` - List transactions/payments
- `GET /api/company-admin/transactions/{payment}` - Get transaction details
**Documents:**
- `GET /api/company-admin/documents` - List documents
- `POST /api/company-admin/documents` - Upload document (encrypted storage)
- `GET /api/company-admin/documents/{document}` - Get document details
- `DELETE /api/company-admin/documents/{document}` - Delete document
**Housekeeping:**
- `GET /api/company-admin/housekeeping/tasks` - List housekeeping tasks (filters: `status`, `venue_id`, `assigned_to`)
- `PUT /api/company-admin/housekeeping/tasks/{task}` - Update housekeeping task
**Messaging:**
- `GET /api/company-admin/messaging/conversations` - List conversations
- `GET /api/company-admin/messaging/conversations/{conversation}` - Get conversation details
- `POST /api/company-admin/messaging/conversations` - Create conversation
- `POST /api/company-admin/messaging/conversations/{conversation}/send` - Send message
**QR Code & Statistics:**
- `POST /api/company-admin/scan-qr` - Scan QR code to find booking
- `GET /api/company-admin/statistics` - Get comprehensive statistics
**Enhancements:**
- Added comprehensive company admin API endpoints for mobile app integration
- Implemented WhatsApp-style messaging API for team communication
- Added inventory management API endpoints
- Enhanced statistics API with occupancy and revenue data
- Added Gantt chart support for venue objects occupation visualization
- Implemented QR code scanner for quick booking lookup
- Added package management for bundled services
- All company admin endpoints require authentication via Sanctum tokens
### Version 1.1.0 (August 4, 2026)
**New Endpoints Added:**
- `GET /api/locations` - Get all locations
- `GET /api/locations/{location}` - Get location details
- `POST /api/locations` - Create new location
- `PUT /api/locations/{location}` - Update location
- `DELETE /api/locations/{location}` - Delete location
- `GET /api/validate-location` - Validate location coordinates
**Enhancements:**
- Added comprehensive location management endpoints
- Implemented location validation with nearest city detection
### Version 1.0.0
**New Endpoints Added:**
- `GET /api/user/dashboard` - Retrieve comprehensive dashboard data including booking statistics, recent/upcoming bookings, total spent, favorites count, and notification count
- `GET /api/user/reviews` - List all reviews by the authenticated user
- `POST /api/user/reviews` - Submit new venue reviews with validation
- `GET /api/user/reviews/{id}` - Retrieve detailed review information
- `GET /api/user/invoices` - List user invoices with optional status filtering
- `GET /api/user/invoices/{id}` - Retrieve detailed invoice information including line items
**Enhancements:**
- Added pagination support to user reviews and invoices endpoints
- Implemented validation for duplicate reviews
- Added booking validation for reviews (only completed bookings can be reviewed)
- Enhanced invoice details with line items and client information
### Version 1.0.0
Initial API release with core authentication, user management, venue discovery, booking, and payment functionality.
---
</details>
## Table of Contents
1. [Authentication](#authentication)
2. [User Profile](#user-profile)
3. [Venues & Locations](#venues--locations)
4. [Bookings](#bookings)
5. [Payments & Transactions](#payments--transactions)
6. [Invoices](#invoices)
7. [Notifications](#notifications)
8. [Favorites & Wishlist](#favorites--wishlist)
9. [Reviews](#reviews)
10. [Bonus Points](#bonus-points)
11. [Location Services](#location-services)
12. [Company Admin API](#company-admin-api)
13. [Developer Portal](#developer-portal)
14. [Error Handling](#error-handling)
15. [Data Models](#data-models)
---
## Authentication
### Register B2B User
**Endpoint:** `POST /api/auth/register/b2b`
**Authentication:** Not required
Creates a B2B owner user, company, and authoritative company membership in one transaction.
Required JSON fields: `name`, `email`, `phone`, `password`, `password_confirmation`, and `company_name`. Optional fields: `company_vat`, `device_name`, and `locale` (`en`, `bg`, or `ru`). A successful response returns HTTP 201 with `user`, `access`, and bearer `token` data.
Registration forms may populate their selectors using `GET /api/timezones`, `GET /api/locations-by-country?country_id={id}`, and `GET /api/places-by-location?location_id={id}`. These three helpers are registered in the web route stack and do not require bearer authentication.
### Authentication Two-Factor Verification
All operations require `Authorization: Bearer {token}`.
| Method | Endpoint | Request | Result |
|--------|----------|---------|--------|
| POST | `/api/auth/2fa/enable` | No body | Sends a verification code to the authenticated user's email |
| POST | `/api/auth/2fa/verify` | `code` — required six-digit string | Verifies and clears the current code |
| POST | `/api/auth/2fa/disable` | No body | Disables two-factor authentication |
Validation failures return HTTP 422. An invalid or expired verification code returns HTTP 400.
### Roles and Mobile Navigation
All operations require `Authorization: Bearer {token}`.
| Method | Endpoint | Request/Response |
|--------|----------|------------------|
| GET | `/api/auth/roles` | Returns `roles`, `current_role`, and `has_multiple_roles` |
| POST | `/api/auth/switch-role` | Requires `role`; returns `current_role` and `redirect_route`. Returns HTTP 403 when the user does not own the requested role |
| GET | `/api/auth/navigation` | Returns `user_type`, `current_role`, and role-aware `navigation` items |
### Register New User
Create a new user account for B2C clients.
**Endpoint:** `POST /api/auth/register`
**Request Body:**
```json
{
"name": "John Doe",
"email": "john.doe@example.com",
"password": "SecurePassword123!",
"password_confirmation": "SecurePassword123!",
"phone": "+359 888 123 456",
"language": "en"
}
```
**Response (201 Created):**
```json
{
"success": true,
"message": "Account created successfully",
"data": {
"user": {
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+359 888 123 456",
"language": "en",
"created_at": "2026-07-31T15:00:00Z"
},
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
}
```
### Login
Authenticate a user and receive an access token.
**Endpoint:** `POST /api/auth/login`
**Request Body:**
```json
{
"email": "john.doe@example.com",
"password": "SecurePassword123!"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Login successful",
"data": {
"user": {
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+359 888 123 456",
"avatar": "https://cdn.zapazime.bg/avatars/user1.jpg"
},
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
}
```
### Google Authentication
Authenticate a user using Google OAuth ID token.
**Endpoint:** `POST /api/auth/google`
**Request Body:**
```json
{
"id_token": "google_id_token_from_mobile_sdk",
"device_name": "mobile"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Google authentication successful",
"data": {
"user": {
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+359 888 123 456",
"avatar": "https://cdn.zapazime.bg/avatars/user1.jpg",
"locale": "en",
"is_b2b": false,
"company_id": null
},
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
}
```
**Mobile App Integration:**
1. Use Google Sign-In SDK in your mobile app
2. Get Google ID token after user authentication
3. Send ID token to this endpoint
4. Receive Sanctum bearer token for subsequent API calls
**Response (401 Unauthorized):**
```json
{
"success": false,
"message": "Invalid Google token"
}
```
### Logout
Invalidate the current authentication token.
**Endpoint:** `POST /api/auth/logout`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"message": "Logged out successfully"
}
```
### Keep-Alive Ping
Keep the authentication session alive by periodically calling this endpoint. This is useful for mobile applications to maintain session validity.
**Endpoint:** `GET /api/auth/ping`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"message": "Pong",
"timestamp": "2026-08-02T07:20:00.000000Z",
"user_id": 123
}
```
**Mobile App Integration:**
- Call this endpoint periodically (e.g., every 5-10 minutes) while the app is active
- Use the timestamp to synchronize client-server time
- Use the user_id to verify the authenticated user context
- Lightweight endpoint with minimal data transfer for optimal performance
**Recommended Usage:**
```javascript
// Example: Call ping every 5 minutes
setInterval(async () => {
const response = await fetch('https://api.zapazime.bg/api/auth/ping', {
headers: {
'Authorization': `Bearer ${token}`
}
});
const data = await response.json();
if (data.success) {
// Session is alive, update last activity timestamp
}
}, 300000); // 5 minutes
```
### Forgot Password
Request a password reset link via email.
**Endpoint:** `POST /api/auth/forgot-password`
**Request Body:**
```json
{
"email": "john.doe@example.com"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Password reset link sent to your email"
}
```
### Reset Password
Reset password using the token received via email.
**Endpoint:** `POST /api/auth/reset-password`
**Request Body:**
```json
{
"token": "reset_token_here",
"email": "john.doe@example.com",
"password": "NewSecurePassword123!",
"password_confirmation": "NewSecurePassword123!"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Password reset successfully"
}
```
---
## User Profile
### Get Profile
Retrieve the authenticated user's profile information.
**Endpoint:** `GET /api/user/profile`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+359 888 123 456",
"date_of_birth": "1990-05-15",
"gender": "male",
"language": "en",
"bio": "Frequent traveler",
"address": "123 Main Street",
"city": "Sofia",
"postal_code": "1000",
"country": "Bulgaria",
"avatar": "https://cdn.zapazime.bg/avatars/user1.jpg",
"created_at": "2026-01-15T10:00:00Z"
}
}
```
### Update Profile
Update the authenticated user's profile information.
**Endpoint:** `PUT /api/user/profile`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"name": "John Smith",
"phone": "+359 899 987 654",
"date_of_birth": "1990-05-15",
"gender": "male",
"language": "en",
"bio": "Updated bio",
"address": "456 New Street",
"city": "Plovdiv",
"postal_code": "4000",
"country": "Bulgaria"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Profile updated successfully",
"data": {
"id": 1,
"name": "John Smith",
"email": "john.doe@example.com",
"phone": "+359 899 987 654",
"date_of_birth": "1990-05-15",
"gender": "male",
"language": "en",
"bio": "Updated bio",
"address": "456 New Street",
"city": "Plovdiv",
"postal_code": "4000",
"country": "Bulgaria"
}
}
```
### Change Password
Change the authenticated user's password.
**Endpoint:** `POST /api/user/change-password`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"current_password": "OldPassword123!",
"password": "NewSecurePassword123!",
"password_confirmation": "NewSecurePassword123!"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Password changed successfully"
}
```
### Get Preferences
Retrieve user preferences.
**Endpoint:** `GET /api/user/preferences`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"language": "en",
"currency": "EUR",
"notifications_enabled": true,
"email_notifications": true,
"sms_notifications": false,
"push_notifications": true,
"marketing_emails": false
}
}
```
### Update Preferences
Update user preferences.
**Endpoint:** `PUT /api/user/preferences`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"language": "bg",
"currency": "EUR",
"notifications_enabled": true,
"email_notifications": true,
"sms_notifications": false,
"push_notifications": true,
"marketing_emails": false
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Preferences updated successfully",
"data": {
"language": "bg",
"currency": "EUR",
"notifications_enabled": true,
"email_notifications": true,
"sms_notifications": false,
"push_notifications": true,
"marketing_emails": false
}
}
```
### Get User Dashboard
Retrieve comprehensive dashboard data for the authenticated user, including booking statistics, recent activity, and upcoming bookings. This endpoint provides all data needed for the B2C client dashboard view.
**Endpoint:** `GET /api/user/dashboard`
**Headers:** `Authorization: Bearer {token}`
**Mobile App Integration:**
- Call this endpoint when the user opens the dashboard screen
- Use the data to display booking statistics, recent bookings, and upcoming reservations
- Refresh periodically (e.g., on pull-to-refresh) to keep data current
- Cache the response locally for offline viewing where appropriate
**Response (200 OK):**
```json
{
"success": true,
"data": {
"booking_stats": {
"total": 25,
"pending": 2,
"confirmed": 18,
"completed": 4,
"cancelled": 1
},
"total_spent": 3450.50,
"favorites_count": 7,
"recent_bookings": [
{
"id": 25,
"booking_number": "BKG-2026-001234",
"venue": {
"id": 1,
"name": "Grand Hotel Sofia",
"image_url": "https://cdn.zapazime.bg/venues/venue1-1.jpg",
"city": "Sofia",
"country": "Bulgaria"
},
"status": "confirmed",
"total_price": 450.00,
"check_in": "2026-08-15T14:00:00Z",
"check_out": "2026-08-18T12:00:00Z",
"booking_date": null,
"created_at": "2026-07-25T10:00:00Z"
}
],
"upcoming_bookings": [
{
"id": 25,
"booking_number": "BKG-2026-001234",
"venue": {
"id": 1,
"name": "Grand Hotel Sofia",
"image_url": "https://cdn.zapazime.bg/venues/venue1-1.jpg",
"city": "Sofia",
"country": "Bulgaria"
},
"status": "confirmed",
"total_price": 450.00,
"check_in": "2026-08-15T14:00:00Z",
"check_out": "2026-08-18T12:00:00Z",
"booking_date": null
}
],
"unread_notifications_count": 3
}
}
```
**Data Fields:**
- `booking_stats`: Object containing booking counts by status
- `total`: Total number of bookings
- `pending`: Number of pending bookings
- `confirmed`: Number of confirmed bookings
- `completed`: Number of completed bookings
- `cancelled`: Number of cancelled bookings
- `total_spent`: Total amount spent on paid bookings (float)
- `favorites_count`: Number of favorite venues (integer)
- `recent_bookings`: Array of last 5 bookings with venue details
- Each booking includes id, booking_number, venue object, status, total_price, dates
- `upcoming_bookings`: Array of next 5 confirmed/pending bookings
- Only includes bookings with future dates
- `unread_notifications_count`: Count of unread notifications (integer)
**Mobile UI Implementation Tips:**
- Display booking stats as cards or a summary row
- Show recent bookings in a scrollable list
- Highlight upcoming bookings prominently
- Use notification badge on dashboard icon based on `unread_notifications_count`
- Format currency values according to user's locale preference
---
## Venues & Locations
### Mobile Home Discovery
The mobile initial screen can fetch these public endpoints without authentication:
| Method | Endpoint | Filters |
|--------|----------|---------|
| GET | `/api/venues/popular-destinations` | Optional `booking_type`: `spots`, `rentals`, or `services` |
| GET | `/api/venues/recommended` | Optional `booking_type`, positive integer `location_id`, and `limit` from 1 to 20 (default 10) |
Popular destinations returns active main locations, each with its public venue count and up to five displayable venues. Recommended venues returns active, verified, certificate-valid featured venues ordered by rating and creation date. Invalid filters return `422`.
### Get Venues List
Retrieve a paginated list of venues with optional filters.
**Endpoint:** `GET /api/venues`
**Query Parameters:**
- `page` (integer, optional): Page number (default: 1)
- `per_page` (integer, optional): Items per page (default: 15)
- `category` (string, optional): Filter by category
- `location` (string, optional): Filter by location
- `search` (string, optional): Search term
- `min_price` (number, optional): Minimum price
- `max_price` (number, optional): Maximum price
- `rating` (number, optional): Minimum rating
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"name": "Grand Hotel Sofia",
"description": "Luxury hotel in the heart of Sofia",
"category": "Hotel",
"location": "Sofia, Bulgaria",
"address": "1 Sveta Nedelya Square",
"latitude": 42.6977,
"longitude": 23.3219,
"price_from": 120.00,
"rating": 4.5,
"reviews_count": 234,
"images": [
"https://cdn.zapazime.bg/venues/venue1-1.jpg",
"https://cdn.zapazime.bg/venues/venue1-2.jpg"
],
"amenities": ["wifi", "parking", "pool", "spa"],
"is_favorite": false
}
],
"meta": {
"current_page": 1,
"per_page": 15,
"total": 150,
"last_page": 10
}
}
```
### Search Venues
Search for venues using advanced search criteria.
**Endpoint:** `GET /api/venues/search`
**Query Parameters:**
- `q` (string, required): Search query
- `category` (string, optional): Filter by category
- `check_in` (date, optional): Check-in date (YYYY-MM-DD)
- `check_out` (date, optional): Check-out date (YYYY-MM-DD)
- `guests` (integer, optional): Number of guests
- `min_price` (number, optional): Minimum price
- `max_price` (number, optional): Maximum price
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"name": "Grand Hotel Sofia",
"description": "Luxury hotel in the heart of Sofia",
"category": "Hotel",
"location": "Sofia, Bulgaria",
"price_from": 120.00,
"rating": 4.5,
"available": true,
"is_favorite": false
}
]
}
```
### Get Venue Details
Retrieve detailed information about a specific venue.
**Endpoint:** `GET /api/venues/{id}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"id": 1,
"name": "Grand Hotel Sofia",
"name_cyrillic": "Гранд Хотел София",
"description": "Luxury hotel in the heart of Sofia with stunning views",
"house_rules": "No smoking indoors\nCheck-out time is 11:00 AM\nQuiet hours after 10 PM",
"category": "Hotel",
"location": "Sofia, Bulgaria",
"address": "1 Sveta Nedelya Square",
"latitude": 42.6977,
"longitude": 23.3219,
"phone": "+359 2 933 4444",
"email": "info@grandhotelsofia.com",
"website": "https://grandhotelsofia.com",
"price_from": 120.00,
"rating": 4.5,
"reviews_count": 234,
"image_url": "https://cdn.zapazime.bg/venues/venue1.jpg",
"gallery_images": [
{
"url": "https://cdn.zapazime.bg/venues/gallery/image1.jpg",
"alt": "Hotel lobby",
"title": "Hotel lobby"
},
{
"url": "https://cdn.zapazime.bg/venues/gallery/image2.jpg",
"alt": "Hotel room",
"title": "Hotel room"
}
],
"seo": {
"meta_title": "Grand Hotel Sofia - Luxury Hotel in Sofia",
"meta_keywords": "hotel, luxury, sofia, accommodation",
"meta_description": "Experience luxury at Grand Hotel Sofia in the heart of Sofia with stunning views",
"og_title": "Grand Hotel Sofia",
"og_description": "Book your stay at Grand Hotel Sofia"
},
"facilities": ["WiFi", "Pool", "Spa", "Restaurant"],
"venue_objects": [
{
"id": 1,
"name": "Deluxe Room",
"description": "Spacious room with city view",
"capacity": 2,
"price": 150.00,
"currency": "EUR"
}
]
}
}
```
"images": [
"https://cdn.zapazime.bg/venues/venue1-1.jpg",
"https://cdn.zapazime.bg/venues/venue1-2.jpg",
"https://cdn.zapazime.bg/venues/venue1-3.jpg"
],
"amenities": [
{"id": 1, "name": "WiFi", "icon": "wifi"},
{"id": 2, "name": "Parking", "icon": "parking"},
{"id": 3, "name": "Pool", "icon": "pool"},
{"id": 4, "name": "Spa", "icon": "spa"}
],
"policies": {
"check_in": "14:00",
"check_out": "12:00",
"cancellation": "24 hours before check-in",
"payment_methods": ["credit_card", "cash", "bank_transfer"]
},
"is_favorite": false,
"company": {
"id": 1,
"name": "Grand Hotel Group",
"logo": "https://cdn.zapazime.bg/companies/company1.png"
}
}
}
```
### Check Venue Availability
Check availability for a specific venue and date range.
**Endpoint:** `POST /api/venues/{id}/availability`
**Request Body:**
```json
{
"check_in": "2026-08-15",
"check_out": "2026-08-18",
"guests": 2
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"available": true,
"available_rooms": [
{
"id": 1,
"name": "Deluxe Room",
"capacity": 2,
"price_per_night": 150.00,
"total_price": 450.00,
"images": ["https://cdn.zapazime.bg/rooms/room1.jpg"]
}
],
"total_price": 450.00
}
}
```
### Get Venue Reviews
Retrieve reviews for a specific venue.
**Endpoint:** `GET /api/venues/{id}/reviews`
**Query Parameters:**
- `page` (integer, optional): Page number (default: 1)
- `per_page` (integer, optional): Items per page (default: 10)
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"user": {
"id": 5,
"name": "Jane Doe",
"avatar": "https://cdn.zapazime.bg/avatars/user5.jpg"
},
"rating": 5,
"title": "Amazing experience!",
"comment": "The hotel was beautiful and the service was excellent.",
"created_at": "2026-07-20T10:30:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 10,
"total": 234,
"last_page": 24
}
}
```
### Get Venue Objects/Rooms
Retrieve available objects/rooms for a specific venue.
**Endpoint:** `GET /api/venues/{venue_id}/objects`
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"name": "Deluxe Room",
"description": "Spacious room with city view",
"capacity": 2,
"price_per_night": 150.00,
"images": ["https://cdn.zapazime.bg/rooms/room1.jpg"],
"amenities": ["tv", "minibar", "safe"]
}
]
}
```
### Get Venue Fiscal Receipts
Retrieve fiscal receipts for a specific venue.
**Endpoint:** `GET /api/venues/{venueId}/fiscal-receipts`
**Query Parameters:**
- `status` (string, optional): Filter by status (printed, failed, cancelled)
- `date_from` (date, optional): Filter by start date (YYYY-MM-DD)
- `date_to` (date, optional): Filter by end date (YYYY-MM-DD)
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"receipt_number": "RCP-2026-001",
"fiscal_number": "FSC-2026-001",
"total_amount": 150.00,
"payment_method": "cash",
"status": "printed",
"printed_at": "2026-08-05 14:30:00",
"booking": {
"id": 123,
"client_name": "John Doe"
}
}
],
"pagination": {
"current_page": 1,
"per_page": 25,
"total": 50,
"last_page": 2
}
}
```
### Get Venue Spots
Retrieve available spots for a specific venue object.
**Endpoint:** `GET /api/venues/{venue_id}/spots`
**Query Parameters:**
- `object_id` (integer, optional): Filter by object ID
- `date` (date, optional): Filter by date
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"name": "Spot A1",
"object_id": 1,
"price": 150.00,
"available": true
}
]
}
```
### Toggle Favorite
Add or remove a venue from favorites.
**Endpoint:** `POST /api/venues/{id}/favorite`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"message": "Venue added to favorites",
"data": {
"is_favorite": true
}
}
```
### Add Venue Review
Submit a review for a venue.
**Endpoint:** `POST /api/venues/{id}/reviews`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"rating": 5,
"title": "Excellent stay!",
"comment": "The hotel exceeded my expectations. Great service and amenities."
}
```
**Response (201 Created):**
```json
{
"success": true,
"message": "Review submitted successfully",
"data": {
"id": 235,
"rating": 5,
"title": "Excellent stay!",
"comment": "The hotel exceeded my expectations. Great service and amenities.",
"created_at": "2026-07-31T15:30:00Z"
}
}
```
### Get Favorites
Retrieve user's favorite venues.
**Endpoint:** `GET /api/user/favorites`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"name": "Grand Hotel Sofia",
"location": "Sofia, Bulgaria",
"price_from": 120.00,
"rating": 4.5,
"image": "https://cdn.zapazime.bg/venues/venue1-1.jpg",
"is_favorite": true
}
]
}
```
---
## Deals
### Public Deal Presentation
| Method | Endpoint | Purpose |
|--------|----------|---------|
| GET | `/api/deals` | Paginated published, active, currently valid, available deals |
| GET | `/api/deals/{deal}` | One public deal by slug or numeric ID, including deal items |
`GET /api/deals` accepts optional `deal_type` (`hot_deals`, `seasonal_deals`, `last_minute_deals`, or `gift_cards`), `page`, and `limit` from 1 to 50 (default 12). Draft, inactive, expired, not-yet-valid, and sold-out deals are never returned publicly.
### Company Deal Management
All endpoints require Sanctum authentication and an active company subscription. Reads require `company.portal`; writes require `company.manage_workspaces`. Every deal and referenced catalog item is restricted to the managed company.
| Method | Endpoint | Purpose |
|--------|----------|---------|
| GET | `/api/company-admin/deals/catalog` | Return eligible venue objects, services, products, and deal types |
| GET | `/api/company-admin/deals` | Paginated company deals with type, status, search, and page-size filters |
| POST | `/api/company-admin/deals` | Create a deal and calculate aggregate prices |
| GET | `/api/company-admin/deals/{deal}` | Return one deal with its items |
| PUT | `/api/company-admin/deals/{deal}` | Replace deal data and items |
| DELETE | `/api/company-admin/deals/{deal}` | Delete a deal and its items |
| POST | `/api/company-admin/deals/{deal}/image` | Upload or replace the deal image using multipart field `image` (maximum 2 MB) |
| POST | `/api/company-admin/deals/{deal}/toggle-publish` | Publish or unpublish the deal |
Create and update requests require `name`, `deal_type`, `is_published`, `is_active`, `sort_order`, and at least one item. Items contain `type` (`venue_object`, `venue_service`, or `product`), `id`, positive integer `quantity`, `unit_price`, and optional `original_unit_price`. Deal and discount totals are calculated by the server.
## Bookings
### Get User Bookings
Retrieve authenticated user's bookings with optional filters.
**Endpoint:** `GET /api/user/bookings`
**Headers:** `Authorization: Bearer {token}`
**Query Parameters:**
- `status` (string, optional): Filter by status (pending, confirmed, completed, cancelled)
- `page` (integer, optional): Page number (default: 1)
- `per_page` (integer, optional): Items per page (default: 15)
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"booking_number": "BKG-2026-001234",
"venue": {
"id": 1,
"name": "Grand Hotel Sofia",
"image": "https://cdn.zapazime.bg/venues/venue1-1.jpg"
},
"check_in": "2026-08-15",
"check_out": "2026-08-18",
"guests": 2,
"total_price": 450.00,
"status": "confirmed",
"created_at": "2026-07-25T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 15,
"total": 25,
"last_page": 2
}
}
```
### Create Booking
Create a new booking.
**Endpoint:** `POST /api/bookings`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"venue_id": 1,
"object_id": 1,
"check_in": "2026-08-15",
"check_out": "2026-08-18",
"guests": 2,
"services": [
{"id": 1, "quantity": 1}
],
"packages": [
{"id": 1, "quantity": 1}
],
"payment_method": "credit_card",
"notes": "Early check-in requested"
}
```
**Response (201 Created):**
```json
{
"success": true,
"message": "Booking created successfully",
"data": {
"id": 1,
"booking_number": "BKG-2026-001234",
"venue": {
"id": 1,
"name": "Grand Hotel Sofia"
},
"check_in": "2026-08-15",
"check_out": "2026-08-18",
"guests": 2,
"total_price": 450.00,
"status": "pending",
"payment_required": true,
"payment_amount": 450.00
}
}
```
### Get Booking Details
Retrieve detailed information about a specific booking.
**Endpoint:** `GET /api/bookings/{id}`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"id": 1,
"booking_number": "BKG-2026-001234",
"venue": {
"id": 1,
"name": "Grand Hotel Sofia",
"address": "1 Sveta Nedelya Square, Sofia",
"phone": "+359 2 933 4444"
},
"object": {
"id": 1,
"name": "Deluxe Room"
},
"check_in": "2026-08-15T14:00:00Z",
"check_out": "2026-08-18T12:00:00Z",
"guests": 2,
"services": [
{
"id": 1,
"name": "Breakfast",
"quantity": 2,
"price": 15.00
}
],
"packages": [],
"total_price": 450.00,
"status": "confirmed",
"payment_status": "paid",
"created_at": "2026-07-25T10:00:00Z",
"qr_code": "https://cdn.zapazime.bg/qr/BKG-2026-001234.png"
}
}
```
### Update Booking
Update an existing booking.
**Endpoint:** `PUT /api/bookings/{id}`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"guests": 3,
"notes": "Updated notes"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Booking updated successfully",
"data": {
"id": 1,
"guests": 3,
"notes": "Updated notes"
}
}
```
### Cancel Booking
Cancel a booking.
**Endpoint:** `POST /api/bookings/{id}/cancel`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"reason": "Change of plans"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Booking cancelled successfully",
"data": {
"id": 1,
"status": "cancelled",
"refund_amount": 450.00,
"refund_status": "processing"
}
}
```
### Request Booking Refund
Request a refund for a booking.
**Endpoint:** `POST /api/bookings/{id}/refund`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"reason": "Service not as described"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Refund request submitted",
"data": {
"refund_id": "REF-2026-000001",
"amount": 450.00,
"status": "processing",
"estimated_processing_time": "5-7 business days"
}
}
```
### Get Booking by QR Code
Retrieve booking information using QR code (for check-in/check-out).
**Endpoint:** `GET /api/bookings/qr/{qrCode}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"id": 1,
"booking_number": "BKG-2026-001234",
"venue": {
"id": 1,
"name": "Grand Hotel Sofia"
},
"guest_name": "John Doe",
"check_in": "2026-08-15",
"check_out": "2026-08-18",
"status": "confirmed",
"can_check_in": true,
"can_check_out": false
}
}
```
### Check In
Perform check-in for a booking.
**Endpoint:** `POST /api/bookings/{booking}/check-in`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"notes": "Guest arrived on time"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Check-in successful",
"data": {
"check_in_time": "2026-08-15T14:30:00Z",
"room_number": "301"
}
}
```
### Check Out
Perform check-out for a booking.
**Endpoint:** `POST /api/bookings/{booking}/check-out`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"notes": "Check-out completed, room clean"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Check-out successful",
"data": {
"check_out_time": "2026-08-18T11:45:00Z",
"final_amount": 450.00
}
}
```
---
## Payments & Transactions
### Get Payment Transactions
Retrieve user's payment transactions.
**Endpoint:** `GET /api/user/transactions`
**Headers:** `Authorization: Bearer {token}`
**Query Parameters:**
- `page` (integer, optional): Page number (default: 1)
- `per_page` (integer, optional): Items per page (default: 15)
- `status` (string, optional): Filter by status
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"transaction_number": "TXN-2026-000123",
"booking_id": 1,
"booking_number": "BKG-2026-001234",
"amount": 450.00,
"currency": "EUR",
"payment_method": "credit_card",
"status": "completed",
"created_at": "2026-07-25T10:05:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 15,
"total": 50,
"last_page": 4
}
}
```
### Get Transaction Details
Retrieve detailed information about a specific transaction.
**Endpoint:** `GET /api/user/transactions/{transaction}`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"id": 1,
"transaction_number": "TXN-2026-000123",
"booking": {
"id": 1,
"booking_number": "BKG-2026-001234",
"venue_name": "Grand Hotel Sofia"
},
"amount": 450.00,
"currency": "EUR",
"payment_method": "credit_card",
"card_last_four": "4242",
"status": "completed",
"created_at": "2026-07-25T10:05:00Z",
"receipt_url": "https://cdn.zapazime.bg/receipts/TXN-2026-000123.pdf"
}
}
```
### Get Transaction Receipt
Download transaction receipt.
**Availability:** No mobile API receipt-download endpoint is currently registered. Use `GET /api/user/transactions/{id}` for transaction data.
**Headers:** `Authorization: Bearer {token}`
**Response:** PDF file download
### MyPOS Online Payment
Create a payment using MyPOS online payment system.
**Endpoint:** `POST /api/mypos/payments/create`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"booking_id": 1,
"amount": 450.00,
"currency": "EUR",
"description": "Payment for booking BKG-2026-001234"
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"payment_id": "MYPOS-2026-000001",
"payment_url": "https://mypos.eu/v1/checkout/...",
"expires_at": "2026-07-31T16:00:00Z"
}
}
```
### Confirm MyPOS Payment
Confirm a MyPOS payment.
**Endpoint:** `POST /api/mypos/payments/confirm`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"payment_id": "MYPOS-2026-000001"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Payment confirmed successfully",
"data": {
"payment_id": "MYPOS-2026-000001",
"status": "completed",
"transaction_id": "TXN-2026-000123"
}
}
```
---
## Invoices
### Get User Invoices
Retrieve user's invoices with optional status filter.
**Endpoint:** `GET /api/user/invoices`
**Headers:** `Authorization: Bearer {token}`
**Query Parameters:**
- `limit` (integer, optional): Items per page (default: 20)
- `status` (string, optional): Filter by status (paid, unpaid, etc.) - default: 'all'
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"invoice_number": "INV-2026-000123",
"booking_id": 1,
"booking_number": "BKG-2026-001234",
"venue_name": "Grand Hotel Sofia",
"amount": 450.00,
"tax": 0.00,
"total": 450.00,
"currency": "EUR",
"status": "paid",
"due_date": "2026-08-01T00:00:00Z",
"paid_date": "2026-07-25T00:00:00Z",
"created_at": "2026-07-25T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 30,
"last_page": 2
}
}
```
### Get Single Invoice
Retrieve detailed information about a specific invoice including line items.
**Endpoint:** `GET /api/user/invoices/{id}`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"id": 1,
"invoice_number": "INV-2026-000123",
"booking": {
"id": 1,
"booking_number": "BKG-2026-001234",
"venue_name": "Grand Hotel Sofia",
"venue_address": "1 Sveta Nedelya Square, Sofia"
},
"client": {
"name": "John Doe",
"vat_number": "BG123456789"
},
"items": [
{
"description": "Deluxe Room (3 nights)",
"quantity": 3,
"unit_price": 150.00,
"total": 450.00
}
],
"subtotal": 450.00,
"tax": 0.00,
"total": 450.00,
"currency": "EUR",
"status": "paid",
"due_date": "2026-08-01T00:00:00Z",
"paid_date": "2026-07-25T00:00:00Z",
"created_at": "2026-07-25T10:00:00Z",
"updated_at": "2026-07-25T10:00:00Z"
}
}
```
### Download Invoice
Download invoice PDF.
**Note:** This endpoint is not yet implemented in the API. It is available in the web interface at `/client/invoices/{invoice}/download`.
**Planned path:** `/api/invoices/{invoice}/download` — not registered; do not call it from the mobile app.
**Headers:** `Authorization: Bearer {token}`
**Response:** PDF file download
---
## Notifications
### Get User Notifications
Retrieve user's notifications.
**Endpoint:** `GET /api/user/notifications`
**Headers:** `Authorization: Bearer {token}`
**Query Parameters:**
- `page` (integer, optional): Page number (default: 1)
- `per_page` (integer, optional): Items per page (default: 20)
- `unread_only` (boolean, optional): Filter unread only
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"type": "booking_confirmation",
"title": "Booking Confirmed",
"message": "Your booking BKG-2026-001234 has been confirmed",
"data": {
"booking_id": 1,
"booking_number": "BKG-2026-001234"
},
"read": false,
"created_at": "2026-07-25T10:30:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 45,
"last_page": 3,
"unread_count": 5
}
}
```
### Mark Notification as Read
Mark a specific notification as read.
**Endpoint:** `POST /api/user/notifications/{id}/read`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"message": "Notification marked as read"
}
```
### Mark All Notifications as Read
Mark all notifications as read.
**Endpoint:** `POST /api/user/notifications/read-all`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"message": "All notifications marked as read"
}
```
### Get Notification Preferences
Retrieve user's notification preferences.
**Endpoint:** `GET /api/user/notification-preferences`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"email_notifications": true,
"sms_notifications": false,
"push_notifications": true,
"booking_updates": true,
"promotional_offers": false,
"newsletters": false
}
}
```
### Update Notification Preferences
Update user's notification preferences.
**Endpoint:** `PUT /api/user/notification-preferences`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"email_notifications": true,
"sms_notifications": false,
"push_notifications": true,
"booking_updates": true,
"promotional_offers": false,
"newsletters": false
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Notification preferences updated",
"data": {
"email_notifications": true,
"sms_notifications": false,
"push_notifications": true,
"booking_updates": true,
"promotional_offers": false,
"newsletters": false
}
}
```
---
## Favorites & Wishlist
### Get Favorites
Retrieve user's favorite venues.
**Endpoint:** `GET /api/user/favorites`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"venue_id": 1,
"venue": {
"id": 1,
"name": "Grand Hotel Sofia",
"location": "Sofia, Bulgaria",
"price_from": 120.00,
"rating": 4.5,
"image": "https://cdn.zapazime.bg/venues/venue1-1.jpg"
},
"created_at": "2026-07-20T15:00:00Z"
}
]
}
```
### Toggle Favorite (Location)
Add or remove a location from favorites.
**Endpoint:** `POST /api/locations/{id}/favorite`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"message": "Location added to favorites",
"data": {
"is_favorite": true
}
}
```
---
## Reviews
### Get User Reviews
Retrieve reviews written by the authenticated user.
**Endpoint:** `GET /api/user/reviews`
**Headers:** `Authorization: Bearer {token}`
**Query Parameters:**
- `limit` (integer, optional): Items per page (default: 20)
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"venue": {
"id": 1,
"name": "Grand Hotel Sofia"
},
"place": {
"id": 1,
"name": "Sofia City Center"
},
"rating": 5,
"title": "Amazing experience!",
"comment": "The hotel was beautiful and the service was excellent.",
"cleanliness_rating": 5,
"location_rating": 5,
"value_rating": 5,
"service_rating": 5,
"created_at": "2026-07-20T10:30:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 12,
"last_page": 1
}
}
```
---
## Bonus Points
### Get Bonus Points Balance
Retrieve user's bonus points balance and statistics.
**Endpoint:** `GET /api/bonus-points`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"current_balance": 2500,
"total_earned": 5000,
"total_spent": 2500,
"tier": "Gold",
"next_tier": "Platinum",
"points_to_next_tier": 2500,
"expiry_date": "2026-12-31"
}
}
```
### Get Bonus Points Transaction History
Retrieve user's bonus points transaction history.
**Endpoint:** `GET /api/bonus-points/transactions`
**Headers:** `Authorization: Bearer {token}`
**Query Parameters:**
- `page` (integer, optional): Page number (default: 1)
- `per_page` (integer, optional): Items per page (default: 20)
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"type": "earned",
"points": 500,
"description": "Points earned from booking BKG-2026-001234",
"balance_after": 2500,
"created_at": "2026-07-25T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 45,
"last_page": 3
}
}
```
### Get Bonus Points Statistics
Retrieve user's bonus points statistics.
**Endpoint:** `GET /api/bonus-points/statistics`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"current_balance": 2500,
"earned_this_month": 500,
"earned_this_year": 3000,
"spent_this_month": 0,
"spent_this_year": 2500,
"average_monthly_earning": 250,
"redemption_rate": 50
}
}
```
### Spend Bonus Points
Redeem bonus points for discounts or rewards.
**Endpoint:** `POST /api/bonus-points/spend`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"points": 1000,
"reward_type": "discount",
"booking_id": 1
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Points redeemed successfully",
"data": {
"points_spent": 1000,
"discount_amount": 10.00,
"remaining_balance": 1500
}
}
```
---
## Location Services
### Location Recommendations and Nearby Venues
| Method | Endpoint | Request |
|--------|----------|---------|
| POST | `/api/location/recommendations` | `latitude` and `longitude` required; optional integer `radius` from 1–100 km (default 20) |
| POST | `/api/location/nearby` | `latitude` and `longitude` required; optional `bounds` array `[sw_lat, sw_lng, ne_lat, ne_lng]`; otherwise a 50 km radius is used |
The routes are currently registered in the web route stack. The recommendations controller expects an authenticated user because it records a location-services bonus. Mobile clients using bearer authentication should not rely on this operation until it is moved under API/Sanctum middleware.
### Get Location Services
Retrieve location-based services available to the user.
**Availability:** The legacy `/api/location-services` endpoint is not registered. Use the recommendation, nearby, status, and preference operations documented in this section.
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"location_enabled": true,
"nearby_venues": [
{
"id": 1,
"name": "Grand Hotel Sofia",
"distance": 0.5,
"unit": "km",
"price_from": 120.00
}
],
"services": [
{
"type": "navigation",
"enabled": true
},
{
"type": "weather",
"enabled": true
}
]
}
}
```
### Get Location Status
Get user's current location status and permissions.
**Endpoint:** `GET /api/user/location/status`
**Headers:** `Authorization: Bearer {token}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"location_enabled": true,
"latitude": 42.6977,
"longitude": 23.3219,
"accuracy": 10.0,
"last_updated": "2026-07-31T15:00:00Z"
}
}
```
### Update Location Preference
Update user's location preferences.
**Endpoint:** `PUT /api/user/location/preferences`
**Headers:** `Authorization: Bearer {token}`
**Request Body:**
```json
{
"location_enabled": true,
"nearby_search_radius": 5.0,
"unit": "km"
}
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Location preferences updated",
"data": {
"location_enabled": true,
"nearby_search_radius": 5.0,
"unit": "km"
}
}
```
### Search Locations
Search for locations with auto-suggest.
**Endpoint:** `GET /api/locations/suggest`
**Query Parameters:**
- `q` (string, required): Search query
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"name": "Sofia",
"country": "Bulgaria",
"latitude": 42.6977,
"longitude": 23.3219,
"venue_count": 45
}
]
}
```
### Advanced Location Search
Advanced search for locations with filters.
**Endpoint:** `GET /api/locations/advanced-search`
**Query Parameters:**
- `q` (string, required): Search query
- `country` (string, optional): Filter by country
- `region` (string, optional): Filter by region
- `min_venues` (integer, optional): Minimum venue count
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"name": "Sofia",
"country": "Bulgaria",
"region": "Sofia Province",
"latitude": 42.6977,
"longitude": 23.3219,
"venue_count": 45,
"featured_image": "https://cdn.zapazime.bg/locations/sofia.jpg"
}
]
}
```
### Get Location Search Criteria
Get all available search criteria for locations page filters. Returns comprehensive filter options organized by booking type (spots, rentals, services) with support for dynamic extensibility.
**Endpoint:** `GET /api/locations/search-criteria`
**Query Parameters:**
- `locale` (string, optional): Language locale (default: app locale)
**Response (200 OK):**
```json
{
"success": true,
"data": {
"booking_types": {
"spots": {
"title": "Find Your Perfect Spot",
"subtitle": "Discover amazing beaches, parks, and camping sites",
"icon": "🏖️",
"filters": {
"location_dates": {
"title": "Location & Dates",
"fields": [
{
"key": "ss",
"type": "text",
"label": "Destination",
"placeholder": "Where are you going?",
"icon": "📍"
},
{
"key": "checkin",
"type": "date",
"label": "Check-in",
"icon": "🏖️"
},
{
"key": "checkout",
"type": "date",
"label": "Check-out",
"icon": "🏖️"
},
{
"key": "group_adults",
"type": "select",
"label": "Adults",
"options": [
{"value": "1", "label": "1"},
{"value": "2", "label": "2"},
{"value": "3", "label": "3"},
{"value": "4", "label": "4"},
{"value": "5", "label": "5+"}
]
},
{
"key": "group_children",
"type": "select",
"label": "Children",
"options": [
{"value": "0", "label": "0"},
{"value": "1", "label": "1"},
{"value": "2", "label": "2"},
{"value": "3", "label": "3+"}
]
}
]
},
"price_budget": {
"title": "Price & Budget",
"fields": [
{
"key": "min_price",
"type": "number",
"label": "Min Price",
"placeholder": "0",
"prefix": "€"
},
{
"key": "max_price",
"type": "number",
"label": "Max Price",
"placeholder": "1000",
"prefix": "€"
},
{
"key": "budget_preset",
"type": "preset_buttons",
"label": "Budget Range",
"options": [
{"value": "0-50", "label": "Budget (€0-50)"},
{"value": "50-150", "label": "Mid-range (€50-150)"},
{"value": "150-300", "label": "Premium (€150-300)"},
{"value": "300+", "label": "Luxury (€300+)"}
]
}
]
},
"property_features": {
"title": "Property & Features",
"fields": [
{
"key": "spot_category",
"type": "select",
"label": "Spot Type",
"options": [
{"value": "", "label": "All Types"},
{"value": "beaches", "label": "🏖️ Beaches"},
{"value": "camping", "label": "🏕️ Camping"},
{"value": "parks", "label": "🌳 Parks"},
{"value": "parking", "label": "🅿️ Parking"}
]
},
{
"key": "amenities",
"type": "checkbox_group",
"label": "Amenities",
"options": [
{"value": "wifi", "label": "📶 WiFi"},
{"value": "parking", "label": "🅿️ Parking"},
{"value": "restrooms", "label": "🚻 Restrooms"}
]
}
]
},
"rating_reviews": {
"title": "Rating & Reviews",
"fields": [
{
"key": "min_rating",
"type": "radio",
"label": "Minimum Rating",
"options": [
{"value": "", "label": "Any rating"},
{"value": "3", "label": "⭐⭐⭐ 3+ Good"},
{"value": "4", "label": "⭐⭐⭐⭐ 4+ Very Good"},
{"value": "4.5", "label": "⭐⭐⭐⭐⭐ 4.5+ Excellent"}
]
},
{
"key": "min_reviews",
"type": "select",
"label": "Minimum Reviews",
"options": [
{"value": "", "label": "Any number"},
{"value": "5", "label": "5+ reviews"},
{"value": "10", "label": "10+ reviews"},
{"value": "25", "label": "25+ reviews"},
{"value": "50", "label": "50+ reviews"}
]
}
]
}
}
},
"rentals": {
"title": "Book Your Perfect Rental",
"subtitle": "Find apartments, houses, and vehicles for rent",
"icon": "🏠",
"filters": {
"location_dates": {
"title": "Location & Dates",
"fields": [
{
"key": "ss",
"type": "text",
"label": "Destination",
"placeholder": "Where are you going?",
"icon": "📍"
},
{
"key": "pickup",
"type": "date",
"label": "Pick-up",
"icon": "🚗"
},
{
"key": "dropoff",
"type": "date",
"label": "Drop-off",
"icon": "🚗"
},
{
"key": "group_adults",
"type": "select",
"label": "Adults",
"options": [
{"value": "1", "label": "1"},
{"value": "2", "label": "2"},
{"value": "3", "label": "3"},
{"value": "4", "label": "4"},
{"value": "5", "label": "5+"}
]
},
{
"key": "group_children",
"type": "select",
"label": "Children",
"options": [
{"value": "0", "label": "0"},
{"value": "1", "label": "1"},
{"value": "2", "label": "2"},
{"value": "3", "label": "3+"}
]
},
{
"key": "no_rooms",
"type": "select",
"label": "Rooms",
"options": [
{"value": "1", "label": "1 room"},
{"value": "2", "label": "2 rooms"},
{"value": "3", "label": "3 rooms"},
{"value": "4", "label": "4+ rooms"}
]
}
]
},
"price_budget": {
"title": "Price & Budget",
"fields": [
{
"key": "min_price",
"type": "number",
"label": "Min Price",
"placeholder": "0",
"prefix": "€"
},
{
"key": "max_price",
"type": "number",
"label": "Max Price",
"placeholder": "1000",
"prefix": "€"
},
{
"key": "budget_preset",
"type": "preset_buttons",
"label": "Budget Range",
"options": [
{"value": "0-50", "label": "Budget (€0-50)"},
{"value": "50-150", "label": "Mid-range (€50-150)"},
{"value": "150-300", "label": "Premium (€150-300)"},
{"value": "300+", "label": "Luxury (€300+)"}
]
}
]
},
"property_features": {
"title": "Property & Features",
"fields": [
{
"key": "property_type",
"type": "select",
"label": "Property Type",
"options": [
{"value": "", "label": "All Properties"},
{"value": "apartment", "label": "🏠 Apartments"},
{"value": "house", "label": "🏡 Houses"},
{"value": "villa", "label": "🏖️ Villas"},
{"value": "vehicle", "label": "🚗 Vehicles"}
]
},
{
"key": "amenities",
"type": "checkbox_group",
"label": "Amenities",
"options": [
{"value": "wifi", "label": "📶 WiFi"},
{"value": "kitchen", "label": "🍳 Kitchen"},
{"value": "ac", "label": "❄️ Air Conditioning"},
{"value": "pool", "label": "🏊 Pool"}
]
}
]
},
"rating_reviews": {
"title": "Rating & Reviews",
"fields": [
{
"key": "min_rating",
"type": "radio",
"label": "Minimum Rating",
"options": [
{"value": "", "label": "Any rating"},
{"value": "3", "label": "⭐⭐⭐ 3+ Good"},
{"value": "4", "label": "⭐⭐⭐⭐ 4+ Very Good"},
{"value": "4.5", "label": "⭐⭐⭐⭐⭐ 4.5+ Excellent"}
]
},
{
"key": "min_reviews",
"type": "select",
"label": "Minimum Reviews",
"options": [
{"value": "", "label": "Any number"},
{"value": "5", "label": "5+ reviews"},
{"value": "10", "label": "10+ reviews"},
{"value": "25", "label": "25+ reviews"},
{"value": "50", "label": "50+ reviews"}
]
}
]
}
}
},
"services": {
"title": "Schedule Professional Services",
"subtitle": "Connect with doctors, lawyers, and other professionals",
"icon": "👩⚕️",
"filters": {
"location_dates": {
"title": "Location & Dates",
"fields": [
{
"key": "ss",
"type": "text",
"label": "Destination",
"placeholder": "Where are you going?",
"icon": "📍"
},
{
"key": "appointment",
"type": "date",
"label": "Appointment Date",
"icon": "🕐"
}
]
},
"price_budget": {
"title": "Price & Budget",
"fields": [
{
"key": "min_price",
"type": "number",
"label": "Min Price",
"placeholder": "0",
"prefix": "€"
},
{
"key": "max_price",
"type": "number",
"label": "Max Price",
"placeholder": "1000",
"prefix": "€"
},
{
"key": "budget_preset",
"type": "preset_buttons",
"label": "Budget Range",
"options": [
{"value": "0-50", "label": "Budget (€0-50)"},
{"value": "50-150", "label": "Mid-range (€50-150)"},
{"value": "150-300", "label": "Premium (€150-300)"},
{"value": "300+", "label": "Luxury (€300+)"}
]
}
]
},
"property_features": {
"title": "Property & Features",
"fields": [
{
"key": "service_category",
"type": "select",
"label": "Service Type",
"options": [
{"value": "", "label": "All Services"},
{"value": "medical", "label": "👩⚕️ Medical"},
{"value": "legal", "label": "⚖️ Legal"},
{"value": "consulting", "label": "💼 Consulting"},
{"value": "beauty", "label": "💅 Beauty & Wellness"}
]
},
{
"key": "features",
"type": "checkbox_group",
"label": "Features",
"options": [
{"value": "online", "label": "💻 Online Available"},
{"value": "emergency", "label": "🚨 Emergency Service"},
{"value": "certified", "label": "✅ Certified"}
]
}
]
},
"rating_reviews": {
"title": "Rating & Reviews",
"fields": [
{
"key": "min_rating",
"type": "radio",
"label": "Minimum Rating",
"options": [
{"value": "", "label": "Any rating"},
{"value": "3", "label": "⭐⭐⭐ 3+ Good"},
{"value": "4", "label": "⭐⭐⭐⭐ 4+ Very Good"},
{"value": "4.5", "label": "⭐⭐⭐⭐⭐ 4.5+ Excellent"}
]
},
{
"key": "min_reviews",
"type": "select",
"label": "Minimum Reviews",
"options": [
{"value": "", "label": "Any number"},
{"value": "5", "label": "5+ reviews"},
{"value": "10", "label": "10+ reviews"},
{"value": "25", "label": "25+ reviews"},
{"value": "50", "label": "50+ reviews"}
]
}
]
}
}
}
},
"common_filters": {
"sort_options": [
{"value": "", "label": "Sort by"},
{"value": "price", "label": "Price"},
{"value": "rating", "label": "Rating"},
{"value": "distance", "label": "Distance"}
],
"view_options": [
{"value": "grid", "label": "Grid"},
{"value": "list", "label": "List"},
{"value": "map", "label": "Map"}
]
}
},
"locale": "en"
}
```
**Field Types:**
- `text`: Text input field
- `date`: Date picker field
- `number`: Numeric input field
- `select`: Dropdown selection
- `radio`: Radio button group
- `checkbox_group`: Multiple checkbox selection
- `preset_buttons`: Predefined button options for quick selection
**Dynamic Extensibility:**
The endpoint structure supports dynamic addition of new filter criteria by:
1. Adding new field definitions to existing filter sections
2. Adding entirely new filter sections to any booking type
3. Adding new booking types with their own filter configurations
4. Extending common filters for shared functionality
---
## Categories
### Get Categories
Retrieve all venue categories.
**Endpoint:** `GET /api/categories`
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"name": "Hotel",
"slug": "hotel",
"icon": "hotel",
"venue_count": 150
},
{
"id": 2,
"name": "Restaurant",
"slug": "restaurant",
"icon": "restaurant",
"venue_count": 89
}
]
}
```
### Get Categories by Booking Type
Retrieve categories filtered by booking type.
**Endpoint:** `GET /api/categories/{bookingType}`
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": 1,
"name": "Hotel",
"slug": "hotel",
"icon": "hotel"
}
]
}
```
---
## Geocoding
### Geocode Address
Convert address to coordinates.
**Endpoint:** `POST /api/geocode/address`
**Request Body:**
```json
{
"address": "1 Sveta Nedelya Square, Sofia, Bulgaria"
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"latitude": 42.6977,
"longitude": 23.3219,
"formatted_address": "1 Sveta Nedelya Square, Sofia, Bulgaria"
}
}
```
### Reverse Geocode
Convert coordinates to address.
**Endpoint:** `POST /api/geocode/reverse`
**Request Body:**
```json
{
"latitude": 42.6977,
"longitude": 23.3219
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"address": "1 Sveta Nedelya Square",
"city": "Sofia",
"country": "Bulgaria",
"postal_code": "1000"
}
}
```
### Validate Coordinates
Validate if coordinates are within service area.
**Endpoint:** `POST /api/geocode/validate`
**Request Body:**
```json
{
"latitude": 42.6977,
"longitude": 23.3219
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"valid": true,
"within_service_area": true,
"nearest_city": "Sofia"
}
}
```
---
## Venue Translation Management
All translation operations require Sanctum authentication, a verified email, and venue-policy authorization.
| Method | Endpoint | Purpose |
|--------|----------|---------|
| GET | `/api/venues/{venue}/translations` | List translations, supported locales, and completion status |
| GET | `/api/venues/{venue}/translations/{locale}` | Retrieve one locale |
| POST | `/api/venues/{venue}/translations` | Create or replace a translation; requires `locale`, `name`, and `description` |
| PUT | `/api/venues/{venue}/translations/{locale}` | Update a locale; requires `name` and `description` |
| DELETE | `/api/venues/{venue}/translations/{locale}` | Delete a locale |
| POST | `/api/venues/{venue}/translations/bulk` | Save a required `translations` array |
| POST | `/api/venues/{venue}/translations/copy` | Copy `from_locale` to `to_locale` |
| GET | `/api/venues/{venue}/translations/status` | Return translation completion status |
| GET | `/api/venues/{venue}/translations/export` | Export all venue translations as JSON data |
| POST | `/api/venues/{venue}/translations/import` | Import a required `translations` array |
| GET | `/api/translations/search` | Search venues by translated content |
| GET | `/api/translations/analytics` | Return translation analytics; controller restricts this operation to administrators |
Translation content additionally supports `short_description`, `address`, `city`, `country`, `directions`, `amenities`, `policies`, `accessibility_info`, `meta_title`, `meta_description`, and `additional_data`.
## Company Admin API
The Company Admin API provides endpoints for managing venues, bookings, clients, users, inventory, messaging, and statistics for company administrators. All endpoints require authentication using Sanctum tokens.
**Base Path:** `/api/company-admin`
**Authentication:** Required (Bearer Token)
### Dashboard Statistics
Get comprehensive dashboard statistics for the company.
**Endpoint:** `GET /api/company-admin/dashboard/stats`
**Response (200 OK):**
```json
{
"total_clients": 150,
"total_users": 25,
"total_bookings": 450,
"total_revenue": 125000.50,
"active_bookings": 35,
"pending_tasks": 12
}
```
### Venues
#### List Venues
Get all venues belonging to the company.
**Endpoint:** `GET /api/company-admin/venues`
**Response (200 OK):**
```json
[
{
"id": 1,
"name": "Hotel Paradise",
"address": "123 Main Street",
"city": "Sofia",
"country": "Bulgaria",
"business_type": "rentals",
"is_active": true
}
]
```
#### Create Venue
Create a new venue.
**Endpoint:** `POST /api/company-admin/venues`
**Request Body:**
```json
{
"name": "New Venue",
"address": "456 New Street",
"city": "Plovdiv",
"country": "Bulgaria",
"business_type": "spot"
}
```
**Response (201 Created):**
```json
{
"id": 2,
"name": "New Venue",
"address": "456 New Street",
"city": "Plovdiv",
"country": "Bulgaria",
"business_type": "spot",
"company_id": 1
}
```
#### Update Venue
Update an existing venue.
**Endpoint:** `PUT /api/company-admin/venues/{venue}`
**Request Body:**
```json
{
"name": "Updated Venue Name",
"address": "789 Updated Street"
}
```
**Response (200 OK):**
```json
{
"id": 1,
"name": "Updated Venue Name",
"address": "789 Updated Street",
"city": "Sofia",
"country": "Bulgaria"
}
```
#### Delete Venue
Delete a venue.
**Endpoint:** `DELETE /api/company-admin/venues/{venue}`
**Response (200 OK):**
```json
{
"message": "Venue deleted successfully"
}
```
### Bookings
#### List Bookings
Get all bookings with optional filtering.
**Endpoint:** `GET /api/company-admin/bookings`
**Query Parameters:**
- `status` (optional): Filter by booking status (pending, confirmed, checked_in, completed, cancelled)
- `date_from` (optional): Filter by check-in date from
- `date_to` (optional): Filter by check-in date to
**Response (200 OK):**
```json
{
"data": [
{
"id": 1,
"client_id": 5,
"venue_id": 1,
"venue_object_id": 10,
"check_in": "2026-08-10",
"check_out": "2026-08-15",
"total_amount": 500.00,
"status": "confirmed",
"client": {
"id": 5,
"name": "John Doe"
},
"venue": {
"id": 1,
"name": "Hotel Paradise"
}
}
],
"current_page": 1,
"total": 100
}
```
#### Get Booking Details
Get detailed information about a specific booking.
**Endpoint:** `GET /api/company-admin/bookings/{booking}`
**Response (200 OK):**
```json
{
"id": 1,
"client_id": 5,
"venue_id": 1,
"venue_object_id": 10,
"check_in": "2026-08-10",
"check_out": "2026-08-15",
"total_amount": 500.00,
"status": "confirmed",
"client": {
"id": 5,
"name": "John Doe",
"email": "john@example.com"
},
"venue": {
"id": 1,
"name": "Hotel Paradise"
},
"stays": [],
"payments": []
}
```
#### Create Booking
Create a new booking.
**Endpoint:** `POST /api/company-admin/bookings`
**Request Body:**
```json
{
"client_id": 5,
"venue_id": 1,
"venue_object_id": 10,
"check_in": "2026-08-10",
"check_out": "2026-08-15",
"total_amount": 500.00,
"booking_type": "rentals"
}
```
**Response (201 Created):**
```json
{
"id": 2,
"status": "pending",
"client_id": 5,
"venue_id": 1,
"venue_object_id": 10
}
```
#### Update Booking
Update an existing booking.
**Endpoint:** `PUT /api/company-admin/bookings/{booking}`
**Request Body:**
```json
{
"total_amount": 550.00,
"status": "confirmed"
}
```
**Response (200 OK):**
```json
{
"id": 1,
"total_amount": 550.00,
"status": "confirmed"
}
```
#### Check In Booking
Check in a guest.
**Endpoint:** `POST /api/company-admin/bookings/{booking}/check-in`
**Response (200 OK):**
```json
{
"id": 1,
"status": "checked_in",
"checked_in_at": "2026-08-10T14:00:00Z",
"checked_in_by": 3
}
```
#### Check Out Booking
Check out a guest.
**Endpoint:** `POST /api/company-admin/bookings/{booking}/check-out`
**Response (200 OK):**
```json
{
"id": 1,
"status": "completed",
"checked_out_at": "2026-08-15T11:00:00Z",
"checked_out_by": 3
}
```
#### Cancel Booking
Cancel a booking.
**Endpoint:** `POST /api/company-admin/bookings/{booking}/cancel`
**Response (200 OK):**
```json
{
"id": 1,
"status": "cancelled"
}
```
### Clients
#### List Clients
Get all clients with optional search.
**Endpoint:** `GET /api/company-admin/clients`
**Query Parameters:**
- `search` (optional): Search by name, email, or phone
**Response (200 OK):**
```json
{
"data": [
{
"id": 5,
"name": "John Doe",
"email": "john@example.com",
"phone": "+359 888 123 456",
"address": "123 Client Street"
}
],
"current_page": 1,
"total": 150
}
```
#### Get Client Details
Get detailed information about a specific client.
**Endpoint:** `GET /api/company-admin/clients/{client}`
**Response (200 OK):**
```json
{
"id": 5,
"name": "John Doe",
"email": "john@example.com",
"phone": "+359 888 123 456",
"reservations": [],
"invoices": []
}
```
#### Create Client
Create a new client.
**Endpoint:** `POST /api/company-admin/clients`
**Request Body:**
```json
{
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "+359 888 987 654",
"address": "456 Client Avenue"
}
```
**Response (201 Created):**
```json
{
"id": 6,
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "+359 888 987 654",
"company_id": 1
}
```
#### Update Client
Update an existing client.
**Endpoint:** `PUT /api/company-admin/clients/{client}`
**Request Body:**
```json
{
"name": "Jane Smith Updated",
"phone": "+359 888 111 222"
}
```
**Response (200 OK):**
```json
{
"id": 6,
"name": "Jane Smith Updated",
"email": "jane@example.com",
"phone": "+359 888 111 222"
}
```
### Users
#### List Users
Get all users in the company with their roles.
**Endpoint:** `GET /api/company-admin/users`
**Response (200 OK):**
```json
[
{
"id": 3,
"name": "Admin User",
"email": "admin@company.com",
"roles": [
{
"id": 1,
"name": "admin"
}
]
}
]
```
#### Create User
Create a new user.
**Endpoint:** `POST /api/company-admin/users`
**Request Body:**
```json
{
"name": "New Staff Member",
"email": "staff@company.com",
"password": "SecurePassword123!"
}
```
**Response (201 Created):**
```json
{
"id": 4,
"name": "New Staff Member",
"email": "staff@company.com",
"company_id": 1
}
```
#### Update User
Update an existing user.
**Endpoint:** `PUT /api/company-admin/users/{user}`
**Request Body:**
```json
{
"name": "Updated Staff Name",
"email": "updated@company.com"
}
```
**Response (200 OK):**
```json
{
"id": 4,
"name": "Updated Staff Name",
"email": "updated@company.com"
}
```
#### Delete User
Delete a user.
**Endpoint:** `DELETE /api/company-admin/users/{user}`
**Response (200 OK):**
```json
{
"message": "User deleted successfully"
}
```
### Venue Objects
#### List Venue Objects
Get all venue objects (rooms, spots, etc.) for the company.
**Endpoint:** `GET /api/company-admin/venue-objects`
**Response (200 OK):**
```json
[
{
"id": 10,
"venue_id": 1,
"name": "Room 101",
"type": "room",
"capacity": 2,
"venue": {
"id": 1,
"name": "Hotel Paradise"
}
}
]
```
#### Create Venue Object
Create a new venue object.
**Endpoint:** `POST /api/company-admin/venue-objects`
**Request Body:**
```json
{
"venue_id": 1,
"name": "Room 102",
"type": "room",
"capacity": 2
}
```
**Response (201 Created):**
```json
{
"id": 11,
"venue_id": 1,
"name": "Room 102",
"type": "room",
"capacity": 2
}
```
### Inventory
#### List Inventory
Get all inventory items (amenities) with their locations and stock levels.
**Endpoint:** `GET /api/company-admin/inventory`
**Response (200 OK):**
```json
[
{
"id": 1,
"name": "Towel Set",
"sku": "TOW-001",
"category": "linens",
"cost_per_unit": 15.50,
"unit": "piece",
"active": true,
"total_quantity": 100,
"inventories": [
{
"id": 1,
"location": "central",
"venue_id": null,
"venue_object_id": null,
"current_quantity": 50,
"minimum_threshold": 10,
"maximum_capacity": 200,
"reorder_quantity": 25
}
]
}
]
```
#### Create Inventory Item
Create a new inventory item.
**Endpoint:** `POST /api/company-admin/inventory`
**Request Body:**
```json
{
"name": "Soap Dispenser",
"sku": "SOAP-002",
"category": "amenities",
"unit": "piece",
"cost_per_unit": 8.00,
"initial_quantity": 200,
"minimum_threshold": 20,
"location": "central"
}
```
Optional stock fields (`initial_quantity`, `minimum_threshold`, `maximum_capacity`, `reorder_quantity`, `venue_id`, `venue_object_id`, `location`) create an initial `AmenityInventory` record when `initial_quantity` is provided.
**Response (201 Created):**
```json
{
"id": 2,
"name": "Soap Dispenser",
"sku": "SOAP-002",
"category": "amenities",
"unit": "piece",
"cost_per_unit": 8.00,
"company_id": 1,
"inventories": [
{
"id": 5,
"location": "central",
"current_quantity": 200,
"minimum_threshold": 20
}
]
}
```
#### Update Inventory Stock
Update stock level for a specific inventory location.
**Endpoint:** `POST /api/company-admin/inventory/inventory/{inventory}/update-stock`
**Request Body:**
```json
{
"quantity": 75
}
```
The `quantity` value is written to the `current_quantity` column of the `AmenityInventory` record. The record must belong to the authenticated user's company.
**Response (200 OK):**
```json
{
"id": 1,
"amenity_id": 1,
"location": "central",
"current_quantity": 75,
"minimum_threshold": 10
}
```
### Messaging
#### List Conversations
Get all conversations for the authenticated user.
**Endpoint:** `GET /api/company-admin/messaging/conversations`
**Response (200 OK):**
```json
[
{
"id": 1,
"name": "Housekeeping Team",
"type": "group",
"participants": [
{
"id": 3,
"name": "Admin User"
}
],
"last_message": {
"id": 10,
"content": "Meeting at 2 PM",
"created_at": "2026-08-04T10:30:00Z"
}
}
]
```
#### Get Conversation Details
Get conversation details with all messages.
**Endpoint:** `GET /api/company-admin/messaging/conversations/{conversation}`
**Response (200 OK):**
```json
{
"conversation": {
"id": 1,
"name": "Housekeeping Team",
"type": "group",
"participants": []
},
"messages": [
{
"id": 10,
"content": "Meeting at 2 PM",
"sender": {
"id": 3,
"name": "Admin User"
},
"created_at": "2026-08-04T10:30:00Z"
}
]
}
```
#### Create Conversation
Create a new conversation (private or group).
**Endpoint:** `POST /api/company-admin/messaging/conversations`
**Request Body:**
```json
{
"type": "group",
"name": "Management Team",
"participants": [4, 5, 6]
}
```
**Response (201 Created):**
```json
{
"id": 2,
"name": "Management Team",
"type": "group",
"company_id": 1,
"created_by": 3
}
```
#### Send Message
Send a message in a conversation.
**Endpoint:** `POST /api/company-admin/messaging/conversations/{conversation}/send`
**Request Body:**
```json
{
"content": "Hello team, please check room 101"
}
```
**Response (201 Created):**
```json
{
"id": 11,
"content": "Hello team, please check room 101",
"conversation_id": 1,
"sender_id": 3,
"type": "text",
"sender": {
"id": 3,
"name": "Admin User"
}
}
```
### Statistics
#### Get Comprehensive Statistics
Get comprehensive statistics for the company.
**Endpoint:** `GET /api/company-admin/statistics`
**Response (200 OK):**
```json
{
"bookings": {
"total": 450,
"confirmed": 150,
"checked_in": 35,
"completed": 250,
"cancelled": 15
},
"revenue": {
"total": 125000.50,
"paid": 100000.00,
"pending": 25000.50
},
"occupancy": {
"total_venue_objects": 50,
"occupied": 35
}
}
```
### Settings
These endpoints mirror the non-Filament Company Admin settings screen. All require a Sanctum bearer token and an active subscription. Reads require `company.portal`; writes require `company.manage_workspaces`. The managed company is resolved from the authenticated membership rather than a client-supplied company ID.
| Method | Endpoint | Purpose |
|--------|----------|---------|
| GET | `/api/company-admin/settings` | Return the complete settings overview |
| PUT | `/api/company-admin/settings` | Backward-compatible profile/regional update |
| PUT | `/api/company-admin/settings/profile` | Update company identity and contact fields |
| POST | `/api/company-admin/settings/profile/logo` | Upload a JPG/PNG/WebP-style image accepted by Laravel, maximum 2 MB; use multipart field `logo` |
| PUT | `/api/company-admin/settings/regional` | Update `currency`, `locale`, and `timezone` |
| PUT | `/api/company-admin/settings/venue` | Update VAT, tourist-tax, municipality, and check-in/out settings |
| PUT | `/api/company-admin/settings/esti` | Update company ESTI configuration |
| GET | `/api/company-admin/settings/{group}` | Read one configurable settings group |
| PUT | `/api/company-admin/settings/{group}` | Validate and update one configurable settings group |
| GET | `/api/company-admin/settings/cancellation` | Read cancellation defaults |
| PUT | `/api/company-admin/settings/cancellation` | Update cancellation defaults |
Allowed `{group}` values are `booking`, `financial`, `notifications`, `discounts`, `pos`, `policies`, and `pwa`. Group updates use this envelope:
```json
{
"settings": {
"enable_pos": true,
"pos_mode": "full",
"accept_cash": true,
"accept_card": true
}
}
```
Unknown keys and invalid configured option values return `422`. Updates are partial. Blank secret values preserve the existing secret. Secret, API-key, password, certificate, and private-key values are write-only; reads return `{"configured": true, "value": null}` instead of the stored value.
Fiscal-device settings remain at `GET|PUT /api/company-admin/fiscal/settings` because they have a separate validation and device-security contract.
### Employees
#### List Employees
Get all employees in the company.
**Endpoint:** `GET /api/company-admin/employees`
**Response (200 OK):**
```json
[
{
"id": 5,
"name": "John Staff",
"email": "john@company.com",
"phone": "+359 888 111 222",
"position": "Housekeeper",
"role": "employee"
}
]
```
#### Create Employee
Create a new employee.
**Endpoint:** `POST /api/company-admin/employees`
**Request Body:**
```json
{
"name": "New Employee",
"email": "new@company.com",
"password": "SecurePassword123!",
"phone": "+359 888 333 444",
"position": "Receptionist"
}
```
**Response (201 Created):**
```json
{
"id": 6,
"name": "New Employee",
"email": "new@company.com",
"phone": "+359 888 333 444",
"position": "Receptionist",
"role": "employee"
}
```
#### Update Employee
Update an existing employee.
**Endpoint:** `PUT /api/company-admin/employees/{user}`
**Request Body:**
```json
{
"name": "Updated Name",
"position": "Senior Receptionist"
}
```
**Response (200 OK):**
```json
{
"id": 5,
"name": "Updated Name",
"email": "john@company.com",
"position": "Senior Receptionist"
}
```
### Gantt Chart
#### Get Venue Objects Occupation
Get venue objects occupation data for Gantt chart visualization.
**Endpoint:** `GET /api/company-admin/gantt-chart/venue-occupation`
**Query Parameters:**
- `start_date` (required): Start date for the period
- `end_date` (required): End date for the period
- `venue_id` (optional): Filter by specific venue
**Response (200 OK):**
```json
[
{
"id": 10,
"name": "Room 101",
"venue_id": 1,
"venue": {
"id": 1,
"name": "Hotel Paradise"
},
"bookings": [
{
"id": 1,
"check_in": "2026-08-10",
"check_out": "2026-08-15",
"status": "confirmed"
}
]
}
]
```
### Products
#### List Products
Get all products for the company.
**Endpoint:** `GET /api/company-admin/products`
**Response (200 OK):**
```json
[
{
"id": 1,
"name": "Towel Set",
"description": "Premium cotton towels",
"price": 25.00,
"product_type": 1,
"sku": "TOW-001",
"is_active": true
}
]
```
#### Create Product
Create a new product.
**Endpoint:** `POST /api/company-admin/products`
**Request Body:**
```json
{
"name": "Soap Dispenser",
"description": "Wall-mounted soap dispenser",
"price": 15.50,
"sale_price": 12.00,
"cost": 6.00,
"quantity": 100,
"product_type": 1,
"currency": "BGN",
"is_active": true,
"stock_management": true,
"sku": "SOAP-002"
}
```
Accepted fields: `name` (required), `sku` (required, unique), `price` (required), `description`, `sale_price`, `cost`, `quantity`, `product_type` (must exist in `product_types`), `currency` (3-letter code), `vat_class_id`, `image`, `is_active`, `stock_management`.
**Response (201 Created):**
```json
{
"id": 2,
"name": "Soap Dispenser",
"description": "Wall-mounted soap dispenser",
"price": 15.50,
"product_type": 1,
"sku": "SOAP-002"
}
```
#### Update Product
Update an existing product.
**Endpoint:** `PUT /api/company-admin/products/{product}`
Accepts the same fields as Create Product (all optional/`sometimes`).
**Request Body:**
```json
{
"price": 18.00,
"description": "Updated description"
}
```
**Response (200 OK):**
```json
{
"id": 1,
"name": "Towel Set",
"price": 18.00,
"description": "Updated description"
}
```
#### Delete Product
Delete a product.
**Endpoint:** `DELETE /api/company-admin/products/{product}`
**Response (200 OK):**
```json
{
"message": "Product deleted successfully"
}
```
### Services
#### List Services
Get all services for the company.
**Endpoint:** `GET /api/company-admin/services`
**Response (200 OK):**
```json
[
{
"id": 1,
"name": "Room Service",
"description": "24/7 room service",
"price": 50.00,
"duration": 60,
"category": "hospitality"
}
]
```
#### Create Service
Create a new service.
**Endpoint:** `POST /api/company-admin/services`
**Request Body:**
```json
{
"name": "Spa Treatment",
"description": "Relaxing spa massage",
"price": 120.00,
"duration": 90,
"category": "wellness"
}
```
**Response (201 Created):**
```json
{
"id": 2,
"name": "Spa Treatment",
"description": "Relaxing spa massage",
"price": 120.00,
"duration": 90,
"category": "wellness"
}
```
### Packages
#### List Packages
Get all packages for the company.
**Endpoint:** `GET /api/company-admin/packages`
**Response (200 OK):**
```json
[
{
"id": 1,
"name": "Weekend Getaway",
"description": "2-night stay with breakfast and spa access",
"type": "stay",
"total_price": 299.00,
"duration_nights": 2,
"max_guests": 2,
"currency": "BGN",
"is_active": true
}
]
```
#### Create Package
Create a new package.
**Endpoint:** `POST /api/company-admin/packages`
**Request Body:**
```json
{
"name": "Romantic Package",
"description": "Includes dinner, champagne, and rose petals",
"type": "addon",
"total_price": 150.00,
"duration_minutes": 1440,
"max_guests": 2,
"currency": "BGN",
"is_active": true
}
```
Accepted fields: `name` (required), `total_price` (required), `description`, `type`, `original_price`, `percentage_discount`, `duration_nights`, `duration_minutes`, `max_guests`, `currency`, `vat_class_id`, `is_active`, `is_featured`, `sort_order`, `features`, `includes`, `excludes`, `image_path`, `gallery`, `available_from`, `available_until`, `availability_days`, `advance_booking_days`, `terms_conditions`.
**Response (201 Created):**
```json
{
"id": 2,
"name": "Romantic Package",
"description": "Includes dinner, champagne, and rose petals",
"type": "addon",
"total_price": 150.00,
"duration_minutes": 1440,
"max_guests": 2,
"currency": "BGN",
"is_active": true
}
```
#### Update Package
Update an existing package.
**Endpoint:** `PUT /api/company-admin/packages/{package}`
Accepts the same canonical fields as Create Package (all optional/`sometimes`).
**Request Body:**
```json
{
"total_price": 175.00,
"is_active": false
}
```
**Response (200 OK):**
```json
{
"id": 2,
"name": "Romantic Package",
"total_price": 175.00,
"is_active": false
}
```
#### Delete Package
Delete a package.
**Endpoint:** `DELETE /api/company-admin/packages/{package}`
**Response (200 OK):**
```json
{
"message": "Package deleted successfully"
}
```
### Transactions
#### List Transactions
Get all transactions/payments for the company.
**Endpoint:** `GET /api/company-admin/transactions`
**Response (200 OK):**
```json
[
{
"id": 1,
"amount": 500.00,
"status": "paid",
"payment_method": "card",
"created_at": "2026-08-04T10:00:00Z",
"booking": {
"id": 1,
"unique_booking_id": "BK-123456"
},
"booking": {
"client": {
"name": "John Doe"
}
}
}
]
```
#### Get Transaction Details
Get detailed information about a specific transaction.
**Endpoint:** `GET /api/company-admin/transactions/{payment}`
**Response (200 OK):**
```json
{
"id": 1,
"amount": 500.00,
"status": "paid",
"payment_method": "card",
"transaction_id": "TXN-123456",
"created_at": "2026-08-04T10:00:00Z",
"booking": {
"id": 1,
"unique_booking_id": "BK-123456",
"client": {
"name": "John Doe"
}
}
}
```
### Documents
#### List Documents
Get all documents for the company.
**Endpoint:** `GET /api/company-admin/documents`
**Response (200 OK):**
```json
[
{
"id": 1,
"document_type": "contract",
"category": "contracts",
"file_name": "contract.pdf",
"file_type": "application/pdf",
"file_size": 102400,
"access_level": "restricted",
"is_public": false,
"status": "active",
"created_by": 3,
"created_at": "2026-08-04T10:00:00Z"
}
]
```
Document file metadata is stored encrypted; `file_name`/`file_type`/`description`/`tags` are decrypted on read. File contents are stored on the private `secure` disk and are not directly downloadable via this API.
#### Upload Document
Upload a new document.
**Endpoint:** `POST /api/company-admin/documents`
**Request Body (multipart/form-data):**
- `document_type`: Required. One of `general`, `contract`, `invoice`, `report`, `certificate`, `legal`, `financial`, `personal`, `confidential`
- `file`: Required. File (max 100MB)
- `category`: Optional string
- `description`: Optional string (stored encrypted)
- `tags`: Optional array of strings (stored encrypted)
- `access_level`: Optional. One of `restricted` (default), `confidential`, `secret`
- `is_public`: Optional boolean (default false)
- `expires_at`: Optional date
**Response (201 Created):**
```json
{
"id": 2,
"document_type": "general",
"category": "general",
"file_name": "new_document.pdf",
"file_type": "application/pdf",
"file_size": 20480,
"access_level": "restricted",
"is_public": false,
"status": "active",
"created_by": 3
}
```
#### Get Document Details
Get document information.
**Endpoint:** `GET /api/company-admin/documents/{document}`
**Response (200 OK):**
```json
{
"id": 1,
"document_type": "contract",
"category": "contracts",
"file_name": "contract.pdf",
"file_type": "application/pdf",
"file_size": 102400,
"access_level": "restricted",
"status": "active"
}
```
#### Delete Document
Delete a document and its encrypted file. Requires the `company.manage_workspaces` capability.
**Endpoint:** `DELETE /api/company-admin/documents/{document}`
**Response (200 OK):**
```json
{
"message": "Document deleted successfully"
}
```
### QR Code Scanner
#### Scan QR Code
Scan a QR code to find the corresponding booking.
**Endpoint:** `POST /api/company-admin/scan-qr`
**Request Body:**
```json
{
"qr_code": "BK-123456"
}
```
**Response (200 OK):**
```json
{
"id": 1,
"unique_booking_id": "BK-123456",
"status": "confirmed",
"check_in": "2026-08-10",
"check_out": "2026-08-15",
"client": {
"id": 5,
"name": "John Doe"
},
"venue": {
"id": 1,
"name": "Hotel Paradise"
},
"venueObject": {
"id": 10,
"name": "Room 101"
}
}
```
**Response (404 Not Found):**
```json
{
"message": "Booking not found"
}
```
### Booking Lookup
#### Lookup Booking by Unique ID
Lookup a booking using its unique booking ID.
**Endpoint:** `GET /api/company-admin/bookings/lookup/{uniqueBookingId}`
**Response (200 OK):**
```json
{
"id": 1,
"unique_booking_id": "BK-123456",
"status": "confirmed",
"check_in": "2026-08-10",
"check_out": "2026-08-15",
"total_amount": 500.00,
"client": {
"id": 5,
"name": "John Doe",
"email": "john@example.com"
},
"venue": {
"id": 1,
"name": "Hotel Paradise"
},
"venueObject": {
"id": 10,
"name": "Room 101"
},
"payments": [],
"invoices": []
}
```
**Response (404 Not Found):**
```json
{
"message": "Booking not found"
}
```
### Additional Invoice Operations
#### Mark Invoice as Paid
Mark an invoice as paid.
**Endpoint:** `PUT /api/company-admin/invoices/{invoice}/mark-paid`
**Response (200 OK):**
```json
{
"id": 1,
"status": "paid",
"paid_at": "2026-08-04T10:00:00Z"
}
```
#### Delete Invoice
Delete an invoice.
**Endpoint:** `DELETE /api/company-admin/invoices/{invoice}`
**Response (200 OK):**
```json
{
"message": "Invoice deleted successfully"
}
```
---
### Point of Sale (POS)
These endpoints expose Zapazime's native Point of Sale module to a company-admin mobile client. They are not myPOS payment-gateway or cash-register endpoints.
**Base path:** `/api/company-admin/pos`
All operations require a Sanctum bearer token, an active company subscription, the `company.portal` capability, and an enabled POS module. Data is always restricted to the authenticated user's managed company. Requests are throttled to 120 per minute.
| Method | Endpoint | Purpose |
|--------|----------|---------|
| GET | `/api/company-admin/pos/catalog` | Return active company products, available venue services, and up to 100 active or pending stays for room-charge selection |
| GET | `/api/company-admin/pos/orders` | Return paginated POS orders with items, stay/client, and folio data |
| GET | `/api/company-admin/pos/orders/{order}` | Return one company-scoped POS order |
| POST | `/api/company-admin/pos/orders` | Create an order, calculate server-side prices, optionally update stock, and optionally post the charge to a stay folio |
#### List POS Orders
**Endpoint:** `GET /api/company-admin/pos/orders`
**Query parameters:**
- `page` — optional pagination page.
- `per_page` — optional integer from 1 to 100; defaults to 20.
#### Get a POS Order
**Endpoint:** `GET /api/company-admin/pos/orders/{order}`
An order belonging to another company returns `404`.
#### Create a POS Order
**Endpoint:** `POST /api/company-admin/pos/orders`
**Request:**
```json
{
"items": [
{ "type": "product", "id": 14, "quantity": 2 },
{ "type": "service", "id": 8, "quantity": 1 }
],
"stay_id": 31,
"guest_name": "Example Guest",
"guest_email": "guest@example.com",
"payment_method": "room_charge",
"fulfilment": "restaurant",
"notes": "Deliver to room 204"
}
```
`items` must contain 1–100 lines. Each line has a `type` of `product` or `service`, an integer `id`, and a positive quantity with at most two decimal places. Supported fulfilment values are `bar`, `restaurant`, and `takeaway`. Supported payment methods are `cash`, `card`, `room_charge`, and `other`.
Prices and totals are resolved by the server; clients cannot submit a price. Cash and card availability, negative-stock prevention, and automatic inventory updates follow the company's POS settings. `room_charge` requires an active or pending company stay with an open folio. When a folio is used, the order status is `posted`; otherwise it is `paid`.
**Response:** `201 Created` with an `order` object containing its items, stay/client, and folio data. Validation failures return `422`; a disabled POS or missing capability returns `403`.
---
### Company Fiscal Device Integration
**Base path:** `/api/company-admin/fiscal`
All operations require a Sanctum bearer token, company-manager or administrator access, and are throttled to 60 requests per minute. Data is tenant-scoped using the authenticated user's company. Responses containing device configuration use `Cache-Control: no-store`.
| Method | Endpoint | Purpose |
|--------|----------|---------|
| GET | `/api/company-admin/fiscal/settings` | Return enabled state and sanitized Windows/Android device profiles |
| PUT | `/api/company-admin/fiscal/settings` | Update a platform-specific fiscal-device profile |
| POST | `/api/company-admin/fiscal/test` | Return a read-only device test plan; it does not contact the fiscal device |
| GET | `/api/company-admin/fiscal/receipts` | Return the company's paginated fiscal payment jobs, 50 per page |
| POST | `/api/company-admin/fiscal/payments` | Record an idempotent cash/card payment and create its fiscal job |
| POST | `/api/company-admin/fiscal/receipts/{id}/claim` | Claim a pending job for execution on one cashier device |
| POST | `/api/company-admin/fiscal/receipts/{id}/complete` | Complete an issuing/uncertain job using receipt evidence |
| POST | `/api/company-admin/fiscal/receipts/{id}/uncertain` | Mark an issuing job uncertain for manual journal reconciliation |
| POST | `/api/company-admin/fiscal/receipts/{id}/reconcile` | After a manager verifies the fiscal journal, reset an issuing/uncertain job to pending; requires `journal_checked` and a 10–1000 character `reason` |
`PUT /settings` requires `platform`, host/port and connection data, operator details, VAT class, and cash/card payment mappings. Windows supports serial/TCP; Android supports Bluetooth/TCP.
`POST /payments` requires a UUID `idempotency_key`, `booking_id`, positive `amount`, and `payment_method` (`cash` or `card`). `terminal_reference` is required for card payments. This operation records an already-collected in-person payment; it does not charge a bank card.
`POST /receipts/{id}/claim` requires `platform`. Execute the returned commands locally against the configured cashier device. Never send fiscal commands through a public documentation server.
`POST /receipts/{id}/complete` requires the returned `claim_token`, `receipt_number`, eight-character `device_serial`, eight-digit `fiscal_memory_number`, and `qr_data`. If device execution cannot be confirmed, call `/uncertain` with the same claim token and an `error_message`; check the fiscal journal before completing, and never automatically reissue.
## Developer Portal
The Zapazime Developer Portal provides developers with secure access to API credentials for integrating with the Zapazime platform.
### Access
- **Developer Portal Home:** `https://zapazime.bg/developer`
- **Registration:** `https://zapazime.bg/developer/register`
- **Login:** `https://zapazime.bg/developer/login`
- **Dashboard:** `https://zapazime.bg/developer/dashboard`
### Registration Process
1. **Sign Up:** Developers register through the registration form with:
- Personal information (name, email, password)
- Company information (company name, website - optional)
- Use case description (how they plan to use the API)
- Agreement to terms of service and privacy policy
2. **Email Verification:** After registration, developers receive an email verification link to activate their account.
3. **API Credentials:** Upon successful registration and verification, developers receive:
- **API Key:** A unique public identifier for authentication (format: `dev_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`)
- **API Secret:** A secret key for secure authentication (format: 64-character hexadecimal string)
### Authentication
Developers authenticate using their API key and secret in HTTP headers:
```
X-API-Key: your_api_key_here
X-API-Secret: your_api_secret_here
```
### Dashboard Features
- **Profile Management:** Update personal and company information
- **API Key Management:** View and regenerate API credentials
- **Status Monitoring:** Check account status (pending, active, suspended)
- **Usage Statistics:** View API call statistics (future feature)
### API Key Management
- **View Credentials:** Display API key and secret in the dashboard
- **Regenerate Keys:** Generate new API key and secret if credentials are compromised
- **Security:** API secrets are hidden by default and only shown once during generation
### Account Status
- **Pending:** Newly registered accounts awaiting email verification
- **Active:** Verified accounts with full API access
- **Suspended:** Accounts suspended due to policy violations or inactivity
### Support
For developer portal support or API integration questions, contact our support team through the dashboard.
---
## Error Handling
All API endpoints follow a consistent error response format:
**Error Response (4xx/5xx):**
```json
{
"success": false,
"message": "Error description",
"errors": {
"field_name": [
"Error message for field"
]
}
}
```
### Common Error Codes
- `400 Bad Request` - Invalid request parameters
- `401 Unauthorized` - Authentication required or invalid token
- `403 Forbidden` - Insufficient permissions
- `404 Not Found` - Resource not found
- `422 Unprocessable Entity` - Validation errors
- `429 Too Many Requests` - Rate limit exceeded
- `500 Internal Server Error` - Server error
### Rate Limiting
The API implements rate limiting to ensure fair usage:
- **Anonymous requests:** 60 requests per hour
- **Authenticated requests:** 1000 requests per hour
Rate limit headers are included in responses:
```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1690848000
```
---
## Data Models
### User Model
```json
{
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+359 888 123 456",
"date_of_birth": "1990-05-15",
"gender": "male",
"language": "en",
"bio": "Frequent traveler",
"address": "123 Main Street",
"city": "Sofia",
"postal_code": "1000",
"country": "Bulgaria",
"avatar": "https://cdn.zapazime.bg/avatars/user1.jpg",
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-07-31T15:00:00Z"
}
```
### Venue Model
```json
{
"id": 1,
"name": "Grand Hotel Sofia",
"description": "Luxury hotel in the heart of Sofia",
"category": "Hotel",
"location": "Sofia, Bulgaria",
"address": "1 Sveta Nedelya Square",
"latitude": 42.6977,
"longitude": 23.3219,
"phone": "+359 2 933 4444",
"email": "info@grandhotelsofia.com",
"website": "https://grandhotelsofia.com",
"price_from": 120.00,
"rating": 4.5,
"reviews_count": 234,
"images": [
"https://cdn.zapazime.bg/venues/venue1-1.jpg"
],
"amenities": ["wifi", "parking", "pool", "spa"],
"policies": {
"check_in": "14:00",
"check_out": "12:00",
"cancellation": "24 hours before check-in"
},
"is_favorite": false
}
```
### Booking Model
```json
{
"id": 1,
"booking_number": "BKG-2026-001234",
"venue_id": 1,
"object_id": 1,
"check_in": "2026-08-15T14:00:00Z",
"check_out": "2026-08-18T12:00:00Z",
"guests": 2,
"total_price": 450.00,
"status": "confirmed",
"payment_status": "paid",
"created_at": "2026-07-25T10:00:00Z",
"updated_at": "2026-07-25T10:30:00Z"
}
```
### Notification Model
```json
{
"id": 1,
"type": "booking_confirmation",
"title": "Booking Confirmed",
"message": "Your booking BKG-2026-001234 has been confirmed",
"data": {
"booking_id": 1,
"booking_number": "BKG-2026-001234"
},
"read": false,
"created_at": "2026-07-25T10:30:00Z"
}
```
---
## Authentication Flow
### 1. Registration Flow
```
Client → POST /api/auth/register → Server
Server → 201 Created + Token → Client
Client → Store Token → Local Storage
```
### 2. Login Flow
```
Client → POST /api/auth/login → Server
Server → 200 OK + Token → Client
Client → Store Token → Local Storage
```
### 3. Authenticated Request Flow
```
Client → GET /api/user/profile + Authorization: Bearer {token} → Server
Server → Validate Token → Get Data → 200 OK → Client
```
### 4. Token Refresh Flow
```
Client → POST /api/auth/refresh + Authorization: Bearer {token} → Server
Server → 200 OK + New Token → Client
Client → Update Stored Token → Local Storage
```
---
## Mobile App Features
Based on the client UI functionality, the mobile app should include:
### Core Features
1. **Venue Discovery**
- Search and filter venues by location, category, price, rating
- View detailed venue information with images and amenities
- Check real-time availability
- View venue reviews and ratings
2. **Booking Management**
- Create new bookings with date, guests, and services selection
- View booking history with status tracking
- Cancel bookings with refund information
- QR code for check-in/check-out
3. **Profile Management**
- View and edit personal information
- Manage address and contact details
- Change password
- Upload profile picture
4. **Payment System**
- Secure payment processing via MyPOS
- View transaction history
- Download receipts
- Multiple payment methods
5. **Notifications**
- Real-time push notifications
- Booking confirmations and updates
- Promotional offers
- Customizable notification preferences
6. **Favorites & Wishlist**
- Save favorite venues
- Quick access to saved venues
- Share favorites with friends
7. **Reviews & Ratings**
- Submit reviews for visited venues
- View past reviews
- Update or delete reviews
8. **Loyalty Program**
- Earn bonus points on bookings
- Track points balance and history
- Redeem points for discounts
- View loyalty tier status
9. **Location Services**
- Find nearby venues
- GPS-based navigation
- Location-based recommendations
- Weather information
10. **Multi-language Support**
- Support for 11 languages: English, Bulgarian, German, Greek, Spanish, French, Italian, Polish, Romanian, Russian, Turkish
- Automatic language detection
- Easy language switching
---
## SDK Integration Guide
### iOS (Swift)
```swift
import Foundation
class ZapazimeAPIClient {
static let shared = ZapazimeAPIClient()
private let baseURL = "https://api.zapazime.bg"
private var authToken: String?
func login(email: String, password: String, completion: @escaping (Result<User, Error>) -> Void) {
let url = URL(string: "\(baseURL)/api/auth/login")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body = ["email": email, "password": password]
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
URLSession.shared.dataTask(with: request) { data, response, error in
// Handle response
}.resume()
}
}
```
### Android (Kotlin)
```kotlin
class ZapazimeAPIClient {
private val baseURL = "https://api.zapazime.bg"
private var authToken: String? = null
suspend fun login(email: String, password: String): Result<User> {
return try {
val response = apiService.login(LoginRequest(email, password))
authToken = response.data.token
Result.success(response.data.user)
} catch (e: Exception) {
Result.failure(e)
}
}
}
```
### React Native
```javascript
import axios from 'axios';
const api = axios.create({
baseURL: 'https://api.zapazime.bg',
headers: {
'Content-Type': 'application/json',
},
});
api.interceptors.request.use((config) => {
const token = AsyncStorage.getItem('authToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
export const login = async (email, password) => {
const response = await api.post('/api/auth/login', { email, password });
await AsyncStorage.setItem('authToken', response.data.data.token);
return response.data;
};
```
---
## Testing
### Postman Collection
A Postman collection is available for testing all API endpoints. Import the collection from:
`/docs/postman/Zapazime-Mobile-API.postman_collection.json`
### Test Environment
- **Sandbox:** `https://sandbox-api.zapazime.bg`
- **Production:** `https://api.zapazime.bg`
### Test Credentials
- **Test User:** `test@zapazime.bg`
- **Test Password:** `TestPassword123!`
---
## Support
For API support and questions:
- **Email:** api-support@zapazime.bg
- **Documentation:** https://docs.zapazime.bg
- **Status Page:** https://status.zapazime.bg
---
## API Implementation Status
### Fully Implemented Endpoints
The following endpoints are fully implemented and available in the current API:
**Authentication:**
- POST `/api/auth/register`
- POST `/api/auth/login`
- POST `/api/auth/google`
- POST `/api/auth/logout`
- POST `/api/auth/forgot-password`
- POST `/api/auth/reset-password`
- POST `/api/auth/verify-email/{token}`
- POST `/api/auth/refresh`
- POST `/api/auth/resend-verification`
**User Profile:**
- GET `/api/user/profile`
- PUT `/api/user/profile`
- POST `/api/user/change-password`
- GET `/api/user/preferences`
- PUT `/api/user/preferences`
- GET `/api/user/favorites`
- GET `/api/user/bookings`
- GET `/api/user/notifications`
- POST `/api/user/notifications/{id}/read`
- POST `/api/user/notifications/read-all`
- GET `/api/user/notification-preferences`
- PUT `/api/user/notification-preferences`
- GET `/api/user/transactions`
- GET `/api/user/transactions/{transaction}`
- Transaction receipt download is not currently available through the mobile API.
- GET `/api/user/invoices`
- GET `/api/user/invoices/{invoice}`
- Invoice download is not currently available through the mobile API.
**Venues (Public):**
- GET `/api/venues/`
- GET `/api/venues/search`
- GET `/api/venues/{id}`
- POST `/api/venues/{id}/availability`
- GET `/api/venues/{id}/reviews`
- GET `/api/venues/{venue_id}/objects`
- GET `/api/venues/{venue_id}/spots`
**Venues (Authenticated):**
- POST `/api/venues/{id}/favorite`
- POST `/api/venues/{id}/reviews`
**Bookings:**
- POST `/api/bookings/`
- GET `/api/bookings/{id}`
- PUT `/api/bookings/{id}`
- POST `/api/bookings/{id}/cancel`
- POST `/api/bookings/{id}/refund`
- GET `/api/bookings/qr/{qrCode}`
- POST `/api/bookings/{booking}/check-in`
- POST `/api/bookings/{booking}/check-out`
- GET `/api/bookings/{booking}/refund-info`
**Locations:**
- GET `/api/locations/suggest`
- GET `/api/locations/search`
- GET `/api/locations/advanced-search`
- POST `/api/locations/{id}/favorite`
**Categories:**
- GET `/api/categories/`
- GET `/api/categories/{bookingType}`
**Geocoding:**
- POST `/api/geocode/address`
- POST `/api/geocode/reverse`
- POST `/api/geocode/validate`
**MyPOS Payments:**
- POST `/api/mypos/payments/create`
- POST `/api/mypos/payments/confirm`
- POST `/api/mypos/payments/void`
- POST `/api/mypos/payments/refund`
- POST `/api/mypos/payments/cancel`
### Admin-Only Endpoints
The following endpoints are for company admin use only and are not part of the B2C mobile app:
**Company Management (B2B):**
- POST `/api/company/`
- GET `/api/company/profile`
- PUT `/api/company/profile`
- GET `/api/company/workspaces`
- POST `/api/company/workspaces`
- GET `/api/company/bookings`
- POST `/api/company/bookings`
- GET `/api/company/users`
- POST `/api/company/users/invite`
- DELETE `/api/company/users/{id}`
- GET `/api/company/invoices`
**ESTI Bulgaria Integration:**
- GET `/api/esti/export/csv`
- GET `/api/esti/export/booking/{id}/csv`
- GET `/api/esti/validate/booking/{id}`
- POST `/api/esti/regix/insert`
- POST `/api/esti/regix/update`
- POST `/api/esti/regix/cancel`
- GET `/api/esti/regix/test-connection`
- GET `/api/esti/configuration`
**Fiscal Receipts:**
- GET `/api/fiscal-receipts/pending`
- GET `/api/fiscal-receipts/status`
- PATCH `/api/fiscal-receipts/{receipt}/processing`
- PATCH `/api/fiscal-receipts/{receipt}/printed`
- PATCH `/api/fiscal-receipts/{receipt}/failed`
**Point of Sale (POS):**
- GET `/api/company-admin/pos/catalog`
- GET `/api/company-admin/pos/orders`
- GET `/api/company-admin/pos/orders/{order}`
- POST `/api/company-admin/pos/orders`
**MyPOS Cash Register:**
- POST `/api/mypos/cash-register/init`
- POST `/api/mypos/cash-register/get-transaction`
- POST `/api/mypos/cash-register/get-transaction-status`
- POST `/api/mypos/cash-register/get-transaction-history`
- POST `/api/mypos/cash-register/subscribe`
- POST `/api/mypos/cash-register/purchase`
- POST `/api/mypos/cash-register/void`
- POST `/api/mypos/cash-register/refund`
- POST `/api/mypos/cash-register/cancel`
- GET `/api/mypos/cash-register/transaction-status`
- POST `/api/mypos/cash-register/notifications`
- POST `/api/mypos/cash-register/create-receipt`
- GET `/api/mypos/cash-register/get-device-status`
- POST `/api/mypos/cash-register/get-receipt`
- POST `/api/mypos/cash-register/get-receipts`
- POST `/api/mypos/cash-register/get-receipt-by-id`
- POST `/api/mypos/cash-register/get-receipt-by-date`
- POST `/api/mypos/cash-register/get-receipt-by-date-range`
- POST `/api/mypos/cash-register/get-receipt-by-payment-method`
---
## Design Guidelines for Mobile App
### Color Scheme
**Primary Colors:**
- Primary Blue: `#2563eb` (blue-600) - Main action buttons, links, brand elements
- Primary Blue Hover: `#1d4ed8` (blue-700) - Hover states
- Brand Name Color: `#2563eb` (blue-600) - "ZapaziMe" logo text
**Background Colors:**
- Primary Background: `#ffffff` (white) - Main backgrounds
- Secondary Background: `#f9fafb` (gray-50) - Section backgrounds
- Card Background: `#ffffff` (white) - Card backgrounds
**Text Colors:**
- Primary Text: `#111827` (gray-900) - Headings, important text
- Secondary Text: `#374151` (gray-700) - Body text
- Tertiary Text: `#6b7280` (gray-600) - Subtitles, labels
- Muted Text: `#9ca3af` (gray-500) - Helper text
**Border Colors:**
- Primary Border: `#e5e7eb` (gray-200) - Standard borders
- Secondary Border: `#d1d5db` (gray-300) - Input borders
**Status Colors:**
- Success: `#10b981` (green-500) - Success states, positive actions
- Success Background: `#f0fdf4` (green-50) - Success backgrounds
- Error: `#ef4444` (red-500) - Error states, destructive actions
- Error Background: `#fef2f2` (red-50) - Error backgrounds
- Warning: `#f59e0b` (yellow-500) - Warning states
- Warning Background: #fefce8 (yellow-50) - Warning backgrounds
- Info: `#3b82f6` (blue-500) - Information states
- Info Background: `#eff6ff` (blue-50) - Information backgrounds
### Typography
**Font Sizes:**
- Large Headings: 24px (text-2xl) - Page titles
- Medium Headings: 20px (text-xl) - Section titles
- Small Headings: 18px (text-lg) - Card titles
- Body Text: 16px (text-base) - Standard text
- Small Text: 14px (text-sm) - Secondary text
- Tiny Text: 12px (text-xs) - Labels, helper text
**Font Weights:**
- Bold: 700 (font-bold) - Headings
- Semibold: 600 (font-semibold) - Emphasized text
- Medium: 500 (font-medium) - Buttons, labels
- Normal: 400 (font-normal) - Body text
### Component Styles
**Buttons:**
- Primary Buttons: `bg-blue-600 text-white` with `hover:bg-blue-700`
- Secondary Buttons: `bg-gray-100 text-gray-700` with `hover:bg-gray-200`
- Danger Buttons: `bg-red-600 text-white` with `hover:bg-red-700`
- Border Radius: 6px (rounded-md)
- Padding: 8px 16px (py-2 px-4)
- Font Weight: 500 (font-medium)
- Focus Ring: `focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`
**Input Fields:**
- Background: `bg-white`
- Border: `border-gray-300`
- Text: `text-gray-900`
- Border Radius: 6px (rounded-md)
- Padding: 8px 12px (py-2 px-3)
- Focus Ring: `ring-2 focus:ring-blue-500 focus:border-transparent`
**Cards:**
- Background: `bg-white`
- Border: `border-gray-200`
- Border Radius: 8px (rounded-lg)
- Shadow: `shadow-sm`
- Padding: 24px (p-6)
### Layout Spacing
**Container Max Widths:**
- Mobile: 100%
- Tablet: 768px
- Desktop: 1280px
**Spacing Scale:**
- Extra Small: 4px (1)
- Small: 8px (2)
- Medium: 16px (4)
- Large: 24px (6)
- Extra Large: 32px (8)
- 2X Large: 48px (12)
### Social Media Brand Colors
**Google:**
- Brand Blue: `#4285F4`
- Brand Green: `#34A853`
- Brand Yellow: `#FBBC05`
- Brand Red: `#EA4335`
**Facebook:**
- Brand Blue: `#1877F2`
### Design Principles
1. **Clean & Minimal:** Use plenty of white space, avoid clutter
2. **Visual Hierarchy:** Clear distinction between headings, body text, and helper text
3. **Contrast:** Ensure text has sufficient contrast against backgrounds
4. **Consistency:** Use the same color palette throughout the app
5. **Accessibility:** Meet WCAG AA standards for color contrast ratios
6. **Touch Targets:** Minimum 44px touch targets for mobile interactions
7. **Responsive:** Design for mobile-first, scale up for larger screens
### Implementation Notes
- Use the exact hex codes provided for consistent branding
- Maintain proper color contrast ratios (minimum 4.5:1 for normal text)
- Test the color scheme in both light and dark modes if applicable
- Ensure the design works across different screen sizes and devices
- Follow the spacing scale for consistent layout
- Use the component styles as a baseline, but adapt to mobile UI patterns
---
## Changelog
### Version 1.0.0 (2026-07-31)
- Initial API documentation release
- Authentication endpoints (fully implemented)
- User profile management (fully implemented)
- Venue search and discovery (fully implemented)
- Booking management (fully implemented)
- Payment integration (MyPOS online payments - fully implemented)
- Notifications system (fully implemented)
- Bonus points system (fully implemented)
- Location services (fully implemented)
- Transactions and invoices (fully implemented)
- Multi-language support
- Added API implementation status section
### Version 1.1.0 (2026-07-31)
- Added API endpoints for Payments & Transactions
- Added API endpoints for Invoices
- Added API endpoints for Bonus Points
- Added API endpoints for Location Services
- All B2C features now fully implemented in API
---
## License
© 2026 Zapazime. All rights reserved.