Skip to main content

Pagemark API

Pagemark is a simple, self-contained REST API for managing bookmarks. It provides endpoints to save, tag, search, and organize URLs, making it a ready-to-use backend for any bookmarking application you want to build.

Why Pagemark Exists

Building a backend for a content-saving application involves a lot of repetitive work: creating CRUD endpoints, handling relationships between items and tags, and implementing a search feature. If you're building a browser extension, a "read-it-later" app, or just a personal link organizer, you have to solve these problems before you can even start on your unique features.

Pagemark provides a clean, feature-rich API for bookmark management so you can focus on the client-side experience. It offers a solid foundation with bookmarks, tags, collections, and full-text search, letting you skip the boilerplate and get straight to building.

The easiest way to think about Pagemark is as a filing cabinet for URLs. Everything you save is organized around three core concepts:

  • Bookmarks: The fundamental item in your cabinet. A bookmark is more than just a URL; it's a record with a title, description, and status (like active or archived).
  • Tags: Think of these as sticky notes or labels you can attach to any number of bookmarks. A single bookmark can have multiple tags, helping you create flexible, overlapping categories (e.g., python, api-design, reading-list).
  • Collections: These are the folders in your filing cabinet. A collection is a named group of bookmarks. They can be manual (you add bookmarks one by one) or smart (automatically populated by a search filter, like a folder for everything tagged python).

How It Works

Pagemark is a standard Flask application with a layered architecture. When a client sends an HTTP request, it flows through these layers:

  1. Routes: Flask endpoints receive the request (e.g., POST /api/bookmarks) and handle the HTTP-specific details.
  2. Service Layer: The core business logic lives here. It validates input, orchestrates operations (like adding a bookmark and updating the search index), and ensures data consistency.
  3. Repository Layer: This layer abstracts the data storage. It provides a simple, in-memory dictionary-based store for bookmarks, tags, and collections.
  4. Models: These are the plain Python data classes (Bookmark, Tag, Collection) that represent the concepts in the system.

Common Use Cases

Here are a few examples of how to interact with the API using curl. The server runs on http://localhost:5000.

Save a new bookmark

When you find a URL you want to save.

curl -X POST http://localhost:5000/api/bookmarks \
-H "Content-Type: application/json" \
-d '{
"url": "https://flask.palletsprojects.com/",
"title": "Flask Documentation",
"description": "The official docs for the Flask web framework."
}'

List all your bookmarks

When you want to see everything you've saved.

curl http://localhost:5000/api/bookmarks

Search for a bookmark

When you remember a keyword but not the exact title or URL.

curl http://localhost:5000/api/bookmarks/search?q=flask

Create a collection

When you want to group related bookmarks together.

curl -X POST http://localhost:5000/api/collections \
-H "Content-Type: application/json" \
-d '{"name": "Python Frameworks"}'

When to Use Pagemark

Pagemark is a great fit if you are:

  • Prototyping a front-end application that needs a realistic but simple backend for managing content.
  • Building a personal tool, like a browser extension or a command-line utility for saving links.
  • Learning Flask by studying a complete, well-structured example application.

When to Look for Alternatives

Pagemark is likely not the right tool if you need:

  • Persistent storage: Pagemark uses an in-memory database, meaning all data is lost when the server restarts.
  • User accounts and authentication: The API is open and has no concept of users, roles, or permissions.
  • Large-scale deployment: The in-memory architecture is not designed to scale across multiple instances or handle millions of records.

Integration

Pagemark is a standalone web service. You can interact with it from any application that can make HTTP requests:

  • Web: JavaScript frontends (React, Vue, etc.) using fetch or axios.
  • Mobile: Native or cross-platform apps.
  • Backend: Other services on your network.
  • CLI: Command-line tools written in any language.

The application itself is written in Python and built with Flask. It has no external service dependencies.

Getting Started

  1. Install dependencies:
    pip install -r requirements.txt
  2. Run the server:
    python run.py

The API will be available at http://localhost:5000.

Limitations and Assumptions

  • In-Memory Storage Only: All data is ephemeral and will be cleared on server shutdown. This is by design to keep the project simple and dependency-free.
  • No Authentication: There is no security or user management. All endpoints are publicly accessible.
  • Single-Instance Design: The service is stateful and intended to be run as a single process. It is not designed for horizontal scaling.
  • Basic Search: The full-text search is based on a simple in-memory inverted index and does not support complex queries or ranking algorithms.

Frequently Asked Questions

Is the data persistent? No. Pagemark uses an in-memory store, which means all bookmarks, tags, and collections are lost when the application stops. It is designed for prototyping and local development.

How do I add user accounts? The API does not include user management or authentication features. You would need to fork the project and build this functionality yourself, likely by adding a user model and integrating an authentication library.

Can I connect it to a real database like PostgreSQL or SQLite? Not out of the box. To use a persistent database, you would need to replace the in-memory BookmarkRepository class with a new implementation that uses a library like SQLAlchemy to communicate with your database.

What are "smart collections"? A smart collection is a group of bookmarks that automatically updates based on a filter rule. For example, you can create a smart collection with the rule "python" that will always contain every bookmark with the word "python" in its title or description.

How do I add a bookmark to a collection? First, create a bookmark and a collection. Then, make a PUT request to /api/collections/<collection_id>/bookmarks with a JSON body containing the bookmark_id.