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.
vinstrrequired17-character Vehicle Identification Number
originstrrequiredAddress 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.
vinstrrequired17-character Vehicle Identification Number
origin_addressstrrequiredAddress string or lat,lng coordinate pair
releasableboolrequiredWhether the vehicle is releasable
detected_atdatetimerequiredTimestamp when releasability was detected
blockerslist[str]Reasons the vehicle cannot be released (when releasable=False)
release_idstrRelease record ID (optional)
releasability_check_urlstrURL 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().
vinstrVehicle Identification Number
originstr | NoneOrigin address or coordinates (echoed back if provided)
is_releasableboolWhether the vehicle can be released
sourcestrData source: "CACHE" or "NOT_AVAILABLE"
blockerslist[str]Reasons preventing release (empty when releasable)
checked_atdatetimeTimestamp when releasability was checked
origin_locationOriginLocation | NoneGeocoded origin location (if available)
OriginLocation
Geocoded origin location returned in the response.
addressstr | NoneRaw address string (if provided)
formatted_addressstr | NoneGeocoded formatted address (if available)
latfloatLatitude coordinate
lngfloatLongitude coordinate
geohashstrPrecision-7 geohash of the canonicalized origin coordinates (≈152 m × 152 m cell) per ADR-041.
UpdateReleasabilityResponse
Returned by update().
messagestrConfirmation message
vinstrVehicle Identification Number
releasableboolWhether the vehicle is releasable
origin_geohashstr | NonePrecision-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