Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/IvanchoDev89/maleku-system/llms.txt

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

Vendors are the lifeblood of the Maleku System marketplace. A vendor is a tourism business — a hotel operator, tour company, rental agency, or transport provider — that joins the platform to list services and receive bookings from clients across Costa Rica and beyond. Vendors get their own authenticated dashboard, analytics, availability management tools, and a public landing page that aggregates all their active listings into a single, SEO-optimised profile. The vendor role grants full CRUD access to the vendor’s own listings (properties, tours, vehicles, boats, transportation), booking management, content creation, and chat, alongside read access to listings and content.

Becoming a Vendor

1

Register a vendor account

Register directly as a vendor by sending a POST request to /api/v1/auth/register/vendor with your user and business details (email, password, full_name, business_name, business_type). This single call creates both a User record (with role set to vendor) and a linked Vendor profile in one transaction. A business_slug is auto-generated from your business name. You will receive an email verification link valid for 24 hours.
2

Vendor account pending review

After registration your Vendor record is created with status set to pending and is_verified set to false. You can log in immediately, but your listings will not be publicly visible until a Super Admin approves your account.
# Vendor model status after registration (app/models/vendor.py)
status = Column(String(20), default=VendorStatus.PENDING.value, nullable=False)
is_verified = Column(Boolean, default=False, nullable=False)
3

Super Admin approves your account

A Super Admin reviews pending applications in the superadmin panel. They can approve the vendor (transitioning status to active) via POST /api/v1/superadmin/vendors/{vendor_id}/approval with action: "approve", or set the is_verified flag directly via PUT /api/v1/vendors/{vendor_id}/verify. Both actions are audit-logged.
4

Create your first listing

Once your account is approved and active, you can access the full vendor dashboard at /vendor/dashboard. From there you can create properties, tours, vehicles, boats, and transportation listings using the dedicated management pages under /vendor/properties, /vendor/tours, /vendor/vehicles, /vendor/boats, and /vendor/transportation.
Listings are not publicly visible until the vendor account has been verified by a Super Admin (is_verified = true). You can create and manage listings in your dashboard during this time, but they will not appear in search results or on public listing pages.

Vendor Dashboard

The vendor dashboard at /vendor/dashboard is the central control panel for your business on Maleku System. It surfaces real-time metrics pulled from GET /api/v1/vendors/me/analytics:
MetricDescription
total_propertiesCount of property listings owned by this vendor
total_toursCount of tour listings owned by this vendor
total_bookingsTotal bookings received across all listing types
pending_bookingsBookings currently awaiting confirmation
confirmed_bookingsBookings confirmed and upcoming
completed_bookingsBookings that have been fulfilled
total_revenueSum of total_amount for all completed bookings
ratingAverage rating score (0–5) across all reviews
total_reviewsTotal approved reviews received
commission_rateYour current platform commission rate (default 0.10)
To update your public business profile (name, description, phone, address, logo, etc.), send a PUT request to /api/v1/vendors/me/profile. Only the following fields are accepted to prevent mass assignment: business_name, description, phone, address, city, country, website, logo_url, tax_id.
# Endpoint: PUT /api/v1/vendors/me/profile
# Rate-limited to 10 requests/minute
allowed_fields = {
    "business_name", "description", "phone", "address",
    "city", "country", "website", "logo_url", "tax_id",
}

Managing Listings

Vendors can create, read, update, and delete five categories of listings. All resources are owner-scoped: the API enforces that a vendor can only modify listings attached to their own vendor_id.

Properties

Hotels, lodges, cabins, and vacation rentals. Support for room types, nightly pricing, amenities, and photo galleries.

Tours

Guided experiences including adventure, cultural, wildlife, and custom tours. Supports scheduled departure slots and group capacity.

Vehicles

Car rentals and self-drive options. Per-day pricing and pickup/drop-off configuration.

Boats

Sport fishing charters, sailing trips, and boat rentals. Capacity and trip duration settings.

Transportation

Private transfers, shuttle routes, and airport pickups. Origin/destination and per-seat pricing.

Flights (future)

Domestic charter flights. The Flight model and relationship on Vendor are already defined in the data layer for future activation.

