API Documentation
RESTful API for programmatic access to the TN Unclaimed Vehicle Portal.
Overview
Authentication & Security
Access Tiers
The /search and /health endpoints are publicly accessible. They return only non-sensitive vehicle and publisher data — no PII is included. Rate limits still apply.
All other endpoints require a valid API key passed via the X-API-Key header. API keys are issued to approved integration partners and carry scoped permissions. Responses at this tier still exclude DPPA-protected PII.
Access to DPPA-protected data (vehicle owner names, addresses, lienholder information) requires OAuth 2.0 client credentials with a DPPA-compliant permissible use declaration on file. Only authorized state agencies and law enforcement systems qualify. Contact the portal administrator to initiate the authorization process.
PII Protection Mechanisms
- ✓PII table separation — Owner/lienholder data is stored in a separate database table with field-level encryption (AES-256-GCM via AWS KMS) and retention metadata. PII is never joined into public API responses.
- ✓Transport encryption — All API traffic is served over TLS 1.2+ (HTTPS). Plaintext HTTP requests are rejected.
- ✓Audit logging — Every API request is logged with timestamp, API key identity, endpoint, and response status. Logs are retained per TN records retention policy.
- ✓Rate limiting & throttling — Per-key rate limits prevent abuse. Excessive requests return
429 Too Many Requests. - ✓Key rotation & revocation — API keys can be rotated or revoked immediately by the portal administrator. Compromised keys are invalidated within seconds.
Endpoints
Returns the current health status of the API service. Use this endpoint for uptime monitoring and connectivity checks. No authentication required.
Example Response
{
"status": "ok",
"timestamp": "2026-03-07T14:30:00.000Z",
"service": "unclaimed-vehicle-portal",
"version": "1.0.0"
}Example Request
curl -X GET https://{your-domain}/api/v1/healthReturns a paginated list of unclaimed vehicle notices. Supports filtering by notice status. Requires API key.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | number | No | Number of results to return. Default: 50, Max: 100. |
| offset | number | No | Number of results to skip for pagination. Default: 0. |
| status | string | No | Filter by notice status (e.g., "active", "owner_identified", "mail_sent"). |
Example Response
{
"data": [
{
"id": "notice-abc123",
"status": "active",
"vin": "1HGBH41JXMN109186",
"plate_number": "ABC1234",
"plate_state": "TN",
"vehicle_year": 2019,
"vehicle_make": "Honda",
"vehicle_model": "Civic",
"vehicle_color": "Silver",
"vehicle_type": "Sedan",
"storage_city": "Nashville",
"storage_state": "TN",
"custody_date": "2026-02-15",
"tow_reason": "Abandoned on public property",
"total_fees": 485,
"publisher_name": "Nashville Towing & Recovery",
"created_at": "2026-02-15T10:30:00.000Z"
}
],
"count": 1,
"limit": 50,
"offset": 0
}Example Request
curl -X GET "https://{your-domain}/api/v1/notices?limit=10&status=active" \
-H "X-API-Key: your-api-key"Returns the full details of a specific unclaimed vehicle notice by its unique ID. Requires API key.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | The unique notice identifier (path parameter). |
404 Not Found: Returns { "error": "Not found" } if no notice exists with the given ID.
Example Response
{
"data": {
"id": "notice-abc123",
"status": "owner_identified",
"vin": "1HGBH41JXMN109186",
"plate_number": "ABC1234",
"plate_state": "TN",
"vehicle_year": 2019,
"vehicle_make": "Honda",
"vehicle_model": "Civic",
"vehicle_color": "Silver",
"vehicle_type": "Sedan",
"storage_address": "456 Impound Ln",
"storage_city": "Nashville",
"storage_state": "TN",
"storage_zip": "37201",
"custody_date": "2026-02-15",
"tow_reason": "Abandoned on public property",
"tow_fee": 185,
"storage_fee": 250,
"admin_fee": 50,
"total_fees": 485,
"payment_methods_accepted": "Cash, Credit Card",
"sale_date": "2026-04-15",
"publisher_name": "Nashville Towing & Recovery",
"created_at": "2026-02-15T10:30:00.000Z",
"updated_at": "2026-02-20T08:15:00.000Z"
}
}Example Request
curl -X GET https://{your-domain}/api/v1/notices/notice-abc123 \
-H "X-API-Key: your-api-key"Searches for unclaimed vehicle notices by VIN or license plate number. This is the same search available through the public web portal. No authentication required.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| q | string | Yes | Search query — a full or partial VIN or plate number. Minimum 3 characters. |
400 Bad Request: Returns { "error": "Query parameter 'q' must be at least 3 characters" } if the query is too short.
Example Response
{
"data": [
{
"id": "notice-abc123",
"status": "active",
"vin": "1HGBH41JXMN109186",
"plate_number": "ABC1234",
"plate_state": "TN",
"vehicle_year": 2019,
"vehicle_make": "Honda",
"vehicle_model": "Civic",
"vehicle_color": "Silver",
"storage_city": "Nashville",
"total_fees": 485,
"publisher_name": "Nashville Towing & Recovery"
}
],
"count": 1,
"query": "ABC1234"
}Example Request
curl -X GET "https://{your-domain}/api/v1/search?q=ABC1234"Advances a notice through one step of the lookup chain, or through the mail steps, for demonstration purposes. Only available in demo/development mode.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| action | string | Yes | The simulation action to perform. Lookup chain, in order: "nmvtis_lookup", "vtrs_lookup", "partner_lookup". Mail: "mail_send", "mail_deliver", "mail_return". Also "run_chain" to run every remaining step in order, and "reset_lookups" to re-run a notice from step 1. |
| notice_id | string | Yes | The ID of the notice to simulate the action against. |
| outcome | string | No | Forces a specific result for a lookup step, so failure paths can be demonstrated: "auto" (default), "found", "not_found", "stolen" (NMVTIS only), "unavailable", or "not_configured". |
Note: This endpoint is only available when the portal is running in demo or development mode. It will return a 404 in production environments.
Lookup steps run in a fixed order: NMVTIS (stolen check and titling state), then VTRS, then the partner network for out-of-state vehicles. Calling a step out of turn returns 409 Conflict. A step never returns owner or lienholder identity — only the decision and the number of parties found.
Example Response
{
"success": true,
"source": "vtrs",
"lookup_status": "completed",
"resolution_status": "resolved",
"status": "owner_identified",
"parties_found": 2,
"summary": "VTRS returned 2 parties of record."
}Example Request
curl -X POST https://{your-domain}/api/v1/demo/simulate \
-H "Content-Type: application/json" \
-d '{"action": "nmvtis_lookup", "notice_id": "notice-abc123"}'DPPA Compliance & Data Protection
This API is designed in compliance with the Driver's Privacy Protection Act (18 U.S.C. § 2721-2725) and TCA § 55-31-104.
- • Owner and lienholder PII (names, addresses) is never returned in Tier 1 or Tier 2 API responses
- • PII is stored in a separate database table with field-level encryption (AES-256-GCM) and retention policies — it cannot be accessed by manipulating request parameters
- • Tier 3 access requires a signed DPPA permissible use agreement and is audited per request
- • All API access is logged for compliance auditing and incident response