Legal

Privacy policy

Last updated

ShipPilot is a shipping tool for businesses. Most of the personal data in it is not about the people who signed up — it is about the people they send parcels to. This page says exactly what is stored, who is responsible for each part of it, and who to ask to change or remove it.

Start here

Three questions cover almost everyone who reads this page.

Someone shipped me a parcel and I want my address removed

Contact the business that sent it to you, not ShipPilot. They hold your address in their own account, they decide what to keep, and they are the only party who can verify that the request is really yours. We are the software they keep it in — we do not own the record, and we cannot safely delete another company’s customer record on a stranger’s say-so.

If you cannot reach them, email [email protected] with the tracking number or order number. We will forward the request to the business that holds it and tell you that we have. See Who is responsible for what.

I have a ShipPilot account

We hold your name, your email address, a hash of your password (or your Google profile and sign-in tokens if that is how you sign in), a record of each session you open including its IP address, your workspace membership and role, and a copy of your name on the records you create — which is kept even if your account is deleted. The full list, with nothing left out, is under What we collect about account holders.

I was sent a tracking link

That page shows the sending business’s name, the order number, delivery status, carrier, service, tracking number, the destination city and state only, and the shipment’s status history. It does not show a street address, your name, a phone number, an email address, or what the shipping cost. Anyone holding the link sees the same page, so treat the link like a password. See Public tracking links.

What is and is not built

This policy describes the product as it behaves today. Some of it is not built yet, and the difference belongs before the detail rather than buried inside it.

The shipping records described on this page are real. Contacts, saved addresses, companies, projects, batches, shipments, packages and carrier connections are written to and read from the database, alongside the account records — sign-up, sign-in, sessions, sign-in methods, workspace membership, invitations and workspace settings. What you type into a shipping screen is saved and survives a restart. An earlier version of this page said the opposite; it was correct when written and was not updated when the screens were connected.

What is not built. These are the gaps that change the answer to a question a reader might actually be asking:

  • Nothing is billed yet. A checkout exists and is not connected to live payments; no charge is issued. Starting a checkout does create a customer record with the payment processor — see Subprocessors — but no card is charged.
  • No self-service export or account deletion. Both are requests to us, carried out by hand. See How long we keep things, which also names the one thing that IS deleted on a schedule.

An earlier version of this list also said that no label was bought, that nothing polled a carrier for tracking, and that a tracking link could not be turned off. All three were true when written and stopped being true in August 2026. Labels are bought and stored, tracking is polled from the issuing carrier, and a link can be turned off from the shipment — each is described in its own section below.

Who is responsible for what

There are two kinds of personal data in ShipPilot, and different people are responsible for each. Getting this the wrong way round is the most common mistake in a policy like this one, and it decides where a deletion request has to go.

  • Account data — ShipPilot is the controller. If you signed up, we decide what is collected about you and why. Ask us directly.
  • Recipient and customer data — the workspace is the controller, ShipPilot is the processor. Contacts, addresses, shipments and tracking history are entered by a business using ShipPilot to run its shipping. We store and process that data on that business’s instruction. We do not decide what goes in it, we do not use it for our own purposes, and we never sell it. We do disclose it to the parties needed to run the service: the delivery address goes to the carriers a workspace has connected whenever it asks for prices, it is held by Supabase, which hosts our database, and it passes through Cloudflare in transit. See Where your data lives and What reaches UPS and FedEx.

This is why a recipient’s request goes to the sender. The business chose to keep your address, can identify you as its customer, and can delete the record from its address book. We cannot verify who you are, and acting on an unverified request would mean altering another company’s records on the word of someone we cannot identify — which would be its own breach.

[FOR LEGAL REVIEW: whether a data processing agreement should be annexed to the terms, and whether standard contractual clauses are needed for workspaces outside the United States.]

What we collect about account holders

