VinChex API

v2.1
Base URL: https://vinchex.com/api
Request Access

Overview

The VinChex API provides endpoints for managing VINs and lienholders. The API uses OAuth 2.0 client credentials flow for authentication and returns JSON responses.

Important Notes

  • • All API requests must use HTTPS
  • • Authentication is required for all protected endpoints
  • • All timestamps are in UTC format

Authentication

The API uses OAuth 2.0 client credentials grant type for authentication. You need to obtain an access token before making requests to protected endpoints.

Get Access Token

POST /oauth/token

Obtain an access token using client credentials.

Parameters

Parameter Type Required Description
grant_type string Yes Must be "client_credentials"
client_id string Yes Your client ID
client_secret string Yes Your client secret

Example Request

curl -X POST "https://vinchex.com/api/oauth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "your_client_id",
    "client_secret": "your_client_secret"
  }'

Example Response

{
  "access_token": "42b6cbb60f1412da0422e8db7b2a8c5f9d3...",
  "token_type": "Bearer",
  "expires_in": 86400,
  "expires_at": 1691766000,
  "company_id": 123,
  "company_name": "Example Company"
}

Response Fields

  • access_token: The Bearer token to use for authentication
  • token_type: Always "Bearer"
  • expires_in: Number of seconds until token expires
  • expires_at: Unix timestamp when token expires
  • company_id: ID of the authenticated company
  • company_name: Name of the authenticated company

Revoke Access Token

POST /oauth/revoke

Revoke an access token.

Example Request

curl -X POST "https://vinchex.com/api/oauth/revoke" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "42b6cbb60f1412da0422e8db7b2a8c5f9d3..."
  }'

Authorization Header

All protected endpoints require a valid Bearer token in the Authorization header:

Authorization: Bearer your_access_token

Data Types

VinState

The VinState data type represents the processing status of a VIN in the system. It is an integer-backed enum with the following values:

Value Label Description
0 Inactive VIN has been deactivated or removed from processing
1 Pending VIN is queued for lienholder lookup processing
2 In Progress VIN lienholder lookup is currently being processed
3 Completed VIN lienholder lookup completed successfully

Usage in API

  • Input: Use integer values (0, 1, 2, 3) in the GET /vins state query parameter
  • Output: Responses use these integer values in the state field. Internal Review records are exposed to API clients as In Progress (2).

VIN Priority

The Priority data type represents the validation priority level of a VIN in the system. It is an integer-backed enum with the following values:

Value Label Description
0 Low Low Risk
1 Medium Medium Risk
2 High High Risk

Usage in API

  • Output only: Priority is output-only and cannot be set through the public API
  • Output: GET /vins returns the integer value in the priority field
  • Processing: VinChex calculates priority internally from verification results and business rules

VinQueue

The VinQueue data type selects the processing workflow for a submitted VIN. It is a string-backed enum with the following values:

Value Label Description
default_lien_check Default Lien Check Runs the standard provider lien-verification workflow. This is the default when queue is omitted.
california_lien_check California Lien Check Bypasses the provider workflow and routes the VIN to manual California DMV verification.

StateAbbreviation

The StateAbbreviation data type is a string containing one of the following supported state, district, or territory abbreviations. UNKNOWN represents an unavailable or unrecognized jurisdiction.

Abbreviation State or Territory
AL Alabama
AK Alaska
AZ Arizona
AR Arkansas
CA California
CO Colorado
CT Connecticut
DE Delaware
FL Florida
GA Georgia
HI Hawaii
ID Idaho
IL Illinois
IN Indiana
IA Iowa
KS Kansas
KY Kentucky
LA Louisiana
ME Maine
MD Maryland
MA Massachusetts
MI Michigan
MN Minnesota
MS Mississippi
MO Missouri
MT Montana
NE Nebraska
NV Nevada
NH New Hampshire
NJ New Jersey
NM New Mexico
NY New York
NC North Carolina
ND North Dakota
OH Ohio
OK Oklahoma
OR Oregon
PA Pennsylvania
RI Rhode Island
SC South Carolina
SD South Dakota
TN Tennessee
TX Texas
UT Utah
VT Vermont
VA Virginia
WA Washington
WV West Virginia
WI Wisconsin
WY Wyoming
DC District of Columbia
PR Puerto Rico
AS American Samoa
GU Guam
MP Northern Mariana Islands
VI U.S. Virgin Islands
UNKNOWN Unknown

