Release

Record vehicle releases from custody. This resource handles the action of releasing a vehicle — distinct from Releasability, which manages whether a vehicle can be released.

Overview

The Release API records that a vehicle has been physically released from custody. This creates an immutable ledger event and publishes a custody.vehicle.released event to EventBridge.

  • Releasability = "Can this vehicle be released?" (query and update releasability status)
  • Release = "This vehicle has been released." (action/event)

Methods

ReleaseVehicleAsync()

Record a vehicle release from custody.

Task<VehicleReleaseResponse> ReleaseVehicleAsync(
    string vin,
    VehicleReleaseRequest request,
    CancellationToken cancellationToken = default);

Parameters:

vinstringrequired

17-character Vehicle Identification Number

requestVehicleReleaseRequestrequired

The release request containing authorization ID, release method, and optional location

cancellationTokenCancellationToken

Cancellation token for async operation

Returns: VehicleReleaseResponse

Throws: ArgumentException, ArgumentNullException, ValidationException (400), AuthorizationNotFoundException (404), InvalidStateException (409), AuthException (401), NetworkException (500/503)

Example:

var request = new VehicleReleaseRequest
{
    AuthorizationId = "AUTH-12345678",
    ReleaseMethod = "web_verifier"
};

var response = await client.ReleaseVehicleAsync("1HGBH41JXMN109186", request);

Console.WriteLine($"Released: {response.Message}");
Console.WriteLine($"VIN: {response.Vin}");
Console.WriteLine($"Authorization: {response.AuthorizationId}");

With location coordinates:

var request = new VehicleReleaseRequest
{
    AuthorizationId = "AUTH-12345678",
    ReleaseMethod = "mobile_verifier",
    Latitude = 33.6407,
    Longitude = -84.4527
};

var response = await client.ReleaseVehicleAsync("1HGBH41JXMN109186", request);

Request & Response Types

VehicleReleaseRequest

AuthorizationIdstringrequired

Authorization identifier for this release (1-128 characters)

ReleaseMethodstringrequired

Method used to release the vehicle (validated by the service)

Latitudedouble?

Release location latitude (-90 to 90)

Longitudedouble?

Release location longitude (-180 to 180)

VehicleReleaseResponse

Messagestring

Confirmation message (e.g., "Vehicle released successfully")

Vinstring

Vehicle Identification Number

AuthorizationIdstring

Authorization identifier used for this release

WarningsIReadOnlyList<string>

Non-fatal warnings from the operation (e.g. EventBridge publish failure). Empty list on full success.

Parameters

ReleaseMethod

The ReleaseMethod property is a string identifying how the vehicle was released. Valid values are defined by the custody service. Passing an invalid value will result in a ValidationException (HTTP 400) from the service.

Location Coordinates

The optional Latitude and Longitude properties record where the vehicle was released. Both must be provided together if used.

Common Use Cases

Release After Gate Verification

// Check releasability first
var status = await client.GetReleasabilityAsync(
    "1HGBH41JXMN109186",
    "1 Auction Blvd, Bordentown, NJ 08505");

if (status.IsReleasable)
{
    // Record the release
    var request = new VehicleReleaseRequest
    {
        AuthorizationId = "AUTH-12345678",
        ReleaseMethod = "mobile_verifier",
        Latitude = 40.1451,
        Longitude = -74.7177
    };

    var result = await client.ReleaseVehicleAsync(
        "1HGBH41JXMN109186", request);

    Console.WriteLine($"Vehicle released: {result.Message}");
}
else
{
    Console.WriteLine($"Cannot release. Blockers: {string.Join(", ", status.Blockers)}");
}

ASP.NET Controller

[ApiController]
[Route("api/vehicles")]
public class VehicleController : ControllerBase
{
    private readonly ICustodyServiceClient _custodyClient;

    public VehicleController(ICustodyServiceClient custodyClient)
    {
        _custodyClient = custodyClient;
    }

    [HttpPost("{vin}/release")]
    public async Task<IActionResult> ReleaseVehicle(
        string vin,
        [FromBody] ReleaseRequest body,
        CancellationToken ct)
    {
        var request = new VehicleReleaseRequest
        {
            AuthorizationId = body.AuthorizationId,
            ReleaseMethod = body.ReleaseMethod,
            Latitude = body.Latitude,
            Longitude = body.Longitude
        };

        var result = await _custodyClient.ReleaseVehicleAsync(vin, request, ct);
        return Ok(result);
    }
}

Error Handling

using CoxAuto.Vecu.CustodySdk.Exceptions;

try
{
    var request = new VehicleReleaseRequest
    {
        AuthorizationId = "AUTH-12345678",
        ReleaseMethod = "web_verifier"
    };

    var result = await client.ReleaseVehicleAsync("1HGBH41JXMN109186", request);
    Console.WriteLine($"Released: {result.Message}");

    // Check for non-fatal warnings
    foreach (var warning in result.Warnings)
    {
        Console.WriteLine($"Warning: {warning}");
    }
}
catch (AuthorizationNotFoundException ex)
{
    // Authorization not found or VIN mismatch
    Console.WriteLine($"Not found: {ex.Message}");
}
catch (InvalidStateException ex)
{
    // Authorization already released, cancelled, expired, or revoked
    Console.WriteLine($"Invalid state: {ex.Message}");
}
catch (ValidationException ex)
{
    // Invalid VIN, missing fields, or invalid release method
    Console.WriteLine($"Validation error: {ex.Message}");
}
catch (AuthException ex)
{
    Console.WriteLine($"Authentication failed: {ex.Message}");
}
catch (NetworkException ex)
{
    Console.WriteLine($"Network/storage error: {ex.Message}");
}

Next Steps