People who sign up. This is the data ShipPilot controls.

  • Your name and email address. Given at sign-up, or taken from your Google profile. The email address is the identifier for the account and is stored lowercased.
  • A hash of your password, if you signed up with an email address and a password. The password itself is never stored and cannot be recovered from the hash.
  • Whether your email address has been verified, and the short-lived verification codes themselves — which are stored hashed, not in plain text.
  • A profile picture URL, only if you signed in with Google and Google supplied one.
  • Your sessions — including your IP address and browser user-agent string. See Sessions, IP address and user agent.
  • Your workspace membership and role (owner, admin or staff), and any invitations you send — which record the invitee’s email address, the role offered, the status, and who sent it.
  • Your name on records you create. A shipment stores the name of the person who made it, as a copy, so the record still reads correctly if the account is later deleted. If your account has no name set, your email address is stored there instead — the field cannot be empty, and your email is the only other thing we have to identify you by. That copy is deliberately kept when the account is deleted, so deleting your account does not remove it.

We also store settings that belong to the workspace rather than to a person: its name, slug, logo, plan, trial end date, support email address, and its order-number counter.

An activity log. When a member buys or voids a label, deletes a shipment, invites, joins, removes or changes the role of a colleague, or links or unlinks a carrier, one line is written: who (their name or email as it was at that moment, so the line outlives their membership), what, which order or person it concerned, and when — plus the carrier, price or role involved. It is never edited or deleted by the product, and it is readable only by the workspace’s owners and admins, under Settings → Activity. Nothing in it is a label file, a token or a carrier credential.

What there is no place for. The system has no field for a payment card number, a bank account, a government identity number, a date of birth, health data, biometric data, or any other special-category data. This is not a promise about intent — there are no such columns.

What a workspace stores about recipients

These are people who never signed up for ShipPilot: a business’s own customers. The business is the controller; we hold the records for it.

A contact and a saved address are only ever created as a by-product of creating a shipment — there is no screen for adding one directly — so in practice a much narrower set of fields is filled in than the schema allows. Both are listed, because what the schema permits is what a future screen could start writing without this page changing.

  • Contacts — schema: name, email address, phone number, job title, and which client company they belong to. Written today: the name, and nothing else. No recipient email address, phone number or job title is captured anywhere in the product.
  • Saved addresses — schema: an optional label (“Home”, “Main warehouse”), contact name, company, phone, email, street line 1 and 2, city, state, postal code, country, and whether the address is residential. Written today: contact name, company, both street lines, city, state and postal code — the address as typed on the shipment. Phone and email are left empty.
  • Shipments — the order number, status, carrier, service, tracking number, cost, an internal reference and description, the delivery options chosen, and a frozen copy of the full ship-to and ship-from address blocks plus the contact’s name as it was at the time. See Correcting an address does not rewrite past labels.
  • Packages — weight, dimensions, description, declared value, and a per-parcel tracking number. No carrier tracking number is issued in this build.
  • Tracking events — the timeline entries ShipPilot writes itself when a shipment changes state. Carrier scans are not collected: nothing polls a carrier, so this table holds no carrier-supplied location data today. See What is and is not built.

Signing in with Google

Google sign-in is optional. It is only offered when the operator has configured it, and an email address and password always work instead. If you use it, we store from your Google profile:

  • your name;
  • your email address;
  • your profile picture URL, if Google returns one;
  • Google’s own account identifier for you, so the sign-in can be matched next time;
  • the OAuth tokens Google issues for the sign-in itself.

We request nothing beyond basic sign-in, and we deliberately do not request offline access. ShipPilot therefore cannot read your Gmail, your Drive, your calendar or your contacts, and cannot act on your Google account when you are not present. Using this option does tell Google that you have an account with ShipPilot.

Sessions, IP address and user agent

When you sign in we create a session record containing an opaque token, an expiry time, your IP address and your browser’s user-agent string. Both are kept for two reasons and no others:

  • Security. They are what makes an unfamiliar sign-in recognisable, and what lets support answer “where am I logged in?”.
  • Session management. Sessions live in the database rather than in a self-contained token, so a session can be ended on our side at any time instead of staying valid until it expires by itself. What that does and does not mean in practice is set out below.

A session lasts at most 30 days and its expiry is extended at most once a day. Resetting your password deletes every existing session.