VIN Management

List VINs

GET /vins

Get a paginated list of VINs with optional filtering.

Note: All filters are optional. queue defaults to default_lien_check when omitted.

Query Parameters

Parameter Type Required Description
vinstringNoPartial VIN match (8-17 characters)
stateintegerNoFilter by VinState: 0=Inactive, 1=Pending, 2=In Progress, or 3=Completed
queuestringNoFilter by VinQueue. Defaults to default_lien_check and may be combined with state.
per_pageintegerNoResults per page (1-10000, default: 100)
pageintegerNoPage number (1-1000, default: 1)

Example Request

curl -X GET "https://vinchex.com/api/vins?queue=california_lien_check&state=2&per_page=20&page=1" \
  -H "Authorization: Bearer your_access_token"

Example Response

{
  "success": true,
  "message": "VINs retrieved successfully",
  "data": [
    {
      "id": 1234,
      "vin": "1HGBH41JXMN109186",
      "state": 2,
      "registered_state": "CA",
      "priority": 2,
      "title_date": null,
      "owner_start_date": null,
      "lienholder": null,
      "restricted_state": false,
      "data_found": false
    },
    {
      "id": 1235,
      "vin": "1HGBH41KXMN109187",
      "state": 2,
      "registered_state": "CA",
      "priority": 1,
      "title_date": "2020-01-01",
      "owner_start_date": "2019-11-15",
      "lienholder": "Chase Auto Finance",
      "restricted_state": true,
      "data_found": true
    }
  ],
  "pagination": {
    "current_page": 1,
    "per_page": 20,
    "total": 98,
    "last_page": 5,
    "from": 1,
    "to": 20
  }
}

Response Fields

  • id: Unique identifier for the VIN record
  • vin: The Vehicle Identification Number
  • state: Processing state (see VinState)
  • registered_state: Two-letter US state abbreviation where vehicle is registered (e.g., "CA", "TX") or null. For restricted rows this is the authoritative specific-state identifier — a restricted California VIN is identified by restricted_state=true and registered_state="CA".
  • priority: Priority level (see VinPriority)
  • title_date: Date from the latest lienholder history record or null
  • owner_start_date: Owner start date from the latest lienholder history record or null
  • lienholder: Name of the lienholder from latest history or null
  • restricted_state: Boolean indicating if the VIN is in a restricted state (true when vehicle registration state restricts data access)
  • data_found: Boolean indicating whether lienholder data was successfully retrieved for this VIN. True when at least one lienholder history record exists, regardless of processing state; false otherwise (including restricted VINs awaiting a manual lien fetch).

Add VINs

POST /vins/add

Add multiple VINs to the system for asynchronous processing. Default lien checks enter Pending (1); California lien checks enter In Progress (2) and bypass the standard provider workflow.

Request Parameters

Field Type Required Description
vins array Yes Array of VIN objects
vins[].vin string Yes VIN string (10-17 alphanumeric characters)
vins[].lienholder string Yes Lienholder name (required for every queue, max 255 characters, case-insensitive lookup).
vins[].origination_date date No Date when the VIN originated (format: YYYY-MM-DD)
vins[].queue string No VinQueue value. Defaults to default_lien_check when omitted.
options.ignore_duplicates boolean No When true, duplicate VINs in the same request are collapsed to their first occurrence instead of causing validation to fail.

Example Request

curl -X POST "https://vinchex.com/api/vins/add" \
  -H "Authorization: Bearer your_access_token" \
  -H "Content-Type: application/json" \
  -d '{
    "vins": [
      {
        "vin": "1HGBH41JXMN109186",
        "lienholder": "Chase Auto Finance",
        "origination_date": "2025-09-15",
        "queue": "default_lien_check"
      },
      {
        "vin": "2T1BURHE0JC123456",
        "lienholder": "California Test Lender",
        "origination_date": "2025-09-20",
        "queue": "california_lien_check"
      }
    ],
    "options": {
      "ignore_duplicates": true
    }
  }'

Example Response (202 Accepted)

{
  "success": true,
  "message": "VINs have been queued for processing",
  "processing_type": "queued",
  "total_vins": 2,
  "size": "0.5 KB"
}

