Skip to main content

Shipment API Testing

This guide provides specific testing approaches and examples for the Equinix Shipments API, building on the general API Testing principles.

Shipments API Overview​

The Shipments API allows you to programmatically schedule and manage inbound and outbound shipments to Equinix IBX data centers, including:

  • Scheduling inbound shipments (receiving packages)
  • Scheduling outbound shipments (sending packages)
  • Updating shipment details
  • Managing shipment tracking information
  • Handling carrier information and tracking numbers

Important Note: All inbound and outbound shipments must be scheduled 24 hours in advance. The Equinix API is a production system that creates real shipment requests. Always follow these testing best practices to ensure you don't create unintended operational work.

Shipment Testing Workflow​

Before testing the Shipments API, ensure you have:

  • Valid API credentials with shipments ordering permissions
  • Access to Equinix IBX locations where you have cages
  • Valid cage IDs for your shipment locations
  • Understanding of carrier requirements and tracking number formats

Creating an Inbound Shipment Request

import requests
import json
from datetime import datetime, timedelta

# Setup authentication
auth_url = "https://api.equinix.com/oauth2/v1/token"
auth_payload = {
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}

auth_response = requests.post(auth_url, data=auth_payload)
token = auth_response.json()["access_token"]

# Test creating an inbound shipment request
base_url = "https://api.equinix.com/colocations/v2"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}

# Calculate delivery date (24+ hours in advance as required)
delivery_date = (datetime.utcnow() + timedelta(days=2)).isoformat() + "Z"

# Example: Create an inbound shipment request
inbound_payload = {
"type": "INBOUND",
"requestedDateTime": delivery_date,
"cageId": "SV1:01:001MC3",
"customerReferenceId": "SHIP-REF-12345",
"description": "Server hardware delivery for data center expansion project",
"details": {
"carrier": "DHL",
"carrierTrackingNumbers": [
"1234567890123",
"1234567890124"
],
"numberOfBoxes": 2,
"accountNumber": "12345"
},
"purchaseOrder": {
"type": "EXISTING",
"number": "PO-789456"
},
"attachments": [
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "packing_list.pdf"
}
],
"contacts": [
{
"type": "TECHNICAL",
"registeredUsers": ["tech.admin@example.com"],
"availability": "WORK_HOURS",
"timezone": "America/New_York"
},
{
"type": "NOTIFICATION",
"registeredUsers": ["notifications@example.com"]
}
]
}

create_response = requests.post(
f"{base_url}/orders/shipments",
headers=headers,
data=json.dumps(inbound_payload)
)

# Verify response
assert create_response.status_code == 201, f"Failed to create shipment: {create_response.text}"

# Extract order ID from Location header
order_number = create_response.json()["OrderNumber"]

print(f"Successfully created inbound shipment with order ID: {order_number}")

Creating an Outbound Shipment Request

# Example: Create an outbound shipment request
outbound_payload = {
"type": "OUTBOUND",
"requestedDateTime": delivery_date,
"cageId": "SV1:01:001MC3",
"customerReferenceId": "OUT-SHIP-67890",
"description": "Returning defective network equipment to vendor",
"details": {
"carrier": "FEDEX",
"carrierTrackingNumbers": [
"987654321098"
],
"numberOfBoxes": 1,
"pickupLocation": "Main cage entrance",
"specialInstructions": "Handle with care - contains sensitive electronic equipment"
},
"purchaseOrder": {
"type": "EXEMPTED"
},
"contacts": [
{
"type": "TECHNICAL",
"registeredUsers": ["shipping@example.com"],
"availability": "ANYTIME"
}
]
}

outbound_response = requests.post(
f"{base_url}/orders/shipments",
headers=headers,
data=json.dumps(outbound_payload)
)

assert outbound_response.status_code == 201, f"Failed to create outbound shipment: {outbound_response.text}"
order_number = outbound_response.json()["OrderNumber"]
print("Successfully created outbound shipment request with order ID: {order_number}")

Testing Error Scenarios​

Always test error handling for your API implementation:

# Test with invalid carrier
invalid_carrier_payload = {
"type": "INBOUND",
"requestedDateTime": delivery_date,
"cageId": "SV1:01:001MC3",
"details": {
"carrier": "INVALID_CARRIER", # Invalid carrier
"carrierTrackingNumbers": ["1234567890"],
"numberOfBoxes": 1
},
"contacts": [
{
"type": "TECHNICAL",
"registeredUsers": ["test@example.com"]
}
]
}

error_response = requests.post(
f"{base_url}/orders/shipments",
headers=headers,
data=json.dumps(invalid_carrier_payload)
)

# Verify error response
assert error_response.status_code == 400, f"Expected error but got: {error_response.status_code}"
error_data = error_response.json()
assert any("carrier" in error["errorMessage"].lower() for error in error_data), "Expected carrier validation error"

# Test with insufficient advance notice (less than 24 hours)
insufficient_time_payload = {
"type": "INBOUND",
"requestedDateTime": (datetime.utcnow() + timedelta(hours=12)).isoformat() + "Z", # Only 12 hours advance
"cageId": "SV1:01:001MC3",
"details": {
"carrier": "DHL",
"carrierTrackingNumbers": ["1234567890"],
"numberOfBoxes": 1
},
"contacts": [
{
"type": "TECHNICAL",
"registeredUsers": ["test@example.com"]
}
]
}

time_error_response = requests.post(
f"{base_url}/orders/shipments",
headers=headers,
data=json.dumps(insufficient_time_payload)
)

assert time_error_response.status_code == 400, f"Expected time validation error but got: {time_error_response.status_code}"

Best Practices for Shipments API Testing​

  1. 24-Hour Advance Rule: Always schedule shipments at least 24 hours in advance
  2. Valid Tracking Numbers: Use realistic tracking number formats for each carrier
  3. Proper Contact Information: Ensure contacts are available during delivery windows
  4. Cage Access: Verify cage IDs and access permissions before testing
  5. International Shipments: Consider customs requirements for international deliveries
  6. Special Instructions: Test with various special handling requirements
  7. File Attachments: Test attachment uploads for packing lists and special instructions
  8. Time Zones: Handle time zone conversions properly for scheduling
  9. Purchase Orders: Test different PO types (NEW, EXISTING, EXEMPTED)

Automation Considerations​

When building automation around the Shipments API:

  • Implement validation for the 24-hour advance scheduling requirement
  • Build in carrier-specific validation for tracking number formats
  • Include proper error handling for carrier availability and capacity issues
  • Implement webhook receivers for shipment status updates
  • Build audit logging for all shipment transactions
  • Validate cage access and permissions before creating requests
  • Ensure proper handling of time zones for international locations

Additional Resources​

Was this page helpful?