A signed-in browser is full access — be plain about this. Two account-level operations, listing your active sessions and unlinking a connected sign-in provider, require a session created in the last 24 hours. Nothing else does. For the life of the session, anyone with access to a signed-in browser can read your shipment and contact data, create shipments, invite or remove members and change their roles, and connect or disconnect carrier accounts. Changing your password requires the current password rather than a recent session. Lock your machine.

Revocation takes effect immediately — but it is not a sign-out.

  • The session itself is checked against the database on every request. Your browser holds no cached copy of it, so a session we delete stops working on the next request rather than at the end of some window. (Better Auth offers a signed short-lived session cookie that would avoid that lookup; it is deliberately switched off here, because one indexed query is not worth a minute of access that cannot be revoked.)
  • Removing someone from a workspace signs them out everywhere. Deleting the membership and deleting every session that person holds happen in the same database transaction — either both or neither. It is every session and not just this workspace’s, because a session record does not reliably say which workspace a browser is looking at. So a removed person is signed out of ShipPilot on every device, on their very next request, including a session they were using for a different workspace they still belong to. This is automatic; it is not a support request.

An honest limit. There is no scheduled job yet that purges expired session rows. The database is indexed for one and it is planned; until it ships, an expired session row — and the IP address and user agent on it — remains until it is cleared by hand.

Cookies

ShipPilot sets three cookies. All of them are first-party, all of them are functional, and there is nothing else.

CookieWhat it doesLife
shippilot.session_tokenProves you are signed in. This is the credential itself.Up to 30 days
shippilot.active_workspaceWhich workspace you are currently looking at.Same as the session
Google sign-in stateSet only while a Google sign-in is in progress, to stop the redirect being forged.Minutes

Every one of them is HttpOnly (no script on the page can read it), SameSite=Lax, scoped to the whole site, and — over HTTPS — marked Secure with a __Secure- name prefix.

There are no analytics cookies, no advertising cookies, no third-party cookies, no tracking pixels, no session recording and no social widgets. There is no cookie banner because there is nothing to consent to: every cookie above is strictly necessary to sign in and stay signed in. Web fonts are served from our own domain, so loading a page does not tell a font provider that you visited.

Where your data lives

These companies receive personal data in the course of running ShipPilot today. The application itself runs on a server we operate, not on a third-party application platform.

CompanyWhat it handlesWhere
SupabaseHosts the Postgres database — every record described on this page, including contacts, saved addresses and shipments.United States (AWS US West, Oregon)
CloudflareDNS, TLS, and the proxy every request passes through — it sees your IP address, the URL you requested and your request headers in transit. Cloudflare R2 also stores the label PDFs a workspace buys, which carry the sender’s and the recipient’s printed address. The bucket is private; labels are served through short-lived signed links, never a public URL.Global edge network
ResendDelivers our transactional email — verification codes, password-reset links, workspace invitations, and the shipment messages described under Email. It receives the recipient’s email address and the contents of that message.United States
AnthropicReads the text an operator pastes into the Copilot, so it can be turned into a shipment draft. It receives that text verbatim and nothing else. Only on deployments where the Copilot is switched on. See What reaches Anthropic.United States
UpstashHolds the Copilot’s usage counters, so the feature can be capped per workspace. It receives a workspace identifier and a count — no message content, no names and no addresses. Only on deployments where the Copilot is switched on.United States
UPS and FedExReceive the shipment details needed to quote a price, including the delivery address. Only the carriers a workspace has connected are contacted. See What reaches UPS and FedEx.United States and the carrier’s own network
StripePayments, once billing is switched on. Starting a checkout creates a customer record there holding the workspace’s name and the account holder’s email address; a card, when one is entered, is entered on Stripe’s page and never reaches us. No live charge is made today. See What is and is not built.United States
GoogleSign-in only, and only if you choose to use it.Google infrastructure

Your data is stored in the United States. [FOR LEGAL REVIEW: the transfer mechanism, if workspaces or recipients in the EEA or the UK are in scope.]

Not connected — nothing is sent to these

