Welcome back

Your shared travel story, in one place.

Flashback

Add some pins to unlock memories ✨

Layers
Status
Who
Kind
Timeline All years
Me
Partner
Together
Wishlist

Travel log

Every place you've been, newest first.

Sort
Who

Gallery

Photos from every pin and trip.

Trips

Group pins into planned, completed, or dreamed-up adventures.

Export CSV
Sort
Who
Status

Countries

Places that have seen your footprints.

Continent
Sort

Settings

Personalise PinDrops for the two of you.

Person A

Name, colour, and this person's private data imports.

📍 Location trail optional not imported

Import this person's Google location history so the map can show a private heatmap of everywhere they've been. ?

no trail uploaded yet

Need help exporting from Google? See Help → Google location history.

⭐ Saved places optional not imported

Import this person's Google Maps "Saved" lists (starred, want to go, favourites…) as a separate map layer.

no saved places yet

Need help exporting? See Help → Google saved places.

Person B

Name, colour, and this person's private data imports.

📍 Location trail optional not imported

Import this person's Google location history so the map can show a private heatmap of everywhere they've been.

no trail uploaded yet

Need help exporting? See Help → Google location history.

⭐ Saved places optional not imported

Import this person's Google Maps "Saved" lists as a separate map layer.

no saved places yet

Need help exporting? See Help → Google saved places.

Shared colours

Map style

Backup

Export or import your entire library as JSON.

Download backup

Photos ?

Imported photos are resized in your browser, then uploaded to the private R2 bucket. Originals stay on your device. Pick how big you want the stored copy to be.

Changing this only affects new imports. Existing photos aren't re-encoded.

AI polish optional ?

Connect an AI provider so you can one-click tidy up journal entries. Your API key is stored in your private database and never sent to the browser.

How to get an API key →
  1. Pick a provider and open its dashboard:
  2. Create an account, add a little bit of credit (a dollar is plenty for journal editing).
  3. Click Create API key, copy it once — you usually can't see it again.
  4. Back here: pick the provider below, paste the key into API key, click Save settings.
  5. Open any travel-log entry → click an entry → write or paste some text → hit ✨ Polish with AI.

Leave model blank for the sensible default per provider (e.g. gpt-4o-mini, claude-haiku-4-5-20251001, deepseek-chat).

No key saved.

Help & how-to

Walkthroughs for the things PinDrops can do. Click any section to expand.

Quick start

  1. Open Settings and set each person's name, colour and (optionally) an AI provider key.
  2. Go to Map, click anywhere to drop a pin, fill in the name, date and which of you it's for.
  3. Your pin shows up on the map, in the Travel log, and counts towards Countries visited.
  4. Group pins into a Trip from the Trips tab to get a single timeline view with legs and a journal.

Everything is private — it's just the two of you behind a shared password.

Plan a multi-stop trip (Tanzania example)

Say you're flying into Kilimanjaro, driving via Arusha and the Serengeti, hopping to Zanzibar and flying home. Here's the flow:

1. Create the trip shell
  1. Go to Trips → New trip.
  2. Name it "Tanzania 2026", set start/end dates, pick who it's for (A, B or both), add a short summary.
  3. Save. You now have an empty trip you can attach pins and legs to.
2. Drop a pin for each stop
  1. Open the Map and click each location in order: Kilimanjaro airport, Arusha, Serengeti camp 1, camp 2, Zanzibar…
  2. For each pin set a date (the day you arrive), who it's for, and choose the trip you just made from the Trip dropdown.
  3. Tip: if you don't know exact coordinates, search by name in the map search box, then click Drop pin here.
3. Connect the stops with legs

A leg is the travel between two pins — a flight, drive, train, ferry or walk. Legs draw lines on the map and build the trip timeline.

  1. Open the trip in Trips.
  2. In the Legs section click Add leg.
  3. Pick the From and To pins, the mode of travel (flight / drive / ferry / etc.), date, and optionally duration or a note.
  4. Repeat for each hop: Kilimanjaro → Arusha (drive), Arusha → Serengeti (drive), Serengeti → Zanzibar (flight), Zanzibar → mainland (ferry), mainland → home (flight).
4. Write as you go
  1. From any pin or the trip view, open Journal and add an entry dated to that day.
  2. Write in plain words — even just bullet points. You can come back later.
  3. When you're home, hit Polish with AI (see the AI polish section below) to turn your notes into a readable diary entry.
5. Shortcuts for faster planning
  • Duplicate as template — in a trip's menu, clone the structure (pins + legs, no journal) to start a similar route.
  • Build from flight confirmation — paste a confirmation email and PinDrops will extract the flights, create airport pins and add the legs for you.

Legs (flights, drives, ferries…)

Legs join two pins and show up as lines on the map and rows in the trip timeline. They're what makes a trip feel like a journey rather than a scatter of dots.

  • Mode controls the line style on the map (dashed for flights, solid for drives, etc.).
  • Date orders the timeline — make sure each leg has the day you actually travelled.
  • Duration and note are optional — handy for recording "6h bus, bumpy" or "overnight sleeper".
  • You can edit or delete legs any time from the trip view.

