API docs · 17 Aug 2026

API updates for mobile developers

New and changed endpoints. All money is ETB. Envelope: { "status", "message", "timestamp", "data" }. Protected calls: Authorization: Bearer <token>.

Guest base: https://zemenbooking.com/api/v1/mobile

Unified login: https://zemenbooking.com/api/v1/auth/login

Staff / hotel admin: https://zemenbooking.com/api/v1/staff

This server: http://196.188.249.180/zemenbooking/api/v1/mobile

1. Unified login

One screen for guest and hotel-admin. Do not try guest login then fall back to staff login — a wrong password would hit rate limits twice.

POST https://zemenbooking.com/api/v1/auth/login  ·  same handler: POST https://zemenbooking.com/api/v1/mobile/auth/login

{
  "email": "abebe@example.com",
  "password": "secret123"
}

Optional user_type: "guest" or "hotel_admin" if the same email exists in both tables (otherwise 409).

Branch on data.user_type"guest" or "hotel_admin".

Guest success

{
  "status": "success",
  "data": {
    "user_type": "guest",
    "token": "eyJ…",
    "token_type": "Bearer",
    "expires_in": 2592000,
    "user": {
      "id": 42,
      "uuid": "…",
      "user_type": "guest",
      "role": "guest",
      "first_name": "Abebe",
      "last_name": "Kebede",
      "email": "abebe@example.com",
      "phone": "+251911234567",
      "avatar_url": null,
      "loyalty_points": 0,
      "total_bookings": 3,
      "status": "active",
      "email_verified": true
    }
  }
}

Guest token has no aud. Use it on /api/v1/mobile/….

Hotel admin success

{
  "status": "success",
  "data": {
    "user_type": "hotel_admin",
    "token": "eyJ…",
    "token_type": "Bearer",
    "expires_in": 86400,
    "hotel_id": 1,
    "user": {
      "id": "uuid-string",
      "name": "Hotel Admin",
      "email": "hotel.admin@zemenbooking.com",
      "user_type": "hotel_admin",
      "role": "hotel-owner",
      "role_slug": "hotel-owner",
      "role_name": "Hotel Owner"
    }
  }
}

Staff token has aud: "staff" and hotel_id. Use it on /api/v1/staff/….

  • 401 wrong email/password
  • 403 guest not active, or staff has no hotel
  • 409 email matches both accounts — send user_type

Test hotel admin: hotel.admin@zemenbooking.com / HotelAdmin@2026

2. Notifications (guest JWT)

Mark-as-read now persists. notification_id is an integer. is_read is a real boolean.

GET https://zemenbooking.com/api/v1/mobile/notifications

{
  "data": {
    "count": 2,
    "unread": 1,
    "items": [
      {
        "notification_id": 133,
        "type": "booking_confirmed",
        "title": "Booking confirmed",
        "message": "Your stay ZB123 is confirmed.",
        "data": { "booking_id": 10, "confirmation_code": "ZB123" },
        "is_read": false,
        "read_at": null,
        "created_at": "2026-08-17 09:00:00"
      }
    ]
  }
}

PATCH https://zemenbooking.com/api/v1/mobile/notifications/{id}/read (also POST)

{ "data": { "notification_id": 133, "is_read": true, "read_at": "2026-08-17 10:15:00", "affected": 1 } }

New: POST https://zemenbooking.com/api/v1/mobile/notifications/mark-all-read

{ "data": { "affected": 4, "unread": 0 } }

3. Hotel reviews

New (public): GET https://zemenbooking.com/api/v1/mobile/hotels/{id}/reviews?page=1&limit=10

Approved only. limit max 50.

{
  "data": {
    "hotel_id": 1,
    "total": 5,
    "page": 1,
    "limit": 10,
    "total_pages": 1,
    "average_rating": 4.6,
    "rating_distribution": { "5": 4, "4": 1, "3": 0, "2": 0, "1": 0 },
    "reviews": [
      {
        "review_id": 12,
        "rating": 5,
        "title": "Great stay",
        "comment": "Clean rooms and friendly staff.",
        "is_verified_purchase": true,
        "status": "approved",
        "reply": "Thank you!",
        "replied_at": "2026-08-16 14:00:00",
        "created_at": "2026-08-15 11:00:00",
        "reviewer": { "first_name": "Abebe", "last_initial": "K.", "display_name": "Abebe K." }
      }
    ]
  }
}

POST https://zemenbooking.com/api/v1/mobile/hotels/{id}/reviews (guest JWT)

{ "rating": 5, "title": "Great stay", "comment": "Clean rooms and friendly staff.", "booking_id": 10 }

Created as pending — it will not show on GET until approved.

4. Hotel admin writes (/api/v1/staff)

Use the staff token from unified login (user_type: hotel_admin).

MethodPathBody
GET / PUT/hotelPartial hotel fields (name, phone, email, address, city, stars, description, check-in/out). PUT /profile is the same.
POST/roomsroom_number, room_type_id, optional room_floor, room_status, room_notes
PUT/rooms/{id}Same fields, all optional
POST/room-typesroom_type_name, room_type_capacity, room_type_bed_type, optional price_per_night
PUT/room-types/{id}Same fields, all optional

Update hotel

PUT https://zemenbooking.com/api/v1/staff/hotel

{ "hotel_phone": "+251911234567", "hotel_check_in_time": "14:00", "hotel_check_out_time": "11:00" }

Create room

POST https://zemenbooking.com/api/v1/staff/rooms

{ "room_number": "401", "room_type_id": 3, "room_floor": 4, "room_status": "available" }

Create room type

POST https://zemenbooking.com/api/v1/staff/room-types

{ "room_type_name": "Deluxe King", "room_type_capacity": 2, "room_type_bed_type": "king", "price_per_night": 4500 }

room_status: available, occupied, occupied_dirty, maintenance, cleaning, out_of_service.
room_type_bed_type: single, double, queen, king, twin, triple, family, bunk, sofa_bed.

Quick curl

curl -sS -X POST https://zemenbooking.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"abebe@example.com","password":"secret123"}'

curl -sS "https://zemenbooking.com/api/v1/mobile/hotels/1/reviews?page=1&limit=10"

curl -sS -X PATCH https://zemenbooking.com/api/v1/mobile/notifications/133/read \
  -H "Authorization: Bearer $TOKEN"

curl -sS -X POST https://zemenbooking.com/api/v1/mobile/notifications/mark-all-read \
  -H "Authorization: Bearer $TOKEN"

curl -sS -X PUT https://zemenbooking.com/api/v1/staff/hotel \
  -H "Authorization: Bearer $STAFF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hotel_phone":"+251911234567"}'

Markdown copy: docs/API-UPDATES-FOR-DEVELOPERS.md in the repo. Full catalog: http://196.188.249.180/zemenbooking/developers.