Releasability
Query and update vehicle releasability status based on origin location context.
SDK-Only Access
To ensure your integration remains stable and supported, always use the official SDKs. The underlying API endpoints are internal implementation details that may change in purpose, functionality, or be removed at any time without notice. Direct API access is not supported. Learn more →
The SDK methods documented here are your supported interface. Versioning is managed through SDK upgrades.
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
GetReleasabilityAsync()
Get the releasability status for a vehicle at a specific origin.
vinstringrequired17-character Vehicle Identification Number
originstringrequiredAddress string or lat,lng coordinate pair (e.g., "1180 Lake Hearn Dr NE, Atlanta, GA 30342" or "33.8463,-84.3621")
cancellationTokenCancellationTokenOptional cancellation token for the async operation
Returns: ReleasabilityResponse
Exceptions:
ArgumentException- VIN or origin is null or whitespaceValidationException- Invalid request parameters (400, 422)AuthException- Authentication failure (401)RateLimitException- Rate limit exceeded (429)NetworkException- Network or server errors (5xx)
Example:
using CoxAuto.Vecu.CustodySdk.Client;
public class ReleasabilityService
{
private readonly ICustodyServiceClient _client;
public ReleasabilityService(ICustodyServiceClient client)
{
_client = client;
}
public async Task<bool> CheckVehicleReleasability(string vin)
{
var result = await _client.GetReleasabilityAsync(
vin,
origin: "1180 Lake Hearn Dr NE, Atlanta, GA 30342");
Console.WriteLine($"Is releasable: {result.IsReleasable}");
Console.WriteLine($"Source: {result.Source}");
Console.WriteLine($"Checked at: {result.CheckedAt}");
if (!result.IsReleasable)
{
Console.WriteLine("Blockers:");
foreach (var blocker in result.Blockers)
{
Console.WriteLine($" - {blocker}");
}
}
if (result.OriginLocation != null)
{
var loc = result.OriginLocation;
Console.WriteLine($"Geocoded: {loc.FormattedAddress}");
Console.WriteLine($"Coordinates: {loc.Lat}, {loc.Lng}");
Console.WriteLine($"Geohash: {loc.Geohash}");
}
return result.IsReleasable;
}
}
UpdateReleasabilityAsync()
Update the releasability status for a vehicle.
vinstringrequired17-character Vehicle Identification Number
requestUpdateReleasabilityRequestrequiredUpdate request body with releasability details
cancellationTokenCancellationTokenOptional cancellation token for the async operation
UpdateReleasabilityRequest Properties
OriginAddressstringrequiredAddress string or lat,lng coordinate pair
ReleasableboolrequiredWhether the vehicle is releasable
DetectedAtDateTimeOffsetrequiredTimestamp when releasability was detected
BlockersIReadOnlyList<string>Reasons the vehicle cannot be released (when Releasable = false)
ReleaseIdstringRelease record ID (optional)
ReleasabilityCheckUrlstringURL for full releasability check (optional)
Returns: UpdateReleasabilityResponse
Exceptions:
ArgumentNullException- Request is nullValidationException- Invalid request parameters (400, 422)AuthException- Authentication failure (401)RateLimitException- Rate limit exceeded (429)NetworkException- Network or server errors (5xx)
Example:
using CoxAuto.Vecu.CustodySdk.Client;
using CoxAuto.Vecu.CustodySdk.Models.Requests;
public async Task UpdateVehicleReleasability(string vin)
{
// Mark vehicle as releasable
var request = new UpdateReleasabilityRequest
{
OriginAddress = "1180 Lake Hearn Dr NE, Atlanta, GA 30342",
Releasable = true,
DetectedAt = DateTimeOffset.UtcNow,
};
var result = await _client.UpdateReleasabilityAsync(vin, request);
Console.WriteLine($"Updated: {result.Message}");
Console.WriteLine($"VIN: {result.Vin}");
Console.WriteLine($"Origin geohash: {result.OriginGeohash}");
}
public async Task MarkVehicleBlocked(string vin)
{
// Mark vehicle as NOT releasable
var request = new UpdateReleasabilityRequest
{
OriginAddress = "33.8463,-84.3621",
Releasable = false,
DetectedAt = DateTimeOffset.UtcNow,
Blockers = new[] { "Payment not cleared", "Title hold" }
};
var result = await _client.UpdateReleasabilityAsync(vin, request);
Console.WriteLine($"Updated: {result.Message}");
}
Response Objects
ReleasabilityResponse
Returned by GetReleasabilityAsync.
VinstringVehicle Identification Number
Originstring?Origin address or coordinates (echoed back if provided)
IsReleasableboolWhether the vehicle can be released
SourcestringData source: "CACHE" or "NOT_AVAILABLE"
BlockersIReadOnlyList<string>Reasons preventing release (empty when releasable)
CheckedAtDateTimeOffsetTimestamp when releasability was checked
OriginLocationOriginLocation?Geocoded origin location (if available)
OriginLocation
Geocoded origin location returned in the response.
Addressstring?Raw address string (if provided)
FormattedAddressstring?Geocoded formatted address (if available)
LatdoubleLatitude coordinate
LngdoubleLongitude coordinate
GeohashstringGeohash encoding of coordinates
UpdateReleasabilityResponse
Returned by UpdateReleasabilityAsync.
MessagestringConfirmation message
VinstringVehicle Identification Number
ReleasableboolWhether the vehicle is releasable
OriginGeohashstringGeohash of the geocoded origin address
Common Use Cases
Pre-Transfer Validation
public async Task<(bool CanTransfer, string Message)> CanInitiateTransfer(
string vin,
string origin)
{
try
{
var result = await _client.GetReleasabilityAsync(vin, origin);
if (result.IsReleasable)
{
return (true, "Vehicle is releasable");
}
var blockers = string.Join(", ", result.Blockers);
return (false, $"Vehicle not releasable. Blockers: {blockers}");
}
catch (ValidationException ex)
{
return (false, $"Invalid request: {ex.Message}");
}
}
Detailed Releasability Report
public async Task PrintReleasabilityReport(string vin, string origin)
{
var result = await _client.GetReleasabilityAsync(vin, origin);
Console.WriteLine($"\n=== Releasability Report for VIN: {vin} ===");
Console.WriteLine($"Status: {(result.IsReleasable ? "RELEASABLE" : "BLOCKED")}");
Console.WriteLine($"Source: {result.Source}");
Console.WriteLine($"Checked at: {result.CheckedAt:yyyy-MM-dd HH:mm:ss}");
if (!result.IsReleasable)
{
Console.WriteLine("\n--- Blockers ---");
foreach (var blocker in result.Blockers)
{
Console.WriteLine($" - {blocker}");
}
}
if (result.OriginLocation != null)
{
var loc = result.OriginLocation;
Console.WriteLine("\n--- Origin Location ---");
Console.WriteLine($"Address: {loc.FormattedAddress ?? loc.Address}");
Console.WriteLine($"Coordinates: {loc.Lat}, {loc.Lng}");
Console.WriteLine($"Geohash: {loc.Geohash}");
}
Console.WriteLine("=====================================\n");
}
Validate Before Creating Authorization
public async Task<AuthorizationResponse?> CreateAuthorizationWithValidation(
string vin,
string origin,
string destination,
string personIdentityKey)
{
// Check releasability first
var relResult = await _client.GetReleasabilityAsync(vin, origin);
if (!relResult.IsReleasable)
{
Console.WriteLine("Vehicle is not releasable:");
foreach (var blocker in relResult.Blockers)
{
Console.WriteLine($" - {blocker}");
}
return null;
}
// Vehicle is releasable - create authorization
var authRequest = new CreateAuthorizationRequest
{
Vin = vin,
Origin = origin,
Destination = destination,
PersonIdentityKey = personIdentityKey,
MakeModel = "Toyota Camry",
AuthorizedBy = "transport-service",
TransportOrderId = $"TO-{DateTime.UtcNow:yyyyMMddHHmmss}"
};
var auth = await _client.CreateAuthorizationAsync(authRequest);
Console.WriteLine($"Authorization created: {auth.AuthorizationId}");
return auth;
}
Check Multiple Vehicles in Parallel
public async Task<Dictionary<string, bool>> CheckMultipleVehicles(
List<string> vins,
string origin)
{
var tasks = vins.Select(async vin =>
{
try
{
var result = await _client.GetReleasabilityAsync(vin, origin);
return (vin, result.IsReleasable);
}
catch
{
return (vin, false);
}
});
var results = await Task.WhenAll(tasks);
return results.ToDictionary(r => r.vin, r => r.Item2);
}
Error Handling
using CoxAuto.Vecu.CustodySdk.Exceptions;
public async Task<ReleasabilityResponse?> GetReleasabilityWithErrorHandling(
string vin,
string origin)
{
try
{
return await _client.GetReleasabilityAsync(vin, origin);
}
catch (ArgumentException ex)
{
Console.WriteLine($"Invalid arguments: {ex.Message}");
return null;
}
catch (ValidationException ex)
{
Console.WriteLine($"Invalid request: {ex.Message}");
return null;
}
catch (RateLimitException ex)
{
Console.WriteLine($"Rate limited. Retry after: {ex.RetryAfter}");
return null;
}
catch (NetworkException ex)
{
Console.WriteLine($"Network error: {ex.Message}");
return null;
}
}
Next Steps
- Custody Permits API - Create authorizations for releasable vehicles
- Error Handling - Exception types and handling strategies
- Testing - Mock releasability checks for testing