Bulk-import trips from CSV

If you'd rather plan a whole trip in a spreadsheet (or already have one from another app), use CSV import/export from the Trips tab.

Grab the template first
  1. Click download the template (or open Trips → Import CSV and use the link inside the modal).
  2. Open it in Excel, Google Sheets, Numbers, or any text editor.
  3. It has two complete example trips — Tanzania safari and Japan in spring — so you can see the shape.
The simple format (9 columns, no coordinates needed)

The template uses the simple format, which is as close to "list your trip on a napkin" as possible:

  • typetrip for a trip header row, pin (or stop) for each place you're visiting.
  • trip — the trip name. Every pin in the same trip just repeats the same name here; PinDrops groups them automatically.
  • name — the trip's title on a trip row, or the place name on a pin row (e.g. "Serengeti National Park").
  • start_date / end_date — ISO dates (YYYY-MM-DD).
  • whoa, b, or both. Leave blank to default to both.
  • status — trip row: planned / completed / idea. Pin row: visited / wishlist.
  • mode — on a pin row, how you got there from the previous pin in the same trip. flight / drive / train / bus / boat / walk. The first pin in a trip has no mode (it's where you start).
  • notes — free text.

That's it. No lat/lng, no pin refs, no leg rows. PinDrops figures all of that out.

Geocoding: how "Serengeti National Park" becomes a pin

When you import, the browser sends each place name to OpenStreetMap's Nominatim to look up its coordinates. You'll see a progress line in the preview like "Geocoding 3 / 8: Serengeti National Park".

  • Geocoding is rate-limited to 1 request per second (Nominatim's fair-use policy), so 10 pins takes about 11 seconds.
  • If a place can't be found (e.g. typo, or a vague name like "the beach"), it's flagged in the preview with "could not geocode". You can fix the spelling in your CSV and re-import, or add a country to disambiguate.
  • Adding a country code or country name makes geocoding much more accurate — "Cambridge" is ambiguous, "Cambridge, UK" is not. You can append it to the place name, or add a country column to your CSV.
  • If you already know the coordinates, add lat and lng columns to your CSV and PinDrops will use those instead of geocoding.
Legs are auto-derived — but you can still tweak them after

On the simple format, PinDrops creates a leg from one pin to the next in row order, whenever the second pin has a mode value. So:

pin,Tanzania 2026,Arusha,2026-09-01,2026-09-02,,,,Start
pin,Tanzania 2026,Serengeti,2026-09-03,2026-09-07,,,drive,
pin,Tanzania 2026,Zanzibar,2026-09-10,2026-09-14,,,flight,

…becomes Arusha → Serengeti (drive) → Zanzibar (flight). After import, open the trip and you can edit, reorder or delete legs exactly like any other trip.

Advanced format (what the exporter produces)

If you export your existing trips with Trips → Export CSV, you'll get a richer file with 25 columns: trip_ref, pin_ref, lat, lng, country_code, tags, rating, kind, from_pin_ref, to_pin_ref, and so on. The importer auto-detects that format too — any header containing trip_ref or pin_ref is treated as advanced. This is useful for round-tripping an existing library, tweaking in Sheets, and re-importing.

If you just want to add trips by hand, stick with the simple format — it's a lot less fiddly.

Import it
  1. Go to Trips and click Import CSV.
  2. Pick the file. A preview modal parses it in the browser and shows a tree of every trip, pin and leg it found.
  3. If any pins need geocoding, the preview updates place-by-place as Nominatim returns results.
  4. Warnings (geocode failures, missing names, etc.) are highlighted in amber.
  5. Hit Import. Everything is inserted in a single atomic batch on the server.
Limits & gotchas
  • 500 trips, 5,000 pins and 5,000 legs max per import.
  • Pins without a trip (or whose trip row is missing) import as untripped pins — they show up on the map but aren't attached to any trip.
  • Re-importing the same file creates new trips — this is an add-only tool, not an update-by-id.
  • Spreadsheets sometimes mangle leading zeros or very precise lat/lng when they save — if that happens, save as plain CSV/UTF-8 and avoid letting Excel "auto-format" the lat/lng columns.

Journal & AI polish

Each pin and each trip can have journal entries. They're dated, ordered, and viewable as a full-screen diary.

  1. Write rough notes while travelling — don't worry about style.
  2. In Settings → AI polish, pick a provider (OpenAI, Anthropic or DeepSeek), paste an API key and choose a model.
  3. Open a journal entry and click Polish with AI. The entry is rewritten in your voice but cleaner. Your original is kept too.

Your API key is stored server-side. The browser never sees it after you save it.

Photos & gallery

  • Upload photos to a pin from the pin modal. They're stored in your private R2 bucket and streamed through the site.
  • The Gallery tab shows everything in one grid — click any image for a full-screen lightbox.
  • Photos attached to a trip's pins automatically appear in the trip view.
  • For bulk import of a phone folder, see the next section.

Import a folder of photos (drag & drop)

PinDrops has a fully browser-side import pipeline so you can drop a whole folder of phone photos and have them resized, deduplicated and attached to the right pins automatically.

Why not just use Google Photos?

In March 2025 Google locked the Photos Library API to only show apps their own uploads, so third-party apps can no longer browse your library. The drag-drop importer gives you the same outcome without depending on any Google API that might disappear tomorrow.

How it works
  1. Go to the Gallery tab. You'll see a storage meter at the top (how much of the 10 GB R2 free tier you've used) and a dropzone below it.
  2. Drag a folder of photos anywhere onto the Gallery view, or click Import folder… to pick one.
  3. For each file, in the browser:
    • EXIF is read to grab GPS coordinates and the date/time the photo was taken.
    • HEIC files (iPhone) are converted to JPEG on the fly.
    • The image is resized to the max dimension set in Settings (default 2048 px on the longest edge) and re-encoded as JPEG.
    • A SHA-256 hash of the resized bytes is computed for dedup.
    • Each photo is matched to the nearest pin: within 500 m preferentially, and whose trip dates cover the photo day.
  4. The preview modal lists every file with its thumbnail, the matched pin (if any), and the original → resized size. Untick anything you don't want.
  5. Hit Import selected. The files upload to R2 and the gallery fills up.

Originals never leave your device — only the resized copies are uploaded.

Storage tuning

R2's free tier is 10 GB. At the default 2048 px / JPEG q82, that's roughly 33,000 photos before you start paying Cloudflare anything.

  • Open Settings → Photos to change the max dimension (1600 / 2048 / 2560 / 3200 px) and JPEG quality (70 / 82 / 90%).
  • Smaller max dimension = more photos per GB but less detail when you zoom into the lightbox.
  • Changing these settings only affects new imports — existing photos aren't re-encoded.
  • The storage meter on the Gallery page turns amber at 75% and red at 92% of the free tier so you see it coming.
Dedup and re-runs
  • Each uploaded photo is identified by a content hash, so re-running the importer on the same folder is a no-op — duplicates are recognised and skipped.
  • If the existing photo isn't attached to a pin yet, the dedup path will still attach it to a matching pin on the re-run.
  • This means you can safely import folders that partially overlap (e.g. a shared trip folder that both of you have copies of).
Photos without GPS
  • Screenshots, screen recordings and photos that have been edited in some apps often have their EXIF stripped. Those photos show up in the preview as no GPS in EXIF.
  • Photos with GPS but no pin within 5 km appear as GPS found, no pin within 5 km. Import them anyway and attach them manually later, or create a pin at that location and re-run the importer.
  • HEIC files that heic2any can't decode are marked as errors and skipped — that's rare, usually only on very old iOS exports.

Import Google location history

Turn your phone's Timeline into a private heatmap and trail of visits — just for the two of you.

  1. On your phone, open Settings → Location → Location services → Timeline and choose Export Timeline data. You'll get a Timeline.json file.
  2. Or, use Google Takeout and download Location History (Timeline).
  3. In PinDrops go to Settings → Location trails, pick whose trail it is and upload the file.
  4. Toggle the Trails layer on the map to see it. The trail shows heat density, visited places and activity segments.

Supported formats: old locations array, Records.json, semantic timelineObjects, and the new 2024+ on-device Timeline array.

Import Google saved / starred places

  1. From Google Takeout download SavedStarred places.json (or any saved list as GeoJSON).
  2. In Settings → Saved places upload the file for the right person.
  3. Turn on the Saved places layer from the map filter bar to see gold-star markers.

Filters & layers

  • The chip bar at the top of Map, Travel log, Trips and Countries lets you filter by person, year or continent.
  • Map layers (pins, trips, trails, saved places, heatmap) are multi-select — pick any combination.
  • Collapse the filter panel with the arrow pill if it's in the way; tap it again to bring it back.

Backup & restore

  • Everything lives in your own Cloudflare D1 database and R2 bucket — nothing leaves your account.
  • Settings → Backup → Download backup gives you a full JSON snapshot of pins, trips, legs, journal entries, starred places and trails. Import the same file on another instance to restore.
  • Trips → Export CSV downloads just the trip structure (trips + pins + legs) in a spreadsheet-friendly format. Good for sharing an itinerary or editing in Sheets.
  • Photos are stored in R2; you can back up or mirror the bucket from the Cloudflare dashboard if you want an offline copy of every image.
  • All three formats round-trip: JSON backup ⇄ JSON import, CSV export ⇄ CSV import, and photos are hash-deduped on re-upload.

Tips & shortcuts

  • Click the map to start a new pin at that exact spot.
  • Drag a pin on the map to correct its location.
  • Esc closes any modal.
  • PWA install: from your browser menu choose Install app to add PinDrops to your home screen. It works offline for pages you've already visited.
  • Mobile: the sidebar collapses into a bottom bar automatically — all tabs are still there.