{"openapi":"3.0.3","info":{"title":"KConnect Backend2 API","version":"0.1.0","description":"Local KeyConnect backend with SQLite storage, file uploads, OTP auth, Smartcar bridge endpoints, and app-compatible /api/v3 routes."},"servers":[{"url":"https://vca-002-keyconnect.limgrow.com"}],"tags":[{"name":"Auth"},{"name":"Users"},{"name":"Vehicles"},{"name":"Smartcar"},{"name":"Catalog"},{"name":"Service Reminders"},{"name":"Uploads"},{"name":"Documents"},{"name":"Device"},{"name":"Reports"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"EmailRequest":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","example":"test@example.com"}}},"OtpCompareRequest":{"type":"object","required":["email","otpRequest"],"properties":{"email":{"type":"string","format":"email","example":"test@example.com"},"otpRequest":{"type":"string","example":"123456"}}},"RefreshTokenRequest":{"type":"object","required":["refreshToken"],"properties":{"refreshToken":{"type":"string"}}},"User":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"email":{"type":"string"},"username":{"type":"string","nullable":true},"avatar":{"type":"string","nullable":true},"role":{"type":"string"},"isPremium":{"type":"boolean"}}},"VehicleInput":{"type":"object","properties":{"make":{"type":"string","example":"Toyota"},"model":{"type":"string","example":"Camry"},"year":{"type":"integer","example":2024},"odo":{"type":"number","example":1200},"picture":{"type":"string","nullable":true},"brandID":{"type":"string","nullable":true}}},"ServiceReminderInput":{"type":"object","properties":{"vehicle":{"type":"string"},"deviceId":{"type":"string"},"serviceTitle":{"type":"string","example":"Oil change"},"serviceType":{"type":"string","nullable":true},"vehicleType":{"type":"string","nullable":true},"status":{"type":"string","example":"PENDING"},"reminderDate":{"type":"string","nullable":true},"reminderAlert":{"type":"string","nullable":true},"cost":{"type":"integer","example":50},"currentOdometer":{"type":"number","example":12500},"nextServiceMileage":{"type":"number","nullable":true},"maintenanceInterval":{"type":"integer","nullable":true},"accessOdometerReading":{"type":"boolean","nullable":true},"note":{"type":"string"},"checkupsList":{"type":"array","items":{"type":"object"}},"attachments":{"type":"array","items":{"type":"object"}},"isDemo":{"type":"boolean"}}}}},"paths":{"/api/token":{"get":{"tags":["Smartcar"],"summary":"Get current Smartcar M2M token","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/connections":{"get":{"tags":["Smartcar"],"summary":"List Smartcar connections","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/vehicles/{vid}/signals":{"get":{"tags":["Smartcar"],"summary":"Get all Smartcar vehicle signals","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/vehicles/{vid}/signals/{code}":{"get":{"tags":["Smartcar"],"summary":"Get one Smartcar signal by code","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}},{"name":"code","in":"path","required":true,"schema":{"type":"string"},"example":"charge-ischarging"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/signals/schema":{"get":{"tags":["Smartcar"],"summary":"Get Smartcar signal schema","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/auth/check-email":{"post":{"tags":["Auth"],"summary":"Check whether an email exists","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/auth/login/request-otp":{"post":{"tags":["Auth"],"summary":"Create login OTP","description":"With OTP_LOG_CODE=true, the generated OTP is printed in the backend terminal.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/auth/signup/request-otp":{"post":{"tags":["Auth"],"summary":"Create signup OTP","description":"With OTP_LOG_CODE=true, the generated OTP is printed in the backend terminal.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/auth/compare-otp":{"post":{"tags":["Auth"],"summary":"Verify OTP and receive temporary OTP token","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtpCompareRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/auth/loginOtp":{"post":{"tags":["Auth"],"summary":"Exchange temporary OTP token for app session tokens","security":[{"bearerAuth":[]}],"parameters":[{"name":"device-id","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/auth/refresh-token":{"post":{"tags":["Auth"],"summary":"Refresh app session","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/users/me/detail":{"get":{"tags":["Users"],"summary":"Get current user profile","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}}}}},"/api/v3/users/me":{"put":{"tags":["Users"],"summary":"Update current user profile","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"username":{"type":"string"},"avatar":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}}}}},"/api/v3/users/me/delete-account":{"delete":{"tags":["Users"],"summary":"Delete current user account","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/vehicles":{"get":{"tags":["Vehicles"],"summary":"List local and Smartcar vehicles","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"post":{"tags":["Vehicles"],"summary":"Create local vehicle","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["Vehicles"],"summary":"Delete all local vehicles","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/vehicles/image":{"get":{"tags":["Vehicles"],"summary":"Get or cache stock vehicle image","parameters":[{"name":"make","in":"query","required":true,"schema":{"type":"string"}},{"name":"model","in":"query","required":false,"schema":{"type":"string"}},{"name":"year","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/vehicles/manual":{"get":{"tags":["Vehicles"],"summary":"Get manual link placeholder","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/vehicles/{vid}":{"get":{"tags":["Vehicles"],"summary":"Get one vehicle","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"put":{"tags":["Vehicles"],"summary":"Update local vehicle connect status","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"connectStatus":{"type":"string"},"connectError":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["Vehicles"],"summary":"Delete local vehicle or revoke Smartcar connection","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/vehicles/{vid}/customImage":{"put":{"tags":["Vehicles"],"summary":"Set custom vehicle image URL","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/vehicles/{vid}/defaultImage":{"put":{"tags":["Vehicles"],"summary":"Reset vehicle image to default","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/vehicleHistories/info/{vin}":{"get":{"tags":["Vehicles"],"summary":"Decode VIN via NHTSA","parameters":[{"name":"vin","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/vehicleHistories/recall/{vin}":{"get":{"tags":["Vehicles"],"summary":"Get recalls by VIN decode via NHTSA","parameters":[{"name":"vin","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/remotes/cars/login":{"get":{"tags":["Smartcar"],"summary":"Build Smartcar Connect login URL for app","parameters":[{"name":"brand","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/remotes/cars/exchange":{"get":{"tags":["Smartcar"],"summary":"Exchange Smartcar callback and link newest vehicle locally","parameters":[{"name":"code","in":"query","required":false,"schema":{"type":"string"}},{"name":"brand","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/remotes/cars/vehicles/locations":{"get":{"tags":["Smartcar"],"summary":"Get Smartcar vehicle locations/state list","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/remotes/cars/vehicles/{vid}/homeScreen":{"get":{"tags":["Smartcar"],"summary":"Get remote car home screen payload","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/remotes/cars/vehicles/{vid}/statusScreen":{"get":{"tags":["Smartcar"],"summary":"Get remote car status screen payload","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/remotes/cars/vehicles/{vid}/lock":{"post":{"tags":["Smartcar"],"summary":"Lock Smartcar vehicle","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/remotes/cars/vehicles/{vid}/unlock":{"post":{"tags":["Smartcar"],"summary":"Unlock Smartcar vehicle","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/remotes/cars/vehicles/{vid}/disconnect":{"post":{"tags":["Smartcar"],"summary":"Disconnect Smartcar vehicle","parameters":[{"name":"vid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/brands":{"get":{"tags":["Catalog"],"summary":"List brands","parameters":[{"name":"showAndroid","in":"query","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/car-models":{"get":{"tags":["Catalog"],"summary":"List car models for brand","parameters":[{"name":"model_id","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/ca-tutorials/search":{"get":{"tags":["Catalog"],"summary":"Get connect tutorial by brand name","parameters":[{"name":"name","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/callAgents":{"get":{"tags":["Catalog"],"summary":"List OEM call agents","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/serviceReminders":{"get":{"tags":["Service Reminders"],"summary":"List service reminders","security":[{"bearerAuth":[]}],"parameters":[{"name":"vehicle","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"post":{"tags":["Service Reminders"],"summary":"Create service reminder","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceReminderInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/serviceReminders/records":{"get":{"tags":["Service Reminders"],"summary":"List service reminder records with total cost","security":[{"bearerAuth":[]}],"parameters":[{"name":"vehicle","in":"query","required":false,"schema":{"type":"string"}},{"name":"deviceId","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/serviceReminders/{id}":{"put":{"tags":["Service Reminders"],"summary":"Update service reminder","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceReminderInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"tags":["Service Reminders"],"summary":"Delete service reminder","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/uploads":{"post":{"tags":["Uploads"],"summary":"Upload one image","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/uploads/multi":{"post":{"tags":["Uploads"],"summary":"Upload multiple images","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["images"],"properties":{"images":{"type":"array","items":{"type":"string","format":"binary"}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/documents/scan":{"post":{"tags":["Documents"],"summary":"Scan uploaded document URLs with optional Gemini OCR","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["driver_license","insurance","certificate_of_title","service_record"]},"images":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/iaps/{type}/android":{"post":{"tags":["Device"],"summary":"Save Android IAP receipt as verified locally","security":[{"bearerAuth":[]}],"parameters":[{"name":"type","in":"path","required":true,"schema":{"type":"string"},"example":"subscription"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"packageName":{"type":"string"},"subscriptionId":{"type":"string"},"productId":{"type":"string"},"purchaseToken":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/device-tokens":{"post":{"tags":["Device"],"summary":"Upsert FCM device token","security":[{"bearerAuth":[]}],"parameters":[{"name":"device-id","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"os":{"type":"string","example":"android"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/v3/reports":{"post":{"tags":["Reports"],"summary":"Save bug or feedback report","security":[{"bearerAuth":[]}],"parameters":[{"name":"device-id","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"issue":{"type":"string"},"carInfo":{"type":"string"},"vinId":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}}}}