Files
api-company/apis/vin-decoder/openapi.yaml
T
agent-company aef849228e
Validate Flux manifests / kustomize-build (pull_request) Failing after 25s
[Phase 1-3] research: VIN Decoder feasibility study and OpenAPI spec draft
- Appended VIN Decoder feasibility session to research/RESEARCH_LOG.md
  - NHTSA vPIC: no rate limits, public domain, 1981-present coverage
  - Competitor audit: 28,500+ combined RapidAPI subscribers across 4 listings
  - Legal/ToS: 17 U.S.C. 105 public domain confirmed, no redistribution restrictions
  - Decision: BUILD confirmed

- Added apis/vin-decoder/openapi.yaml with:
  - GET /decode?vin={vin} - full single VIN decode
  - POST /batch - up to 50 VINs per request
  - GET /health - service health + cache stats
  - Full OAS 3.1 schema (nullable fields use type arrays)
  - Passes redocly lint with zero errors

Closes leeworks-agents/api-company#117
2026-05-30 10:06:59 +00:00

406 lines
12 KiB
YAML

openapi: 3.1.0
info:
title: VIN Decoder API
version: 1.0.0
description: |
Decode any 17-character Vehicle Identification Number (VIN) into structured
vehicle data including make, model, year, trim, engine, body style, and more.
Powered by the NHTSA vPIC public-domain database.
**Data source:** NHTSA Product Information Catalog and Vehicle Listing (vPIC)
public API - US federal government data, public domain (17 U.S.C. 105).
**Coverage:** Model years 1981-present, all major manufacturers registered
with NHTSA (domestic and import).
**Caching:** Decoded results are cached for 90 days; cache status is
indicated by the X-Cache response header.
contact:
name: leeworks.dev API Support
url: https://docs.leeworks.dev
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: https://vin.leeworks.dev/v1
description: Production
security:
- RapidApiProxy: []
tags:
- name: decode
description: VIN decoding endpoints
- name: health
description: Service health and observability
paths:
/decode:
get:
operationId: decodeVin
summary: Decode a single VIN
description: |
Decodes a 17-character VIN and returns structured vehicle attributes.
Results are cached for 90 days; a cache hit is indicated by
X-Cache: HIT in the response headers.
tags:
- decode
parameters:
- name: vin
in: query
required: true
description: 17-character Vehicle Identification Number (uppercase, no I/O/Q).
schema:
type: string
minLength: 17
maxLength: 17
pattern: "^[A-HJ-NPR-Z0-9]{17}$"
example: 1HGCM82633A004352
- name: raw
in: query
required: false
description: If true, include raw NHTSA vPIC fields in the response.
schema:
type: boolean
default: false
responses:
"200":
description: VIN successfully decoded
headers:
X-Cache:
schema:
type: string
enum: [HIT, MISS]
description: Whether the result was served from cache
X-Data-Source:
schema:
type: string
description: Upstream data source identifier
X-Request-Id:
schema:
type: string
description: Unique request identifier
content:
application/json:
schema:
$ref: "#/components/schemas/VinDecodeResult"
"400":
description: Invalid VIN format or missing parameter
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
"403":
description: Missing or invalid RapidAPI proxy secret
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
"429":
description: Rate limit exceeded for your plan
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
"500":
description: Internal server error or upstream NHTSA API failure
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/batch:
post:
operationId: decodeVinBatch
summary: Decode up to 50 VINs in a single request
description: |
Accepts a JSON body with an array of VINs (1-50) and returns a decoded
result for each. Each VIN is processed independently; partial failures
return an error object in that position rather than failing the whole batch.
tags:
- decode
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- vins
properties:
vins:
type: array
minItems: 1
maxItems: 50
items:
type: string
minLength: 17
maxLength: 17
pattern: "^[A-HJ-NPR-Z0-9]{17}$"
description: Array of 17-character VINs to decode
example:
vins:
- 1HGCM82633A004352
- WBABW33486PX01612
responses:
"200":
description: Batch decode results (one entry per input VIN, in order)
headers:
X-Request-Id:
schema:
type: string
content:
application/json:
schema:
type: object
properties:
results:
type: array
items:
oneOf:
- $ref: "#/components/schemas/VinDecodeResult"
- $ref: "#/components/schemas/VinDecodeError"
count:
type: integer
description: Total number of VINs processed
cached_count:
type: integer
description: Number of results served from cache
error_count:
type: integer
description: Number of VINs that could not be decoded
"400":
description: Invalid request body
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
"403":
description: Missing or invalid RapidAPI proxy secret
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
"429":
description: Rate limit exceeded
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
"500":
description: Internal server error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/health:
get:
operationId: healthCheck
summary: Service health check
description: |
Returns health status of the VIN Decoder service including cache
statistics and NHTSA API reachability. Does not require X-RapidAPI-Proxy-Secret.
tags:
- health
security: []
responses:
"200":
description: Service is healthy
content:
application/json:
schema:
$ref: "#/components/schemas/HealthResponse"
"503":
description: Service is degraded (upstream unreachable or DB error)
content:
application/json:
schema:
$ref: "#/components/schemas/HealthResponse"
components:
securitySchemes:
RapidApiProxy:
type: apiKey
in: header
name: X-RapidAPI-Proxy-Secret
description: |
RapidAPI proxy secret injected automatically by RapidAPI on every
subscriber request. Direct callers must include this header manually.
schemas:
VinDecodeResult:
type: object
required:
- vin
- error_code
properties:
vin:
type: string
description: The input VIN (uppercased)
example: 1HGCM82633A004352
make:
type: ["string", "null"]
description: Vehicle manufacturer brand
example: HONDA
model:
type: ["string", "null"]
description: Vehicle model name
example: Accord
model_year:
type: ["string", "null"]
description: Model year as a 4-digit string
example: "2003"
trim:
type: ["string", "null"]
description: Trim level (e.g. EX, LX, Sport)
example: EX
series:
type: ["string", "null"]
description: Series designation if applicable
body_class:
type: ["string", "null"]
description: Body style classification
example: Sedan/Saloon
drive_type:
type: ["string", "null"]
description: Drive configuration
example: FWD/Front-Wheel Drive
engine_displacement_cc:
type: ["number", "null"]
description: Engine displacement in cubic centimetres
example: 2354
engine_displacement_l:
type: ["number", "null"]
description: Engine displacement in litres
example: 2.4
engine_cylinders:
type: ["integer", "null"]
description: Number of engine cylinders
example: 4
fuel_type_primary:
type: ["string", "null"]
description: Primary fuel type
example: Gasoline
transmission_style:
type: ["string", "null"]
description: Transmission type (Automatic, Manual, CVT, etc.)
example: Automatic
transmission_speeds:
type: ["string", "null"]
description: Number of transmission speeds as string
example: "5"
plant_city:
type: ["string", "null"]
description: Assembly plant city
example: MARYSVILLE
plant_state:
type: ["string", "null"]
description: Assembly plant state/province
example: OHIO
plant_country:
type: ["string", "null"]
description: Assembly plant country
example: UNITED STATES (USA)
manufacturer_name:
type: ["string", "null"]
description: Full legal name of the manufacturer
example: HONDA OF AMERICA MFG., INC.
vehicle_type:
type: ["string", "null"]
description: NHTSA vehicle type classification
example: PASSENGER CAR
error_code:
type: string
description: NHTSA decode error code. "0" means successful decode.
example: "0"
error_text:
type: ["string", "null"]
description: Human-readable decode error (null when error_code is "0")
cached:
type: boolean
description: Whether this result was served from the local cache
example: true
VinDecodeError:
type: object
required:
- vin
- error
- message
properties:
vin:
type: string
description: The VIN that could not be decoded
error:
type: string
description: Error code
example: INVALID_VIN
message:
type: string
description: Human-readable error description
example: VIN must be exactly 17 alphanumeric characters
Error:
type: object
required:
- error
- message
- status
properties:
error:
type: string
description: Machine-readable error code
example: BAD_REQUEST
message:
type: string
description: Human-readable error description
example: "Query parameter 'vin' is required"
status:
type: integer
description: HTTP status code
example: 400
HealthResponse:
type: object
required:
- status
- version
properties:
status:
type: string
enum: [ok, degraded]
description: Overall service health
version:
type: string
description: Service version
example: "1.0.0"
uptime_seconds:
type: integer
description: Seconds since the service started
example: 86400
cache:
type: object
properties:
entries:
type: integer
description: Number of cached VIN records
hit_rate_24h:
type: number
description: Cache hit rate over the last 24 hours (0.0-1.0)
size_mb:
type: number
description: SQLite cache file size in megabytes
upstream:
type: object
properties:
nhtsa_vpic:
type: string
enum: [reachable, unreachable]
description: NHTSA vPIC API reachability
last_check:
type: string
format: date-time
description: ISO-8601 timestamp of last upstream health check