RateShip is now an open-source SDK
RateShip started as a hosted shipping service. You created an account, pasted your Shippo, EasyPost, and ShipEngine API keys into our dashboard, and called rateship.rates.get(...) against our API. We fanned out to your providers and returned normalized rates.
Today we're flipping the model. RateShip is now an open-source Node SDK. Free, MIT-licensed, published to npm. No account, no dashboard, no hosted service. You install it, configure it with your own provider keys, and run it on your own backend.
Why we pivoted
The feedback from early users was consistent: "why do I need a middleman?" Teams already had backend infrastructure. They were happy to handle their own rate-limiting, their own secret storage, their own webhook endpoints. What they wanted was the normalization layer (one typed API across providers) without a hosted service in the middle adding another hop, another point of failure, and another vendor to trust with provider credentials.
The honest take: for the 95% of developers who already run a Node backend, the hosted service added friction without adding value. The 5% who did benefit were small teams who wanted a GUI for ops staff to buy labels by hand, and those users can build that GUI on top of the SDK in an afternoon.
What changed
The entire rate-fetching, label-purchasing, and webhook-verification layer now lives inside the rateship npm package. You use it like this:
import { RateShip, easypost, shippo, shipengine } from "rateship";
const client = new RateShip({
providers: [
easypost({ apiKey: process.env.EASYPOST_KEY! }),
shippo({ apiKey: process.env.SHIPPO_KEY! }),
shipengine({ apiKey: process.env.SHIPENGINE_KEY! }),
],
});
const { rates, errors } = await client.getRates(request);
const label = await client.createLabel(rates[0]);
const event = client.webhooks.verify({
provider: "easypost",
rawBody,
signature,
secret: process.env.EASYPOST_WEBHOOK_SECRET!,
});Zero runtime dependencies. Node 20+. Full TypeScript types. Tree-shakable if you only use one provider. The adapters, the normalization, the HMAC verification. All of it runs on your backend, talks directly to the providers, and never phones home.
What this means for existing users
Your current setup keeps working. If you already have a RateShip account with active provider keys and webhook endpoints, the hosted API continues to serve you. You're grandfathered in for as long as you need. We'll reach out individually with migration guidance when you're ready to move over. It's mostly a matter of swapping a few method names.
The hosted service is closed to new sign-ups. New users go straight to the SDK. That's cleaner for you (no vendor to evaluate), cleaner for us (no hosted uptime to defend), and means the only thing we're shipping going forward is open-source code.
What's next
v2.0 is US-domestic only (addresses are locked to country: "US", weight in lb / oz, distance in in, rates filtered to USD). The roadmap from here:
- v2.1: international. Widen
countryto ISO 3166-1, addkg/cm, customs forms, ShipEngine webhook RSA+JWKS verification. - v2.2+: multi-parcel shipments, label format options (PDF / PNG / ZPL / return labels), address validation, and a public adapter interface so you can plug in providers we haven't written.
Everything's on GitHub. Issues, PRs, and feedback open the conversation. That's how we knew to do this in the first place.
Get started
npm install rateshipThen head to the docs. You'll be making real rate calls inside 10 minutes.