Secure Printing
Send shipping labels directly to printers without exposing PII to your WMS
Secure Printing
Data Border's Print API completes the secure label workflow. After generating a label via the Label Proxy, use the Print API to send the unredacted label directly to a printer—bypassing your WMS entirely.
The Complete Flow
sequenceDiagram
participant WMS
participant ADB
participant S3 as S3 Storage
participant DeviceHub as Device Hub
participant Printer
Note over WMS: Step 1: Generate label
WMS->>ADB: POST /api/label-proxy/forward
ADB->>WMS: {shipment_id, documents: [{uuid}]}
Note over WMS: Step 2: Request print
WMS->>ADB: POST /api/print/send<br/>{shipment_id, label_uuids}
ADB->>ADB: Lookup shipment
ADB->>S3: Fetch unredacted labels
S3->>ADB: Return label PDFs
ADB->>DeviceHub: POST print job
DeviceHub->>Printer: Print label
Printer->>DeviceHub: Acknowledge
DeviceHub->>ADB: Job complete
ADB->>ADB: Increment print count
ADB->>WMS: {status: "sent", is_reprint: false}Notice that your WMS never touches the actual label file—it only references it by UUID.
Setting Up Device Hub
Device Hub is a local print server that runs in your warehouse. Data Border sends print jobs to it over HTTPS.
Device Hub Configuration
Each tenant in Data Border can have a Device Hub URL configured:
Tenant Configuration:
- deviceHubHost: https://devicehub.warehouse.local:8443
Contact your Data Border administrator to configure your Device Hub URL.
Network Requirements
Device Hub must be accessible from Data Border:
- HTTPS - TLS encryption required
- Authentication - Device Hub should authenticate Data Border requests
- Firewall - Allow inbound from Data Border's IP ranges
Sending Print Jobs
Request Format
curl -X POST https://adb.example.com/api/print/send \
-H "Content-Type: application/json" \
-H "x-seller-access-token: YOUR_SELLER_TOKEN" \
-H "x-amazon-token-secret: YOUR_TOKEN_SECRET" \
-d '{
"shipment_id": "ship_abc123def456",
"printer_type": "label",
"printer_id": "warehouse-1-zebra",
"label_uuids": ["550e8400-e29b-41d4-a716-446655440000"]
}'
Request Fields
| Field | Type | Description |
|---|---|---|
shipment_id | string | Data Border shipment ID from label generation |
printer_type | string | "label" (thermal) or "laser" |
printer_id | string | Target printer identifier in Device Hub |
label_uuids | array | UUIDs of documents to print |
Response
First Print:
{
"success": true,
"data": {
"status": "sent",
"shipment_id": "ship_abc123def456",
"documents_sent": 1,
"print_count": 1,
"is_reprint": false
}
}
Reprint:
{
"success": true,
"data": {
"status": "sent",
"shipment_id": "ship_abc123def456",
"documents_sent": 1,
"print_count": 2,
"is_reprint": true,
"warning": "Reprint detected. First printed: 2024-01-15T10:30:00.000Z"
}
}
Reprint Detection
Data Border tracks how many times each shipment's labels have been printed:
- First print:
print_count: 1,is_reprint: false - Subsequent prints:
print_count: N,is_reprint: true, includes warning
This creates an audit trail for reprints, which can indicate:
- Legitimate reprints (printer jammed, label damaged)
- Potential fraud (duplicate labels)
- Process issues (labels being wasted)
Your WMS can use is_reprint to:
- Show warnings to warehouse staff
- Require supervisor approval for reprints
- Log reprint reasons in your system
Error Handling
Shipment Not Found
{
"is_adb_error": true,
"success": false,
"error": {
"message": "Shipment not found",
"details": "No shipment found with id ship_abc123def456"
}
}
Device Hub Not Configured
{
"is_adb_error": true,
"success": false,
"error": {
"message": "Device Hub not configured for this tenant",
"details": "Contact your administrator to configure the Device Hub host"
}
}
Invalid Label UUIDs
{
"is_adb_error": true,
"success": false,
"error": {
"message": "Invalid label UUIDs",
"details": "The following UUIDs are not part of this shipment: 550e8400-..."
}
}
Device Hub Unreachable
{
"is_adb_error": true,
"success": false,
"error": {
"message": "Device Hub communication failed",
"details": "Connection timeout after 30000ms"
}
}
Printer Types
Label Printers ("label")
Thermal printers like Zebra, DYMO, or Brother:
- Typically 4x6" or 4x8" labels
- ZPL or EPL format
- Direct thermal or thermal transfer
Laser Printers ("laser")
Standard office printers:
- Letter or A4 paper
- PDF format
- For packing slips, invoices, customs forms
Best Practices
Validate UUIDs Before Printing
Store the documents array from label generation and validate before print requests:
// After label generation
const labelResponse = await generateLabel(orderData);
const shipmentId = labelResponse.shipment_id;
const documentUUIDs = labelResponse.documents.map(d => d.uuid);
// Store in your database
await saveShipment({
orderId: orderData.orderId,
shipmentId,
documentUUIDs
});
// Before printing
const shipment = await getShipment(orderId);
const validUUIDs = documentUUIDs.filter(
uuid => shipment.documentUUIDs.includes(uuid)
);
Handle Reprints Appropriately
const printResponse = await sendPrintJob(shipmentId, uuids);
if (printResponse.is_reprint) {
logger.warn({
type: 'print',
shipmentId,
printCount: printResponse.print_count,
firstPrinted: printResponse.warning
}, 'Label reprint detected');
// Optionally require confirmation
if (printResponse.print_count > 2) {
await requireSupervisorApproval(shipmentId);
}
}
Configure Timeouts
The default Device Hub timeout is 30 seconds. For large print jobs or slow networks, consider:
- Printing labels individually rather than in batches
- Implementing retry logic with exponential backoff
- Monitoring Device Hub response times
End-to-End Example
Here's the complete workflow for shipping an Amazon order:
// 1. Generate label with placeholders
const labelResponse = await fetch('/api/label-proxy/forward', {
method: 'POST',
headers: {
'x-seller-access-token': sellerToken,
'x-amazon-token-secret': tokenSecret,
'x-original-url': 'https://api.easypost.com/v2/shipments',
'x-amazon-order-id': amazonOrderId,
'x-unique-shipment-id': `${orderId}-${Date.now()}`
},
body: JSON.stringify({
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: warehouseAddress,
parcel: packageDimensions
}
})
});
const { shipment_id, documents } = await labelResponse.json();
// 2. Store shipment info in your WMS
await saveShipment({
orderId,
amazonOrderId,
shipmentId: shipment_id,
trackingNumber: scrubbed_response.tracking_code,
documentUUIDs: documents.map(d => d.uuid)
});
// 3. Print the label
const printResponse = await fetch('/api/print/send', {
method: 'POST',
headers: {
'x-seller-access-token': sellerToken,
'x-amazon-token-secret': tokenSecret
},
body: JSON.stringify({
shipment_id: shipment_id,
printer_type: 'label',
printer_id: workstationPrinter,
label_uuids: documents.map(d => d.uuid)
})
});
// 4. Label prints at workstation
// Your WMS never saw the customer address!
