Releasability

Query and update vehicle releasability status based on origin location context.

Overview

Releasability operations determine if a vehicle can be released from custody at a given origin. The service evaluates:

  • Origin Location: Geocoded address or coordinates for the release point
  • Blockers: Reasons preventing release (empty when releasable)
  • Source: Whether data came from cache or was not available

Methods

get()

Get the releasability status for a vehicle at a specific origin.

vinstrrequired

17-character Vehicle Identification Number

originstrrequired

Address string or lat,lng coordinate pair (e.g., "1180 Lake Hearn Dr NE, Atlanta, GA 30342" or "33.8463,-84.3621")

Returns: ReleasabilityResponse

Raises: ValidationError, AuthenticationError, ServiceUnavailableError

Example:

from vecu_custody import CustodyClient

client = CustodyClient.sandbox(token="your-jwt-token")

status = client.releasability.get(
    "1HGBH41JXMN109186",
    origin="1180 Lake Hearn Dr NE, Atlanta, GA 30342"
)

if status.is_releasable:
    print(f"Vehicle is releasable (source: {status.source})")
else:
    print("Cannot release. Blockers:")
    for blocker in status.blockers:
        print(f"  - {blocker}")

# Check geocoded origin
if status.origin_location:
    loc = status.origin_location
    print(f"Geocoded: {loc.formatted_address}")
    print(f"Coordinates: {loc.lat}, {loc.lng}")
    print(f"Geohash: {loc.geohash}")

update()

Update the releasability status for a vehicle.

vinstrrequired

17-character Vehicle Identification Number

origin_addressstrrequired

Address string or lat,lng coordinate pair

releasableboolrequired

Whether the vehicle is releasable

detected_atdatetimerequired

Timestamp when releasability was detected

blockerslist[str]

Reasons the vehicle cannot be released (when releasable=False)

release_idstr

Release record ID (optional)

releasability_check_urlstr

URL for full releasability check (optional)

Returns: UpdateReleasabilityResponse

Raises: ValidationError, AuthenticationError, ServiceUnavailableError

Example:

from datetime import datetime, timezone
from vecu_custody import CustodyClient

client = CustodyClient.sandbox(token="your-jwt-token")

# Update a vehicle as releasable
result = client.releasability.update(
    "1HGBH41JXMN109186",
    origin_address="1180 Lake Hearn Dr NE, Atlanta, GA 30342",
    releasable=True,
    detected_at=datetime.now(timezone.utc),
)

print(f"Updated: {result.message}")
print(f"VIN: {result.vin}")
print(f"Origin geohash: {result.origin_geohash}")
# Update a vehicle as NOT releasable
result = client.releasability.update(
    "1HGBH41JXMN109186",
    origin_address="33.8463,-84.3621",
    releasable=False,
    detected_at=datetime.now(timezone.utc),
    blockers=["Payment not cleared", "Title hold"]
)

Response Objects

ReleasabilityResponse

Returned by get().

vinstr

Vehicle Identification Number

originstr | None

Origin address or coordinates (echoed back if provided)

is_releasablebool

Whether the vehicle can be released

sourcestr

Data source: "CACHE" or "NOT_AVAILABLE"

blockerslist[str]

Reasons preventing release (empty when releasable)

checked_atdatetime

Timestamp when releasability was checked

origin_locationOriginLocation | None

Geocoded origin location (if available)

OriginLocation

Geocoded origin location returned in the response.

addressstr | None

Raw address string (if provided)

formatted_addressstr | None

Geocoded formatted address (if available)

latfloat

Latitude coordinate

lngfloat

Longitude coordinate

geohashstr

Precision-7 geohash of the canonicalized origin coordinates (≈152 m × 152 m cell) per ADR-041.

UpdateReleasabilityResponse

Returned by update().

messagestr

Confirmation message

vinstr

Vehicle Identification Number

releasablebool

Whether the vehicle is releasable

origin_geohashstr | None

Precision-7 geohash of the canonicalized origin address (≈152 m × 152 m cell) per ADR-041. The marker key the service uses for (VIN, origin) uniqueness is derived from this geohash, not from the raw origin_address string. Nullable for migration-window and pre-ADR-041 terminal records that were backfilled without geohash data; populated on all new responses.

Common Use Cases

Pre-Transfer Check

from vecu_custody import CustodyClient

client = CustodyClient.sandbox(token="your-jwt-token")

def can_initiate_transfer(vin: str, origin: str) -> tuple[bool, str]:
    """Check if vehicle transfer can be initiated."""
    status = client.releasability.get(vin, origin=origin)

    if status.is_releasable:
        return True, "Ready for transfer"

    blocker_msg = ", ".join(status.blockers)
    return False, f"Blocked: {blocker_msg}"

# Usage
can_transfer, message = can_initiate_transfer(
    "1HGBH41JXMN109186",
    origin="1180 Lake Hearn Dr NE, Atlanta, GA 30342"
)
print(message)

Releasability Status Report

status = client.releasability.get(
    "1HGBH41JXMN109186",
    origin="1180 Lake Hearn Dr NE, Atlanta, GA 30342"
)

print(f"Releasability Report for VIN: {status.vin}")
print(f"Status: {'RELEASABLE' if status.is_releasable else 'BLOCKED'}")
print(f"Source: {status.source}")
print(f"Checked at: {status.checked_at}\n")

if not status.is_releasable:
    print("Blockers:")
    for i, blocker in enumerate(status.blockers, 1):
        print(f"  {i}. {blocker}")

if status.origin_location:
    loc = status.origin_location
    print(f"\nOrigin: {loc.formatted_address or loc.address}")
    print(f"Geohash: {loc.geohash}")

Record Releasability After Inspection

from datetime import datetime, timezone

# After an inspection confirms vehicle is ready for release
result = client.releasability.update(
    "1HGBH41JXMN109186",
    origin_address="1180 Lake Hearn Dr NE, Atlanta, GA 30342",
    releasable=True,
    detected_at=datetime.now(timezone.utc),
    release_id="REL-2026-0042"
)

print(f"Releasability recorded: {result.message}")
print(f"Origin geohash: {result.origin_geohash}")

Error Handling

from vecu_custody import CustodyClient
from vecu_custody.exceptions import (
    NotFoundError,
    ValidationError,
    AuthenticationError,
    ServiceUnavailableError
)

client = CustodyClient.sandbox(token="your-jwt-token")

try:
    status = client.releasability.get(
        "1HGBH41JXMN109186",
        origin="1180 Lake Hearn Dr NE, Atlanta, GA 30342"
    )
    print(f"Releasable: {status.is_releasable}")
except ValidationError as e:
    print(f"Invalid parameters: {e.message}")
except AuthenticationError as e:
    print(f"Authentication failed: {e.message}")
except ServiceUnavailableError as e:
    print(f"Service unavailable: {e.message}")

Next Steps

  • Custody Permits - Create permits for releasable vehicles
  • Transfers - Initiate transfers after confirming releasability