Dealer API Documentation

Welcome to our friendly API! ๐Ÿš€ Let's get you integrated quickly and easily.

๐ŸŒ API Environments

Choose the appropriate environment for your integration:

Sandbox (Pre-production)

Testing and development environment

https://preprodapi.efel.app/

Production

Live production environment

https://prodapi.efel.app/

๐Ÿ” Authentication

Dealer API uses JWT (JSON Web Token) authentication. All requests except login require a valid Bearer token.

Authentication Flow

  1. 1. Login with dealer credentials to get JWT tokens
  2. 2. Include Authorization header in all subsequent requests
  3. 3. Refresh tokens before expiration (1 hour default)

Required Headers

Security Notes

๐Ÿ“ก API Endpoints (21 Core Operations)

POST /api/dealer/login โ–ผ
Authenticate dealer user and receive JWT tokens
Authenticate dealer user and receive JWT tokens
๐Ÿ”“ No Authentication

Request Body (JSON):

{
  "email": "dealer@example.com",
  "password": "dealer_password"
}

Response (JSON):

JWT access and refresh tokens

{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
  "refresh_token": "a1b2c3d4e5f6...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "expires_at": "2025-10-27T15:39:27+01:00"
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
POST /api/dealer/refresh โ–ผ
Refresh expired access token using refresh token
Refresh expired access token using refresh token
๐Ÿ”“ No Authentication

Request Body (JSON):

{
  "refresh_token": "a1b2c3d4e5f6..."
}

Response (JSON):

New JWT access token

{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "expires_at": "2025-10-27T16:39:27+01:00"
}
Possible Errors:
  • 401 Unauthorized
POST /api/dealer/logout โ–ผ
Invalidate the current dealer session
Invalidate the current dealer session
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Request Body (JSON):

{
  "refresh_token": "your_refresh_token_here"
}

Response (JSON):

Logout confirmation

{
  "message": "Logged out successfully"
}
Possible Errors:
  • 401 Unauthorized
POST /api/dealer/change-password โ–ผ
Change the authenticated dealer's password
Change the authenticated dealer's password
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Request Body (JSON):

{
  "current_password": "old_password",
  "new_password": "new_secure_password",
  "confirm_password": "new_secure_password"
}

Response (JSON):

Password change confirmation

{
  "message": "Password changed successfully"
}
Possible Errors:
  • 400 Bad Request
  • 401 Unauthorized
GET /api/dealer/stations โ–ผ
Retrieve dealer's authorized pickup and dropoff stations with multilingual CMS c ...
Retrieve dealer's authorized pickup and dropoff stations with multilingual CMS content
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Query Parameters:

lang: Language code (optional): fr, de, en, nl (default: en). Returns localized agency descriptions and information.
agency: Filter by specific agency (optional)
city: Filter by city (optional)

Response (JSON):

List of available stations with optional localized CMS content

{
  "stations": [
    {
      "id": 1,
      "name": "Paris Center",
      "phone": "+33123456789",
      "email": "paris@blacksheep-van.com",
      "address": {
        "street": "123 Avenue des Champs-ร‰lysรฉes",
        "city": "Paris",
        "postalCode": "75008",
        "country": "France"
      },
      "isDeliveryPossible": true,
      "isPetsAllowed": false,
      "isParkingOnSite": true,
      "description": "<p>Localized agency description from CMS...</p>",
      "infos_supplementaires": "<p>Additional information...</p>",
      "googlemaps": "https://maps.app.goo.gl/...",
      "visuel": "/media/agency-image.jpg",
      "horaires": "Monday to Saturday: 08:30-18:30 | Sunday: 8:30-12:00 / 14:00-18:30",
      "SEO": {
        "title": "Localized SEO title",
        "metadescription": "Localized meta description",
        "h1": "Localized H1 heading",
        "slug": "agency-slug"
      }
    }
  ]
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
GET /api/dealer/stations/{id} โ–ผ
Retrieve detailed information for a specific station by ID with optional multili ...
Retrieve detailed information for a specific station by ID with optional multilingual CMS content
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

id: Station ID (integer)

Query Parameters:

lang: Language code (optional): fr, de, en, nl (default: en). Returns localized agency descriptions and information.

Response (JSON):

Detailed station information including available vehicles grouped by category and localized CMS content

{
  "id": 1,
  "name": "Paris Center",
  "phone": "+33123456789",
  "email": "paris@blacksheep-van.com",
  "address": {
    "street": "123 Avenue des Champs-ร‰lysรฉes",
    "city": "Paris",
    "postalCode": "75008",
    "country": "France"
  },
  "isDeliveryPossible": true,
  "isPetsAllowed": false,
  "isParkingOnSite": true,
  "description": "<p>Localized agency description from CMS...</p>",
  "infos_supplementaires": "<p>Additional information...</p>",
  "googlemaps": "https://maps.app.goo.gl/...",
  "visuel": "/media/agency-image.jpg",
  "horaires": "Monday to Saturday: 08:30-18:30 | Sunday: 8:30-12:00 / 14:00-18:30",
  "SEO": {
    "title": "Localized SEO title",
    "metadescription": "Localized meta description",
    "h1": "Localized H1 heading",
    "slug": "agency-slug"
  },
  "vehicles_by_category": [
    {
      "category_id": 1,
      "category_name": "Economy Cars",
      "vehicles": [
        {
          "id": 123,
          "label": "Renault Clio",
          "model": {
            "id": 1,
            "label": "Clio",
            "brand": "Renault"
          },
          "productCategory": {
            "id": 1,
            "label": "Economy"
          }
        }
      ]
    },
    {
      "category_id": 2,
      "category_name": "Luxury Cars",
      "vehicles": [
        {
          "id": 456,
          "label": "BMW 3 Series",
          "model": {
            "id": 2,
            "label": "3 Series",
            "brand": "BMW"
          },
          "productCategory": {
            "id": 2,
            "label": "Luxury"
          }
        }
      ]
    }
  ],
  "total_vehicle_categories": 2,
  "total_vehicles": 2
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
GET /api/dealer/vehicles โ–ผ
Retrieve all vehicles available to the dealer with optional multilingual CMS con ...
Retrieve all vehicles available to the dealer with optional multilingual CMS content. Supports pagination to handle large result sets efficiently.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Query Parameters:

lang: Language code (optional): fr, de, en, nl (default: en). Returns localized vehicle descriptions, specifications, and media from CMS.
page: Page number (default: 1, min: 1)
limit: Items per page (default: 50, min: 1, max: 100)

Response (JSON):

List of dealer vehicles grouped by category with optional localized CMS content

{
  "vehicles_by_category": [
    {
      "category_id": 1,
      "category_name": "Campervan",
      "vehicles": [
        {
          "id": 123,
          "label": "EXPE_NUGGET",
          "description": "<p>Le van amรฉnagรฉ Ford Nugget...</p>",
          "model": {
            "id": 1,
            "label": "Ford Nugget",
            "brand": "Ford"
          },
          "productCategory": {
            "id": 1,
            "label": "Van"
          },
          "productCategoryImages": [
            {
              "id": 1,
              "fileUrl": "https://prodapi.efel.app/uploads/category/van.jpg",
              "filePath": "van.jpg",
              "isDefault": true
            }
          ],
          "images": [
            {
              "id": 1,
              "fileUrl": "https://prodapi.efel.app/uploads/product/nugget.jpg",
              "filePath": "nugget.jpg"
            }
          ],
          "specifications": [
            {
              "id": 2,
              "name": "Siรจges",
              "value": "4 places"
            },
            {
              "id": 14,
              "name": "Couchages",
              "value": "2 couchages"
            }
          ],
          "visuel": "https://cms.efel.app/media/VF%201%20%282%29.jpg",
          "gallery": [
            "https://cms.efel.app/media/VF%202%20%282%29.jpg",
            "https://cms.efel.app/media/VF%203%20%282%29.jpg"
          ],
          "modele": "Ford Nugget",
          "vantype": "Van",
          "slug": "expedition-nugget",
          "SEO": {
            "title": "Localized SEO title",
            "metadescription": "Localized meta description",
            "h1": "Localized H1 heading",
            "slug": "expedition-nugget"
          }
        }
      ]
    }
  ],
  "pagination": {
    "current_page": 1,
    "per_page": 50,
    "total_items": 125,
    "total_pages": 3,
    "has_next_page": true,
    "has_previous_page": false
  },
  "total_categories": 2,
  "total_vehicles": 50
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
GET /api/dealer/vehicles/{id} โ–ผ
Retrieve detailed information for a specific vehicle by ID with optional multili ...
Retrieve detailed information for a specific vehicle by ID with optional multilingual CMS content
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

id: Vehicle ID (integer)

Query Parameters:

lang: Language code (optional): fr, de, en, nl (default: en). Returns localized vehicle descriptions, specifications, and media from CMS.

Response (JSON):

Detailed vehicle information including optional localized CMS content

{
  "id": 123,
  "label": "EXPE_NUGGET",
  "description": "<p>Le van amรฉnagรฉ Ford Nugget (sans WC) est adaptรฉ au transport de personnes...</p>",
  "model": {
    "id": 1,
    "label": "Ford Nugget",
    "brand": "Ford"
  },
  "productCategory": {
    "id": 1,
    "label": "Van"
  },
  "productCategoryImages": [
    {
      "id": 1,
      "fileUrl": "https://prodapi.efel.app/uploads/category/van.jpg",
      "filePath": "van.jpg",
      "isDefault": true
    }
  ],
  "images": [
    {
      "id": 1,
      "fileUrl": "https://prodapi.efel.app/uploads/product/nugget.jpg",
      "filePath": "nugget.jpg"
    }
  ],
  "specifications": [
    {
      "id": 2,
      "name": "Siรจges",
      "value": "4 places"
    },
    {
      "id": 14,
      "name": "Couchages",
      "value": "2 couchages"
    },
    {
      "id": 16,
      "name": "Cuisine extรฉrieure",
      "value": "Cuisine extรฉrieure"
    }
  ],
  "visuel": "https://cms.efel.app/media/VF%201%20%282%29.jpg",
  "gallery": [
    "https://cms.efel.app/media/VF%202%20%282%29.jpg",
    "https://cms.efel.app/media/VF%203%20%282%29.jpg",
    "https://cms.efel.app/media/VF%204%20%282%29.jpg"
  ],
  "videos": [],
  "modele": "Ford Nugget",
  "vantype": "Van",
  "slug": "expedition-nugget",
  "logoMarque": "https://cms.efel.app/media/ford-logo.png",
  "cmsName": "EXPEDITION NUGGET (SANS WC)",
  "SEO": {
    "title": "Localized SEO title",
    "metadescription": "Localized meta description",
    "h1": "Localized H1 heading",
    "slug": "expedition-nugget"
  }
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
POST /api/dealer/availability โ–ผ
Check vehicle availability for specific dates with optional promo code validatio ...
Check vehicle availability for specific dates with optional promo code validation and options retrieval. IMPORTANT: This endpoint performs real-time availability checks and ONLY returns vehicles that are actually available for the requested dates (available: true). Can check a single vehicle (with vehicle_id), filter by category (with category_id), or get all available vehicles in an agency (without vehicle_id/category_id). Supports pagination for large result sets to prevent timeouts.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Request Body (JSON):

{
  "pickup_date": "2025-10-15T10:00:00",
  "dropoff_date": "2025-10-20T10:00:00",
  "agency_id": 1,
  "vehicle_id": 123,      // Optional - check specific vehicle availability
  "category_id": 5,       // Optional - filter available vehicles by category
  "promo_code": "EARLYBIRDY120", // Optional - validate and apply promo code
  "page": 1,              // Optional - page number (default: 1, min: 1)
  "limit": 50             // Optional - items per page (default: 50, min: 1, max: 100)
}

Response (JSON):

Vehicle availability information with HT and TTC pricing, promo code validation, and available options. Returns single vehicle data if vehicle_id provided, or list of all available vehicles grouped by category if vehicle_id omitted. Invalid promo codes return availability data with validation error in the response.

// Single vehicle response with promo code and options:
{
  "vehicle_id": 123,
  "available": true,
  "daily_price_ht": 37.50,
  "daily_price_ttc": 45.00,
  "total_price_ht": 187.50,
  "total_price_ttc": 225.00,
  "vat_amount": 37.50,
  "dealer_commission": 15.00,
  "promo_code": {
    "code": "EARLYBIRDY120",
    "valid": false,
    "error": "Promo code not found"
  },
  "available_options": [
    {
      "id": 1,
      "name": "GPS Navigation",
      "description": "Advanced GPS navigation system",
      "price": 25.00,
      "calculated_per_day": false,
      "calculated_per_booking": true,
      "max_quantity": 1,
      "available": true
    },
    {
      "id": 2,
      "name": "Child Seat",
      "description": "Safety child seat for young passengers",
      "price": 15.00,
      "calculated_per_day": true,
      "calculated_per_booking": false,
      "max_quantity": 2,
      "available": true
    }
  ],
  "total_vehicles": 1
}

// All vehicles response (grouped by category with pagination, promo code, and options):
{
  "agency_id": 1,
  "agency_name": "Paris Center",
  "pickup_date": "2025-10-15 10:00:00",
  "dropoff_date": "2025-10-20 10:00:00",
  "promo_code": {
    "code": "EARLYBIRDY120",
    "valid": false,
    "error": "Promo code not found"
  },
  "available_options": [
    {
      "id": 1,
      "name": "GPS Navigation",
      "description": "Advanced GPS navigation system",
      "price": 25.00,
      "calculated_per_day": false,
      "calculated_per_booking": true,
      "max_quantity": 1,
      "available": true
    },
    {
      "id": 2,
      "name": "Child Seat",
      "description": "Safety child seat for young passengers",
      "price": 15.00,
      "calculated_per_day": true,
      "calculated_per_booking": false,
      "max_quantity": 2,
      "available": true
    }
  ],
  "available_vehicles_by_category": [
    {
      "category_id": 1,
      "category_name": "Economy Cars",
      "vehicles": [
        {
          "vehicle_id": 123,
          "vehicle_name": "Renault Clio",
          "available": true,
          "daily_price_ht": 21.25,
          "daily_price_ttc": 25.50,
          "total_price_ht": 106.25,
          "total_price_ttc": 127.50,
          "vat_amount": 21.25,
          "dealer_commission": 3.83
        }
      ]
    },
    {
      "category_id": 2,
      "category_name": "Luxury Cars",
      "vehicles": [
        {
          "vehicle_id": 456,
          "vehicle_name": "BMW 3 Series",
          "available": true,
          "daily_price_ht": 70.83,
          "daily_price_ttc": 85.00,
          "total_price_ht": 354.17,
          "total_price_ttc": 425.00,
          "vat_amount": 70.83,
          "dealer_commission": 12.75
        }
      ]
    }
  ],
  "pagination": {
    "current_page": 1,
    "per_page": 50,
    "total_items": 85,
    "total_pages": 2,
    "has_next_page": true,
    "has_previous_page": false
  },
  "total_categories": 2,
  "total_vehicles": 85
}

// Response with invalid promo code (returns availability data + validation error):
{
  "agency_id": 1,
  "agency_name": "Paris Center",
  "pickup_date": "2025-10-15 10:00:00",
  "dropoff_date": "2025-10-20 10:00:00",
  "promo_code": {
    "code": "EARLYBIRDY120X",
    "valid": false,
    "error": "Promo code not found"
  },
  "available_options": [
    {
      "id": 1,
      "name": "GPS Navigation",
      "description": "Advanced GPS navigation system",
      "price": 25.00,
      "calculated_per_day": false,
      "calculated_per_booking": true,
      "max_quantity": 1,
      "available": true
    },
    {
      "id": 2,
      "name": "Child Seat",
      "description": "Safety child seat for young passengers",
      "price": 15.00,
      "calculated_per_day": true,
      "calculated_per_booking": false,
      "max_quantity": 2,
      "available": true
    }
  ],
  "available_vehicles_by_category": [
    {
      "category_id": 1,
      "category_name": "Economy Cars",
      "vehicles": [
        {
          "vehicle_id": 123,
          "vehicle_name": "Renault Clio",
          "available": true,
          "daily_price_ht": 21.25,
          "daily_price_ttc": 25.50,
          "total_price_ht": 106.25,
          "total_price_ttc": 127.50,
          "vat_amount": 21.25,
          "dealer_commission": 3.83
        }
      ]
    },
    {
      "category_id": 2,
      "category_name": "Luxury Cars",
      "vehicles": [
        {
          "vehicle_id": 456,
          "vehicle_name": "BMW 3 Series",
          "available": true,
          "daily_price_ht": 70.83,
          "daily_price_ttc": 85.00,
          "total_price_ht": 354.17,
          "total_price_ttc": 425.00,
          "vat_amount": 70.83,
          "dealer_commission": 12.75
        }
      ]
    }
  ],
  "pagination": {
    "current_page": 1,
    "per_page": 50,
    "total_items": 85,
    "total_pages": 2,
    "has_next_page": true,
    "has_previous_page": false
  },
  "total_categories": 2,
  "total_vehicles": 85
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
POST /api/dealer/booking โ–ผ
Create a new booking for the authenticated dealer. You can book by specific vehi ...
Create a new booking for the authenticated dealer. You can book by specific vehicle_id OR by category_id (system auto-selects first available vehicle). The total_price parameter is optional - if not provided, the price will be automatically calculated based on the vehicle pricing and selected extras.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Request Body (JSON):

{
  "vehicle_id": 123,      // Option 1: Book specific vehicle
  // OR
  "category_id": 5,       // Option 2: Book by category (auto-selects available vehicle)
  "agency_id": 1,         // Required when using category_id
  "pickup_date": "2025-07-10T10:00:00.000Z",
  "dropoff_date": "2025-07-18T10:00:00.000Z",
  "total_price": 425.00,  // Optional - will be auto-calculated if not provided
  "external_reference": "CAMPERDAYS-12345",  // Optional - Your booking reference for tracking
  "extras": [             // Optional - supports two formats:
    {"id": 1, "quantity": 2},  // Format 1: Object with quantity (recommended)
    {"id": 2, "quantity": 1}
    // OR
    // [1, 2]            // Format 2: Simple ID array (quantity defaults to 1)
  ],
  "promo_code": "SUMMER2025", // Optional promo code for discount
  "send_email": true,     // Optional boolean to send confirmation email (default: false)
  "customer": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@example.com",
    "phone": "+33123456789",
    "address": {
      "name": "Home",
      "street": "123 Main St",
      "additional_street": "Apt 4B",
      "city": "Paris",
      "zip_code": "75001",
      "state": "รŽle-de-France",
      "country": "FR"  // Accept ISO code (FR, IT, etc.) or numeric ID
    }
  }
}

Response (JSON):

Booking confirmation with reservation details. HTTP 200 means booking is CONFIRMED and vehicle is blocked. The payment_status "pending" refers only to payment (bank transfer), NOT booking confirmation. For dealer bookings, payment is automatically set with real booking price, VIR method, and pending status. Deposit and remaining amount are 0. Promo code discount is applied if provided. If send_email is true, a confirmation email is sent to the customer with trip summary, next steps, required documents, and agency information (no price details included).

{
  "booking_number": "D5-123",
  "booking_reference": "RESA-0001",
  "external_reference": "CAMPERDAYS-12345",  // Only if provided in request
  "total_price": "375.00",
  "deposit": "0.00",
  "remaining_amount": "0.00",
  "commission": "0.00",
  "estimate_reference": "DE-1-28-2025-0001",
  "estimate_invoice_path": "/estimate/DE-1-28-2025-0001.pdf",
  "booking_invoice_path": "/invoice/RESA-0001.pdf",
  "payment_status": "pending",  // Refers to payment, NOT booking confirmation
  "payment_method": "VIR",
  "payment_amount": "375.00",
  "promo_code": "SUMMER2025",
  "promo_discount": "50.00",
  "promo_applied": true,
  "email_sent": true
}
Possible Errors:
  • 400 Bad Request - Invalid promo code
  • 400 Bad Request - Promo code is not yet valid
  • 400 Bad Request - Promo code has expired
  • 400 Bad Request - Promo code does not apply to pickup date
  • 400 Bad Request - Promo code does not apply to dropoff date
  • 400 Bad Request - Promo code is not valid for this agency
  • 400 Bad Request - Promo code is not valid for this product category
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
DELETE /api/dealer/booking/cancel/{reference} โ–ผ
Cancel a validated booking using its booking reference (e.g., RESA-0001)
Cancel a validated booking using its booking reference (e.g., RESA-0001)
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

reference: Booking reference (string) - e.g., "RESA-0001"

Response (JSON):

Cancellation confirmation

{
  "message": "Booking cancelled successfully",
  "booking_id": 123,
  "reference": "RESA-0001",
  "cancelled_at": "2025-11-20 16:45:30"
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 400 Bad Request
GET /api/dealer/options/by-station โ–ผ
Retrieve all available options grouped by station/agency with pagination. Shows ...
Retrieve all available options grouped by station/agency with pagination. Shows options available at each station.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Query Parameters:

agency_id: Filter by specific agency/station ID (optional)
page: Page number (default: 1, min: 1)
limit: Items per page (default: 10, min: 1, max: 100)
textuelUniqPerso: Filter for unique personalized text options (optional)

Response (JSON):

List of stations with their available options

{
  "options_by_station": [
    {
      "station_id": 37,
      "station_name": "LYON",
      "station_city": "Lyon",
      "options_count": 5,
      "options": [
        {
          "id": 1,
          "option_id": 10,
          "label": "GPS Navigation",
          "description": "Advanced GPS navigation system",
          "price": 25.00,
          "image": "https://prodapi.efel.app/uploads/options/gps.jpg",
          "consumable": false,
          "stock_control": true,
          "type": "equipment",
          "quantity": 15,
          "max_quantity_per_booking": 1,
          "calculated_per_day": false,
          "calculated_per_booking": true,
          "enabled": true,
          "updated_at": "2025-12-15 10:30:00"
        },
        {
          "id": 2,
          "option_id": 11,
          "label": "Child Seat",
          "description": "Safety child seat for young passengers",
          "price": 15.00,
          "image": "https://prodapi.efel.app/uploads/options/child-seat.jpg",
          "consumable": false,
          "stock_control": true,
          "type": "safety",
          "quantity": 8,
          "max_quantity_per_booking": 2,
          "calculated_per_day": false,
          "calculated_per_booking": true,
          "enabled": true,
          "updated_at": "2025-12-15 10:30:00"
        }
      ]
    },
    {
      "station_id": 38,
      "station_name": "PARIS",
      "station_city": "Paris",
      "options_count": 3,
      "options": [...]
    }
  ],
  "pagination": {
    "current_page": 1,
    "per_page": 10,
    "total_items": 5,
    "total_pages": 1,
    "has_next_page": false,
    "has_previous_page": false
  },
  "total_stations": 2
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
GET /api/dealer/options/station/{id} โ–ผ
Retrieve all available options for a specific station/agency by ID. NOTE: This e ...
Retrieve all available options for a specific station/agency by ID. NOTE: This endpoint returns station-specific pricing and configuration from OptionStock. The same option may have different prices/quantities at different stations. Option pricing rules: calculated_per_day=true means price ร— days, calculated_per_booking=true means price ร— quantity. If both are false, it is a one-time flat fee (unusual).
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

id: Station/Agency ID (integer)

Response (JSON):

Detailed options information for a specific station

{
  "station_id": 37,
  "station_name": "LYON",
  "station_city": "Lyon",
  "options_count": 5,
  "options": [
    {
      "id": 1,
      "option_id": 10,
      "label": "GPS Navigation",
      "description": "Advanced GPS navigation system",
      "price": 25.00,
      "image": "https://prodapi.efel.app/uploads/options/gps.jpg",
      "consumable": false,
      "stock_control": true,
      "type": "equipment",
      "quantity": 15,
      "max_quantity_per_booking": 1,
      "calculated_per_day": false,
      "calculated_per_booking": true,
      "enabled": true,
      "updated_at": "2025-12-15 10:30:00"
    },
    {
      "id": 2,
      "option_id": 11,
      "label": "Child Seat",
      "description": "Safety child seat for young passengers",
      "price": 15.00,
      "image": "https://prodapi.efel.app/uploads/options/child-seat.jpg",
      "consumable": false,
      "stock_control": true,
      "type": "safety",
      "quantity": 8,
      "max_quantity_per_booking": 2,
      "calculated_per_day": false,
      "calculated_per_booking": true,
      "enabled": true,
      "updated_at": "2025-12-15 10:30:00"
    }
  ]
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
GET /api/dealer/booking/{reference} โ–ผ
Retrieve complete booking data by passing the booking reference. Returns booking ...
Retrieve complete booking data by passing the booking reference. Returns booking details including customer info, creator, agencies, and booking items.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

reference: Booking reference (string, e.g., RESA-0001)

Response (JSON):

Booking information with customer and booking items

{
  "success": true,
  "data": {
    "id": 789,
    "reference": "RESA-0001",
    "status": "validated",
    "totalPrice": "250.00",
    "dateBegin": "2026-01-10 10:00:00",
    "dateEnd": "2026-01-12 18:00:00",
    "createdAt": "2026-01-01 12:00:00",
    "updatedAt": "2026-01-05 14:30:00",
    "customer": {
      "id": 5,
      "firstName": "John",
      "lastName": "Doe",
      "email": "john.doe@example.com"
    },
    "creator": {
      "id": 47,
      "firstName": "Agent",
      "lastName": "Smith",
      "email": "agent@example.com"
    },
    "bookingAgencySource": {
      "id": 11,
      "name": "Lyon Agency"
    },
    "bookingAgencyTarget": {
      "id": 11,
      "name": "Lyon Agency"
    },
    "bookingItems": [
      {
        "id": 456,
        "estimate": {
          "id": 123
        },
        "amount": "250.00",
        "isActive": true
      }
    ]
  }
}
Possible Errors:
  • 401 Unauthorized
  • 404 Not Found
  • 400 Bad Request
POST /api/dealer/booking/{reference}/send-notification โ–ผ
Send a booking confirmation notification email to a specified email address by p ...
Send a booking confirmation notification email to a specified email address by passing the booking reference. Sends a dealer-specific email template that hides pricing information.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}
Content-Type: application/json

Path Parameters:

reference: Booking reference (string, e.g., RESA-0001)

Request Body (JSON):

{
  "email": "customer@example.com",
  "lang": "fr"
}

Response (JSON):

Confirmation that email was sent

{
  "success": true,
  "message": "Notification email sent successfully",
  "bookingReference": "RESA-0001",
  "recipientEmail": "customer@example.com"
}
Possible Errors:
  • 401 Unauthorized
  • 404 Not Found
  • 400 Bad Request
GET /api/dealer/calendar-fees โ–ผ
Retrieve calendar fees for dealers. Can get fees for specific dealer or all fees ...
Retrieve calendar fees for dealers. Can get fees for specific dealer or all fees if no dealer_id specified.
๐Ÿ”“ No Authentication

Query Parameters:

dealer_id: Filter by specific dealer ID (optional)

Response (JSON):

List of calendar fees with date ranges and fee amounts

{
  "calendar_fees": [
    {
      "id": 1,
      "dealer": {
        "id": 1,
        "name": "Dealer Name"
      },
      "start_date": "2025-01-01",
      "end_date": "2025-12-31",
      "fee_amount": 50.00,
      "fee_type": "daily",
      "description": "Peak season fee"
    }
  ]
}
Possible Errors:
  • 404 Not Found
POST /api/dealer/calendar-fees โ–ผ
Create a new calendar fee entry for a dealer with date range and fee amount.
Create a new calendar fee entry for a dealer with date range and fee amount.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Request Body (JSON):

{
  "dealer_id": 1,
  "start_date": "2025-06-01",
  "end_date": "2025-08-31",
  "fee_amount": 75.00,
  "fee_type": "daily",
  "description": "Summer peak season fee"
}

Response (JSON):

Created calendar fee details

{
  "id": 123,
  "dealer": {
    "id": 1,
    "name": "Dealer Name"
  },
  "start_date": "2025-06-01",
  "end_date": "2025-08-31",
  "fee_amount": 75.00,
  "fee_type": "daily",
  "description": "Summer peak season fee",
  "created_at": "2025-01-15T10:30:00Z"
}
Possible Errors:
  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
GET /api/dealer/calendar-fees/{id} โ–ผ
Retrieve detailed information for a specific calendar fee by ID.
Retrieve detailed information for a specific calendar fee by ID.
๐Ÿ”“ No Authentication

Path Parameters:

id: Calendar fee ID (integer)

Response (JSON):

Detailed calendar fee information

{
  "id": 123,
  "dealer": {
    "id": 1,
    "name": "Dealer Name"
  },
  "start_date": "2025-06-01",
  "end_date": "2025-08-31",
  "fee_amount": 75.00,
  "fee_type": "daily",
  "description": "Summer peak season fee",
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T10:30:00Z"
}
Possible Errors:
  • 404 Not Found
PATCH /api/dealer/calendar-fees/{id} โ–ผ
Update an existing calendar fee. Only provide fields that need to be updated.
Update an existing calendar fee. Only provide fields that need to be updated.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

id: Calendar fee ID (integer)

Request Body (JSON):

{
  "fee_amount": 80.00,
  "description": "Updated summer peak season fee"
}

Response (JSON):

Updated calendar fee details

{
  "id": 123,
  "dealer": {
    "id": 1,
    "name": "Dealer Name"
  },
  "start_date": "2025-06-01",
  "end_date": "2025-08-31",
  "fee_amount": 80.00,
  "fee_type": "daily",
  "description": "Updated summer peak season fee",
  "updated_at": "2025-01-16T14:20:00Z"
}
Possible Errors:
  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
DELETE /api/dealer/calendar-fees/{id} โ–ผ
Delete a calendar fee by ID. This action cannot be undone.
Delete a calendar fee by ID. This action cannot be undone.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

id: Calendar fee ID (integer)

Response (JSON):

Deletion confirmation

{
  "message": "Calendar fee deleted successfully",
  "deleted_fee_id": 123
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
GET /api/dealer-commissions โ–ผ
Retrieve commission data for dealers with optional filtering by date range and d ...
Retrieve commission data for dealers with optional filtering by date range and dealer ID. Supports pagination.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Query Parameters:

dealerId: Filter by specific dealer ID (optional)
startDate: Filter by start date (YYYY-MM-DD format, optional)
endDate: Filter by end date (YYYY-MM-DD format, optional)
page: Page number (default: 1, min: 1)
limit: Items per page (default: 50, min: 1, max: 100)

Response (JSON):

Commission data with pagination information

{
  "commissions": [
    {
      "id": 1,
      "dealer": {
        "id": 1,
        "name": "Dealer Name"
      },
      "booking": {
        "id": 123,
        "reference": "RESA-0001",
        "totalPrice": 500.00
      },
      "commission_amount": 75.00,
      "commission_rate": 15.0,
      "created_at": "2025-01-15T10:30:00Z"
    }
  ],
  "pagination": {
    "current_page": 1,
    "per_page": 50,
    "total_items": 125,
    "total_pages": 3,
    "has_next_page": true,
    "has_previous_page": false
  },
  "total_commissions": 125,
  "total_amount": 9375.00
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
GET /api/dealer/stats โ–ผ
Retrieve comprehensive statistics for dealers including booking counts, revenue, ...
Retrieve comprehensive statistics for dealers including booking counts, revenue, and API usage metrics.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Query Parameters:

startDate: Filter statistics from start date (YYYY-MM-DD format, optional)
endDate: Filter statistics to end date (YYYY-MM-DD format, optional)
dealerId: Filter by specific dealer ID (optional)

Response (JSON):

Comprehensive dealer statistics

{
  "overview": {
    "total_dealers": 25,
    "active_dealers": 22,
    "total_bookings": 1250,
    "total_revenue": 125000.00,
    "average_booking_value": 100.00
  },
  "bookings_by_status": {
    "validated": 980,
    "pending": 150,
    "cancelled": 120
  },
  "revenue_by_month": [
    {
      "month": "2025-01",
      "revenue": 12500.00,
      "bookings": 125
    },
    {
      "month": "2025-02",
      "revenue": 15000.00,
      "bookings": 150
    }
  ],
  "top_performers": [
    {
      "dealer_id": 1,
      "dealer_name": "Top Dealer",
      "bookings": 85,
      "revenue": 8500.00
    }
  ],
  "api_usage": {
    "total_requests": 5000,
    "successful_requests": 4850,
    "failed_requests": 150,
    "success_rate": 97.0
  }
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
POST /api/dealer/create โ–ผ
Create a new dealer account with basic information and credentials.
Create a new dealer account with basic information and credentials.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Request Body (JSON):

{
  "name": "New Dealer Company",
  "email": "dealer@company.com",
  "password": "secure_password",
  "phone": "+33123456789",
  "address": {
    "street": "123 Business St",
    "city": "Paris",
    "postal_code": "75001",
    "country": "FR"
  },
  "contact_person": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@company.com"
  }
}

Response (JSON):

Created dealer information

{
  "id": 123,
  "name": "New Dealer Company",
  "email": "dealer@company.com",
  "phone": "+33123456789",
  "status": "active",
  "created_at": "2025-01-15T10:30:00Z",
  "contact_person": {
    "id": 456,
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@company.com"
  }
}
Possible Errors:
  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 409 Conflict
PATCH /api/dealer/update/{id} โ–ผ
Update dealer information. Only provide fields that need to be updated.
Update dealer information. Only provide fields that need to be updated.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

id: Dealer ID (integer)

Request Body (JSON):

{
  "name": "Updated Dealer Name",
  "phone": "+33123456788",
  "status": "active"
}

Response (JSON):

Updated dealer information

{
  "id": 123,
  "name": "Updated Dealer Name",
  "email": "dealer@company.com",
  "phone": "+33123456788",
  "status": "active",
  "updated_at": "2025-01-16T14:20:00Z"
}
Possible Errors:
  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
POST /api/dealer/getvehicle โ–ผ
Retrieve detailed vehicle information by providing vehicle ID in request body.
Retrieve detailed vehicle information by providing vehicle ID in request body.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Request Body (JSON):

{
  "vehicle_id": 123
}

Response (JSON):

Detailed vehicle information including specifications and availability

{
  "id": 123,
  "label": "EXPE_NUGGET",
  "description": "The Ford Nugget campervan...",
  "model": {
    "id": 1,
    "label": "Ford Nugget",
    "brand": "Ford"
  },
  "productCategory": {
    "id": 1,
    "label": "Campervan"
  },
  "specifications": [
    {
      "name": "Seats",
      "value": "4 seats"
    },
    {
      "name": "Sleeping",
      "value": "2 berths"
    }
  ],
  "daily_price_ht": 37.50,
  "daily_price_ttc": 45.00,
  "available": true
}
Possible Errors:
  • 400 Bad Request
  • 401 Unauthorized
  • 404 Not Found
GET /api/dealer/{dealerId}/agencies โ–ผ
Retrieve all agencies associated with a specific dealer.
Retrieve all agencies associated with a specific dealer.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

dealerId: Dealer ID (integer)

Response (JSON):

List of agencies associated with the dealer

{
  "dealer_id": 123,
  "dealer_name": "Dealer Company",
  "agencies": [
    {
      "id": 1,
      "name": "Paris Center",
      "phone": "+33123456789",
      "email": "paris@dealer.com",
      "address": {
        "street": "123 Avenue des Champs-ร‰lysรฉes",
        "city": "Paris",
        "postalCode": "75008",
        "country": "France"
      },
      "is_primary": true
    },
    {
      "id": 2,
      "name": "Lyon Branch",
      "phone": "+33412345678",
      "email": "lyon@dealer.com",
      "address": {
        "street": "456 Rue de la Rรฉpublique",
        "city": "Lyon",
        "postalCode": "69001",
        "country": "France"
      },
      "is_primary": false
    }
  ],
  "total_agencies": 2
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
POST /api/dealer/{dealerId}/add-agency/{agencyId} โ–ผ
Associate an existing agency with a dealer.
Associate an existing agency with a dealer.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

dealerId: Dealer ID (integer)
agencyId: Agency ID (integer)

Response (JSON):

Association confirmation

{
  "message": "Agency successfully added to dealer",
  "dealer_id": 123,
  "agency_id": 456,
  "association_created_at": "2025-01-15T10:30:00Z"
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 409 Conflict
DELETE /api/dealer/{dealerId}/remove-agency/{agencyId} โ–ผ
Remove an agency association from a dealer.
Remove an agency association from a dealer.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

dealerId: Dealer ID (integer)
agencyId: Agency ID (integer)

Response (JSON):

Removal confirmation

{
  "message": "Agency successfully removed from dealer",
  "dealer_id": 123,
  "agency_id": 456,
  "association_removed_at": "2025-01-15T10:30:00Z"
}
Possible Errors:
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
POST /api/dealer/booking/add-options/{reference} โ–ผ
Add additional options/extras to an existing booking.
Add additional options/extras to an existing booking.
๐Ÿ”’ Authentication Required

Headers:

Authorization: Bearer {token}

Path Parameters:

reference: Booking reference (string, e.g., RESA-0001)

Request Body (JSON):

{
  "options": [
    {
      "option_id": 1,
      "quantity": 1
    },
    {
      "option_id": 2,
      "quantity": 2
    }
  ]
}

Response (JSON):

Updated booking with new options and adjusted pricing

{
  "booking_reference": "RESA-0001",
  "message": "Options added successfully",
  "added_options": [
    {
      "option_id": 1,
      "name": "GPS Navigation",
      "quantity": 1,
      "price": 25.00
    }
  ],
  "updated_total_price": 450.00,
  "additional_cost": 25.00
}
Possible Errors:
  • 400 Bad Request
  • 401 Unauthorized
  • 404 Not Found
  • 409 Conflict

๐Ÿš€ Let's Get You Started!

Copy and paste these ready-to-use examples - we've got everything you need to integrate smoothly! ๐Ÿ’ซ

๐Ÿ’ป Code Examples

cURL
JavaScript
PHP

Login

curl -X POST https://prodapi.efel.app/api/dealer/login \
  -H "Content-Type: application/json" \
  -d '{"email": "dealer@example.com", "password": "password"}'

Refresh Token

curl -X POST https://prodapi.efel.app/api/dealer/refresh \
  -H "Content-Type: application/json" \
  -d '{"refresh_token": "your_refresh_token_here"}'

Logout

curl -X POST https://prodapi.efel.app/api/dealer/logout \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"refresh_token": "your_refresh_token_here"}'

Change Password

curl -X POST https://prodapi.efel.app/api/dealer/change-password \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "current_password": "old_password",
    "new_password": "new_secure_password",
    "confirm_password": "new_secure_password"
  }'

Get Stations

curl -X GET "https://prodapi.efel.app/api/dealer/stations?lang=en" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Get Station Details

curl -X GET "https://prodapi.efel.app/api/dealer/stations/123?lang=en" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Get Vehicles

curl -X GET "https://prodapi.efel.app/api/dealer/vehicles?category=Economy&available=true" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Get Vehicle Details

curl -X GET https://prodapi.efel.app/api/dealer/vehicles/123 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Check Availability

curl -X POST https://prodapi.efel.app/api/dealer/availability \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "pickup_date": "2025-10-15T10:00:00",
    "dropoff_date": "2025-10-20T10:00:00",
    "vehicle_id": 1,
    "agency_id": 1,
    "promo_code": "EARLYBIRDY120"
  }' | jq '.daily_price_ht, .daily_price_ttc, .total_price_ht, .total_price_ttc, .promo_code, .available_options'

Get All Available Vehicles in Agency

curl -X POST https://prodapi.efel.app/api/dealer/availability \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "pickup_date": "2025-10-15T10:00:00",
    "dropoff_date": "2025-10-20T10:00:00",
    "agency_id": 1,
    "promo_code": "EARLYBIRDY120",
    "page": 1,
    "limit": 20
  }' | jq '.promo_code, .available_options, .available_vehicles_by_category | .[] | .vehicles | .[] | .vehicle_name, .final_price_ttc'

Create Booking

curl -X POST https://prodapi.efel.app/api/dealer/booking \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "vehicle_id": 123,
    "pickup_date": "2025-07-10T10:00:00.000Z",
    "dropoff_date": "2025-07-18T10:00:00.000Z",
    "total_price": 425.00,
    "extras": [1, 2],
    "customer": {
      "first_name": "John",
      "last_name": "Doe",
      "email": "john.doe@email.com",
      "phone": "+33123456789"
    }
  }'

Create Booking (Auto Price)

curl -X POST https://prodapi.efel.app/api/dealer/booking \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "vehicle_id": 123,
    "pickup_date": "2025-07-10T10:00:00.000Z",
    "dropoff_date": "2025-07-18T10:00:00.000Z",
    "extras": [1, 2],
    "customer": {
      "first_name": "John",
      "last_name": "Doe",
      "email": "john.doe@email.com",
      "phone": "+33123456789"
    }
  }'

Cancel Booking

curl -X DELETE https://prodapi.efel.app/api/dealer/booking/cancel/RESA-0001 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Get Calendar Fees

curl -X GET "https://prodapi.efel.app/api/dealer/calendar-fees?dealer_id=1" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Create Calendar Fee

curl -X POST https://prodapi.efel.app/api/dealer/calendar-fees \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "dealer_id": 1,
    "start_date": "2025-06-01",
    "end_date": "2025-08-31",
    "fee_amount": 75.00,
    "fee_type": "daily",
    "description": "Summer peak season fee"
  }'

Update Calendar Fee

curl -X PATCH https://prodapi.efel.app/api/dealer/calendar-fees/123 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fee_amount": 80.00,
    "description": "Updated summer peak season fee"
  }'

Delete Calendar Fee

curl -X DELETE https://prodapi.efel.app/api/dealer/calendar-fees/123 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Get Dealer Commissions

curl -X GET "https://prodapi.efel.app/api/dealer-commissions?dealerId=1&startDate=2025-01-01&endDate=2025-12-31&page=1&limit=50" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Get Dealer Statistics

curl -X GET "https://prodapi.efel.app/api/dealer/stats?startDate=2025-01-01&endDate=2025-12-31" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Create Dealer

curl -X POST https://prodapi.efel.app/api/dealer/create \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "New Dealer Company",
    "email": "dealer@company.com",
    "password": "secure_password",
    "phone": "+33123456789",
    "address": {
      "street": "123 Business St",
      "city": "Paris",
      "postal_code": "75001",
      "country": "FR"
    },
    "contact_person": {
      "first_name": "John",
      "last_name": "Doe",
      "email": "john.doe@company.com"
    }
  }'

Update Dealer

curl -X PATCH https://prodapi.efel.app/api/dealer/update/123 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Dealer Name",
    "phone": "+33123456788",
    "status": "active"
  }'

Get Vehicle by ID

curl -X POST https://prodapi.efel.app/api/dealer/getvehicle \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "vehicle_id": 123
  }'

Get Dealer Agencies

curl -X GET https://prodapi.efel.app/api/dealer/123/agencies \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Add Agency to Dealer

curl -X POST https://prodapi.efel.app/api/dealer/123/add-agency/456 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Remove Agency from Dealer

curl -X DELETE https://prodapi.efel.app/api/dealer/123/remove-agency/456 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Add Options to Booking

curl -X POST https://prodapi.efel.app/api/dealer/booking/add-options/RESA-0001 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "options": [
      {
        "option_id": 1,
        "quantity": 1
      },
      {
        "option_id": 2,
        "quantity": 2
      }
    ]
  }'