Processing Notes

  • • All VINs are queued for background processing
  • • Returns HTTP 202 (Accepted) status immediately
  • • Maximum payload size: 2MB
  • • origination_date is optional and must be a valid date when supplied
  • • Duplicate VINs in the same request will cause validation error
  • • Use options.ignore_duplicates: true to skip duplicates
  • • Set queue: "california_lien_check" on an individual VIN to route it to manual California DMV verification. A lienholder is still required.
  • • A plain or default add cannot move an active California-queue VIN into the provider workflow; it is skipped and its review progress is preserved.
  • • Re-submitting an active California-queue VIN to the same queue is a no-op. A completed California verification has left the queue and may be submitted again.

Deactivate VINs

PATCH /vins/remove

Deactivate VINs by setting their state to VinState INACTIVE

Example Request

curl -X PATCH "https://vinchex.com/api/vins/remove" \
  -H "Authorization: Bearer your_access_token" \
  -H "Content-Type: application/json" \
  -d '{
    "vins": [
      "1HGBH41JXMN109186",
      "2T1BURHE0JC123456"
    ]
  }'

Example Response

{
  "success": true,
  "message": "Processed 2 VINs successfully, 0 failed",
  "summary": {
    "total": 2,
    "successful": 2,
    "failed": 0
  }
}

Unique VIN Count

GET /vins/unique-count

Return the number of distinct VINs belonging to the authenticated company.

{
  "success": true,
  "message": "Unique VIN count retrieved successfully",
  "data": {
    "unique_vins": 1250
  }
}

Lienholder Management

Every lienholder endpoint is company scoped. Your visible scope is global plus your company-owned lienholders. california_lien_check_enabled is always the authenticated company's effective value, including for a global lienholder.

List Lienholders

GET /lienholders

Returns visible lienholders with pagination. Optional query parameters are search (1-255 characters), california_lien_check_enabled=true|false, per_page (1-100, default 100), and page (positive page number).

curl -X GET "https://vinchex.com/api/lienholders?california_lien_check_enabled=true&per_page=100" \
  -H "Authorization: Bearer your_access_token"

Example Response (200 OK)

{
  "success": true,
  "data": [
    {
      "id": 42,
      "name": "Chase Auto Finance",
      "is_global": true,
      "aliases": [],
      "california_lien_check_enabled": true
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 100,
    "total": 1
  }
}

The literal query value false returns disabled visible lienholders, including both missing settings and settings explicitly stored as false.

Lienholder Detail

GET /lienholders/{lienholder}

Returns one visible lienholder using the same fields as the list endpoint. An ID owned by another company and a nonexistent ID both return 404.

curl -X GET "https://vinchex.com/api/lienholders/42" \
  -H "Authorization: Bearer your_access_token"
{
  "success": true,
  "data": {
    "id": 42,
    "name": "Chase Auto Finance",
    "is_global": true,
    "aliases": [],
    "california_lien_check_enabled": true
  }
}

Search Lienholders

GET /lienholders/search

Search accessible global and company lienholders by a case-insensitive partial name or alias match. Each result includes the authenticated company's effective California setting.

name is required and must be between 1 and 255 characters.

curl -X GET "https://vinchex.com/api/lienholders/search?name=Chase" \
  -H "Authorization: Bearer your_access_token"

Example Response (200 OK)

{
  "success": true,
  "message": "Found 1 lienholder(s) matching 'Chase'",
  "data": [
    {
      "id": 42,
      "name": "Chase Auto Finance",
      "aliases": [
        {
          "id": 87,
          "alias": "Chase Auto",
          "alias_type": "user_generated"
        }
      ],
      "is_global": true,
      "california_lien_check_enabled": true
    }
  ]
}

Create Lienholder

POST /lienholders/create

Create a company-scoped lienholder with optional aliases. Returns HTTP 201 on success and HTTP 409 when the name already exists for the company or globally.

curl -X POST "https://vinchex.com/api/lienholders/create" \
  -H "Authorization: Bearer your_access_token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Example Credit Union",
    "aliases": [
      {"alias": "Example CU"}
    ]
  }'

Example Response (201 Created)

{
  "success": true,
  "message": "Lienholder created successfully",
  "data": {
    "id": 43,
    "name": "Example Credit Union",
    "is_global": false,
    "aliases": [
      {
        "id": 88,
        "alias": "Example CU",
        "alias_type": "user_generated"
      }
    ],
    "california_lien_check_enabled": false
  }
}

