Skip to content

Lock your preview link behind a password

An unguessable URL is fine access control right up until someone forwards it. Password protection adds the second layer: same link, but opening it demands a password first.

What you get

A protected drop keeps its normal URL. Visitors land on a password gate instead of your content; submitting the right passphrase sets a 12-hour session cookie on that hostname and the page loads. No visitor accounts to manage, and the password never travels in a URL — it passes in a header, or in a separate message to your recipient. Your call.

This is a paid feature — Pro ($4/mo) and Team ($19/mo) — and every request demands your sp_ API key, which means zero anonymous password deploys. Set the password during publish, add or rotate it later via the API or the drop's dashboard page, or hand off control to an agent via the MCP tools set_drop_password and remove_drop_password.

Be clear-eyed about the threat model: it's one shared password, not individual accounts. You get no per-recipient revocation, no audit trail, and zero way to pull back a page someone already viewed, downloaded or screenshotted. For regulated workloads, set up real SSO — but for "what if someone forwards this link?", a password is exactly the right amount of lock.

Lock down a drop

Lock on deploy

curl -fsS -X POST https://ship.page/deploy \
  -H "Authorization: Bearer sp_your_key" \
  -H "Content-Type: text/html" \
  -H "X-Ship-Password: correct-horse-battery-staple" \
  --data-binary @index.html | jq -r .url

8-128 Unicode characters, at most 512 UTF-8 bytes — passphrases encouraged. URL-encode the header value (spaces and symbols first). The password never appears in the URL or the response.

Add or rotate it later

curl -fsS -X PUT https://ship.page/drops/<slug>/password \
  -H "Authorization: Bearer sp_your_key" \
  -H "Content-Type: application/json" \
  -d '{"password": "a-fresh-passphrase"}'

Rotating bumps the credential version, quietly invalidating every existing visitor session — the next visit asks again. Omitting the password header on a named redeploy leaves the current password in place.

Strip it

curl -fsS -X DELETE https://ship.page/drops/<slug>/password \
  -H "Authorization: Bearer sp_your_key"

Removal always works — even after your subscription lapses, so a lapsed plan can never lock you out of opening a drop back up. Protected reads are never cached, so the change hits on the next request.

The required API key

Everything here demands an active paid plan and an sp_ key — passwords belong to accounts, so anonymous deploys can't use them. Mint a key in the dashboard under Keys, and never put it in client-side code: it is write access to your drops.

One safety guarantee worth noting: if the billing backend can't be reached while you set or rotate a password, the call fails closed — you get a 503, not a silently public drop.

Prompts to run

Prompt

Deploy this report directory to ship.page as a named drop called client-review, and password-protect it using the passphrase I paste next.

Prompt

Rotate the password for my ship.page drop launch-preview and verify that old visitor sessions no longer work.

Prompt

List all my ship.page drops and point out which ones are password protected.

Questions

What does my client see?

The drop URL serves a password screen instead of your content. The right password clears the gate for 12 hours on that hostname via a secure, HttpOnly session cookie — no account, no app, nothing to install. Send the password over a separate channel than the link, or you've built a very elaborate envelope for one letter.

Does the password survive a redeploy?

Yes — on a named drop, redeploy without the password header and the existing password stays put. Pass the header only when you want to set or rotate. Recreating an expired or purged name starts fresh: send the password again.

Can I append files to a protected drop?

Sure, but the append call (POST /deploy/<slug>) flatly rejects a password in the same request — append first, then set or rotate the password afterwards. Dropping a top-level password property into a JSON files body fails too; passwords only travel in the header or the password endpoints.

What happens if my subscription lapses?

Setting new passwords shuts off. Everything else carries on: the drop stays protected through its restore window, and stripping a password is never billing-gated — you can always open a drop back up.

Is this enough for confidential material?

It's a shared password: one credential for all visitors, zero per-person revocation, no audit log, and no taking back anything already viewed or downloaded. It handles "the link got forwarded" — nothing more. If a leak is a genuine security incident rather than an embarrassment, put the page behind your own accounts instead.

Can the password page be framed or scraped?

Protected drops serve frame-ancestors 'none' and never cache, so nobody can wrap the unlock page in an iframe, and protected reads return 401 until a valid unlock. Web scrapers and search engines see zero content — every drop serves noindex, protected or not.

Lock down the next preview you send

Pro is $4/mo — named drops, passwords, no expiry. Wire it once; every deploy can carry a lock.