Portal
    Wholesale APIv1
    Operational

    WHOLESALE INVENTORY API

    Your Clients See Your Brand.
    Our Fleet Powers It.

    Live wholesale pricing, real-time availability, and complete fleet specs — delivered through a single API. Build your own booking experience. Set your own margins. Own your client relationships. We handle the boats, the crews, the operations. You handle the clients.

    Base: /api/v1Auth: Bearer TokenFormat: JSONRate: 100 req/min

    What You're Getting

    This isn't a listing feed. This is wholesale infrastructure that turns your website into a booking engine — without owning a single vessel or managing a single crew.

    3-tier pricing

    Wholesale Pricing

    See what you pay vs. what your client pays. Every yacht shows wholesale cost AND retail price — your margin is visible and yours to control.

    real-time

    Live Availability

    Real-time calendar for every vessel. Single-date checks or full monthly grids — know exactly what's bookable before your client even asks.

    20+ fields

    Complete Fleet Data

    Full specs, multiple photos, video, descriptions, capacity, location, inclusions/exclusions — everything you need to sell, in one payload.

    zero manual

    Auto Attribution

    Every booking through your API key is automatically attributed to you. Commissions tracked, performance measured, fee waivers calculated.

    vessel-specific

    Add-On Catalog

    Jet skis, catering, photographers, DJs — upsell add-ons with wholesale pricing. Size-filtered per vessel so you only show what fits.

    per-duration

    Margin Visibility

    Every duration shows retailPricing, wholesalePricing, AND the margin object — the exact dollar spread you earn per booking.

    The real superpower: You can build a completely white-label booking site. Your client never sees VCYC. They see your brand, your prices, your experience. Behind the scenes, we handle the fleet, the captains, the insurance, the fuel, the docking — everything that makes yacht charters operationally complex. You just sell.

    Quickstart — 3 Minutes to Live Data

    From zero to a working fleet integration in three steps.

    1

    Get your API key

    Subscribe at /broker/api — your key is generated automatically after checkout. It starts with vcyc_wh_.

    2

    Fetch the fleet

    your first request
    curl https://your-domain.com/api/v1/inventory \
      -H "Authorization: Bearer vcyc_wh_your_key_here"
    3

    Display and sell

    Parse the response, display yachts with your branding, show your markup as the client price. When they're ready to book, send them to the booking flow or handle it via WhatsApp/phone.

    example — display on your site
    const res = await fetch("/api/v1/inventory", {
      headers: { "Authorization": "Bearer vcyc_wh_your_key" }
    });
    const { data: yachts, addOns } = await res.json();
    
    yachts.forEach(yacht => {
      // YOUR wholesale cost (what you pay)
      const cost4h = yacht.wholesalePricing.fourHour / 100;
      
      // Retail price (what the client pays)
      const retail4h = yacht.retailPricing.fourHour / 100;
      
      // Your margin — already calculated for you
      const margin4h = yacht.margin.fourHour / 100;
      
      console.log(`${yacht.specs.length}' ${yacht.specs.builder} ${yacht.specs.model}`);
      console.log(`  Wholesale: ${cost4h} → Retail: ${retail4h} → You earn: ${margin4h}`);
    });

    Authentication

    Every request requires a Bearer token. Your key is tied to your broker account, commission tracking, and performance metrics.

    header format
    Authorization: Bearer vcyc_wh_your_api_key_here

    Prefix

    vcyc_wh_

    Length

    40 characters total

    Scope

    Read-only

    Server-side only

    Never expose your API key in client-side JavaScript, mobile apps, or public repos. All API calls should originate from your backend server.

    Fleet Inventory

    One call to get the entire active fleet — wholesale pricing, retail pricing, margins, specs, images, and availability status.

    GET/api/v1/inventory

    Query Parameters

    page
    int

    Page number (default: 1)

    limit
    int

    Items per page (default: 50, max: 100)

    request
    curl "https://your-domain.com/api/v1/inventory?page=1&limit=10" \
      -H "Authorization: Bearer vcyc_wh_your_key_here"
    response
    {
      "data": [
        {
          "id": "yacht-mia-101",
          "name": "Julia Valentine",
          "slug": "julia-valentine",
          "webId": "MIA52",
          "specs": {
            "builder": "Azimut",
            "model": "Flybridge 52",
            "length": 52,
            "year": 2020,
            "maxGuests": 13,
            "cabins": 3,
            "bathrooms": 2,
            "horsepower": 1400,
            "speed": 28
          },
          "retailPricing": {
            "fourHour": 250000,
            "sixHour": 320000,
            "eightHour": 420000
          },
          "wholesalePricing": {
            "fourHour": 190000,
            "sixHour": 250000,
            "eightHour": 330000
          },
          "margin": {
            "fourHour": 60000,
            "sixHour": 70000,
            "eightHour": 90000
          },
          "wholesaleDepositCents": 100000,
          "minGratuityPercent": 20,
          "images": [
            "https://storage.googleapis.com/...",
            "https://storage.googleapis.com/..."
          ],
          "coverImage": "https://storage.googleapis.com/...",
          "description": "Luxury motor yacht with flybridge...",
          "category": "motor_yacht",
          "location": "Miami Beach Marina",
          "pickupAddress": "300 Alton Rd, Miami Beach",
          "inclusions": "Captain, fuel, ice, water, bluetooth",
          "serviceLevel": "Monaco",
          "available": true,
          "exclusiveFleet": true,
          "yachtAddOns": [
            {
              "id": "addon-1",
              "name": "Jet Ski (1hr)",
              "pricePerHour": 250,
              "available": true
            }
          ]
        }
      ],
      "addOns": [
        {
          "id": "addon-global-1",
          "name": "Jet Ski Rental (1hr)",
          "category": "water_sports",
          "wholesalePriceCents": 35000,
          "duration": "1 hour",
          "popular": true,
          "minYachtLength": 30,
          "maxYachtLength": null
        }
      ],
      "pagination": {
        "page": 1,
        "limit": 10,
        "total": 24,
        "totalPages": 3,
        "hasMore": true
      },
      "meta": {
        "currency": "USD",
        "pricesInCents": true,
        "timestamp": "2026-02-25T14:30:00.000Z"
      }
    }

    Key insight: The response gives you three pricing tiers —wholesalePricing (your cost),retailPricing (suggested client price), andmargin (your earnings per booking). You can charge whatever you want — the margin field is just the spread between retail and wholesale.

    Yacht Detail

    Get everything about a single vessel — full specs, all images, video, add-ons specific to that yacht's size, and complete pricing.

    GET/api/v1/inventory/:id

    Path Parameters

    idreq
    string

    Yacht ID or slug (e.g. 'julia-valentine' or 'yacht-mia-101')

    request
    curl "https://your-domain.com/api/v1/inventory/julia-valentine" \
      -H "Authorization: Bearer vcyc_wh_your_key_here"
    response
    {
      "data": {
        "id": "yacht-mia-101",
        "name": "Julia Valentine",
        "slug": "julia-valentine",
        "specs": {
          "builder": "Azimut",
          "model": "Flybridge 52",
          "length": 52,
          "year": 2020,
          "maxGuests": 13,
          "cabins": 3,
          "bathrooms": 2,
          "horsepower": 1400,
          "draft": 4.5,
          "beam": 14.8,
          "speed": 28
        },
        "retailPricing": { "fourHour": 250000, "sixHour": 320000, "eightHour": 420000 },
        "wholesalePricing": { "fourHour": 190000, "sixHour": 250000, "eightHour": 330000 },
        "margin": { "fourHour": 60000, "sixHour": 70000, "eightHour": 90000 },
        "images": ["https://...", "https://...", "https://..."],
        "coverImage": "https://...",
        "videoUrl": "https://...",
        "description": "Premium flybridge yacht with spacious entertaining areas...",
        "location": "Miami Beach Marina",
        "pickupAddress": "300 Alton Rd, Miami Beach, FL 33139",
        "inclusions": "Captain, fuel, ice, water, bluetooth speakers",
        "exclusions": "Food, alcohol, gratuity",
        "serviceLevel": "Monaco",
        "available": true,
        "exclusiveFleet": true,
        "hasCalendar": true,
        "yachtAddOns": [
          { "id": "jetski-1", "name": "Jet Ski (1hr)", "pricePerHour": 250, "available": true },
          { "id": "paddleboard", "name": "Paddleboard", "pricePerHour": 50, "available": true }
        ]
      },
      "applicableAddOns": [
        {
          "id": "addon-global-1",
          "name": "Jet Ski Rental",
          "category": "water_sports",
          "wholesalePriceCents": 35000,
          "duration": "1 hour",
          "popular": true
        },
        {
          "id": "addon-global-2",
          "name": "Professional Photographer",
          "category": "entertainment",
          "wholesalePriceCents": 45000,
          "duration": "2 hours",
          "popular": false
        }
      ],
      "meta": { "currency": "USD", "pricesInCents": true }
    }

    Two add-on sources: yachtAddOns are vessel-specific (built into the yacht listing).applicableAddOns are from the global catalog, filtered by vessel size — so a jet ski won't show up for a yacht that's too small to carry one.

    Real-Time Availability

    Check if a yacht is bookable on a specific date, or pull a full monthly grid to build an availability calendar in your app. Reflects live bookings and calendar blocks — no caching, no stale data.

    GET/api/v1/inventory/:id/availability

    Option A — Single Date

    datereq
    string

    YYYY-MM-DD format

    Option B — Monthly Grid

    monthreq
    string

    YYYY-MM format

    Single Date Check

    Fast boolean check — is this yacht bookable on this date? Use this when a client picks a date.

    request
    curl "https://your-domain.com/api/v1/inventory/julia-valentine/availability?date=2026-03-15" \
      -H "Authorization: Bearer vcyc_wh_your_key_here"
    response — available
    {
      "data": {
        "yachtId": "yacht-mia-101",
        "date": "2026-03-15",
        "available": true,
        "blockedSlots": 0,
        "bookedSlots": 0
      },
      "meta": { "timestamp": "2026-02-25T14:30:00.000Z" }
    }
    response — booked
    {
      "data": {
        "yachtId": "yacht-mia-101",
        "date": "2026-03-15",
        "available": false,
        "blockedSlots": 0,
        "bookedSlots": 1
      }
    }

    Monthly Grid

    Get availability for every day in a month. Use this to build a calendar widget — green/red days, date pickers, availability heatmaps.

    request
    curl "https://your-domain.com/api/v1/inventory/julia-valentine/availability?month=2026-03" \
      -H "Authorization: Bearer vcyc_wh_your_key_here"
    response
    {
      "data": {
        "yachtId": "yacht-mia-101",
        "month": "2026-03",
        "grid": {
          "2026-03-01": { "available": true },
          "2026-03-02": { "available": true },
          "2026-03-03": { "available": false },
          "2026-03-04": { "available": true },
          "...": "...",
          "2026-03-31": { "available": true }
        }
      },
      "meta": { "timestamp": "2026-02-25T14:30:00.000Z" }
    }

    Pro tip: Cache the monthly grid on your end for 5-10 minutes to reduce API calls. For the final booking confirmation, always do a fresh single-date check to avoid double-booking.

    Response Field Reference

    Every field in the yacht object, explained. All monetary values are in US cents (divide by 100 for dollars).

    Identity

    id
    string

    Unique yacht identifier (stable, never changes)

    name
    string

    Display name (e.g. 'Julia Valentine')

    slug
    string

    URL-safe identifier — use for deep links

    webId
    string

    Short fleet code (e.g. 'MIA52') — useful for quick reference

    Specs

    specs.builder
    string

    Manufacturer (Azimut, Sunseeker, Sea Ray, etc.)

    specs.model
    string

    Model name

    specs.length
    int

    Length in feet

    specs.year
    int

    Year built or refitted

    specs.maxGuests
    int

    Maximum passenger capacity (USCG certified)

    specs.cabins
    int

    Number of sleeping cabins

    specs.bathrooms
    int

    Number of heads/bathrooms

    specs.horsepower
    int

    Total engine horsepower

    specs.speed
    int

    Cruising speed in knots

    specs.draft
    float

    Draft in feet

    specs.beam
    float

    Beam width in feet

    Pricing (cents)

    wholesalePricing
    object

    What you pay — keys: threeHour, fourHour, sixHour, eightHour (null if not offered)

    retailPricing
    object

    Suggested client price — same keys as wholesale

    margin
    object

    retailPricing minus wholesalePricing — your earnings per duration

    wholesaleDepositCents
    int

    Required deposit amount in cents

    minGratuityPercent
    int

    Minimum crew gratuity percentage (typically 20%)

    Media & Content

    images
    string[]

    Array of photo URLs (high-res, CDN-served)

    coverImage
    string

    Primary hero image URL

    videoUrl
    string

    Walkthrough or promo video URL (nullable)

    description
    string

    Marketing description for listing pages

    Operations

    location
    string

    Home marina or dock location

    pickupAddress
    string

    Client pickup/boarding address

    inclusions
    string

    What's included (captain, fuel, ice, etc.)

    exclusions
    string

    What's not included (food, alcohol, gratuity)

    serviceLevel
    string

    Service tier: Easy, Monaco, etc.

    category
    string

    Vessel type: motor_yacht, center_console, catamaran, etc.

    available
    bool

    Whether this yacht is currently active in the fleet

    exclusiveFleet
    bool

    true = managed exclusively by VCYC (more reliable availability)

    hasCalendar
    bool

    true = real-time calendar available via /availability endpoint

    Booking Attribution

    Every booking that comes through your integration is automatically attributed to your broker account. No tracking codes, no manual entry, no attribution disputes.

    How It Works

    1Client browses yachts on your platform
    2You build the experience using our API data
    3Client books — your broker ID is attached automatically
    4Commission calculated and tracked in your dashboard
    5Booking counts toward your monthly waiver threshold

    Performance Waiver

    3completed bookings per billing cycle
    API fee automatically waived (both $99 and $149 tiers)
    Credit applied before next invoice — no action needed
    Track progress in real-time on your broker dashboard
    No lock-in, cancel anytime

    Shareable links: You can also share direct inventory URLs with your broker token embedded. All bookings originating from those links are automatically attributed to your account, even without API integration.

    Add-On Catalog

    Upsell premium experiences. The fleet inventory endpoint includes a global add-on catalog with wholesale pricing. The yacht detail endpoint filters add-ons by vessel size so you only show what's applicable.

    Global Add-On Fields

    id
    string

    Unique add-on identifier

    name
    string

    Display name (e.g. 'Jet Ski Rental')

    category
    string

    Category: water_sports, entertainment, catering, equipment, etc.

    wholesalePriceCents
    int

    Your wholesale cost in cents

    duration
    string

    Duration description (e.g. '1 hour', '2 hours')

    popular
    bool

    Flag for featured/popular add-ons

    minYachtLength
    int

    Minimum yacht length in feet (null = no minimum)

    maxYachtLength
    int

    Maximum yacht length in feet (null = no maximum)

    add-on pricing example
    // Wholesale add-on cost: $350 (35000 cents)
    // You can mark it up however you want
    const jetSki = addOns.find(a => a.category === "water_sports");
    const yourPrice = jetSki.wholesalePriceCents * 1.3; // 30% markup = $455
    const yourMargin = yourPrice - jetSki.wholesalePriceCents; // $105 profit

    Rate Limits

    100

    req / min

    60s

    window

    429

    exceeded

    Response Headers

    X-RateLimit-Limit
    int

    Max requests per window (100)

    X-RateLimit-Remaining
    int

    Remaining requests in current window

    X-RateLimit-Reset
    unix

    Unix timestamp when the window resets

    429 response
    {
      "error": "Rate limit exceeded",
      "message": "Maximum 100 requests per minute. Try again later.",
      "retryAfter": 42
    }

    100 req/min is generous. Cache the inventory list for 5 minutes and you'll rarely hit 10 requests. Most integrations use fewer than 50 requests per hour.

    Error Handling

    400
    Bad Request

    Missing or invalid query parameters (e.g. bad date format). Check the message field.

    401
    Unauthorized

    Missing, malformed, or invalid API key. Verify your Authorization header.

    403
    Forbidden

    Broker account not approved. Contact admin to activate your account.

    404
    Not Found

    Yacht ID or slug doesn't match any active vessel.

    429
    Too Many Requests

    Rate limit exceeded. Respect the X-RateLimit headers and implement backoff.

    500
    Server Error

    Something broke on our end. If persistent, contact support.

    error response format
    {
      "error": "Short error code",
      "message": "Human-readable explanation of what went wrong"
    }

    Versioning & Stability

    /api/v1/inventory

    Backward Compatible

    New fields and endpoints are added without breaking existing integrations. Your code won't break.

    Breaking Changes

    Released under a new version (e.g., /api/v2). V1 remains active for at least 6 months after v2 launches.

    Price Format

    All monetary values are in US cents (integer). Divide by 100 for dollars. Currency is always USD.

    Null Safety

    Optional fields return null, never undefined. Always check for null before using pricing or spec fields.

    Ready to integrate?

    Get your API key, pull the fleet, and start selling in minutes. We handle the boats — you handle the clients.