Login

// // Login and get tokens
const loginResponse = await fetch('/api/dealer/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'dealer@example.com',
    password: 'password'
  })
});
const { access_token, refresh_token } = await loginResponse.json();

// Store tokens securely
localStorage.setItem('dealer_token', access_token);
localStorage.setItem('dealer_refresh_token', refresh_token);

Refresh Token

// // Refresh access token
const refreshResponse = await fetch('/api/dealer/refresh', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    refresh_token: localStorage.getItem('dealer_refresh_token')
  })
});
const { access_token } = await refreshResponse.json();
localStorage.setItem('dealer_token', access_token);

Logout

// // Logout
const logoutResponse = await fetch('/api/dealer/logout', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('dealer_token')}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    refresh_token: localStorage.getItem('dealer_refresh_token')
  })
});
const logoutData = await logoutResponse.json();

Change Password

// // Change password
const passwordResponse = await fetch('/api/dealer/change-password', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('dealer_token')}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    current_password: 'old_password',
    new_password: 'new_secure_password',
    confirm_password: 'new_secure_password'
  })
});
const passwordData = await passwordResponse.json();

Get Stations

// // Get stations with language support
const lang = 'en'; // or 'fr', 'de', 'nl'
const stationsResponse = await fetch(`/api/dealer/stations?lang=${lang}&city=Paris`, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('dealer_token')}`
  }
});
const stationsData = await stationsResponse.json();

Get Station Details

// // Get station details with language support
const lang = 'en'; // or 'fr', 'de', 'nl'
const stationResponse = await fetch(`/api/dealer/stations/123?lang=${lang}`, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('dealer_token')}`
  }
});
const stationData = await stationResponse.json();

