shelff JSON Specification
shelff stores metadata and reading progress for PDF files as JSON files in iCloud. This page describes the specification of the JSON files that shelff reads and writes.
shelff manages its data through these JSON files. Other tools can interoperate with shelff by reading and writing the same files.
Overview
shelff uses three types of JSON files.
| File | Location | Purpose |
|---|---|---|
*.pdf.meta.json |
Same directory as the PDF | Per-PDF metadata, reading progress, and display settings |
categories.json |
shelff document root | Category definitions and ordering |
tags.json |
shelff document root | Tag display order |
The metadata file (*.pdf.meta.json) is automatically created when a PDF is first opened in shelff. At that point, dc:title is set to the filename.
All files use UTF-8 encoding. Dates are recorded in ISO 8601 format.
Metadata File *.pdf.meta.json
A metadata file corresponds to a single PDF file. It is stored in the same directory as the PDF, with .meta.json appended to the original filename.
Example: my-book.pdf → my-book.pdf.meta.json
Example
{
"schemaVersion": 1,
"metadata": {
"dc:title": "Introduction to Programming",
"dc:creator": ["Jane Smith"],
"dc:publisher": "Tech Press",
"dc:date": "2024",
"dc:language": "en",
"dc:subject": ["Programming", "Introduction"],
"dc:identifier": "978-0-00-000000-0"
},
"reading": {
"lastReadPage": 42,
"totalPages": 300,
"lastReadAt": "2025-03-20T14:30:00Z",
"status": "reading",
"finishedAt": null
},
"display": {
"direction": "LTR",
"pageLayout": "spread-with-cover"
},
"category": "Technical",
"tags": ["Swift", "Beginner"]
}
Top-level Fields
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion |
Integer | Yes | Schema version. Currently 1 |
metadata |
Object | Yes | Bibliographic metadata (see below) |
reading |
Object | No | Reading progress (see below) |
display |
Object | No | Display settings (see below) |
category |
String | No | Category name (one per PDF) |
tags |
Array of strings | No | Tag names |
metadata Object
Bibliographic metadata. Field names use dc:-prefixed keys based on Dublin Core Metadata Terms.
| Field | Type | Required | Description |
|---|---|---|---|
dc:title |
String | Yes | Title |
dc:creator |
Array of strings | No | Author(s) |
dc:date |
String | No | Date. "2024", "2024-06", and "2024-06-15" are all valid |
dc:publisher |
String | No | Publisher |
dc:language |
String | No | Language code (e.g., "ja", "en") |
dc:subject |
Array of strings | No | Subjects / keywords |
dc:identifier |
String | No | Identifier (e.g., ISBN) |
reading Object
| Field | Type | Required | Description |
|---|---|---|---|
lastReadPage |
Integer | Yes | Last read page number (1-based) |
totalPages |
Integer | Yes | Total number of pages |
lastReadAt |
String | Yes | Last read timestamp (ISO 8601) |
status |
String | No | Reading status: "unread" / "reading" / "finished" |
finishedAt |
String | No | Completion timestamp (ISO 8601) |
display Object
| Field | Type | Required | Description |
|---|---|---|---|
direction |
String | Yes | Reading direction: "LTR" (left-to-right) / "RTL" (right-to-left) |
pageLayout |
String | No | Page layout: "single" / "spread" / "spread-with-cover" |
Categories File categories.json
Stored in the shelff document root, this file defines the available categories. Each PDF can belong to at most one category.
Example
{
"version": 1,
"categories": [
{ "name": "Technical", "order": 0 },
{ "name": "Fiction", "order": 1 },
{ "name": "Papers", "order": 2 }
]
}
| Field | Type | Description |
|---|---|---|
version |
Integer | Schema version. Currently 1 |
categories |
Array | Array of categories. Each element has name (string) and order (integer, 0-based) |
Tags File tags.json
Stored in the shelff document root, this file defines the display order of tags. Tags themselves are defined in the tags field of each PDF's metadata file. This file only manages display ordering.
Example
{
"version": 1,
"tagOrder": ["Swift", "SwiftUI", "Programming", "To Read"]
}
| Field | Type | Description |
|---|---|---|
version |
Integer | Schema version. Currently 1 |
tagOrder |
Array of strings | Tag display order. Tags not in this array are appended in name order |
JSON Schema
Formal JSON Schema definitions for each file format are available in the following repository.