Integration Best Practices

View as Markdown

Authentication & Credentials

Use the right header format for the right endpoint. Both endpoint groups use a Personal Access Token (PAT) generated from Integrations > API Tokens in the dashboard, but the header format differs. The logisticslabelprintingapi endpoints (label creation, bulk cancel, rate shopping) use Authorization: <PAT>. The api.shipbob.com / sandbox-api.shipbob.com endpoints (webhook subscriptions) use Authorization: Bearer <PAT> — this is the more common pattern. Mixing up the header format is the most common cause of 401 errors.

Rotate and store credentials securely. Never hardcode tokens in client-side code or commit them to source control. Store them in environment variables or a secrets manager.


Testing in Sandbox First

Always validate your integration in sandbox before going to production. The sandbox environment (logisticslabelprintingapi-stage.shipbob.dev) behaves identically to production for label creation, rate shopping, and webhooks. Use it to test edge cases like oversized packages, signature-required orders, and cancellation/resubmission flows without incurring real shipping costs.

Use location_id: 33 (or 19) in sandbox. These are the fixed sandbox location IDs for label creation and rate shopping. Using any other value will cause failures. Your production location_id is different — get it from your ShipBob rep before going live.

Add the test credit card during sandbox setup. Sandbox label creation requires a payment method on file. Use card number 4242 4242 4242 4242 with any valid CVC, expiration date, and zip code.


Label Creation

Use whole numbers for all package measurements. The measurements object requires integer values for weight (in ounces) and all dimensions (in inches). Passing decimals may result in unexpected behavior.

Make reference_id truly unique per order. This is your primary identifier for an order within ShipBob Logistics. Reusing a reference_id is only valid after explicitly canceling the original via the bulk-cancel endpoint. Otherwise, the API may reject or conflict the submission.

Know when requires_signature is automatically enforced. If you set insurance_amount to $300 or more, signature confirmation is applied automatically regardless of your requires_signature field value. Account for this in your downstream order processing logic.

Pass products when you want pick lists and batching. The products array is optional, but including it unlocks pick list printing and order batching features in the ShipBob dashboard.


Rate Shopping

All fields are mandatory. Unlike the label creation endpoint (which has several optional fields), the rate shopping request requires every field — actualWeight, all three packageDimensions, destinationAddress, fulfillmentCenterId, serviceName, hasSignature, and insuranceAmount. Missing any field will cause the request to fail.

Match serviceName exactly to your ShipBob dashboard ship option. The value is case-sensitive and must match your configured ship option name precisely (e.g., "Standard Ground", not "standard ground" or "Standard Ground "). Mismatches are a common source of no-results responses.

Use rate shopping before label creation for cost-sensitive workflows. Call the rate shopping endpoint first to retrieve the flatRate for a given service and destination, then decide whether to proceed with label creation. This is especially useful if you’re offering customers real-time shipping cost estimates.


Tracking Updates

Prefer webhooks over polling. The order.shipment.tracking_received webhook typically fires within 5 minutes of label creation. Webhooks are more reliable and timely than polling for high-volume integrations. Reserve polling for fallback or reconciliation scenarios.

If you do poll, don’t exceed every 30 minutes. Polling more frequently than that offers little benefit and adds unnecessary load. Tracking details are generated within 3 minutes of the label being created, so it is recommended to poll at least every 3 minutes when retrieving tracking details.

Your webhook handler must return HTTP 200. ShipBob considers any non-2xx response a delivery failure. Ensure your handler responds with 200 OK before performing any heavy downstream processing — use an async queue if needed.

Verify your webhook URL is publicly accessible. Local development URLs (e.g., localhost) will not receive events. Use a tunneling tool like ngrok during development and register the public URL when subscribing.


Carrier & Service Mapping

API carrier values are case-sensitive and must be exact. When specifying carrier services, use the values from the Carriers reference table exactly as listed. For example, DHL’s API carrier value is DhlEcs, not DHL or dhlecs.

Be aware of service-level aliases. Several DHL services (e.g., “Parcel Plus Expedited Domestic” and “Parcels Expedited Domestic”) map to the same API Carrier Service Value (DHLParcelExpedited). If you’re building a carrier-mapping layer, account for these many-to-one relationships to avoid duplicating logic.


Error Handling

Handle 400 and 500 errors differently. A 400 indicates a problem with your request payload — validate your JSON structure and required fields before retrying. A 500 is a server-side issue; implement exponential backoff and retry logic rather than failing immediately.

Log interim_order_id and shipment_id from label creation responses. These IDs are your references for tracking down issues with ShipBob support. Store them alongside your internal order record.