The Pickard provides a RESTful API for accessing vehicle diagnostics, parts database, and web search functionality. All API endpoints are built with Next.js API routes and use JSON for request and response payloads.
Development: http://localhost:3000/api
Production: https://your-domain.com/api
All authenticated endpoints require a valid Clerk session. Include the session token in your requests:
// Client-side with Clerk
import { useAuth } from '@clerk/nextjs'
const { getToken } = useAuth()
const token = await getToken()
fetch('/api/endpoint', {
headers: {
'Authorization': `Bearer ${token}`
}
})Search for vehicles or problems based on filters.
Query Parameters:
type(string): Search type -vehiclesorproblemsq(string): Search query textvehicleId(string): Vehicle ID for problem searchyearFrom(number): Filter by year range startyearTo(number): Filter by year range endmake(string): Vehicle manufacturermodel(string): Vehicle modelengineType(string): Engine type filterdriveType(string): Drive type -AWD,2WD, or4WDsubmodel(string): Vehicle submodel
Example Request:
GET /api/search?type=vehicles&make=Honda&model=Accord&yearFrom=2020&yearTo=2023Response:
{
"success": true,
"data": [
{
"id": "vehicle-123",
"year": 2022,
"make": "Honda",
"model": "Accord",
"engineType": "2.0L Turbo",
"driveType": "FWD"
}
]
}Perform advanced search with complex filters.
Request Body:
{
"type": "vehicles",
"filters": {
"year": [2020, 2023],
"make": ["Honda"],
"model": ["Accord"],
"engineType": ["2.0L Turbo"]
}
}Response:
{
"success": true,
"data": [...]
}Perform web search for automotive repair information.
Authentication: Not required (public endpoint)
Request Body:
{
"query": "engine won't start",
"category": "engine",
"vehicleTypes": ["car", "truck"],
"type": "specific_problem"
}Parameters:
query(string, required): Search querycategory(string, optional): Category filter -engine,transmission,brakes, etc.vehicleTypes(string[], optional): Vehicle types to focus ontype(string, optional): Search type -automotive_termsorspecific_problem
Response:
{
"success": true,
"query": "engine won't start",
"category": "engine",
"results": [
{
"title": "How to Fix: engine won't start - Complete Guide",
"url": "https://example.com/guide",
"snippet": "Learn how to diagnose and repair...",
"source": "example.com"
}
],
"timestamp": "2024-01-15T10:30:00.000Z"
}Environment Variables Required:
GOOGLE_CUSTOM_SEARCH_API_KEY- Google Custom Search API keyGOOGLE_CUSTOM_SEARCH_ENGINE_ID- Search engine ID
If API keys are not configured, the endpoint returns simulated results for development.
Get endpoint information.
Response:
{
"message": "Web search API endpoint",
"usage": "POST with query parameter",
"timestamp": "2024-01-15T10:30:00.000Z"
}Manage saved web search results.
Authentication: Required (Clerk)
Save a web search result to user's collection.
Request Body:
{
"title": "How to Fix Engine Issues",
"url": "https://example.com/guide",
"snippet": "Comprehensive guide...",
"source": "example.com",
"searchTerm": "engine problems",
"category": "engine",
"tags": ["diagnostic", "repair"],
"notes": "Useful troubleshooting steps"
}Required Fields:
title(string)url(string)searchTerm(string)category(string)
Optional Fields:
snippet(string)source(string)tags(string[])notes(string)
Response:
{
"success": true,
"data": {
"id": 1,
"userId": "user-123",
"title": "How to Fix Engine Issues",
"url": "https://example.com/guide",
"isBookmarked": false,
"createdAt": "2024-01-15T10:30:00.000Z"
},
"message": "Search result saved successfully"
}Error Responses:
400- Missing required fields401- Unauthorized (no valid session)404- User not found409- URL already saved by user500- Internal server error
Get user's saved search results.
Query Parameters:
category(string, optional): Filter by categorybookmarked(boolean, optional): Filter bookmarked itemslimit(number, optional): Results per page (default: 20)offset(number, optional): Pagination offset (default: 0)
Example Request:
GET /api/search-results?category=engine&bookmarked=true&limit=10Response:
{
"success": true,
"data": [
{
"id": 1,
"title": "Engine Diagnostic Guide",
"url": "https://example.com/guide",
"category": "engine",
"tags": ["diagnostic"],
"isBookmarked": true,
"createdAt": "2024-01-15T10:30:00.000Z"
}
],
"pagination": {
"total": 45,
"limit": 10,
"offset": 0,
"hasMore": true
}
}Update a saved search result.
Request Body:
{
"id": 1,
"isBookmarked": true,
"tags": ["diagnostic", "advanced"],
"notes": "Updated notes"
}Required Fields:
id(number)
Optional Fields (at least one required):
isBookmarked(boolean)tags(string[])notes(string)
Response:
{
"success": true,
"data": {
"id": 1,
"isBookmarked": true,
"tags": ["diagnostic", "advanced"],
"updatedAt": "2024-01-15T11:00:00.000Z"
},
"message": "Search result updated successfully"
}Delete a saved search result.
Query Parameters:
id(number, required): Search result ID
Example Request:
DELETE /api/search-results?id=1Response:
{
"success": true,
"message": "Search result deleted successfully"
}Submit a contact form message.
Request Body:
{
"name": "John Doe",
"email": "john@example.com",
"subject": "Technical Support",
"message": "I need help with..."
}Response:
{
"success": true,
"message": "Message sent successfully"
}Clerk webhook handler for user lifecycle events.
Authentication: Clerk webhook signature verification
Events Handled:
user.created- New user registrationuser.updated- User profile updatesuser.deleted- User account deletion
Webhook Configuration:
Set webhook URL in Clerk dashboard to: https://your-domain.com/api/webhooks/clerk
All endpoints follow a consistent error response format:
{
"success": false,
"error": "Error message description"
}Common HTTP Status Codes:
200- Success400- Bad Request (invalid parameters)401- Unauthorized (authentication required)403- Forbidden (insufficient permissions)404- Not Found (resource doesn't exist)409- Conflict (duplicate resource)500- Internal Server Error
Current Status: Not implemented Planned: 100 requests per minute per IP address
interface SearchFilters {
year?: number[]
make?: string[]
model?: string[]
engineType?: string[]
driveType?: ('AWD' | '2WD' | '4WD')[]
submodel?: string[]
}type SearchCategory =
| 'engine'
| 'transmission'
| 'brakes'
| 'electrical'
| 'suspension'
| 'hvac'
| 'diesel'
| 'general'// lib/api-client.ts
export class PickardAPIClient {
private baseURL: string
constructor(baseURL: string = '/api') {
this.baseURL = baseURL
}
async searchVehicles(filters: SearchFilters) {
const response = await fetch(`${this.baseURL}/search`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'vehicles', filters })
})
return response.json()
}
async webSearch(query: string, category?: string) {
const response = await fetch(`${this.baseURL}/web-search`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, category })
})
return response.json()
}
async saveSearchResult(data: SaveSearchResultRequest) {
const response = await fetch(`${this.baseURL}/search-results`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
return response.json()
}
}Current Version: v1 (implicit)
Future: API versioning will be implemented as /api/v2/... when breaking changes are introduced
For API support or questions:
- Check this documentation
- Review code examples in
/src/app/api/ - See type definitions in
/src/types/ - Contact development team for clarifications
Last Updated: 2024-01-15