The codebase contains libraries for file storage (Vercel Blob), a second AI provider (OpenAI) and background jobs (Inngest). None of them is configured, none holds credentials, and no personal data reaches any of them. They are named here because they are visible in the repository and because this page will be updated before any of them is switched on. Stripe used to be on this list and is now in the table above: the checkout is built, and starting one creates a customer record there, even though no live charge is made yet.

Upstash Redis used to be on this list and no longer is. It now holds the Copilot’s usage counters — how many messages a workspace has sent in the current hour and day, so the feature can be capped. What is stored is a workspace identifier and a number. No message content, no recipient, no address, and nothing that identifies a person. The counters expire on their own within a day.

Diagnostic reports when something breaks

When a page or a background job fails, the application sends a report about the failure to an error-tracking service so we can find and fix it. That service runs on infrastructure we operate ourselves, on the same domain as this site, and it is not a third-party analytics product. No new company receives personal data because of it — the reports pass through Cloudflare, which is already listed above.

A report contains the error and where in the code it happened: the error’s type, its message, the stack trace, which build of the software was running, and the page path with record identifiers removed. Where it helps us work out what went wrong, it also carries the internal identifier of the record involved — a shipment or workspace id, never a name and never an address. Our own log lines leading up to it are included; most of those name only the KIND of failure, and some carry the error’s own message.

What is deliberately stripped out before a report is sent: names, addresses, cookies, anything you typed into a form, the whole of the query string on any URL, and the tokens in a tracking or invitation link. The last one is the reason this is handled in code rather than by policy: a tracking link is a password in the shape of a URL, and an error on the tracking page would otherwise have put a working one in a report.

Your IP address is not sent. A browser does not contact the error-tracking service directly — the report goes to this application first and our server passes it on, so the service sees our address and never yours.

There is no session recording, no screen capture and no replay of what you did. That is a property of how the software is configured, and it is checked by an automated test rather than left as an intention.

Reports are deleted by the error-tracking service on its own schedule — the one place in this system where something is removed automatically rather than by a person. See How long we keep things.

What reaches Anthropic

The Copilot lets an operator paste an order — an email, a message, a note — and turns it into a shipment draft they review before anything is created. Doing that means sending the pasted text to Anthropic, which runs the model that reads it.

  • What is sent — the message the operator typed or pasted, verbatim; the shipment draft as it currently stands; and the last few messages of the same conversation, so a follow-up like “make it three boxes” makes sense. In a typical order that includes a recipient’s name, full street address, and often a phone number and email address.
  • What is not sent — nothing else from our database. No contacts, no saved addresses, no past shipments, no workspace or account identifiers. Only the current conversation goes, never an earlier one, and only its most recent few messages — never the whole chat, however much of it we have stored. Messages we restored for the operator after a refresh count as part of that conversation, so stored text can be sent again on a later day.
  • What the Copilot can do on its own — read a message, edit the draft, check an address with a carrier, and ask carriers for prices. Buying a label and voiding one always stop and ask the operator first; nothing the model produces can complete either without a person pressing a button that names the amount.
  • What we keep — the conversation. The operator’s messages and the Copilot’s replies are stored as text, together with the shipment draft being built from them, filed under the workspace and the operator they belong to so the chat can be given back after a refresh. A pasted order is a customer’s details, so that means recipient names and addresses, and often a phone number and an email address, are in it. The rate list is not kept — a carrier is asked again before any card shows a price — but a price the Copilot mentioned in a reply is part of the reply we store, and the confirmation card itself is never restored. A conversation ends when a label is bought or when the operator starts a new shipment; a finished one is never reopened, and it is not deleted either. See How long we keep things.
  • We do record what each message cost us — how many tokens it used, how long it took, and the price. That’s billing metadata about our own spending: it contains no part of the message, the reply, or the recipient.
  • A thumbs-up or thumbs-down is kept separately as well. Pressing one stores that reply and the rating in a record of its own, so we can see which answers were wrong and improve them. That record holds the reply and the rating and nothing else — not the operator’s message — but a reply often quotes the address back (“I’ve got 123 Main St, Austin TX — is that right?”), so rating one can store a customer’s details. Nothing is kept there unless the button is pressed, and pressing it again deletes the record.
  • Anthropic’s own retention is governed by their terms, not ours.

