The REST API We Wish More Privacy Tools Shipped
A lot of API documentation reads like it was written for a compliance checklist: here are the endpoints, here’s the auth header, good luck. We wanted ours to read like it was written by people who actually expect you to build something real with it, because we do.
What’s actually in it
The REST API covers full CRUD on links — create, read, update, delete — plus analytics retrieval, conversion goal management, and bulk operations, all scoped to Enterprise accounts and authenticated with a bearer token you generate (and can revoke) from your dashboard. Nothing exotic. What we spent the extra effort on is the stuff that’s easy to skip and expensive to be missing later.
Webhooks, for one. You can register a URL and a secret, and we’ll deliver events — link created, link clicked, conversion recorded — as signed payloads you can verify came from us. Polling an API for changes is a workaround for not having webhooks, not a real integration pattern, and we didn’t want to ship an API that quietly expected you to poll.
Rate limiting, for two, with real headers telling you where you stand — not a silent 429 with no context, and not an unbounded API that falls over under load and takes your integration down with it. If you’re building something that calls us on a schedule, you should be able to build backoff logic against real numbers instead of guessing.
Idempotent bulk endpoints, for three. If a bulk request fails partway through — a network blip, a timeout on your end — retrying it shouldn’t create duplicate links. That’s a small detail that turns into a very annoying data integrity problem the first time it bites you in production, so we handled it up front instead of after a support ticket.
The constraint that shaped everything
Every API response still has to respect the same guarantee the rest of the product makes: we can’t hand back plaintext destination URLs, because we never have them. This shows up in small ways throughout the docs — endpoints that return link metadata clearly note what’s available server-side (click counts, timestamps, status) versus what only exists client-side and requires the caller to have the decryption key already. It’s a slightly less convenient API than one built without that constraint. We think it’s the honest shape for an API sitting on top of a genuinely zero-knowledge system, rather than one that quietly breaks the model for the sake of a cleaner integration guide.
Why we’re writing about our own docs
Mostly because we think API design is a real signal of whether a “privacy-first” product means it structurally or just in the parts customers see first. It’s easy to build a pretty dashboard around client-side encryption. It’s a different test to extend that same discipline all the way through a REST API that developers will use in ways you didn’t anticipate. If you’re integrating with us, the full reference has the specifics — this post is the “why it’s built this way,” not a replacement for it.