Назад към всички

shelv

// Convert PDFs into structured Markdown filesystems and hydrate them into your workspace for exploration with standard Unix tools

$ git log --oneline --stat
stars:1,933
forks:367
updated:March 4, 2026
SKILL.mdreadonly
SKILL.md Frontmatter
nameshelv
descriptionConvert PDFs into structured Markdown filesystems and hydrate them into your workspace for exploration with standard Unix tools
version1.0.3
metadata[object Object]

Shelv

Shelv converts PDF documents (contracts, books, research papers, regulations) into structured Markdown filesystems. Upload a PDF, wait for processing, then hydrate the result into your workspace as real files you can explore with ls, cat, grep, and find.

API base URL: https://api.shelv.dev Auth: Authorization: Bearer $SHELV_API_KEY on every request.

Get your API key at shelv.dev → Settings → API Keys.

Core Workflows

1. Upload a document

Upload a PDF to create a new shelf. Processing runs asynchronously.

SHELF_ID=$({baseDir}/scripts/shelv-upload.sh /path/to/document.pdf --name "My Document")

With options:

# Use a structuring template
SHELF_ID=$({baseDir}/scripts/shelv-upload.sh document.pdf --name "Q4 Contract" --template legal-contract)

# Enable review mode (pause before finalizing)
SHELF_ID=$({baseDir}/scripts/shelv-upload.sh document.pdf --review)

# Upload and wait for processing to complete
SHELF_ID=$({baseDir}/scripts/shelv-upload.sh document.pdf --wait)

The script prints the shelf public ID (e.g. shf_0123456789abcdef01234567) to stdout.

Available templates: book, legal-contract, academic-paper. Omit to let Shelv auto-detect structure.

Inline alternative (without the script):

curl -X POST "https://api.shelv.dev/v1/shelves" \
  -H "Authorization: Bearer $SHELV_API_KEY" \
  -F "file=@document.pdf" \
  -F "name=My Document"

Response (201):

{
  "publicId": "shf_0123456789abcdef01234567",
  "name": "My Document",
  "status": "uploading",
  "template": null,
  "reviewMode": false,
  "pageCount": null,
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

2. Poll for processing completion

Wait for a shelf to finish processing:

{baseDir}/scripts/shelv-poll-status.sh shf_0123456789abcdef01234567

The script polls GET /v1/shelves/{id} every 5 seconds and prints the current status. It exits 0 when the shelf reaches ready or review, and exits 1 on failed (with error details) or timeout (10 minutes).

Processing flow: uploadingparsingstructuringverifyingready

If review mode is enabled, the flow pauses at review instead of ready.

Inline alternative:

curl -s "https://api.shelv.dev/v1/shelves/$SHELF_ID" \
  -H "Authorization: Bearer $SHELV_API_KEY" | jq '.status'

3. Hydrate a shelf into the workspace

Download and extract the shelf's Markdown filesystem into your workspace:

{baseDir}/scripts/shelv-hydrate.sh shf_0123456789abcdef01234567

This downloads the archive, verifies its checksum, and extracts it to ~/.openclaw/workspace/shelves/<name>/. The script prints a file listing after extraction.

Override the directory name:

{baseDir}/scripts/shelv-hydrate.sh shf_0123456789abcdef01234567 --name my-contract

Replace an existing shelf (required if the directory already exists):

{baseDir}/scripts/shelv-hydrate.sh shf_0123456789abcdef01234567 --force

After hydration, explore the files:

ls ~/.openclaw/workspace/shelves/my-contract/
cat ~/.openclaw/workspace/shelves/my-contract/README.md
find ~/.openclaw/workspace/shelves/my-contract/ -name "*.md"
grep -r "force majeure" ~/.openclaw/workspace/shelves/my-contract/

4. List and browse existing shelves

List all shelves:

curl -s "https://api.shelv.dev/v1/shelves?page=1&limit=20" \
  -H "Authorization: Bearer $SHELV_API_KEY" | jq '.data[] | {publicId, name, status}'

Get the file tree (flat JSON map of path → content):

curl -s "https://api.shelv.dev/v1/shelves/$SHELF_ID/tree" \
  -H "Authorization: Bearer $SHELV_API_KEY" | jq '.files | keys[]'

Response shape:

{
  "shelfPublicId": "shf_0123456789abcdef01234567",
  "name": "My Contract",
  "fileCount": 8,
  "files": {
    "README.md": "# My Contract\n...",
    "clauses/force-majeure.md": "# Force Majeure\n..."
  }
}

5. Read individual files without hydration

Read a single file by path (useful for targeted lookups without downloading the full archive):

curl -s "https://api.shelv.dev/v1/shelves/$SHELF_ID/files/README.md" \
  -H "Authorization: Bearer $SHELV_API_KEY"
curl -s "https://api.shelv.dev/v1/shelves/$SHELF_ID/files/clauses/force-majeure.md" \
  -H "Authorization: Bearer $SHELV_API_KEY"

Returns raw Markdown content (text/markdown).

Workspace Conventions

Hydrated shelves live at:

~/.openclaw/workspace/shelves/{name}/

The {name} is derived from the shelf's display name (lowercased, spaces and special characters replaced with hyphens). Override with --name when hydrating.

If a directory already exists at the target path, the script will refuse to overwrite it unless --force is passed.

After hydration, use standard Unix tools to explore:

# List all files
find ~/.openclaw/workspace/shelves/{name}/ -type f

# Read a specific file
cat ~/.openclaw/workspace/shelves/{name}/README.md

# Search across all files
grep -r "keyword" ~/.openclaw/workspace/shelves/{name}/

# Count files
find ~/.openclaw/workspace/shelves/{name}/ -type f | wc -l

Async Operations

Shelf processing is asynchronous. After uploading, the shelf progresses through:

uploading → parsing → structuring → verifying → ready

Use the poll script to wait for completion:

{baseDir}/scripts/shelv-poll-status.sh $SHELF_ID

If the shelf reaches failed, the error message and failed step are printed. You can retry:

curl -X POST "https://api.shelv.dev/v1/shelves/$SHELF_ID/retry" \
  -H "Authorization: Bearer $SHELV_API_KEY"

For review mode shelves, approve to finalize:

curl -X POST "https://api.shelv.dev/v1/shelves/$SHELF_ID/approve" \
  -H "Authorization: Bearer $SHELV_API_KEY"

Or regenerate the structure:

curl -X POST "https://api.shelv.dev/v1/shelves/$SHELF_ID/regenerate" \
  -H "Authorization: Bearer $SHELV_API_KEY"

Status-Gated Endpoint Matrix

Not all endpoints are available in every status. The archive, tree, and file endpoints require ready or review:

EndpointProcessingreviewreadyfailed
GET /v1/shelves/{id}YesYesYesYes
GET .../treeNoYesYesNo
GET .../files/*NoYesYesNo
GET .../archive-urlNoYesYesNo
POST .../approveNoYesNoNo
POST .../regenerateNoYesNoNo
POST .../retryNoNoNoYes

A 409 Conflict is returned if you call an endpoint outside its allowed statuses.

Rate Limits

ScopeLimit
Reads (GET)120 requests / min
Writes (POST/DELETE)20 requests / min
Shelf creation10 / hour

On 429 Too Many Requests, back off and retry after the indicated period.

Reference Pointers

For detailed API documentation, error codes, and lifecycle diagrams, see:

  • {baseDir}/references/api-reference.md — Full endpoint docs and response shapes
  • {baseDir}/references/shelf-lifecycle.md — Status flow, review mode, template behavior
  • {baseDir}/references/error-handling.md — Error codes, retry strategies