Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/astrxnomo/tourify/llms.txt

Use this file to discover all available pages before exploring further.

Resource hierarchy

Tourify organises its content as a three-level hierarchy:
Cities
└── Places  (each place belongs to one city and one category)
    └── Reviews, Images, Events
Categories
└── Places  (cross-cutting — a category groups places across cities)
All city, category, and place listing endpoints are public — no authentication required.

Cities

GET /api/cities

Returns all cities ordered alphabetically, each with their associated images.
curl -s http://localhost:8000/api/cities \
  -H "Accept: application/json"

GET /api/cities/

Returns a single city with full nested data: its images, all places (with images, category, and average rating), and all events (with images and associated place).
curl -s http://localhost:8000/api/cities/1 \
  -H "Accept: application/json"

Categories

GET /api/categories

Returns all categories ordered alphabetically.
curl -s http://localhost:8000/api/categories \
  -H "Accept: application/json"

GET /api/categories/

Returns a single category with all its places. Each place includes images, the city it belongs to, and an average_rating computed from its reviews.
curl -s http://localhost:8000/api/categories/3 \
  -H "Accept: application/json"

Places

GET /api/places

Returns all places, optionally filtered. Results include images, city, category, and an average_rating field. The list is sorted by average_rating descending — highest-rated places appear first. Query parameters
city_id
integer
Filter places to a specific city. Pass the numeric city ID (e.g. city_id=1).
category_id
integer
Filter places to a specific category. Pass the numeric category ID (e.g. category_id=3).
Full-text search across the place name, address, and city name. The search is case-insensitive and uses a LIKE %term% match.
curl -s "http://localhost:8000/api/places" \
  -H "Accept: application/json"
Response (200)
[
  {
    "id": 10,
    "city_id": 1,
    "category_id": 3,
    "name": "Sagrada Família",
    "description": "Basílica modernista diseñada por Antoni Gaudí.",
    "address": "Carrer de Mallorca, 401, Barcelona",
    "latitude": "41.4036299",
    "longitude": "2.1743558",
    "average_rating": 4.8,
    "created_at": "2025-01-15T09:00:00.000000Z",
    "updated_at": "2025-01-15T09:00:00.000000Z",
    "images": [
      { "id": 22, "url": "https://example.com/storage/places/sagrada.jpg" }
    ],
    "city": { "id": 1, "name": "Barcelona" },
    "category": { "id": 3, "name": "Monumentos" }
  }
]
Combine city_id and category_id together to power the filtered browse view — e.g. “all museums in Barcelona”.

GET /api/places/

Returns a single place with complete detail. The response includes:
FieldDescription
imagesAll images associated with this place via the polymorphic imageable relationship
cityThe parent city object
categoryThe parent category object
reviewsAll reviews, each including the user who wrote it
average_ratingArithmetic mean of all review ratings, rounded to 1 decimal place
curl -s http://localhost:8000/api/places/10 \
  -H "Accept: application/json"

Sorting logic

The GET /api/places endpoint sorts results by reviews_avg_rating in descending order before returning the collection. This means the best-rated places always appear at the top of the list, regardless of other applied filters.
PlaceController.php (excerpt)
$places = $query->orderByDesc('reviews_avg_rating')->get()
    ->map(fn($place) => [
        ...$place->toArray(),
        'average_rating' => round($place->reviews_avg_rating ?? 0, 1),
    ]);
Places with no reviews have an average_rating of 0.0 and appear at the end.

Build docs developers (and LLMs) love