Complete code examples and tutorials for common integration scenarios
Get started with a simple estimate generation example using JavaScript/Node.js.
const axios = require('axios');
const CODEX_API_KEY = process.env.CODEX_API_KEY;
const CODEX_BASE_URL = 'https://api.crashcodex.xyz';
async function generateEstimate(vehicleData, damageDescription) {
try {
const response = await axios.post(`${CODEX_BASE_URL}/api/v1/estimates/generate`, {
vin: vehicleData.vin,
year: vehicleData.year,
make: vehicleData.make,
model: vehicleData.model,
damage_description: damageDescription,
options: {
include_adas: true,
drp_rules: "GEICO",
location: "California"
}
}, {
headers: {
'Authorization': `Bearer ${CODEX_API_KEY}`,
'Content-Type': 'application/json'
},
timeout: 60000 // 60 second timeout
});
return response.data;
} catch (error) {
console.error('Error generating estimate:', error.response?.data || error.message);
throw error;
}
}
// Example usage
const vehicleInfo = {
vin: "1HGCM82633A123456",
year: 2024,
make: "Honda",
model: "Accord"
};
generateEstimate(vehicleInfo, "Front end collision with bumper damage")
.then(estimate => {
console.log('Estimate generated:', estimate);
})
.catch(error => {
console.error('Failed to generate estimate:', error);
});The API returns a comprehensive estimate object including labor operations, parts list, materials, totals, and DRP compliance notes.
import requests
import os
from typing import Dict, Any
class CrashCodexClient:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = 'https://api.crashcodex.xyz'
self.session = requests.Session()
self.session.headers.update({
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
})
def generate_estimate(self, vehicle_data: Dict,
damage_description: str) -> Dict[str, Any]:
endpoint = f'{self.base_url}/api/v1/estimates/generate'
payload = {
'vin': vehicle_data['vin'],
'year': vehicle_data['year'],
'make': vehicle_data['make'],
'model': vehicle_data['model'],
'damage_description': damage_description,
'options': {
'include_adas': True,
'drp_rules': 'GEICO',
'location': 'California'
}
}
try:
response = self.session.post(endpoint, json=payload, timeout=60)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error generating estimate: {e}")
raise
def query_knowledge_base(self, query: str,
max_results: int = 5) -> Dict[str, Any]:
endpoint = f'{self.base_url}/api/v1/intelligence/query'
payload = {
'query': query,
'max_results': max_results
}
response = self.session.post(endpoint, json=payload, timeout=30)
response.raise_for_status()
return response.json()
# Usage example
client = CrashCodexClient(os.getenv('CODEX_API_KEY'))
vehicle = {
'vin': '1HGCM82633A123456',
'year': 2024,
'make': 'Honda',
'model': 'Accord'
}
estimate = client.generate_estimate(vehicle,
"Front bumper damaged, headlight cracked")
print(f"Total estimate: {estimate['totals']['grand_total']}")
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class CrashCodexClient
{
private readonly HttpClient _httpClient;
private readonly string _baseUrl = "https://api.crashcodex.xyz";
public CrashCodexClient(string apiKey)
{
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey);
_httpClient.Timeout = TimeSpan.FromSeconds(60);
}
public async Task<EstimateResponse> GenerateEstimateAsync(
VehicleData vehicle, string damageDescription)
{
var request = new EstimateRequest
{
VIN = vehicle.VIN,
Year = vehicle.Year,
Make = vehicle.Make,
Model = vehicle.Model,
DamageDescription = damageDescription,
Options = new EstimateOptions
{
IncludeADAS = true,
DRPRules = "GEICO",
Location = "California"
}
};
var json = JsonConvert.SerializeObject(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
try
{
var response = await _httpClient.PostAsync(
$"{_baseUrl}/api/v1/estimates/generate", content);
response.EnsureSuccessStatusCode();
var responseJson = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<EstimateResponse>(responseJson);
}
catch (HttpRequestException ex)
{
throw new Exception($"Error generating estimate: {ex.Message}", ex);
}
}
public void Dispose()
{
_httpClient?.Dispose();
}
}
public class VehicleData
{
public string VIN { get; set; }
public int Year { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
public class EstimateRequest
{
public string VIN { get; set; }
public int Year { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public string DamageDescription { get; set; }
public EstimateOptions Options { get; set; }
}
public class EstimateOptions
{
public bool IncludeADAS { get; set; }
public string DRPRules { get; set; }
public string Location { get; set; }
}
For complex estimates that may take longer to process, use webhooks to receive notifications when processing is complete.
// Submit estimate with webhook URL
const submitEstimate = async (vehicleData, damage) => {
const response = await fetch('/api/v1/estimates/generate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
'X-Webhook-URL': 'https://your-app.com/webhooks/estimate'
},
body: JSON.stringify({
...vehicleData,
damage_description: damage,
async: true // Enable async processing
})
});
const { requestId } = await response.json();
console.log(`Request submitted: ${requestId}`);
return requestId;
};// Express.js webhook handler
const express = require('express');
const app = express();
app.post('/webhooks/estimate', express.json(), (req, res) => {
const { requestId, status, result, error } = req.body;
console.log(`Estimate ${requestId} status: ${status}`);
if (status === 'completed') {
// Process successful estimate
processCompletedEstimate(requestId, result);
} else if (status === 'failed') {
// Handle failed estimate
console.error(`Estimate failed: ${error}`);
handleFailedEstimate(requestId, error);
}
// Always respond with 200 to acknowledge receipt
res.status(200).json({ received: true });
});
const processCompletedEstimate = (requestId, estimate) => {
// Update database with completed estimate
// Notify user of completion
// Trigger downstream processes
};Process multiple estimates efficiently using batch operations and concurrency control.
const pLimit = require('p-limit');
class BatchEstimateProcessor {
constructor(apiKey, concurrency = 5) {
this.apiKey = apiKey;
this.limit = pLimit(concurrency); // Limit concurrent requests
this.results = [];
this.errors = [];
}
async processBatch(estimateRequests) {
console.log(`Processing ${estimateRequests.length} estimates...`);
const promises = estimateRequests.map((request, index) =>
this.limit(() => this.processEstimate(request, index))
);
await Promise.allSettled(promises);
return {
successful: this.results.length,
failed: this.errors.length,
results: this.results,
errors: this.errors
};
}
async processEstimate(request, index) {
try {
const estimate = await this.generateEstimate(request);
this.results.push({
index,
requestId: request.id,
estimate
});
console.log(`✓ Completed estimate ${index + 1}`);
} catch (error) {
this.errors.push({
index,
requestId: request.id,
error: error.message
});
console.error(`✗ Failed estimate ${index + 1}: ${error.message}`);
}
}
async generateEstimate(request) {
const response = await fetch('https://api.crashcodex.xyz/api/v1/estimates/generate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
}
}
// Usage
const processor = new BatchEstimateProcessor(process.env.CODEX_API_KEY, 3);
const estimates = [
{ id: 'est-001', vin: '1HGCM82633A123456', damage_description: 'Front damage' },
{ id: 'est-002', vin: '1FTFW1ET5DFC69282', damage_description: 'Rear damage' },
// ... more estimates
];
processor.processBatch(estimates)
.then(results => {
console.log(`Batch complete: ${results.successful} successful, ${results.failed} failed`);
});Implement comprehensive error handling with exponential backoff and circuit breaker patterns.
class CrashCodexAPIClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseURL = 'https://api.crashcodex.xyz';
this.maxRetries = 3;
this.retryDelay = 1000; // 1 second base delay
}
async makeRequest(endpoint, data, options = {}) {
const maxRetries = options.maxRetries || this.maxRetries;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await this.executeRequest(endpoint, data);
return response;
} catch (error) {
if (attempt === maxRetries) {
throw error; // Final attempt failed
}
if (this.shouldRetry(error)) {
const delay = this.calculateDelay(attempt);
console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
await this.sleep(delay);
} else {
throw error; // Don't retry certain errors
}
}
}
}
async executeRequest(endpoint, data) {
const response = await fetch(`${this.baseURL}${endpoint}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
// Handle different response types
if (response.status === 401) {
throw new APIError('Unauthorized - Check your API key', 401, false);
}
if (response.status === 403) {
throw new APIError('Forbidden - Insufficient permissions', 403, false);
}
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
throw new APIError('Rate limit exceeded', 429, true, retryAfter);
}
if (response.status >= 500) {
throw new APIError('Server error', response.status, true);
}
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new APIError(
errorData.message || 'Request failed',
response.status,
false
);
}
return response.json();
}
shouldRetry(error) {
// Retry on server errors and rate limits
return error.retryable ||
error.status >= 500 ||
error.status === 429;
}
calculateDelay(attempt) {
// Exponential backoff with jitter
const baseDelay = this.retryDelay * Math.pow(2, attempt - 1);
const jitter = Math.random() * 0.1 * baseDelay;
return Math.min(baseDelay + jitter, 30000); // Max 30 seconds
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
class APIError extends Error {
constructor(message, status, retryable = false, retryAfter = null) {
super(message);
this.name = 'APIError';
this.status = status;
this.retryable = retryable;
this.retryAfter = retryAfter;
}
}
// Usage with proper error handling
const client = new CrashCodexAPIClient(process.env.CODEX_API_KEY);
async function generateEstimateWithErrorHandling(vehicleData, damage) {
try {
const estimate = await client.makeRequest('/api/v1/estimates/generate', {
...vehicleData,
damage_description: damage
});
return estimate;
} catch (error) {
if (error.name === 'APIError') {
console.error(`API Error (${error.status}): ${error.message}`);
// Handle specific error types
switch (error.status) {
case 401:
// Refresh API key or notify admin
break;
case 429:
// Back off and try later
break;
case 500:
// Log for investigation
break;
}
} else {
console.error('Unexpected error:', error);
}
throw error;
}
}import { useState, useEffect } from 'react';
const useEstimateGeneration = () => {
const [loading, setLoading] = useState(false);
const [estimate, setEstimate] = useState(null);
const [error, setError] = useState(null);
const generateEstimate = async (vehicleData, damage) => {
setLoading(true);
setError(null);
try {
const response = await fetch('/api/generate-estimate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ vehicleData, damage })
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const result = await response.json();
setEstimate(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
return { generateEstimate, loading, estimate, error };
};
// Component usage
export default function EstimateForm() {
const { generateEstimate, loading, estimate, error } = useEstimateGeneration();
const [vehicleData, setVehicleData] = useState({
vin: '',
year: '',
make: '',
model: ''
});
const [damage, setDamage] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
generateEstimate(vehicleData, damage);
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
<button type="submit" disabled={loading}>
{loading ? 'Generating...' : 'Generate Estimate'}
</button>
{error && <div className="error">{error}</div>}
{estimate && <EstimateDisplay estimate={estimate} />}
</form>
);
}<?php
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class CrashCodexService
{
private string $apiKey;
private string $baseUrl;
public function __construct()
{
$this->apiKey = config('services.crash_codex.api_key');
$this->baseUrl = config('services.crash_codex.base_url',
'https://api.crashcodex.xyz');
}
public function generateEstimate(array $vehicleData, string $damage): array
{
try {
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $this->apiKey,
'Content-Type' => 'application/json'
])
->timeout(60)
->post($this->baseUrl . '/api/v1/estimates/generate', [
'vin' => $vehicleData['vin'],
'year' => $vehicleData['year'],
'make' => $vehicleData['make'],
'model' => $vehicleData['model'],
'damage_description' => $damage,
'options' => [
'include_adas' => true,
'drp_rules' => 'GEICO',
'location' => 'California'
]
]);
if ($response->successful()) {
return $response->json();
}
throw new \Exception(
'API request failed: ' . $response->status() .
' - ' . $response->body()
);
} catch (\Exception $e) {
Log::error('Crash CODEX API Error: ' . $e->getMessage());
throw $e;
}
}
public function queryKnowledgeBase(string $query, int $maxResults = 5): array
{
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $this->apiKey,
'Content-Type' => 'application/json'
])
->timeout(30)
->post($this->baseUrl . '/api/v1/intelligence/query', [
'query' => $query,
'max_results' => $maxResults
]);
return $response->json();
}
}
// Usage in controller
class EstimateController extends Controller
{
public function generate(Request $request, CrashCodexService $codex)
{
$request->validate([
'vin' => 'required|string|size:17',
'year' => 'required|integer|min:1900|max:' . (date('Y') + 1),
'make' => 'required|string',
'model' => 'required|string',
'damage' => 'required|string'
]);
try {
$estimate = $codex->generateEstimate(
$request->only(['vin', 'year', 'make', 'model']),
$request->input('damage')
);
return response()->json($estimate);
} catch (\Exception $e) {
return response()->json([
'error' => 'Failed to generate estimate'
], 500);
}
}
}
?>Our technical team provides integration support and can help you implement these patterns in your specific environment.