The Copilot is optional, and it is off unless the operator of this deployment has configured it. Where it is off, no text reaches Anthropic and the shipment form works exactly as it does with it on. Pasted text is treated as data and never as instructions — a message that tries to give the model orders is read for shipping details and nothing more.

What reaches UPS and FedEx

When a workspace asks ShipPilot for prices, we send the shipment to each carrier that workspace has connected, and each returns its own quote. That request necessarily contains the delivery details:

  • About the recipient, to UPS — the name and company as entered on the shipment, and the full street address: address lines, city, state, postal code and country.
  • About the recipient, to FedEx — the full street address, city, state, postal code, country and whether it is residential. The name is not sent.
  • The recipient’s phone number is sent to the carrier when one is entered— a carrier may call about a delivery — and their email address is not. The email address, where a workspace enters one, is used by ShipPilot to send the recipient its own tracking message and for nothing else.
  • About the sender — the ship-from location’s address, and its contact name, phone number and email address where the workspace has set them. That is the workspace’s own data, not a recipient’s.
  • To both — the weight, dimensions and declared value of each parcel, and the delivery options chosen.

There is no way to obtain a real carrier price without disclosing where the parcel is going. If that is not acceptable for a given recipient, the answer is not to rate-shop that shipment here.

Buying a label sends the same details again, and keeps the result. A purchase is a second call to the same carrier with the same shipment, after which the carrier issues a tracking number and returns a label PDF. That PDF has the sender’s and the recipient’s address printed on it; it is stored in Cloudflare R2 and served only through short-lived signed links. Tracking a parcel afterwards sends the tracking number to the carrier that issued it — nothing about the recipient — and stores the scan history the carrier returns.

A workspace’s carrier account number and API credentials are stored encrypted, with a key derived per workspace, so a stored credential is useless outside the workspace it belongs to. See How it is protected.

How long we keep things

These rules are in force. The one thing to know up front is that exactly one kind of record is deleted on a schedule: a Copilot conversation that nobody has touched for ninety days and that never bought a label. Every other deletion below is performed by a person. See What is and is not built.

One more, named so the sentence above stays exact: the error-tracking service described under Diagnostic reports removes old reports on its own schedule. That is the service’s own housekeeping, not a rule about your records, and the reports it deletes have already had personal data stripped out of them before they were sent.

  • Shipments are kept. A purchased label is a financial record. Its address blocks are frozen copies rather than links, so they survive the deletion of the address book entry they were copied from.
  • Contacts and companies can be archived, not deleted. Archiving hides one from the pickers and the lists; the record stays, because the database refuses to delete a contact or a client company that a shipment still refers to, and a shipment has to say who it went to. A contact created by shipping to someone stays until the workspace is deleted or we remove it by hand on request.
  • Shipments without a label can be deleted by the workspace. Once a label has been bought, the record cannot be deleted in the product.
  • Copilot conversations are kept for ninety days of inactivity, then deleted — unless they bought a label. A scheduled job removes any conversation nobody has touched for ninety days that never ended in a purchase, with every message in it; a conversation that did buy a label is part of that shipment’s record and stays with it. Ending a conversation — buying the label, or pressing “Start a new shipment” — only stops it being added to. See What reaches Anthropic for what is in one.
  • Verification codes are short-lived, stored hashed, and destroyed after three wrong attempts.
  • Sessions end at expiry or on revocation — with the caveat about expired rows noted under Sessions.
  • Deleting a user removes their sessions, their sign-in methods, their workspace membership and the invitations they sent. Records they created keep their name as a stored copy — a shipment has to say who made it — and the link to their user account is cleared. Where the account had no name set, that copy is their email address, and it survives the deletion in the same way. This is the one piece of account-holder data that a deletion does not remove. Their Copilot conversations go the other way — a conversation belongs to the operator who had it, so deleting the user deletes those conversations and every message in them rather than leaving them behind without an owner. A conversation with no owner is one nobody can open, and it holds a customer’s pasted details.
  • Deleting a workspace removes everything inside it: shipments, packages, tracking events, contacts, addresses, companies, projects, batches, warehouses, package presets, carrier connections, and Copilot conversations and their messages all cascade. There is no soft-delete column anywhere in the schema, so nothing lingers marked as deleted.