Get Vehicles

// // Get vehicles
const vehiclesResponse = await fetch('/api/dealer/vehicles?category=Economy&available=true', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('dealer_token')}`
  }
});
const vehiclesData = await vehiclesResponse.json();

Get Vehicle Details

// // Get vehicle details
const vehicleResponse = await fetch('/api/dealer/vehicles/123', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('dealer_token')}`
  }
});
const vehicleData = await vehicleResponse.json();

Check Availability

// // Check single vehicle availability
const availabilityResponse = await fetch('/api/dealer/availability', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('dealer_token')}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    pickup_date: '2025-10-15T10:00:00',
    dropoff_date: '2025-10-20T10:00:00',
    agency_id: 1,
    vehicle_id: 123
  })
});
const availabilityData = await availabilityResponse.json();
console.log(`Daily Price HT: โ‚ฌ${availabilityData.daily_price_ht}`);
console.log(`Daily Price TTC: โ‚ฌ${availabilityData.daily_price_ttc}`);
console.log(`Total Price HT: โ‚ฌ${availabilityData.total_price_ht}`);
console.log(`Total Price TTC: โ‚ฌ${availabilityData.total_price_ttc}`);
console.log(`VAT Amount: โ‚ฌ${availabilityData.vat_amount}`);

Get All Available Vehicles in Agency

