Overview
Pagemark API is a lightweight, developer-friendly REST service for managing bookmarks. Built with Flask, it provides a structured way to save URLs, organize them with tags and collections, and find them instantly using a built-in full-text search engine.
The Problem
Web browsers have built-in bookmarking, but they are often silos—hard to search programmatically, difficult to organize with complex metadata, and not easily accessible via API for custom tools or dashboards. Pagemark API provides a standalone, headless service to centralize your "read later" lists and reference links in a way that is easy to integrate into your own workflows.
Core Concepts
- Bookmarks: The primary entity representing a saved URL. Each bookmark includes a title, description, and metadata.
- Tags: Flexible, color-coded labels that can be attached to multiple bookmarks for cross-cutting organization.
- Collections: Named groups used to cluster related bookmarks (e.g., "Project Research" or "Recipes").
- Status Lifecycle: Bookmarks move through states:
ACTIVEfor daily use,ARCHIVEDfor long-term storage, andTRASHEDfor soft-deletion. - Search Index: An in-memory inverted index that allows for instant full-text search across titles and descriptions.
How it Works
The application follows a classic layered architecture designed for maintainability and testability:
- Route Layer: Flask blueprints (in
app.routes) handle HTTP request parsing and response formatting. - Service Layer: The
BookmarkService(a singleton) acts as the central orchestrator. It handles business logic, validation, and coordinates between the repository and the search index. - Repository Layer: The
BookmarkRepositoryabstracts data access. In the current version, this is an in-memory store, but it is designed to be swapped for a persistent database. - Search & Cache: As bookmarks are saved, they are automatically indexed by the
SearchIndexand cached in anLRUCachefor high-performance retrieval.
Use Cases
Creating a Bookmark
You can save a new bookmark by sending a POST request. The service validates the URL and title before persisting it.
# Example using the internal BookmarkService directly
from app.services.bookmark_service import BookmarkService
service = BookmarkService()
bookmark, error = service.create_bookmark({
"url": "https://github.com",
"title": "GitHub",
"description": "Where the world builds software"
})
Searching Your Library
The API supports full-text search that ranks results based on token frequency in the title and description.
# Search for bookmarks containing "python"
curl http://localhost:5000/api/bookmarks/search?q=python&limit=5
Organizing with Tags
Tags can be created and then attached to bookmarks to build a flexible taxonomy.
from app.services.bookmark_service import BookmarkService
service = BookmarkService()
# Create a tag
tag, _ = service.create_tag({"name": "Programming", "color": "blue"})
# The service handles updating the bookmark and invalidating caches
service.update_bookmark(bookmark_id="abc123", data={"tags": [tag.id]})
When to Use / When Not to Use
Use Pagemark API if:
- You need a lightweight backend for a personal bookmarking tool.
- You are prototyping a "read-it-later" application.
- You want a simple, searchable index of links for a small team or internal project.
Look elsewhere if:
- Persistence is critical: The current implementation uses in-memory storage; data is lost when the server restarts.
- Multi-user isolation: There is currently no built-in authentication or user-scoping for data.
- Massive scale: The in-memory search and repository are optimized for thousands, not millions, of entries.
Stack Compatibility
- Language: Python 3.10+
- Framework: Flask 3.0+
- Storage: In-memory (pluggable
BookmarkRepositorypattern) - Search: Custom in-memory inverted index
Getting Started Pointers
- To explore the API structure, see the Routes documentation.
- For details on the data shapes, check the Domain Models section.
- To understand the core logic, read about the BookmarkService.
Limitations
- Volatile Storage: All data is stored in RAM. To persist data, you must implement a database-backed version of
BookmarkRepository. - No Auth: The API is open by default. It is intended to run behind a proxy or on a local network.
- Single Instance: Because the state is in-memory, you cannot scale this horizontally without a shared data store.
FAQ
How do I persist my bookmarks?
Currently, the API resets on every restart. You would need to modify app/db/repository.py to use a database like SQLite or PostgreSQL.
Does it support browser extensions? The REST API is compatible with standard browser extension patterns, but no official extension is provided in this repository.
Can I search by tags? Yes, you can filter the bookmark list by status and retrieve bookmarks associated with specific tags via the service layer.
Is there a UI? This is a headless API. You are expected to build your own frontend or use tools like Postman/cURL to interact with it.
How does the search ranking work?
The SearchIndex uses a simple token-frequency algorithm. It counts how many times your search terms appear in the title and description and sorts the results accordingly.