What is not built. There is no self-service “delete my account” or “delete my workspace” button today, and workspace deletion is deliberately disabled in the API because it destroys a company’s entire shipping history in one call. Both are done by writing to [email protected], and are carried out by hand. Apart from the stale Copilot conversations named above, nothing is deleted on a timer — every other deletion described here is something a person performs.

When a workspace closes. Our intention is that a closed workspace’s records stay retrievable for a stated period, so the business can ask us for a copy, and are deleted after it. Neither half is built. There is no export in the product, there is no deletion job, and workspace deletion is disabled in the API — so today a copy and a deletion are both a request to [email protected], done by hand, and we do not commit to a window we have no mechanism to honour. Our terms of service state the same intention in the same terms, and neither document commits to a number.

We have not fixed a retention period for shipment records, or a length for the window above. [FOR LEGAL REVIEW: these are one determination and should be made together — the commercial and tax record-keeping periods that apply in the operating jurisdiction set the retention floor, and the post-closure retrieval window has to sit inside it. Nothing should be committed to in this page or in the terms before a mechanism exists to honour it, and both pages have to change in the same commit.]

Correcting an address does not rewrite past labels

When a shipment is created, ShipPilot takes a copy of the ship-to and ship-from addresses and of the contact’s name, and stores that copy on the shipment itself. The address blocks are frozen. Editing the address book afterwards changes what future shipments use; it does not change the address a past shipment says it went to, and that is deliberate: a shipping record is a record of what was actually sent where, and silently rewriting it would falsify the record and break every reconciliation done against it.

The contact’s name behaves differently, and it is worth being exact. A shipment is displayed with the contact’s name as it reads now, falling back to the stored copy only if the contact has been removed. So renaming a contact does change the name shown against shipments already made. The stored copy is a safety net for a deleted contact, not a freeze. (Today there is no screen for editing a contact, so this is reachable only if one is added — but the display already works this way, and the distinction matters if you are relying on a past record.)

For you, that means correcting an address stops future parcels going to the wrong place but leaves the old address on shipments already made. Removing it from those records means deleting the shipment records themselves — a decision for the business that made them, and one the product does not allow once a label has been purchased.

Your rights

If you have a ShipPilot account

You can ask for access to your data, correction of it, deletion of it, a copy in a portable form, and you can object to or ask us to restrict a particular use. Email [email protected] from the address on the account.

Honestly, about how these are handled today: there is no self-service export and no self-service account deletion in the product. Your name and email address are the ones supplied at sign-up or by Google, and changing them is a support request. Every request above is handled manually by a person. We will confirm receipt and act within the period the applicable law allows.

If a business shipped something to you

Send your request to that business. They are the controller: they decide what to keep, and they can verify that you are who you say you are. If you cannot reach them, email [email protected] with the tracking or order number and we will forward it and confirm that we have. We will not alter or delete a workspace’s records on the instruction of someone we cannot identify as the workspace.

GDPR

Where the GDPR or the UK GDPR applies, the rights above are the rights it grants: access, rectification, erasure, restriction, portability, and objection — plus the right to complain to your supervisory authority. For account data ShipPilot is the controller and answers directly. For recipient and customer data ShipPilot is a processor and acts on the controlling workspace’s instructions.

[FOR LEGAL REVIEW: the lawful basis for each processing purpose, and whether an EU/UK representative is required.]

CCPA and CPRA (California)

