Delivery API Testing Guide
This document provides testing instructions and curl examples for the CROP Delivery Services API.
Delivery API Testing Guide
Overview
This document provides testing instructions and curl examples for the CROP Delivery Services API.
API Base URL: https://delivery-service-222426967009.us-east1.run.app
Supported Providers:
ups- UPS shipping (requires credentials)clinton_tractor- Local pickup/delivery (mock provider for testing)
CROP Source Identification
All shipments created through the CROP platform include source markers for identification:
| Field | Format | Example |
|---|---|---|
reference | CROP-{env}-{orderId} | CROP-prod-ORD-12345 |
instructions | CROP-{env} | {notes} | CROP-prod | Leave at door |
Where {env} is one of: dev, stage, prod, unknown
API Endpoints
1. Health Check
Check if the API is running and connected to dependencies.
curl -s "https://delivery-service-222426967009.us-east1.run.app/health" | jq .Response:
{
"status": "healthy",
"database": "connected",
"providers": ["ups", "clinton_tractor"]
}2. Get Providers
List available shipping providers.
curl -s "https://delivery-service-222426967009.us-east1.run.app/providers" | jq .Response:
["ups", "clinton_tractor"]3. Get Shipping Rates
Get shipping rates from all available providers.
curl -s -X POST "https://delivery-service-222426967009.us-east1.run.app/rates" \
-H "Content-Type: application/json" \
-d '{
"from_address": {
"name": "Clinton Tractor",
"street": "6500 Collamer Road",
"city": "East Syracuse",
"state": "NY",
"postal_code": "13057",
"country": "US"
},
"to_address": {
"name": "Test Customer",
"street": "123 Main St",
"city": "New York",
"state": "NY",
"postal_code": "10001",
"country": "US"
},
"packages": [{
"weight": 2,
"length": 30,
"width": 20,
"height": 15,
"value": 100
}],
"reference": "CROP-dev-TEST-001",
"instructions": "CROP-dev | Test order"
}' | jq .Response:
[
{
"provider": "clinton_tractor",
"service_type": "Clinton Tractor In-Store Pickup",
"cost": 0.0,
"currency": "USD",
"estimated_days": 0,
"estimated_date": null
},
{
"provider": "ups",
"service_type": "UPS Ground",
"cost": 12.50,
"currency": "USD",
"estimated_days": 3,
"estimated_date": "2026-01-24"
}
]Note: UPS rates require valid credentials configured in the backend.
4. Create Shipment
Create a new shipment with the selected provider.
curl -s -X POST "https://delivery-service-222426967009.us-east1.run.app/shipments?provider=clinton_tractor" \
-H "Content-Type: application/json" \
-d '{
"from_address": {
"name": "Clinton Tractor",
"street": "6500 Collamer Road",
"city": "East Syracuse",
"state": "NY",
"postal_code": "13057",
"country": "US"
},
"to_address": {
"name": "Test Customer",
"street": "123 Main St",
"city": "New York",
"state": "NY",
"postal_code": "10001",
"country": "US"
},
"packages": [{
"weight": 2,
"length": 30,
"width": 20,
"height": 15,
"value": 100
}],
"reference": "CROP-dev-ORDER-12345",
"instructions": "CROP-dev | Please handle with care"
}' | jq .Response:
{
"success": true,
"shipment": {
"shipment_id": "CT-CT-66532632",
"tracking_number": "CT-66532632",
"provider": "clinton_tractor",
"status": "pending",
"service_type": "Default",
"label_url": null,
"created_at": "2026-01-21T15:28:29.285124"
},
"message": "Shipment created successfully"
}5. Track Shipment
Get tracking information for a shipment.
# Replace CT-66532632 with your tracking number
curl -s "https://delivery-service-222426967009.us-east1.run.app/shipments/CT-66532632" | jq .Response:
{
"tracking_number": "CT-66532632",
"provider": "clinton_tractor",
"status": "in_transit",
"current_location": null,
"estimated_delivery": "2026-01-23T15:28:38.255580",
"events": [
{
"timestamp": "2026-01-20T15:28:38.255590",
"location": "Clinton, IA",
"description": "Shipment in transit"
}
]
}6. Cancel Shipment
Cancel an existing shipment.
# Replace CT-66532632 with your tracking number
curl -s -X POST "https://delivery-service-222426967009.us-east1.run.app/shipments/CT-66532632/cancel" | jq .Response:
{
"success": true,
"message": "Shipment cancelled successfully"
}7. Validate Address
Validate a shipping address using UPS Address Validation API.
curl -s -X POST "https://delivery-service-222426967009.us-east1.run.app/addresses/validate" \
-H "Content-Type: application/json" \
-d '{
"street": "123 Main St",
"city": "New York",
"state": "NY",
"postal_code": "10001",
"country": "US"
}' | jq .Response:
{
"is_valid": true,
"candidates": [
{
"AddressKeyFormat": {
"AddressLine": "123 MAIN ST",
"PoliticalDivision2": "NEW YORK",
"PoliticalDivision1": "NY",
"PostcodePrimaryLow": "10001",
"PostcodeExtendedLow": "1234",
"CountryCode": "US"
}
}
]
}Full Test Cycle Example
Run a complete create → track → cancel cycle:
#!/bin/bash
# Full delivery API test cycle
API_URL="https://delivery-service-222426967009.us-east1.run.app"
echo "=== 1. Health Check ==="
curl -s "$API_URL/health" | jq .
echo -e "\n=== 2. Get Rates ==="
RATES=$(curl -s -X POST "$API_URL/rates" \
-H "Content-Type: application/json" \
-d '{
"from_address": {"name":"Clinton Tractor","street":"6500 Collamer Road","city":"East Syracuse","state":"NY","postal_code":"13057","country":"US"},
"to_address": {"name":"Test","street":"123 Main St","city":"New York","state":"NY","postal_code":"10001","country":"US"},
"packages": [{"weight":2,"length":30,"width":20,"height":15}],
"reference": "CROP-dev-FULLTEST",
"instructions": "CROP-dev | Full test cycle"
}')
echo "$RATES" | jq .
echo -e "\n=== 3. Create Shipment ==="
SHIPMENT=$(curl -s -X POST "$API_URL/shipments?provider=clinton_tractor" \
-H "Content-Type: application/json" \
-d '{
"from_address": {"name":"Clinton Tractor","street":"6500 Collamer Road","city":"East Syracuse","state":"NY","postal_code":"13057","country":"US"},
"to_address": {"name":"Test","street":"123 Main St","city":"New York","state":"NY","postal_code":"10001","country":"US"},
"packages": [{"weight":2,"length":30,"width":20,"height":15}],
"reference": "CROP-dev-FULLTEST",
"instructions": "CROP-dev | Full test cycle"
}')
echo "$SHIPMENT" | jq .
# Extract tracking number
TRACKING=$(echo "$SHIPMENT" | jq -r '.shipment.tracking_number')
echo -e "\nTracking Number: $TRACKING"
echo -e "\n=== 4. Track Shipment ==="
curl -s "$API_URL/shipments/$TRACKING" | jq .
echo -e "\n=== 5. Cancel Shipment ==="
curl -s -X POST "$API_URL/shipments/$TRACKING/cancel" | jq .
echo -e "\n=== Test Complete ==="Error Responses
422 Validation Error
{
"detail": [
{
"loc": ["body", "from_address", "postal_code"],
"msg": "field required",
"type": "value_error.missing"
}
]
}404 Not Found
{
"detail": "Shipment not found"
}500 Internal Server Error
{
"detail": "Internal server error"
}Integration Tests
Run the integration tests:
bun test lib/delivery-api/__tests__/delivery-api.integration.test.tsRelated Files
- Frontend client:
lib/delivery-api/client.ts - Source markers:
lib/delivery-api/source-marker.ts - Types:
lib/delivery-api/types.ts - Unit tests:
lib/delivery-api/source-marker.test.ts
Commits
| Commit | Description |
|---|---|
| 1d508dd | Add CROP source identification to shipment requests |
| 283ce6c | Fix lint/typecheck errors |
| ad984a3 | Add double-marker protection and unit tests |
Notes
-
Clinton Tractor is a mock provider for testing. It simulates shipment creation, tracking, and cancellation without real carrier integration.
-
UPS Integration requires valid credentials:
UPS_CLIENT_IDUPS_CLIENT_SECRETUPS_ACCOUNT_NUMBER
-
CROP Markers are passed to the backend but the backend task to use them in tracking numbers is pending. See
docs/backend-tasks/CROP_SOURCE_IDENTIFICATION.md.
Clerk Authentication Setup
Application: CROP Public App (crop-front-mu.vercel.app) Last Updated: 2025-12-03 Status: ✅ Implemented (Basic Auth) Provider: Clerk(https://clerk.com/)
AI Agent Test Report
Date: 2025-01-28 Environment: https://crop-dev.app Deployment: (promoted to production) Commit: - fix(ai): prevent hallucination of manufacturer names