A Placemoir archive holds a whole Placemoir journal in one file: places, visits, ratings, notes, tags, weather, photos, voice memos and other attachments. Placemoir writes one when you export your journal (You › Export journal), and reads one back under You › Import an archive, or when you open the file from Files, Mail or AirDrop.
The format is public so that anyone, including scripts and AI assistants, can write files Placemoir imports: from Day One, Apple Journal, a spreadsheet, a travel blog or another app's export. This document is the whole contract. The machine-readable version is library-v1.json (JSON Schema 2020-12), and example-library.json is a complete example.
The words MUST, SHOULD and MAY are used as in RFC 2119.
For AI assistants and scripts
Someone has asked you to make a file they can import into Placemoir, an iPhone journal of places they've been and want to go. Follow these steps.
- Read what they gave you. It might be another app's export (Day One, Apple Journal, a spreadsheet), notes, or just a request like "the best coffee in Lisbon". If you can't tell which place, date or rating something belongs to, ask before guessing.
- Write
library.jsonin the format below. It must validate against the schema; if you can run code, check it. - Photos and audio. If the source has them and you can create files, put them in a
media/folder, list each on its visit as an attachment, and ziplibrary.jsonandmedia/together into a file ending in.placemoirarchive(see Writing archives from other apps). If you can't make a zip, hand overlibrary.jsonalone, leave outattachments, and say the photos weren't included. - Hand over the file as a download named after its contents, such as
Lisbon 2025.placemoirarchiveorLisbon coffee.json. Tell the person: save it to the Files app, then open it (a.placemoirarchive) or choose it in Placemoir under You › Import an archive (either kind).
Rules:
- Strict JSON. UTF-8, no comments, no trailing commas, no text before or after the object.
- Don't invent anything. Only real places. Leave out any field you don't know instead of guessing: coordinates, addresses, ratings, dates. A place without coordinates still imports.
- One place per real place. Put every visit to the same place under one place, not one place per visit.
- Use stable ids. Give each place and visit an
id, taken from the source when it has one (a Day One entryuuid, a spreadsheet row id). Then importing the same file again adds nothing new. - Keep their words. Copy the person's own text into
notesas plain text. Turn Markdown or HTML into plain text, keep line breaks, and drop image placeholders. - Dates: keep the source's time and time zone offset when it has them. When there's only a day, write the day alone (
2025-10-30). - Ratings: only when the source has one. Convert other scales to 1–5 in half steps (8/10 → 4, 3 of 4 → 4). Use
goBackonly when the person said whether they'd return. - Categories: pick the closest of
restaurant,cafe,bar,hotel,park,museum,attraction, otherwiseother. Bakeries and dessert shops arecafe; beaches, viewpoints and gardens arepark; galleries aremuseum; shops, markets and anything else areattractionorother. - Want to go: a place they haven't been to yet (a recommendation, a trip plan) has no
visits. It lands on their Want to go list. Put why it's on the list in the place'snotes. - Recommendations you research: only places that exist and are open now, with a full street address. Leave out coordinates you aren't sure of.
If Placemoir refuses the file, it lists each problem with its location, like places[2].visits[0].rating: must be 1 to 5, not 9. Fix exactly those and hand over the file again.
At a glance
Lisbon.placemoirarchive (a ZIP file)
├── library.json the journal, as JSON (required)
└── media/ attachments named in library.json (optional)
├── 0D9E8F7A-…/Photo.jpg
└── fado.m4a
{
"format": "placemoir-library",
"formatVersion": 1,
"places": [
{
"name": "Tasca do Chico",
"category": "bar",
"latitude": 38.7115,
"longitude": -9.1442,
"visits": [
{
"date": "2025-10-30T22:15:00+01:00",
"rating": 4.5,
"goBack": "yes",
"notes": "Fado after 10pm.",
"attachments": [{ "path": "media/fado.m4a" }]
}
]
}
]
}
The file
- Extension:
.placemoirarchive. Uniform Type Identifier:com.tweetingbirds.placemoir.archive(conforms topublic.dataandpublic.archive). MIME type:application/vnd.placemoir.archive+zip. - The file MUST be a ZIP archive (PKWARE APPNOTE 6.3). Entries MUST be stored (method 0) or deflated (method 8), and MUST NOT be encrypted. ZIP64 is supported. Names SHOULD be UTF-8.
library.jsonMUST be at the top level. Placemoir also accepts it inside a single top-level folder (Lisbon/library.json), which is what Finder's Compress makes; then everypathis relative to that folder.__MACOSX/entries are ignored.- Placemoir writes
library.jsonfirst, deflated, and then each attachment stored (photos and audio are already compressed) atmedia/<attachment id>/<file name>. Readers MUST NOT depend on that order or layout. - No attachment may be larger than 1 GB, and
library.jsonno larger than 256 MB.
Without a zip
A library.json on its own (any file name ending in .json) also imports, from You › Import an archive. It can't carry attachments, so it MUST NOT list any. This is the easiest shape for a script or an AI assistant that can't make a zip.
library.json
UTF-8 JSON. Unknown keys are ignored at every level, so a file MAY carry extra data (for example the original app's ids) without harm. Every field below is optional unless marked required. null counts as missing.
Top level
| Field | Type | |
|---|---|---|
format |
string | Required. Exactly "placemoir-library". |
formatVersion |
integer | Required. 1 for this document. |
exportedAt |
date | When the file was made. Shown before importing. |
generator |
string | What made the file, e.g. "Placemoir 1.0 (3) for iOS" or "Day One converter". Shown before importing. |
places |
array of places |
Place
Somewhere you've been or want to go. A place holds its visits.
| Field | Type | |
|---|---|---|
id |
id | |
name |
string | Required, not blank. |
category |
string | restaurant, cafe, bar, hotel, park, museum, attraction or other. Placemoir ignores case, and imports any other value as other. |
address |
string | Street address. |
locality |
string | City or neighbourhood, as shown under the name ("Paris 11e"). |
country |
string | |
latitude, longitude |
number | Decimal degrees, WGS 84. Give both or neither. |
wantToGo |
boolean | On the Want to go list. Defaults to true for a place with no visits and false otherwise. |
notes |
string | About the place itself, such as why you saved it. Notes about a visit go on the visit. |
createdAt |
date | When it was added to the journal. |
visits |
array of visits |
Visit
One time you went: its own date, rating, notes, weather and attachments.
| Field | Type | |
|---|---|---|
id |
id | |
date |
date | Required. When you went, or checked in. |
endDate |
date | Check-out, for stays. Not before date. |
rating |
number | Stars, 1 to 5, in half steps. Other values in range round to the nearest half (4.3 → 4.5). |
goBack |
string | "Would you go back?": yes, maybe or no. Placemoir's Simple rating shows yes as "I'll be back" and no as "Never again". |
notes |
string | Plain text. Line breaks are kept. |
tags |
array of strings | Blank tags are dropped. |
companions |
string | Who you were with, as free text. |
weather |
object | summary (string, "Partly cloudy"), symbol (string, an SF Symbols name such as cloud.sun) and temperatureCelsius (number). All optional. |
isDraft |
boolean | An unfinished entry, shown with drafts. Default false. |
createdAt, updatedAt |
date | Default to date. |
attachments |
array of attachments | In the order they show. |
Attachment
A photo, voice memo, PDF or other file. The bytes live in the archive; this record points at them.
| Field | Type | |
|---|---|---|
id |
id | |
path |
string | Required. Where the file is in the archive, relative to library.json, with / between folders: media/lisbon/tasca.jpg. MUST NOT contain ... A leading ./ is allowed. |
kind |
string | photo, audio, pdf or file. When missing, it comes from the file extension. |
filename |
string | The name shown in the app. Defaults to the last part of path. |
caption |
string | |
duration |
number | Seconds, for audio. |
createdAt |
date |
Photos can be any format iOS reads (JPEG, HEIC, PNG). Placemoir keeps the original bytes and makes its own thumbnail. Audio SHOULD be M4A (AAC) or MP3. Video isn't supported yet; attach it as file if you want to keep it.
Dates
Dates are ISO 8601 strings. Placemoir writes 2026-11-01T18:30:00Z and reads any of these:
| Written as | Means |
|---|---|
2026-11-01T18:30:00Z, 2026-11-01T18:30:00+01:00 |
That moment. |
2026-11-01T18:30:00.250Z |
That moment, with fractions of a second. |
2026-11-01T18:30:00, 2026-11-01T18:30 |
That time, in the time zone of the device importing it. |
2026-11-01 |
Midday on that day, local time, so it never slips into the day before. |
Anything else, such as Nov 1, 2026 or a Unix timestamp, is an error.
Ids
An id is any non-empty string, unique among the places (or visits, or attachments) in the file. Placemoir writes UUIDs. Any other string, such as a Day One entry id, is turned into a UUID the same way every time, so ids from another app keep working across imports.
Give every place and visit an id when you can. It is what makes importing the same file twice safe.
How Placemoir imports
Importing merges: it adds what's new and never changes or removes what's already in the journal.
- A place is already there when it has the same id, or the same name (ignoring case) within 150 m. When either side has no position, the same name is enough. A matched place keeps its own fields, and gains any that were blank (address, locality, country, notes, position, a category other than
other). - A visit is already there when it has the same id. A visit without an id is already there when the same place has a visit within a minute of it with the same notes. Visits already there are skipped, with their attachments.
- An attachment keeps its id unless the journal already uses it, in which case it gets a new one.
- A Want to go place that the file says you've visited (
"wantToGo": falsewith visits) comes off the list.
So restoring a backup into the journal it came from adds nothing, and importing the same file twice adds nothing the second time. To replace a journal instead, use You › Delete all data first.
Before anything is imported, the whole file is checked. If anything is wrong, nothing is imported and Placemoir lists the problems with where to find them:
The library has 2 problems:
• places[0].visits[3].rating: must be 1 to 5, not 9.
• places[2].visits[0].attachments[0].path: “media/IMG_0042.jpg” isn’t in the archive.
Versions
formatVersion changes only when a file written to the new version would be misread by an app that reads the old one. Adding an optional field doesn't change it; readers ignore fields they don't know. Placemoir refuses a file with a formatVersion newer than it supports and asks you to update the app.
| Version | Placemoir | Changes |
|---|---|---|
| 1 | 1.0 | First version. |
Writing archives from other apps
The shortest path from another app is usually: export from that app, have a script or an AI assistant turn its export into library.json, then zip that with the photos.
# library.json and a media/ folder of photos it names, in the current folder:
zip -r -X "Day One.placemoirarchive" library.json media
Or in Python, which AI assistants that run code usually have:
import pathlib, zipfile
with zipfile.ZipFile("Day One.placemoirarchive", "w", zipfile.ZIP_DEFLATED) as archive:
archive.write("library.json")
for file in pathlib.Path("media").rglob("*"):
if file.is_file():
archive.write(file, file.as_posix())
Notes for common sources:
- Day One (JSON export): each entry is a visit. Use
location.placeNamefor the placename,location.latitude/longitudefor its position,creationDatefordate,textfornotes,tagsfortags, and the entry'suuidfor the visitid. Photos are in the export'sphotos/folder, named by theirmd5andtype. Group entries at the same place into one place with several visits. - Apple Journal (exported as HTML pages): each page is an entry. Its date and location become a visit and place, the text becomes
notes, and the images in itsResourcesfolder become photo attachments. - A list of places with no visits (a trip plan): places without
visits. They land in Want to go.
Placemoir's own exports are the best reference for anything this page doesn't cover.