The categories of personal information involved are:

  • Identifiers — name, email address, postal address, IP address, account identifiers. A recipient’s delivery address is an identifier and a customer record, not merely commercial information, and is listed here for that reason.
  • Internet or network activity — limited to your own session: the user-agent string of the browser you signed in with, and — only when something fails — the page path you were on, with record identifiers removed, in a diagnostic report. See Diagnostic reports when something breaks.
  • Commercial information — shipment records, and the recipient details a workspace enters.

We do not sell personal information, and we do not share it for cross-context behavioural advertising. There is no advertising technology anywhere in this product. We do not use personal information for profiling or automated decision-making — no such feature exists. The only element that may count as sensitive personal information is your account log-in and password, which are held solely to sign you in and used for nothing else. To exercise a right, email [email protected]; we will not discriminate against you for doing so.

How it is protected

Measures that exist in the code today, not aspirations:

  • Passwords are hashed with scrypt and never stored in a readable form.
  • Verification codes are hashed at rest, expire quickly, and are destroyed after three wrong attempts — the attempt limit, not the length, is what makes a six-digit code safe.
  • Sessions are revocable immediately because they live in the database and are checked there on every request, and every session is deleted when a password is reset. See Sessions.
  • Cookies are HttpOnly, SameSite=Lax and Secure over HTTPS, so a script injected into a page cannot read your session, and a cross-site form cannot use it.
  • Traffic is encrypted in transit, with two honest caveats. TLS runs from your browser to Cloudflare and TLS again from Cloudflare to our server, with HTTP Strict Transport Security set to two years including subdomains. But Cloudflare terminates the first connection and re-encrypts, so Cloudflare can see request contents, not merely the IP address and URL — including form submissions carrying recipient names and addresses. And the final hop, from our web server to the application on the same machine, is plain HTTP over a private network interface rather than TLS. Neither is “end to end”, and we have stopped describing it that way.
  • Browser-side hardening — a Content Security Policy restricting where scripts, styles, images and network connections may come from, framing of the site denied outright, MIME-type sniffing off, a strict-origin-when-cross-origin referrer policy, and camera and geolocation access denied.
  • Records cannot cross workspaces: that half is enforced by the database. Every record carries the id of the workspace that owns it, and every reference between records is a composite foreign key on (record id, workspace id). Postgres refuses to write a row in one workspace that points at a row in another — and it refuses it to a migration, a bulk import and a hand-typed query in a database console just as firmly as to the application.
  • Which workspace a query reads is enforced by application code, not by the database. There is no row-level security policy in this system: a query issued without a workspace filter would return another workspace’s rows, and the database would not stop it. Instead, reads and writes go through a handle that is bound to one workspace and adds that filter itself, so a query is scoped by default and cannot be pointed at a table that has no workspace column without failing to compile. There is one deliberate way out, for the few requests that have no workspace yet — resolving a public tracking token, signing in, a webhook — and it is named unsafeUnscopedDb so that searching for that one word finds every use of it. This makes the correct query the easy one and the wrong one visible in review. It is not a proof, and we do not present it as one.
  • Carrier credentials are encrypted at rest with AES-256-GCM under a key derived separately for each workspace, and the workspace is bound into the encryption itself — so a credential copied out of the database cannot be decrypted in the context of a different workspace.
  • Sign-in requests are origin-checked against a list of our own origins, and Google sign-in requests no scope beyond basic identity.

What we do not claim. ShipPilot has not been through an independent security audit and holds no certification — no SOC 2, no ISO 27001. No system is perfectly secure, and we do not say otherwise.

Email

Verification codes, password-reset links and workspace invitations are delivered through Resend, which receives the recipient’s email address and the contents of the message. It is listed under Where your data lives. We send no marketing email and operate no mailing list — every message is one you or a colleague triggered.

Three messages are about shipments, and two of them go to people with no account. When a workspace buys a label with “email the recipient” switched on for that shipment, the recipient is sent a message saying a package is on the way, with a tracking link, and — when the carrier later reports it delivered — a second message saying so. Both carry the workspace’s name and the destination city, and both are answered to the workspace’s support address, not ours. Neither goes out without that per-shipment switch and a recipient address, and nothing is sent for a shipment whose carrier never reports a delivery. The third message goes the other way: when a carrier flags a delivery as needing attention, the workspace’s owners and admins are emailed the carrier’s own words and a link to the shipment. That one can be turned off for the whole workspace under Settings → Company.