// // Get all available vehicles in agency (with pagination)
const allAvailabilityResponse = await fetch('/api/dealer/availability', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('dealer_token')}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    pickup_date: '2025-10-15T10:00:00',
    dropoff_date: '2025-10-20T10:00:00',
    agency_id: 1,
    page: 1,      // Optional: page number (default: 1)
    limit: 20     // Optional: items per page (default: 50, max: 100)
  })
});
const allAvailabilityData = await allAvailabilityResponse.json();

// Check pagination info
console.log(`Page ${allAvailabilityData.pagination.current_page} of ${allAvailabilityData.pagination.total_pages}`);
console.log(`Total vehicles: ${allAvailabilityData.pagination.total_items}`);
if (allAvailabilityData.pagination.has_next_page) {
  console.log('More results available on next page');
}

Create Booking

// // Create booking with provided price
const bookingResponse = await fetch('/api/dealer/booking', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('dealer_token')}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    vehicle_id: 123,
    pickup_date: '2025-07-10T10:00:00.000Z',
    dropoff_date: '2025-07-18T10:00:00.000Z',
    total_price: 425.00,
    extras: [1, 2],
    customer: {
      first_name: 'John',
      last_name: 'Doe',
      email: 'john.doe@email.com',
      phone: '+33123456789'
    }
  })
});
const bookingData = await bookingResponse.json();