HTTP 409 Conflict: Returned with success: false when the requested name already exists for the company, exists globally, or matches an existing alias.

Update Lienholder Settings

PUT /lienholders/{lienholder}/settings

Send one or more known settings. Today the supported key is california_lien_check_enabled (boolean). The operation is idempotent, changes only the authenticated company's settings, and returns id plus the settings that were updated. Additional settings can be added later without requiring this field.

curl -X PUT "https://vinchex.com/api/lienholders/42/settings" \
  -H "Authorization: Bearer your_access_token" \
  -H "Content-Type: application/json" \
  -d '{"california_lien_check_enabled": true}'

Send {"california_lien_check_enabled": false} to disable it. False persists a disabled setting and does not delete the lienholder. One company's change does not change another company's setting.

A linked company lienholder uses its canonical parent setting. Linking, unlinking, or reparenting changes which canonical group's setting applies; settings are not migrated. Eligible restricted California provider results remain IN_PROGRESS in the California Lien Check Queue.

Example Response (200 OK)

{
  "success": true,
  "data": {
    "id": 42,
    "california_lien_check_enabled": true
  }
}

Validation Error (422)

{
  "message": "At least one setting must be provided.",
  "errors": {
    "settings": [
      "At least one setting must be provided."
    ]
  }
}

Unauthenticated (401)

{
  "error": "unauthorized",
  "error_description": "Invalid or expired token"
}

Invisible or Missing Lienholder (404)

{
  "message": "Not Found"
}

Sandbox Testing

Sandbox accounts use the same OAuth credentials, endpoints, and payloads as production. Ask your Vinchex contact to enable sandbox mode for your account. VINs submitted by a sandbox account are never sent to real data providers — a built-in simulator fabricates a result for each VIN, typically within ~1 minute.

By default the simulator returns realistic, randomized results. To get a specific result on demand for testing, submit one of the reserved VINs below instead — regardless of the lienholder value you submit, the result is deterministic. They're reusable: resubmitting a completed reserved VIN runs it through the same flow again.

Scenario Reserved VINs Result
Confirmed lien 1HGCM82633ACLR001–003 Matches submitted lienholder, priority Low
Possible lien loss 1HGCM82633ALOS001–003 Different lienholder than submitted, priority High
Restricted state 1HGCM82633ARES001–003 Matches submitted lienholder, restricted_state: true, priority Medium
No results 1HGCM82633ANOD001–003 Completes with data_found: false, priority High
Unknown lienholder 1HGCM82633AUNK001–003 Lienholder returns as "Unknown", priority Medium
Owner start date 1HGCM82633AOSD001–003 Matches submitted lienholder, guaranteed owner_start_date, priority Low

Try it

Submit 1HGCM82633ACLR001 via Add VINs, then poll List VINs after about a minute to see the deterministic result. These VINs are reserved — avoid using them for real production data.

Error Responses

Error bodies vary between OAuth authentication and protected resource endpoints. Handle the documented shape for each category.

Validation Error (422)

{
  "success": false,
  "message": "Validation failed",
  "errors": {
    "vin": ["The vin field is required."]
  }
}

Authentication Error (401)

{
  "error": "unauthorized",
  "error_description": "Invalid or expired token"
}

VIN Removal Not Found (404)

{
  "success": false,
  "message": "Processed 0 VINs successfully, 2 failed",
  "summary": {
    "total": 2,
    "successful": 0,
    "failed": 2
  }
}

Server Error (500)

{
  "success": false,
  "message": "An error occurred while processing the request",
  "error": "Detailed error message"
}

Best Practices

Security

  • • Always use HTTPS for API requests
  • • Store access tokens securely
  • • Request a new access token with your client credentials before expiration; refresh tokens are not issued

Error Handling

  • • Handle OAuth error responses separately from resource endpoint success responses
  • • Implement retry logic for transient errors
  • • Use exponential backoff for retries

Performance

  • • Use pagination for large datasets
  • • Validate data before sending requests
  • • Implement request caching when appropriate

API Usage

  • • Use appropriate HTTP methods
  • • Paginate list requests and avoid unnecessary polling
  • • Send proper Content-Type headers

Support & Contact

For API support, questions, or feature requests, please contact our development team.

Documentation

Additional technical documentation and guides are available in the project repository.

Token Lifetime

Access tokens normally expire after 24 hours. Request another token through the client-credentials endpoint before expiration.