Availability Management

Before a booking can be confirmed, the platform validates that the selected listing is available for the requested dates using two service functions from app/services/availability_service.py:
  • check_room_availability(db, property_id, room_type_id, check_in, check_out, guests) — Used for property bookings. Queries existing confirmed bookings and room inventory to ensure the requested room type has capacity for the requested date range.
  • check_tour_availability(db, tour_id, date, guests) — Used for tour bookings. Checks departure slot capacity and any manual blackout dates set by the vendor.
Both functions are called at booking creation time in POST /api/v1/bookings/ and also exposed directly via POST /api/v1/availability/rooms/check and POST /api/v1/availability/tours/check so frontends can render real-time availability calendars before the user attempts to book. Room calendar views are available at GET /api/v1/availability/rooms/{room_id}/calendar. Vendors configure availability through their /vendor/properties and /vendor/tours management pages, which write directly to the room inventory and tour slot tables.

Payouts

Maleku System processes vendor payouts through Stripe Connect. The platform deducts a commission before disbursing funds to the vendor’s connected Stripe account. Commission structure:
  • Platform commission: 10% (stored as commission_rate = 0.10 on each Vendor record; configurable per vendor by a Super Admin)
  • Vendor payout: the remaining amount after commission
# From app/services/pricing_service.py
def calculate_commission_amount(amount: float, commission_rate: float = 0.10) -> float:
    return round(amount * commission_rate, 2)
Stripe Connect setup:
  1. Navigate to /vendor/payouts in the vendor dashboard.
  2. Click Connect Stripe Account to be redirected through Stripe’s OAuth onboarding flow.
  3. On completion, stripe_account_id and stripe_connected = True are written to your Vendor record.
  4. Future payouts for completed bookings are routed to your connected account automatically.
# From app/models/vendor.py
stripe_account_id = Column(String(255), nullable=True)
stripe_connected = Column(Boolean, default=False)
commission_rate = Column(Numeric(5, 2), default=0.10)
Until stripe_connected is True, completed bookings will still accrue revenue in your analytics, but automatic Stripe disbursement will not occur.

Analytics

The /vendor/analytics page in the vendor dashboard gives you a historical view of your business performance. Key metrics surfaced include:
  • Total revenue — cumulative earnings from completed bookings
  • Booking count by status — pending, confirmed, completed, and cancelled breakdown
  • Listing performance — individual property and tour booking counts
  • Rating trends — average rating over time and total review count
  • Commission rate — current platform fee applied to your earnings
All of this data is backed by GET /api/v1/vendors/me/analytics which queries live booking and review records for your vendor account. No separate analytics store is required — calculations are performed on PostgreSQL aggregate queries at request time.

Vendor Public Profile

Every vendor gets a public-facing landing page accessible at /vendor/{slug} on the frontend, powered by the landing endpoint:
GET /api/v1/vendors/slug/{slug}/landing
This endpoint returns a VendorLandingResponse — a single aggregated payload containing everything needed to render the full vendor profile without additional API calls.
The VendorLandingResponse schema is the canonical object for vendor public pages. It bundles LandingPropertyItem, LandingTourItem, LandingVehicleItem, LandingBoatItem, and LandingTransportItem lists (capped at 5 per category by default), alongside LandingStats, LandingRanking, and up to 10 recent approved LandingReview objects. Use the *_has_more boolean flags to show “View all” pagination links without a second request.
The simpler detail endpoint, GET /api/v1/vendors/{vendor_id}, returns a VendorResponse with full vendor details including ratings and commission rate. Both endpoints are Redis-cached for 600 seconds (10 minutes) with cache tags scoped to the individual vendor, so cache invalidation on profile updates is surgical and does not affect other vendors.
# Cache TTLs defined in app/api/v1/vendors.py
CACHE_TTL_LIST = 300    # 5 minutes for vendor lists
CACHE_TTL_DETAIL = 600  # 10 minutes for vendor detail/landing pages
You can also look up a vendor by their URL slug via GET /api/v1/vendors/slug/{slug}, which is what the frontend uses for human-readable permalinks like /vendor/costa-rica-adventures.

Build docs developers (and LLMs) love