whereparcel
v0.3.0
Published
Official WhereParcel SDK — Track parcels across 64+ live carriers (request more anytime). Detect carrier from a tracking number, real-time webhooks, unified JSON.
Maintainers
Readme
WhereParcel
Official Node.js SDK for the WhereParcel multi-carrier tracking API. Track parcels across 64+ live carriers (USPS, FedEx, UPS, DHL, OnTrac, Royal Mail, Japan Post, and more) via a single REST API. Don't see a carrier? Request it on our community board — we add new carriers fast.
- 🌍 64+ live carriers in production with rapid on-request additions
- 🔍
detect()from a tracking number alone — no carrier code required - 📦 Bulk tracking — up to 5 parcels per request
- 🔔 Webhooks — real-time delivery notifications with HMAC signing
- 📘 TypeScript first — full type definitions, strict null checks
- ⚡ Zero dependencies — uses native
fetch(Node.js 18+) - 🔁 ESM + CJS — works with both module systems
Install
npm install whereparcel
# or
pnpm add whereparcel
# or
yarn add whereparcelGet your API key at whereparcel.com/dashboard (7-day free trial on every paid plan, no charge if cancelled).
Quick Start
import { WhereParcel } from 'whereparcel';
const wp = new WhereParcel('YOUR_API_KEY', 'YOUR_SECRET_KEY');
// Track a parcel
const response = await wp.track([
{ carrier: 'us.usps', trackingNumber: '9400111899562537866361' },
]);
const result = response.data[0];
if (result.status === 'success') {
console.log(result.data.deliveryStatus); // 'in_transit', 'delivered', etc.
console.log(result.data.events); // Array of tracking events
} else {
console.log(result.error.code); // e.g., 'TRACKING_NOT_FOUND'
}API Reference
Constructor
const wp = new WhereParcel(apiKey, secretKey, options?);| Parameter | Type | Description |
|-----------|------|-------------|
| apiKey | string | Your API key from the dashboard |
| secretKey | string | Your secret key from the dashboard |
| options.timeout | number | Request timeout in ms (default: 30000) |
detect(trackingNumber) ⭐
Detect possible carrier(s) from a tracking number alone. Performs regex matching against 200+ carrier patterns + service-type lookup (USPS Service Type Codes, UPS prefixes, etc.). Free endpoint — no quota usage, response < 10ms.
const detected = await wp.detect('9302010623390236546635');
if (detected.confirmed) {
// single carrier matched — proceed with track()
const response = await wp.track([
{ carrier: detected.confirmed, trackingNumber: detected.normalized },
]);
} else if (!detected.noMatch) {
// ambiguous — show candidates to user or try them in order
console.log('Candidates:', detected.candidates.map((c) => c.code));
console.log('Service hint:', detected.candidates[0].serviceTypes); // e.g. ['Collect on Delivery']
} else {
console.log('Not a recognized tracking number');
}Response shape:
{
input: '9302010623390236546635',
normalized: '9302010623390236546635',
candidates: [
{
code: 'us.usps',
name: 'USPS (United States Postal Service)',
country: 'US',
pattern: { regex: '...', description: 'USPS — 22자리 IMpb...' },
formatName: 'USPS 22',
serviceTypes: ['Collect on Delivery'],
},
// ... more candidates ranked by specificity
],
confirmed: 'us.usps', // undefined if ambiguous
format: 'USPS — 22자리 IMpb (9X STC)...',
noMatch: false,
}Use cases:
- Decide which carrier to query when only the tracking number is available
- Validate user input (reject invalid formats early)
- Pre-route shipments to the right integration
Try it without an API key — paste any number into our free Tracking Number Validator (runs entirely in your browser).
track(items)
Track one or more parcels (max 5 items per request).
// Single parcel
const response = await wp.track([
{ carrier: 'us.usps', trackingNumber: '9400111899562537866361' },
]);
// Multiple parcels (max 5)
const response = await wp.track([
{ carrier: 'us.usps', trackingNumber: '9400111899562537866361' },
{ carrier: 'us.fedex', trackingNumber: '123456789012' },
{ carrier: 'kr.cj', trackingNumber: '1234567890', clientId: 'order-42' },
]);
console.log(response.summary);
// { total: 3, success: 2, failed: 1, usageIncremented: 2 }
for (const result of response.data) {
if (result.status === 'success') {
console.log(`${result.carrier}: ${result.data.deliveryStatus}`);
} else {
console.log(`${result.carrier}: ${result.error.code}`);
}
}Carriers
getCarriers()
List all supported carrier codes.
const carriers = await wp.getCarriers();
// ['us.usps', 'us.fedex', 'us.ups', 'kr.cj', 'jp.post', ...]getCountries()
const countries = await wp.getCountries();
// [{ code: 'us', name: 'United States' }, { code: 'kr', name: 'South Korea' }, ...]getCarriersByCountry(country) / getCarriersByRegion(country, region)
const usCarriers = await wp.getCarriersByCountry('us');
const caCarriers = await wp.getCarriersByRegion('us', 'ca');Webhooks
registerWebhook(options)
Subscribe parcels to receive real-time status changes via your webhook endpoint.
// Recurring monitoring until delivery
const subscription = await wp.registerWebhook({
trackingItems: [{ carrier: 'us.usps', trackingNumber: '...' }],
recurring: true,
webhookEndpointId: 'wep_abc123',
});createWebhookEndpoint(options) / updateWebhookEndpoint / deleteWebhookEndpoint / getWebhookEndpoints
Manage webhook URLs that receive tracking events.
const endpoint = await wp.createWebhookEndpoint({
name: 'Production',
url: 'https://yourapp.com/webhooks/whereparcel',
});
console.log(endpoint.secret); // Use this to verify webhook HMAC signaturesgetSubscriptions() / getSubscription(id) / deleteSubscription(id)
Inspect or cancel webhook subscriptions.
Error Handling
The SDK throws typed errors you can instanceof check:
import {
WhereParcelError,
AuthenticationError,
RateLimitError,
NotFoundError,
} from 'whereparcel';
try {
const response = await wp.track([{ carrier: 'us.usps', trackingNumber: '...' }]);
} catch (error) {
if (error instanceof AuthenticationError) {
// 401 — wrong API key
} else if (error instanceof RateLimitError) {
// 429 — back off (error.retryAfter seconds)
} else if (error instanceof NotFoundError) {
// 404 — endpoint not found
} else if (error instanceof WhereParcelError) {
// other API/network error
console.log(error.code, error.statusCode);
}
}TypeScript
All types are exported from the package root:
import type {
WhereParcel,
TrackingRequest,
TrackingResult,
TrackingStatus,
BulkTrackingResponse,
DetectResponse,
DetectedCandidate,
WebhookEndpoint,
} from 'whereparcel';Pricing
The SDK itself is free and MIT-licensed. The underlying API has these plans (as of 2026):
| Plan | Price | Requests/month | Rate limit | |------|-------|----------------|-----------| | Starter | $49/mo | 10,000 | 30 req/min | | Pro | $99/mo | 30,000 | 60 req/min | | Business | $650/mo | 300,000 | 200 req/min |
Every paid plan includes a 7-day free trial (no charge if cancelled). Plus 3 months of Starter free via the ambassador program — one short blog post mentioning WhereParcel.
Resources
- 📘 API Documentation
- 🛠 Tracking Number Validator (free tool)
- 🎯 API Playground
- 📚 5-minute setup guide
- 📊 Best Parcel Tracking API 2026 — comparison
- 💬 Community board (request a carrier)
License
MIT © WhereParcel — see LICENSE.
