openapi: 3.0.3
info:
title: 'Laravel API Documentation'
description: ''
version: 1.0.0
servers:
-
url: 'https://100.53.191.230'
tags:
-
name: 'API Key Management'
description: "\nAPIs for managing developer API keys."
-
name: Authentication
description: "\nAPIs for handling user login, registration and logout."
-
name: Endpoints
description: ''
-
name: Predictions
description: "\nEndpoints for AI-powered repair cost predictions, VIN extraction, and prediction feedback.\nAll endpoints require a valid API key in the Authorization header."
paths:
/api/v1/dashboard/keys:
get:
summary: 'List API Keys'
operationId: listAPIKeys
description: 'Get a list of all API keys for the authenticated user.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
status: success
data:
-
id: 1
name: 'My Key'
public_key: pk_test_...
secret_key: sk_test_...
environment: test
last_used_at: null
properties:
status:
type: string
example: success
data:
type: array
example:
-
id: 1
name: 'My Key'
public_key: pk_test_...
secret_key: sk_test_...
environment: test
last_used_at: null
items:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: 'My Key'
public_key:
type: string
example: pk_test_...
secret_key:
type: string
example: sk_test_...
environment:
type: string
example: test
last_used_at:
type: string
example: null
nullable: true
tags:
- 'API Key Management'
post:
summary: 'Generate API Key'
operationId: generateAPIKey
description: 'Create a new API key for the authenticated user.'
parameters: []
responses:
201:
description: ''
content:
application/json:
schema:
type: object
example:
status: success
message: 'API key generated successfully...'
data:
id: 1
name: 'Mobile App'
public_key: pk_test_...
secret_key: sk_test_...
environment: test
properties:
status:
type: string
example: success
message:
type: string
example: 'API key generated successfully...'
data:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: 'Mobile App'
public_key:
type: string
example: pk_test_...
secret_key:
type: string
example: sk_test_...
environment:
type: string
example: test
tags:
- 'API Key Management'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'The name/label for the key.'
example: 'Mobile App'
environment:
type: string
description: 'The environment (live or test).'
example: test
required:
- name
- environment
'/api/v1/dashboard/keys/{id}':
delete:
summary: 'Revoke API Key'
operationId: revokeAPIKey
description: 'Delete an API key, preventing any future access with it.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
status: success
message: 'API key revoked successfully.'
properties:
status:
type: string
example: success
message:
type: string
example: 'API key revoked successfully.'
tags:
- 'API Key Management'
parameters:
-
in: path
name: id
description: 'The ID of the API key to revoke.'
example: 1
required: true
schema:
type: integer
/api/v1/auth/login:
post:
summary: 'Authenticate User'
operationId: authenticateUser
description: 'Log in a user with their email and password to receive a management token.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
status: success
message: 'Authenticated successfully'
data:
user:
id: 1
name: 'John Doe'
session_token: 1|...
properties:
status:
type: string
example: success
message:
type: string
example: 'Authenticated successfully'
data:
type: object
properties:
user:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: 'John Doe'
session_token:
type: string
example: 1|...
tags:
- Authentication
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
description: 'The email of the user.'
example: user@example.com
password:
type: string
description: 'The password of the user.'
example: password
required:
- email
- password
security: []
/api/v1/auth/register:
post:
summary: 'Register User'
operationId: registerUser
description: 'Create a new developer account and receive a management token.'
parameters: []
responses:
201:
description: ''
content:
application/json:
schema:
type: object
example:
status: success
message: 'User registered successfully'
data:
user:
id: 1
name: 'John Doe'
session_token: 2|...
properties:
status:
type: string
example: success
message:
type: string
example: 'User registered successfully'
data:
type: object
properties:
user:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: 'John Doe'
session_token:
type: string
example: 2|...
tags:
- Authentication
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'The name of the user.'
example: 'John Doe'
email:
type: string
description: 'The email of the user.'
example: john@example.com
password:
type: string
description: 'The password (min 8 chars).'
example: password
required:
- name
- email
- password
security: []
/api/v1/auth/user/logout:
post:
summary: Logout
operationId: logout
description: 'Revoke the current management token.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
status: success
message: 'Logged out successfully'
properties:
status:
type: string
example: success
message:
type: string
example: 'Logged out successfully'
tags:
- Authentication
/api/v1/admin/problems:
get:
summary: ''
operationId: getApiV1AdminProblems
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
/api/v1/admin/problems/stats:
get:
summary: ''
operationId: getApiV1AdminProblemsStats
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
'/api/v1/admin/problems/{parentId}/children':
get:
summary: ''
operationId: getApiV1AdminProblemsParentIdChildren
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
parameters:
-
in: path
name: parentId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/admin/problems/{id}/show':
get:
summary: ''
operationId: getApiV1AdminProblemsIdShow
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
parameters:
-
in: path
name: id
description: 'The ID of the problem.'
example: architecto
required: true
schema:
type: string
'/api/v1/admin/problems/{id}/details':
get:
summary: ''
operationId: getApiV1AdminProblemsIdDetails
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
parameters:
-
in: path
name: id
description: 'The ID of the problem.'
example: architecto
required: true
schema:
type: string
/api/v1/admin/vehicles:
get:
summary: ''
operationId: getApiV1AdminVehicles
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
post:
summary: ''
operationId: postApiV1AdminVehicles
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
vehicle_model_id:
type: string
description: 'The id of an existing record in the vehicle_models table.'
example: architecto
nullable: true
new_make:
type: string
description: 'This field is required when vehicle_model_id is not present. Must not be greater than 255 characters.'
example: 'n'
nullable: true
new_model:
type: string
description: 'This field is required when vehicle_model_id is not present. Must not be greater than 255 characters.'
example: g
nullable: true
new_year:
type: integer
description: 'This field is required when vehicle_model_id is not present. Must be at least 1900. Must not be greater than 2100.'
example: 16
nullable: true
vin_mask:
type: string
description: 'Must be at least 11 characters. Must not be greater than 17 characters.'
example: miyvdlj
current_mileage:
type: integer
description: 'Must be at least 0.'
example: 52
plate_no:
type: string
description: 'Must not be greater than 20 characters.'
example: ikhwaykcmyuwpwlv
nullable: true
motor_vehicle_type:
type: string
description: 'Must not be greater than 255 characters.'
example: q
nullable: true
motor_vehicle_type_group:
type: string
description: 'Must not be greater than 255 characters.'
example: w
nullable: true
seed_facility_id:
type: string
description: 'The id of an existing record in the service_facilities table.'
example: null
nullable: true
required:
- vin_mask
- current_mileage
security: []
/api/v1/admin/vehicles/stats:
get:
summary: ''
operationId: getApiV1AdminVehiclesStats
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
/api/v1/admin/vehicles/form-options:
get:
summary: ''
operationId: getApiV1AdminVehiclesFormOptions
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
/api/v1/admin/vehicles/search-models:
get:
summary: ''
operationId: getApiV1AdminVehiclesSearchModels
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
'/api/v1/admin/vehicles/{vehicle_id}':
get:
summary: ''
operationId: getApiV1AdminVehiclesVehicle_id
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiV1AdminVehiclesVehicle_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
vin_mask:
type: string
description: 'Must be at least 11 characters. Must not be greater than 17 characters.'
example: bngzmiy
current_mileage:
type: integer
description: 'Must be at least 0.'
example: 60
plate_no:
type: string
description: 'Must not be greater than 20 characters.'
example: dljnikhwaykcmyuw
nullable: true
motor_vehicle_type:
type: string
description: 'Must not be greater than 255 characters.'
example: p
nullable: true
motor_vehicle_type_group:
type: string
description: 'Must not be greater than 255 characters.'
example: w
nullable: true
required:
- vin_mask
- current_mileage
security: []
delete:
summary: ''
operationId: deleteApiV1AdminVehiclesVehicle_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
parameters:
-
in: path
name: vehicle_id
description: 'The ID of the vehicle.'
example: 019ca9f7-adeb-731e-9b71-062301ab7efe
required: true
schema:
type: string
/api/v1/admin/regions:
get:
summary: ''
operationId: getApiV1AdminRegions
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
post:
summary: ''
operationId: postApiV1AdminRegions
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
facility_name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
city:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
nullable: true
state:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
zip_code:
type: string
description: 'Must not be greater than 20 characters.'
example: zmiyvdljnikhwayk
nullable: true
country:
type: string
description: 'Must not be greater than 255 characters.'
example: c
nullable: true
avg_labor_rate:
type: number
description: 'Must be at least 0.'
example: 38
nullable: true
required:
- facility_name
security: []
/api/v1/admin/regions/stats:
get:
summary: ''
operationId: getApiV1AdminRegionsStats
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
/api/v1/admin/regions/states:
get:
summary: ''
operationId: getApiV1AdminRegionsStates
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
/api/v1/admin/regions/recalculate:
post:
summary: ''
operationId: postApiV1AdminRegionsRecalculate
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
'/api/v1/admin/regions/{facility_id}':
get:
summary: ''
operationId: getApiV1AdminRegionsFacility_id
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiV1AdminRegionsFacility_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
facility_name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
city:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
nullable: true
state:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
zip_code:
type: string
description: 'Must not be greater than 20 characters.'
example: zmiyvdljnikhwayk
nullable: true
country:
type: string
description: 'Must not be greater than 255 characters.'
example: c
nullable: true
avg_labor_rate:
type: number
description: 'Must be at least 0.'
example: 38
nullable: true
required:
- facility_name
security: []
delete:
summary: ''
operationId: deleteApiV1AdminRegionsFacility_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
parameters:
-
in: path
name: facility_id
description: 'The ID of the facility.'
example: 1
required: true
schema:
type: integer
/api/v1/admin/transactions:
get:
summary: ''
operationId: getApiV1AdminTransactions
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
post:
summary: ''
operationId: postApiV1AdminTransactions
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
/api/v1/admin/transactions/stats:
get:
summary: ''
operationId: getApiV1AdminTransactionsStats
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
/api/v1/admin/transactions/form-options:
get:
summary: ''
operationId: getApiV1AdminTransactionsFormOptions
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
'/api/v1/admin/transactions/{transaction_id}':
get:
summary: ''
operationId: getApiV1AdminTransactionsTransaction_id
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiV1AdminTransactionsTransaction_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
delete:
summary: ''
operationId: deleteApiV1AdminTransactionsTransaction_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
parameters:
-
in: path
name: transaction_id
description: 'The ID of the transaction.'
example: 1
required: true
schema:
type: integer
'/api/v1/admin/transactions/{transaction_id}/details':
get:
summary: ''
operationId: getApiV1AdminTransactionsTransaction_idDetails
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
parameters:
-
in: path
name: transaction_id
description: 'The ID of the transaction.'
example: 1
required: true
schema:
type: integer
/api/v1/secure-data:
post:
summary: 'Access Secure Data'
operationId: accessSecureData
description: "This endpoint is protected by the API Key middleware.\nYou must provide a valid secret key in the Authorization header."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Secure data accessed successfully'
api_key_used: 'My Key'
properties:
message:
type: string
example: 'Secure data accessed successfully'
api_key_used:
type: string
example: 'My Key'
tags:
- Endpoints
/api/user:
get:
summary: ''
operationId: getApiUser
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
/api/v1/predict:
post:
summary: 'Get Repair Cost Prediction'
operationId: getRepairCostPrediction
description: "Calculates a repair price estimate using local historical data combined with\nAI predictions from Gemini and DeepSeek. Results are cached for 3 days using\na memory decay system (100% fresh → 0% at expiry)."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
success: true
session_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
memory_source: fresh
memory_decay_remaining: 100.0
memory_expires_at: '2026-03-08T12:00:00+00:00'
red_flag: false
red_flag_reason: null
match_percentage: 87.5
aggregated_ai_average: 450.0
local_prediction:
average_total_estimate: 425.5
low_total_estimate: 350.0
high_total_estimate: 500.0
gemini_prediction:
ai_average_estimate: 460.0
match_percentage: 92.0
deepseek_prediction:
ai_average_estimate: 440.0
match_percentage: 96.5
repair_breakdown:
source: local_scaled
parts:
-
name: 'Brake Pad Set'
unit_price: 45.0
quantity: 2
total_price: 90.0
estimated_labor_hours: 1.5
total_parts_cost: 90.0
total_estimate: 425.5
properties:
success:
type: boolean
example: true
session_id:
type: string
example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
memory_source:
type: string
example: fresh
memory_decay_remaining:
type: number
example: 100.0
memory_expires_at:
type: string
example: '2026-03-08T12:00:00+00:00'
red_flag:
type: boolean
example: false
red_flag_reason:
type: string
example: null
nullable: true
match_percentage:
type: number
example: 87.5
aggregated_ai_average:
type: number
example: 450.0
local_prediction:
type: object
properties:
average_total_estimate:
type: number
example: 425.5
low_total_estimate:
type: number
example: 350.0
high_total_estimate:
type: number
example: 500.0
gemini_prediction:
type: object
properties:
ai_average_estimate:
type: number
example: 460.0
match_percentage:
type: number
example: 92.0
deepseek_prediction:
type: object
properties:
ai_average_estimate:
type: number
example: 440.0
match_percentage:
type: number
example: 96.5
repair_breakdown:
type: object
properties:
source:
type: string
example: local_scaled
parts:
type: array
example:
-
name: 'Brake Pad Set'
unit_price: 45
quantity: 2
total_price: 90
items:
type: object
properties:
name:
type: string
example: 'Brake Pad Set'
unit_price:
type: number
example: 45.0
quantity:
type: integer
example: 2
total_price:
type: number
example: 90.0
estimated_labor_hours:
type: number
example: 1.5
total_parts_cost:
type: number
example: 90.0
total_estimate:
type: number
example: 425.5
404:
description: ''
content:
application/json:
schema:
type: object
example:
success: false
message: 'Vehicle not found based on the provided VIN.'
error_code: VEHICLE_NOT_FOUND
properties:
success:
type: boolean
example: false
message:
type: string
example: 'Vehicle not found based on the provided VIN.'
error_code:
type: string
example: VEHICLE_NOT_FOUND
500:
description: ''
content:
application/json:
schema:
type: object
example:
success: false
message: 'An error occurred while calculating the estimate.'
error_details: 'Error message here'
properties:
success:
type: boolean
example: false
message:
type: string
example: 'An error occurred while calculating the estimate.'
error_details:
type: string
example: 'Error message here'
tags:
- Predictions
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
vin:
type: string
description: 'The vehicle VIN (11 or 17 characters).'
example: 1HGBH41JXMN109186
zip_code:
type: string
description: 'The zip code for regional pricing.'
example: '90210'
problem_identifier:
type: string
description: 'The problem category ID or identifier.'
example: '42'
required:
- vin
- zip_code
- problem_identifier
/api/v1/predict/problems:
post:
summary: 'Get Problem Identifiers'
operationId: getProblemIdentifiers
description: "Fetches available problem categories for a vehicle's group based on its VIN.\nReturns hierarchical category names (Parent > Child) that can be used as the\n`problem_identifier` parameter in the predict endpoint."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
success: true
data:
-
id: 42
display_name: 'Brakes > Brake Pad Replacement'
-
id: 15
display_name: 'Engine > Oil Change'
-
id: 78
display_name: 'Suspension > Shock Absorber'
properties:
success:
type: boolean
example: true
data:
type: array
example:
-
id: 42
display_name: 'Brakes > Brake Pad Replacement'
-
id: 15
display_name: 'Engine > Oil Change'
-
id: 78
display_name: 'Suspension > Shock Absorber'
items:
type: object
properties:
id:
type: integer
example: 42
display_name:
type: string
example: 'Brakes > Brake Pad Replacement'
404:
description: ''
content:
application/json:
schema:
type: object
example:
success: false
message: 'Vehicle not found based on the provided VIN.'
error_code: VEHICLE_NOT_FOUND
properties:
success:
type: boolean
example: false
message:
type: string
example: 'Vehicle not found based on the provided VIN.'
error_code:
type: string
example: VEHICLE_NOT_FOUND
500:
description: ''
content:
application/json:
schema:
type: object
example:
success: false
message: 'An error occurred while fetching problems.'
error_details: 'Error message here'
properties:
success:
type: boolean
example: false
message:
type: string
example: 'An error occurred while fetching problems.'
error_details:
type: string
example: 'Error message here'
tags:
- Predictions
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
vin:
type: string
description: 'The vehicle VIN (11 or 17 characters).'
example: 1HGBH41JXMN109186
required:
- vin
/api/v1/predict/categories:
get:
summary: 'List Problem Categories (Main)'
operationId: listProblemCategoriesMain
description: 'Returns all top-level (parent) problem identifier categories.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
success: true
data:
-
id: 1
name: Brakes
description: 'Brake system issues'
-
id: 2
name: Engine
description: 'Engine related problems'
properties:
success:
type: boolean
example: true
data:
type: array
example:
-
id: 1
name: Brakes
description: 'Brake system issues'
-
id: 2
name: Engine
description: 'Engine related problems'
items:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: Brakes
description:
type: string
example: 'Brake system issues'
tags:
- Predictions
'/api/v1/predict/categories/{parentId}/sub':
get:
summary: 'List Sub-Categories'
operationId: listSubCategories
description: 'Returns all child problem identifier categories under a given main category.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
success: true
data:
-
id: 10
name: 'Brake Pad Replacement'
description: null
-
id: 11
name: 'Brake Rotor Replacement'
description: null
properties:
success:
type: boolean
example: true
data:
type: array
example:
-
id: 10
name: 'Brake Pad Replacement'
description: null
-
id: 11
name: 'Brake Rotor Replacement'
description: null
items:
type: object
properties:
id:
type: integer
example: 10
name:
type: string
example: 'Brake Pad Replacement'
description:
type: string
example: null
nullable: true
404:
description: ''
content:
application/json:
schema:
type: object
example:
success: false
message: 'Main category not found.'
properties:
success:
type: boolean
example: false
message:
type: string
example: 'Main category not found.'
tags:
- Predictions
parameters:
-
in: path
name: parentId
description: 'The ID of the main category.'
example: 1
required: true
schema:
type: integer
/api/v1/predict/red-flags:
get:
summary: 'Get Red Flags / Prediction History'
operationId: getRedFlagsPredictionHistory
description: "Returns the most recent 50 predictions with red flag analysis and feedback counts.\nAdmins see all predictions; regular users see only their own."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
success: true
data:
-
id: 1
session_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
vin: 1HGBH41JXMN109186
problem_name: 'Brakes > Brake Pad Replacement'
red_flag: true
red_flag_reason: 'Local estimate appears unrealistically low compared to the aggregated AI prediction.'
match_percentage: 45.2
local_average_estimate: 150.0
ai_average_estimate: 450.0
feedbacks_count: 3
good_feedbacks_count: 2
created_at: '2026-03-05T10:30:00.000000Z'
properties:
success:
type: boolean
example: true
data:
type: array
example:
-
id: 1
session_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
vin: 1HGBH41JXMN109186
problem_name: 'Brakes > Brake Pad Replacement'
red_flag: true
red_flag_reason: 'Local estimate appears unrealistically low compared to the aggregated AI prediction.'
match_percentage: 45.2
local_average_estimate: 150
ai_average_estimate: 450
feedbacks_count: 3
good_feedbacks_count: 2
created_at: '2026-03-05T10:30:00.000000Z'
items:
type: object
properties:
id:
type: integer
example: 1
session_id:
type: string
example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
vin:
type: string
example: 1HGBH41JXMN109186
problem_name:
type: string
example: 'Brakes > Brake Pad Replacement'
red_flag:
type: boolean
example: true
red_flag_reason:
type: string
example: 'Local estimate appears unrealistically low compared to the aggregated AI prediction.'
match_percentage:
type: number
example: 45.2
local_average_estimate:
type: number
example: 150.0
ai_average_estimate:
type: number
example: 450.0
feedbacks_count:
type: integer
example: 3
good_feedbacks_count:
type: integer
example: 2
created_at:
type: string
example: '2026-03-05T10:30:00.000000Z'
tags:
- Predictions
/api/v1/predict/extract-vin:
post:
summary: 'Extract VIN from Image'
operationId: extractVINFromImage
description: "Uses Gemini AI vision to extract a 17-character VIN from an uploaded image.\nSupports photos of VIN plates, stickers, dashboards, and registration documents."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
success: true
vin: 1HGBH41JXMN109186
message: 'VIN extracted successfully'
properties:
success:
type: boolean
example: true
vin:
type: string
example: 1HGBH41JXMN109186
message:
type: string
example: 'VIN extracted successfully'
422:
description: ''
content:
application/json:
schema:
type: object
example:
success: false
message: 'Could not detect a valid 17-character VIN in the provided image.'
properties:
success:
type: boolean
example: false
message:
type: string
example: 'Could not detect a valid 17-character VIN in the provided image.'
500:
description: ''
content:
application/json:
schema:
type: object
example:
success: false
message: 'An error occurred during AI image processing.'
error_details: 'Error message here'
properties:
success:
type: boolean
example: false
message:
type: string
example: 'An error occurred during AI image processing.'
error_details:
type: string
example: 'Error message here'
tags:
- Predictions
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
image:
type: string
format: binary
description: 'The image file containing a VIN. Max 10MB. Allowed types: jpeg, png, jpg, webp.'
required:
- image
/api/v1/predict/feedback:
post:
summary: 'Submit Prediction Feedback'
operationId: submitPredictionFeedback
description: "Allows users to rate a prediction as \"good\" or \"wrong\" with an optional comment.\nAdmins can submit feedback on any prediction; regular users only on their own."
parameters: []
responses:
201:
description: ''
content:
application/json:
schema:
type: object
example:
success: true
message: 'Feedback submitted successfully.'
data:
id: 1
prediction_history_id: 42
rating: good
comment: 'Price was accurate for my area.'
created_at: '2026-03-05T12:00:00.000000Z'
properties:
success:
type: boolean
example: true
message:
type: string
example: 'Feedback submitted successfully.'
data:
type: object
properties:
id:
type: integer
example: 1
prediction_history_id:
type: integer
example: 42
rating:
type: string
example: good
comment:
type: string
example: 'Price was accurate for my area.'
created_at:
type: string
example: '2026-03-05T12:00:00.000000Z'
422:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'The given data was invalid.'
errors:
session_id:
- 'The selected session id is invalid.'
properties:
message:
type: string
example: 'The given data was invalid.'
errors:
type: object
properties:
session_id:
type: array
example:
- 'The selected session id is invalid.'
items:
type: string
tags:
- Predictions
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
session_id:
type: string
description: 'The UUID session ID of the prediction.'
example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
rating:
type: string
description: 'The rating value. Must be "good" or "wrong".'
example: good
comment:
type: string
description: 'Optional feedback comment (max 1000 chars).'
example: 'Price was accurate for my area.'
nullable: true
required:
- session_id
- rating
'/api/v1/predict/feedback/{session_id}':
get:
summary: 'Get Feedback Stats'
operationId: getFeedbackStats
description: "Returns feedback statistics and all feedback entries for a prediction.\nIncludes total count, good/wrong breakdown, and a calculated feedback score (0-100%).\nAdmins can view any prediction's feedback; regular users only their own."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
success: true
session_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
total_feedbacks: 5
good_count: 4
wrong_count: 1
feedback_score: 80.0
feedbacks:
-
id: 1
rating: good
comment: 'Very accurate!'
created_at: '2026-03-05T12:00:00.000000Z'
properties:
success:
type: boolean
example: true
session_id:
type: string
example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
total_feedbacks:
type: integer
example: 5
good_count:
type: integer
example: 4
wrong_count:
type: integer
example: 1
feedback_score:
type: number
example: 80.0
feedbacks:
type: array
example:
-
id: 1
rating: good
comment: 'Very accurate!'
created_at: '2026-03-05T12:00:00.000000Z'
items:
type: object
properties:
id:
type: integer
example: 1
rating:
type: string
example: good
comment:
type: string
example: 'Very accurate!'
created_at:
type: string
example: '2026-03-05T12:00:00.000000Z'
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'No query results for model [App\Models\PredictionHistory].'
properties:
message:
type: string
example: 'No query results for model [App\Models\PredictionHistory].'
tags:
- Predictions
parameters:
-
in: path
name: session_id
description: 'The UUID session ID of the prediction.'
example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
required: true
schema:
type: string