Integration Examples

Complete code examples and tutorials for common integration scenarios

Quick Start Integration

Basic Estimate Generation

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/intelligent-estimate`, {
      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);
  });

Response Structure

The API returns a comprehensive estimate object including labor operations, parts list, materials, totals, and DRP compliance notes.

Language-Specific Examples

Python Integration

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/intelligent-estimate'
        
        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/rag-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']}")

C# Integration

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/intelligent-estimate", 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; }
}

Advanced Integration Patterns

Webhook Integration for Async Processing

For complex estimates that may take longer to process, use webhooks to receive notifications when processing is complete.

Submit Request with Webhook

// Submit estimate with webhook URL
const submitEstimate = async (vehicleData, damage) => {
  const response = await fetch('/api/intelligent-estimate', {
    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;
};

Handle Webhook Callback

// 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
};

Batch Processing Example

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/intelligent-estimate', {
      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`);
  });

Error Handling & Retry Logic

Robust Error Handling

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/intelligent-estimate', {
      ...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;
  }
}

Framework-Specific SDKs

React/Next.js Integration

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/Laravel Integration

<?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/intelligent-estimate', [
                '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/rag-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);
        }
    }
}
?>

Need Help with Integration?

Our technical team provides integration support and can help you implement these patterns in your specific environment.