Quick Start

Get the VECU Custody Python SDK running in your application in minutes.

What You Will Build

By the end of this guide, you'll have a working integration that can create custody authorizations, track transfers, and check vehicle releasability.

Prerequisites

Before you begin, ensure you have: - Python 3.11 or higher installed - Access to Cox Automotive Artifactory - Your JWT token for authentication

Step 1: Configure Artifactory

The SDK is hosted in Cox Automotive's Artifactory. Configure pip to use the private registry.

Create or update ~/.pip/pip.conf (Linux/macOS) or %APPDATA%\pip\pip.ini (Windows):

[global]
extra-index-url = https://cai.jfrog.io/artifactory/api/pypi/pypi-release-local/simple
trusted-host = cai.jfrog.io

Or use environment variables:

export PIP_EXTRA_INDEX_URL="https://cai.jfrog.io/artifactory/api/pypi/pypi-release-local/simple"

Step 2: Install the SDK

pip install vecu-custody-python-sdk

Step 3: Initialize the Client

Create a client instance with your JWT token. The SDK provides both synchronous and asynchronous clients:

from vecu_custody import CustodyClient

# Sandbox environment (for development and testing)
client = CustodyClient.sandbox(token="your-jwt-token")

# Production environment
client = CustodyClient.production(token="your-jwt-token")

Which client should I use?

Use Sync Client for simple scripts and synchronous applications. Use Async Client for FastAPI, async frameworks, or when you need concurrent operations. See Advanced Async Patterns for detailed patterns.

Security

Never hardcode credentials in source code. Use environment variables or a secrets manager for production deployments.

Step 4: Create an Authorization

Create an authorization that permits custody transfer for a vehicle:

# Create an authorization
authorization = client.authorizations.create(
    vin="9HGBH41JXMN999999",
    origin="LOC-AUCTION-MANHEIM-ATLANTA",
    destination="LOC-DEALERSHIP-CARMAX-ORLANDO",
    person_identity_key="vecu_gfTRAjYnn_y-8zj-aBc4dEf5",
    authorized_by="system-auction-integration",
    make_model="Honda Accord 2023"
)

print(f"Authorization ID: {authorization.authorization_id}")
print(f"Status: {authorization.status}")
print(f"Expires at: {authorization.expires_at}")

Step 5: Check Vehicle Releasability

Verify if a vehicle can be released:

# Check if vehicle is releasable
result = client.releasability.check_vin(vin="9HGBH41JXMN999999")

print(f"Releasable: {result.is_releasable}")
if not result.is_releasable:
    for blocker in result.blockers:
        print(f"  - {blocker}")

Complete Example

from vecu_custody import CustodyClient
from vecu_custody.exceptions import (
    AuthorizationNotFoundError,
    ValidationError,
    CustodyError
)

def main():
    # Initialize client
    client = CustodyClient.sandbox(token="your-jwt-token")

    vin = "9HGBH41JXMN999999"

    try:
        # Step 1: Create authorization
        print("Creating authorization...")
        authorization = client.authorizations.create(
            vin=vin,
            origin="LOC-AUCTION-MANHEIM-ATLANTA",
            destination="LOC-DEALERSHIP-CARMAX-ORLANDO",
            person_identity_key="vecu_gfTRAjYnn_y-8zj-aBc4dEf5",
            authorized_by="system-auction-integration",
            make_model="Honda Accord 2023"
        )
        print(f"Created authorization: {authorization.authorization_id}")

        # Step 2: Check releasability
        print("\nChecking releasability...")
        result = client.releasability.check_vin(vin=vin)

        if result.is_releasable:
            print(f"Releasable: {result.is_releasable}")

            # Step 3: Create transfer
            print("\nInitiating transfer...")
            transfer = client.transfers.create(
                vin=vin,
                transfer_type="PICKUP",
                credential_id=authorization.authorization_id,
                location_id="LOC-AUCTION-MANHEIM-ATLANTA"
            )
            print(f"Transfer initiated: {transfer.transfer_id}")

            # Step 4: Check transfer status
            status = client.transfers.get_status(vin=vin)
            print(f"Current custodian: {status.current_custodian}")
            print(f"Current location: {status.current_location}")
        else:
            print("Vehicle is not releasable")
            for blocker in result.blockers:
                print(f"  Blocker: {blocker}")

    except AuthorizationNotFoundError as e:
        print(f"Authorization not found: {e}")
    except ValidationError as e:
        print(f"Validation error: {e.message}")
    except CustodyError as e:
        print(f"Custody error: {e}")

if __name__ == "__main__":
    main()

What's Next?

Now that you have a basic integration working:

  1. Installation - Detailed installation options
  2. Configuration - Full configuration reference
  3. Advanced Async Patterns - FastAPI, concurrency, background tasks
  4. Error Handling - Handle errors gracefully
  5. API Reference - Complete API documentation