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

Testing and development environment

https://erpblacksheep.blacksheep-van.com/api/dealer/

Production

Live production environment

https://api.efel.app/api/dealer/

🔐 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 (8 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://api.efel.app/uploads/category/van.jpg",
              "filePath": "van.jpg",
              "isDefault": true
            }
          ],
          "images": [
            {
              "id": 1,
              "fileUrl": "https://api.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://api.efel.app/uploads/category/van.jpg",
      "filePath": "van.jpg",
      "isDefault": true
    }
  ],
  "images": [
    {
      "id": 1,
      "fileUrl": "https://api.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. Can check a single vehicle (with ...
Check vehicle availability for specific dates. 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
  "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. Returns single vehicle data if vehicle_id provided, or list of all available vehicles grouped by category if vehicle_id omitted.

// Single vehicle response:
{
  "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,
  "total_vehicles": 1
}

// All vehicles response (grouped by category with pagination):
{
  "agency_id": 1,
  "agency_name": "Paris Center",
  "pickup_date": "2025-10-15 10:00:00",
  "dropoff_date": "2025-10-20 10:00:00",
  "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
  "extras": [1, 2],       // Optional array of extra option IDs
  "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. 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",
  "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",
  "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://api.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://api.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
Retrieve all available options for a specific station/agency by ID
🔒 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://api.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://api.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

🚀 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://api.efel.app/api/dealer/login \
  -H "Content-Type: application/json" \
  -d '{"email": "dealer@example.com", "password": "password"}'

Refresh Token

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

Logout

curl -X POST https://api.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://api.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://api.efel.app/api/dealer/stations?lang=en" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Get Station Details

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

Get Vehicles

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

Get Vehicle Details

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

Check Availability

curl -X POST https://api.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
  }' | jq '.daily_price_ht, .daily_price_ttc, .total_price_ht, .total_price_ttc'

Get All Available Vehicles in Agency

curl -X POST https://api.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,
    "page": 1,
    "limit": 20
  }'

Create Booking

curl -X POST https://api.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://api.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://api.efel.app/api/dealer/booking/cancel/RESA-0001 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

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://api.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://api.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