Label Proxy
Generate shipping labels through carrier APIs with automatic PII handling
Label Proxy API
The Label Proxy forwards carrier API requests with automatic PII placeholder replacement and response scrubbing. Your WMS sends requests with placeholders like {{ship_to_name}}, and Data Border injects real PII from Amazon, then scrubs the carrier response.
Forward Label Request
Proxies a request to a carrier API with PII injection.
POST /api/label-proxy/forward
Authentication
| Header | Required | Description |
|---|---|---|
x-seller-access-token | Yes | Valid seller access token |
x-amazon-token-secret | Yes | Secret used during OAuth |
Required Headers
| Header | Description |
|---|---|
x-original-url | Full URL of the carrier API endpoint |
x-amazon-order-id | Amazon order ID for PII lookup |
x-unique-shipment-id | Your unique identifier for this shipment |
Optional Headers
| Header | Description |
|---|---|
authorization | Forwarded to carrier (e.g., Bearer API_KEY) |
x-api-key | Forwarded to carrier for authentication |
Request Body
JSON body to send to the carrier. Use PII placeholders for customer data:
{
"shipment": {
"to_address": {
"name": "{{ship_to_name}}",
"street1": "{{ship_to_address1}}",
"street2": "{{ship_to_address2}}",
"city": "{{ship_to_city}}",
"state": "{{ship_to_state}}",
"zip": "{{ship_to_zip}}",
"country": "{{ship_to_country}}",
"phone": "{{ship_to_phone}}"
},
"from_address": {
"name": "Your Warehouse",
"street1": "123 Warehouse Ave",
"city": "Commerce City",
"state": "CO",
"zip": "80022",
"country": "US"
},
"parcel": {
"length": 10,
"width": 8,
"height": 4,
"weight": 16
}
}
}
PII Placeholders
| Placeholder | Description | Amazon Field |
|---|---|---|
{{ship_to_name}} | Recipient name | ShippingAddress.Name |
{{ship_to_address1}} | Address line 1 | ShippingAddress.AddressLine1 |
{{ship_to_address2}} | Address line 2 | ShippingAddress.AddressLine2 |
{{ship_to_address3}} | Address line 3 | ShippingAddress.AddressLine3 |
{{ship_to_city}} | City | ShippingAddress.City |
{{ship_to_state}} | State/region | ShippingAddress.StateOrRegion |
{{ship_to_zip}} | Postal code | ShippingAddress.PostalCode |
{{ship_to_country}} | Country code | ShippingAddress.CountryCode |
{{ship_to_phone}} | Phone number | ShippingAddress.Phone |
{{buyer_name}} | Buyer name | BuyerInfo.BuyerName |
{{buyer_email}} | Buyer email | BuyerInfo.BuyerEmail |
Whitelisted Carriers
| Carrier | Allowed Origins |
|---|---|
| EasyPost | https://api.easypost.com |
| ShipStation | https://ssapi.shipstation.com |
| Shippo | https://api.goshippo.com |
| UPS | https://onlinetools.ups.com, https://wwwcie.ups.com |
| FedEx | https://apis.fedex.com, https://apis-sandbox.fedex.com |
| USPS | https://secure.shippingapis.com |
| DHL | https://express.api.dhl.com, https://api-sandbox.dhl.com |
Response
{
"success": true,
"data": {
"scrubbed_response": {
"tracking_code": "1Z999AA10123456784",
"label_url": "https://carrier.com/labels/abc123"
},
"shipment_id": "ship_abc123def456",
"amazon_order_id": "123-4567890-1234567",
"unique_shipment_id": "WMS-SHIP-001",
"documents": [
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"path": "label.pdf"
}
]
}
}
| Field | Description |
|---|---|
scrubbed_response | Carrier response with PII values redacted |
shipment_id | Data Border shipment ID (use for printing) |
amazon_order_id | Associated Amazon order |
unique_shipment_id | Your original shipment ID |
documents | Array of unredacted document references |
Example
curl -X POST "https://adb.example.com/api/label-proxy/forward" \
-H "Content-Type: application/json" \
-H "x-seller-access-token: YOUR_SELLER_TOKEN" \
-H "x-amazon-token-secret: YOUR_TOKEN_SECRET" \
-H "x-original-url: https://api.easypost.com/v2/shipments" \
-H "x-amazon-order-id: 123-4567890-1234567" \
-H "x-unique-shipment-id: WMS-SHIP-001" \
-H "Authorization: Bearer EASYPOST_API_KEY" \
-d '{
"shipment": {
"to_address": {
"name": "{{ship_to_name}}",
"street1": "{{ship_to_address1}}",
"city": "{{ship_to_city}}",
"state": "{{ship_to_state}}",
"zip": "{{ship_to_zip}}",
"country": "{{ship_to_country}}"
},
"from_address": {
"name": "Warehouse",
"street1": "123 Main St",
"city": "Denver",
"state": "CO",
"zip": "80202",
"country": "US"
},
"parcel": {
"length": 10,
"width": 8,
"height": 4,
"weight": 16
}
}
}'
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Missing required header: x-amazon-order-id | Required header missing |
| 400 | Carrier origin not in whitelist | URL not from approved carrier |
| 400 | Invalid placeholders in request body | Unknown placeholder used |
| 401 | Invalid seller access token | Token expired or invalid |
| 404 | Order not found | Order doesn't exist for seller |
Flow Diagram
sequenceDiagram
participant WMS
participant ADB
participant Amazon as Amazon SP-API
participant Carrier as Carrier API
participant S3 as S3 Storage
WMS->>ADB: POST /api/label-proxy/forward<br/>Body with placeholders
ADB->>ADB: Validate carrier whitelist
ADB->>ADB: Validate placeholders
ADB->>Amazon: GET /orders/{orderId}/address<br/>(using RDT token)
Amazon->>ADB: Return PII data
ADB->>ADB: Replace placeholders with PII
ADB->>Carrier: POST to carrier API
Carrier->>ADB: Return label response
ADB->>S3: Store unredacted labels
ADB->>ADB: Scrub PII from response
ADB->>ADB: Create shipment record
ADB->>WMS: Return scrubbed response + document UUIDsCarrier-Specific Examples
EasyPost
const response = await fetch(`${ADB_URL}/api/label-proxy/forward`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-seller-access-token': sellerToken,
'x-amazon-token-secret': amazonSecret,
'x-original-url': 'https://api.easypost.com/v2/shipments',
'x-amazon-order-id': order.amazonOrderId,
'x-unique-shipment-id': `${order.id}-${Date.now()}`,
'Authorization': `Bearer ${EASYPOST_KEY}`
},
body: JSON.stringify({
shipment: {
to_address: {
name: '{{ship_to_name}}',
street1: '{{ship_to_address1}}',
street2: '{{ship_to_address2}}',
city: '{{ship_to_city}}',
state: '{{ship_to_state}}',
zip: '{{ship_to_zip}}',
country: '{{ship_to_country}}',
phone: '{{ship_to_phone}}'
},
from_address: warehouseAddress,
parcel: parcelDimensions
}
})
})
ShipStation
const response = await fetch(`${ADB_URL}/api/label-proxy/forward`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-seller-access-token': sellerToken,
'x-amazon-token-secret': amazonSecret,
'x-original-url': 'https://ssapi.shipstation.com/shipments/createlabel',
'x-amazon-order-id': order.amazonOrderId,
'x-unique-shipment-id': order.id,
'Authorization': `Basic ${SHIPSTATION_CREDENTIALS}`
},
body: JSON.stringify({
carrierCode: 'ups',
serviceCode: 'ups_ground',
shipTo: {
name: '{{ship_to_name}}',
street1: '{{ship_to_address1}}',
city: '{{ship_to_city}}',
state: '{{ship_to_state}}',
postalCode: '{{ship_to_zip}}',
country: '{{ship_to_country}}',
phone: '{{ship_to_phone}}'
},
shipFrom: warehouseAddress,
weight: { value: 16, units: 'ounces' },
dimensions: parcelDimensions
})
})
Document Handling
What Gets Stored
Data Border stores unredacted versions of documents found in the carrier response:
- Shipping labels (PDF, PNG, ZPL)
- Commercial invoices
- Customs documents
- Packing slips
Using Document UUIDs
The documents array contains references to unredacted documents:
{
"documents": [
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"path": "label.pdf"
},
{
"uuid": "660e8400-e29b-41d4-a716-446655440001",
"path": "commercial_invoice.pdf"
}
]
}
Use these UUIDs with the Print API to send labels to Device Hub.
Response Scrubbing
Data Border automatically scrubs PII from carrier responses:
Original carrier response:
{
"to_address": {
"name": "John Doe",
"street1": "123 Main Street",
"city": "Anytown"
},
"tracking_code": "1Z999AA1"
}
Scrubbed response returned to WMS:
{
"to_address": {
"name": "[REDACTED]",
"street1": "[REDACTED]",
"city": "[REDACTED]"
},
"tracking_code": "1Z999AA1"
}
Best Practices
Use Unique Shipment IDs
// Good: Unique, traceable ID
const uniqueShipmentId = `${orderId}-${warehouseId}-${Date.now()}`
// Bad: Reused or non-unique
const uniqueShipmentId = orderId // Could conflict on re-ships
Handle Multiple Labels
const result = await createLabel(order)
// Store all document references
await db.shipments.create({
orderId: order.id,
adbShipmentId: result.shipment_id,
trackingNumber: result.scrubbed_response.tracking_code,
documents: result.documents // Store the full array
})
// Print all documents
for (const doc of result.documents) {
await printLabel(result.shipment_id, [doc.uuid])
}
Error Handling
try {
const result = await labelProxy.forward(request)
return result
} catch (error) {
if (error.message.includes('Carrier origin not in whitelist')) {
// Configuration error - check your carrier URL
throw new ConfigError('Invalid carrier URL')
}
if (error.message.includes('Invalid placeholders')) {
// Check placeholder spelling
throw new ValidationError('Invalid placeholder in request')
}
throw error
}