Create Booking (Auto Price)

// // Create booking with auto-calculated price
const bookingAutoResponse = await fetch('/api/dealer/booking', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('dealer_token')}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    vehicle_id: 123,
    pickup_date: '2025-07-10T10:00:00.000Z',
    dropoff_date: '2025-07-18T10:00:00.000Z',
    extras: [1, 2],
    customer: {
      first_name: 'John',
      last_name: 'Doe',
      email: 'john.doe@email.com',
      phone: '+33123456789'
    }
    // total_price omitted - will be auto-calculated
  })
});
const bookingAutoData = await bookingAutoResponse.json();

Cancel Booking

// // Cancel booking
const cancelResponse = await fetch('/api/dealer/booking/cancel/RESA-0001', {
  method: 'DELETE',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('dealer_token')}`
  }
});
const cancelData = await cancelResponse.json();

Login

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://prodapi.efel.app/api/dealer/login");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    "email" => "dealer@example.com",
    "password" => "password"
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
$tokens = json_decode($response, true);
curl_close($ch);

// Store tokens
$_SESSION["dealer_token"] = $tokens["access_token"];
$_SESSION["dealer_refresh_token"] = $tokens["refresh_token"];
?>

Refresh Token

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://prodapi.efel.app/api/dealer/refresh");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    "refresh_token" => $_SESSION["dealer_refresh_token"]
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
$newTokens = json_decode($response, true);
curl_close($ch);

// Update stored token
$_SESSION["dealer_token"] = $newTokens["access_token"];
?>

๐Ÿ†˜ Need Help? We're Here for You!

๐ŸŽฏ Quick Start Checklist

  1. ๐Ÿค Get your dealer credentials from your account manager
  2. ๐Ÿ”‘ Test login endpoint to verify credentials
  3. ๐Ÿš— Implement vehicle availability search
  4. ๐Ÿ“ Add booking creation functionality
  5. โš ๏ธ Handle error responses appropriately
  6. ๐Ÿ”„ Implement token refresh logic