When a message cannot be sent, the failure is recorded in our server log deliberately without the code, without the reset link and without your email address, so a log line cannot be used to take over an account. Nothing falls back to printing a code where a log reader could find it.

Email verification is not enforced at sign-in, deliberately: requiring it would lock out every account created during any period when delivery was misconfigured. If you are locked out, email [email protected].

Children

ShipPilot is a tool for businesses. It is not directed to children, and we do not knowingly collect personal data from anyone under 16 — under 13 in the United States. If you believe a child’s data has reached us through an account, email [email protected] and we will remove it.

A business using ShipPilot may of course ship to an address belonging to a young person. That record belongs to the business, and the routing described under Who is responsible for what applies to it.

Changes to this policy

When this page changes we update the date at the top and describe what changed here. There is no mechanism that notifies you of a change to this page — we can send transactional email, but nothing in the product mails account holders when a policy is revised, so the date at the top is the notice. It is worth checking it before you rely on anything here.

21 September 2026. A workspace activity log was added, and What we collect about account holders now describes it: one line per label bought or voided, shipment deleted, member invited, joined, removed or re-roled, and carrier linked or unlinked — with the member’s name as it was at the time, readable by the workspace’s owners and admins, and never edited or deleted by the product.

20 September 2026. Two shipment messages were added, and the Email section now describes all three. A recipient who was told a package is on the way is now also told when the carrier reports it delivered, under the same per-shipment switch and the same address; and a workspace’s owners and admins are emailed when a carrier flags a delivery, which a workspace can switch off. Resend’s row under Where your data lives now says it carries these too.

27 August 2026. Error tracking was switched on. When something in the application fails, a report about the failure is now sent to an error-tracking service we run ourselves on the same domain as this site — see Diagnostic reports when something breaks for what a report contains and, more to the point, what is stripped out of one before it is sent. Three consequences are recorded here rather than left to be inferred: your IP address is not sent, because the report travels through our own server rather than from your browser; the tokens in tracking and invitation links are removed from every report, because such a link is a credential and an error on the tracking page would otherwise have carried a working one; and the retention section above now names the one thing in this system that is deleted on a schedule rather than by a person. Nothing changed about session recording — there is still none, and there is now a test that fails if that stops being true.

4 August 2026. Corrected. This page previously stated that the database held account records only, that no code read or wrote shipping records, that no carrier was contacted and that no email provider was configured. Each of those was true when written and none had been true for some time: the shipping screens were connected to the database, live rate requests to UPS and FedEx were switched on, and email delivery through Resend was configured, without this page being updated alongside. The subprocessor list now includes Resend and the carriers, and What reaches UPS and FedEx sets out what leaves the system. The description of a 60-second session cookie was also removed: that cache is switched off, so session revocation is immediate rather than delayed.

The same review corrected three further understatements. The summary at the top of this page claimed the account data listed there was “the whole list”; it was not, and it now points at the full one. Where an account has no name set, the copy stored on records that person created is their email address, and it survives deletion of the account — that was not disclosed anywhere and now is. And the recipient fields listed below are separated into what the schema allows and the narrower set anything actually writes, rather than implying every field is populated.

Contact

Privacy questions, and any request under the sections above: [email protected]. For anything commercial, [email protected].

ShipPilot is operated by [LEGAL ENTITY NAME], registered at [REGISTERED ADDRESS]. This policy is governed by the law of [GOVERNING JURISDICTION].

We have not appointed a data protection officer or an EU/UK representative. Privacy requests are handled at the address above. If you are in the EEA or the UK you may also complain to your national data protection authority.

See also our terms of service.

ShipPilot

Shipping, without the busywork.

Legal

UPS® and FedEx® are registered trademarks of their respective owners. ShipPilot is not affiliated with, endorsed by, or sponsored by UPS or FedEx.

© 2026 ShipPilot. All rights reserved.