OpenCarrier
Carrier API · labels · quotes · tracking

One API for every carrier. Every choice explained.

OpenCarrier buys labels, gets quotes and tracks packages across carriers through one REST API, on your own carrier accounts. When it picks the carrier for you, it records every option it weighed and why it chose one.

Planpl_7KQ2M9XW3D · policy auto/v1
Pkgs1 of 1
Ship toARLINGTON VA 22201 · RESIDENTIAL
Wt2.3 LB
FedEx 2Day$11.92 · due Tue
  • fedex 2_day$11.92chosen
  • fedex standard_overnight$26.75higher score
  • fedex express_saver$9.85misses deliver-by
  • fedex ground$8.10misses deliver-by
  • fedex priority_overnight$31.06higher score
794953535000EXAMPLE · stored with the plan
Carrier choice

A decision you can audit, not a black box.

Ask for an auto plan and OpenCarrier quotes every eligible account and service at once. It drops options that break a rule, such as a deliver-by date or a cost cap, and scores the rest by price plus the expected cost of a late delivery.

  • Every candidate is kept. Quotes, delivery estimates, on-time rates and the reason each option lost are stored with the plan.
  • Policies are versioned. Each plan names the policy that made it, so a decision can be replayed and compared later.
  • You set the rules. Deliver-by date, service level, signature, a maximum cost and preferred carriers.
POST /v1/shipments/{id}/plansresponse, trimmed
"policy": "auto/v1",
"chosen": 0,  // index into candidates
"candidates": [
  { "carrier": "fedex", "service": "2_day",
    "cost": { "amountMinor": 1192, "currency": "USD" },
    "estimate": { "deliverBy": "2026-10-27", "source": "carrier" },
    "onTimeRate": 0.97, "eligible": true,
    "score": 1207 },  // $11.92 + 3% × $5.00 late cost
  { "carrier": "fedex", "service": "express_saver",
    "cost": { "amountMinor": 985, "currency": "USD" },
    "excluded": ["misses_deliver_by"] },
  … every other account and service, with its reason
]
Purchase guarantee

A timeout never buys the same label twice.

Carrier APIs time out. A naive retry pays for a second label. OpenCarrier records the purchase before it calls the carrier, and a request with the same Idempotency-Key returns the stored result instead of calling again.

When a carrier's answer is lost, the purchase is marked unknown, never retried blindly, and settled by lookup or by an operator.

purchasing

Recorded with a lease before the carrier is called. A repeat request reads this row.

purchased

Tracking numbers and labels stored, in PDF and ZPL for thermal printers.

rejected

The carrier refused with a code, such as a bad address. Nothing was bought; plan again safely.

unknown

The carrier may have created it. Never retried automatically; reconciled instead.

voided

Canceled with the carrier. Voiding twice is harmless.

Your accounts

Bring your own carrier accounts and your own rates.

Connect the UPS and FedEx accounts you already have. You keep your negotiated rates and your relationship with the carrier; OpenCarrier does not resell postage.

  • Encrypted at rest. Each account's credentials are sealed with AES-256-GCM under their own data key, and are never returned by the API or written to logs.
  • Checked before use. Credentials are validated when you connect an account, and a verify call tests them with the carrier.
  • Isolated by tenant. Every read of a credential requires the tenant it belongs to.
After the label

Know where it is, and what it really cost.

Quotes are promises. OpenCarrier keeps following each package until it is delivered, then compares what you were quoted with what the carrier billed.

One tracking feed

Every carrier's scans in one set of statuses, from label created to delivered or returned. Read them as one ordered feed, so nothing is missed between polls.

GET /v1/tracking-events?after=…

Signed webhooks

Register an endpoint and receive each event as it happens. Deliveries are signed, retried, and safe to receive twice.

OpenCarrier-Signature: v1=…

Settled cost

Import the carrier's invoice CSV. Amounts are matched to labels to the cent, and re-importing a file changes nothing.

POST /v1/invoices

Carrier outcomes report

For any period: delivered packages, on-time rate, average days late, and quoted against settled cost, for each carrier and service. The numbers the next carrier choice should be based on.

GET /v1/reports/outcomes?from=…&to=…
API

Four calls from intent to label.

Describe what has to move. Get a plan. Buy it. Print it. Every call is documented in OpenAPI and authenticated with a per-tenant key.

Carriers
FedEx · quotes, labels, tracking UPS · labels, tracking Mock (for tests) USPS · planned Regional · planned

The mock carrier is deterministic and can be told to time out or refuse, so you can test your failure paths before a real carrier ever sees them.

curlUS domestic
# 1. Say what has to move
curl -X POST $OC/v1/shipments \
  -H "Authorization: Bearer $OC_KEY" \
  -H "Idempotency-Key: order-58213" \
  -d '{"origin": {...}, "destination": {...},
       "packages": [{"weightGrams": 1040}],
       "constraints": {"deliverBy": "2026-10-27"}}'

# 2. Let OpenCarrier choose, and keep the reasons
curl -X POST $OC/v1/shipments/$ID/plans \
  -d '{"mode": "auto"}'

# 3. Buy it, once, however often you retry
curl -X POST $OC/v1/shipments/$ID/purchase \
  -H "Idempotency-Key: order-58213-buy"

# 4. Print it on a thermal printer
curl $OC/v1/shipments/$ID/labels/0?format=zpl
POST/v1/quotesPrices for a shipment, without saving anything
POST/v1/shipments/{id}/voidCancel a purchase with the carrier
GET/v1/carriersWhat each carrier supports: services, limits, signature, tracking
POST/v1/carrier-accountsConnect a carrier account with your own credentials
POST/v1/webhook-endpointsReceive signed tracking events
GET/v1/reports/outcomesOn-time rate and settled cost by carrier and service
Early access

Ship your first label through OpenCarrier.

OpenCarrier is in early access for US domestic parcel shippers, warehouse systems and 3PLs. Tell us your daily volume and which carrier accounts you have, and we'll set up a tenant and API key.

Write to
hello@opencarrier.dev

Include your daily parcel volume and your carrier accounts.