Skip to main content

Importing Documents

The hister import command collects related import tools under one command. Every import sends documents to a running Hister server.

Hister v0.16.0 uses the standalone hister import-browser command. To import browser history with that release, replace hister import browser in the examples below with hister import-browser. The unified import command is available in rolling builds and stable releases newer than v0.16.0.

Available Import Sources

CommandSourceDefault label
hister import file INPUT...Hister exports, archives, and saved pagesimport
hister import browser [BROWSER] [DB_PATH]Browser history databasesbrowser
hister import linkding INSTANCE_URLA Linkding instance through its HTTP APIlinkding
hister import linkwarden INSTANCE_URLA Linkwarden instance through its HTTP APIlinkwarden
hister import karakeep INSTANCE_URLA Karakeep instance through its HTTP APIkarakeep
hister import shaarli INSTANCE_URLA Shaarli instance through its HTTP APIshaarli
hister import wallabag INSTANCE_URLA wallabag instance through its HTTP APIwallabag

Use the global --server-url and --token flags when the destination Hister server differs from your configured server or requires authentication.

Use --label LABEL with any import source to attach the same label to every imported document. Without this flag, labels stored in imported documents or resumed browser jobs are preserved. The default shown above is applied only when no label was supplied by the user or the imported document.

Hister also limits each batch according to the byte limit advertised by the destination server. Documents are serialized before batching so stored HTML and other large fields are measured accurately. If another HTTP server imposes a smaller limit, Hister splits a rejected batch and retries it automatically. A document that exceeds the limit by itself is reported with its URL, encoded size, and the server limit when known.

Importing Files

Use hister import file with any number of files or directories:

hister import file export.json page.html ~/Downloads/saved-pages

Supported inputs are:

InputBehavior
Hister JSON exportRestores serialized documents without extracting their stored content again
7z archiveReads the first JSON export inside the archive
HTML or HTM pageExtracts the canonical URL and sends the saved page to Hister for processing
DirectoryImports supported files directly inside it in filename order

Directory imports are not recursive. Unsupported files and nested directories are ignored.

The following options apply to file imports:

FlagPurpose
--skip-existingKeep documents whose URL already exists in Hister
--label LABELOverride stored labels and the default import label
--batch-size NSubmit at most 1 through 100 documents per request
--start-date YYYY-MM-DDImport documents added on or after the date
--end-date YYYY-MM-DDImport documents added on or before the date
--globalImport for all users when authenticated as an administrator
--user-id IDImport for one user when authenticated as an administrator

Importing Browser History

Browser history contains URLs and visit information, but it does not contain the page contents. Hister reads the URLs from the browser database and fetches the pages before indexing them.

Automatic Detection

Run the command without arguments to detect supported browser databases in their standard locations:

hister import browser

Automatic detection supports Firefox, Firefox Developer Edition, Zen, Waterfox, Chrome, Chromium, Brave, Vivaldi, Edge, Opera, and Ladybird.

Selecting a Browser or Database

You can provide a browser name, a database path, or both:

# Detect the Firefox database path
hister import browser firefox

# Detect the browser type from a database
hister import browser ~/.mozilla/firefox/example.default/places.sqlite

# Specify both values
hister import browser firefox ~/.mozilla/firefox/example.default/places.sqlite

Firefox stores history in places.sqlite inside its profile directory. Chromium based browsers usually store it in a file named History inside their profile directory.

Use --min-visit N to import only URLs that have at least N recorded visits. Use --start-date YYYY-MM-DD to import only URLs whose most recent recorded visit is on or after that date:

hister import browser --start-date 2025-01-01

The date filter uses timestamps from the browser database. The indexed document timestamp still describes when Hister fetched the page.

Browser history documents receive the browser label by default. Use --label LABEL to replace it. Resumed browser import jobs reuse their stored label unless this flag is supplied again.

Resume and Inspect a Browser Import

Browser imports use persistent crawl jobs named browser-import-YYYY-MM-DD. It is safe to interrupt the process and continue it later. Completed URLs remain completed, pending URLs resume, and failed URLs remain recorded for inspection.

hister crawl list
hister crawl show browser-import-YYYY-MM-DD
hister crawl errors browser-import-YYYY-MM-DD
hister crawl urls browser-import-YYYY-MM-DD

Add --count to hister crawl urls when only the number of tracked URLs is needed. Use --status pending, --status failed, --status done, or --status skipped to filter the rows.

Browser Import Backends

The default HTTP backend is fast, but it cannot execute JavaScript. Select a browser based backend when a site requires client side rendering:

hister import browser --backend chromedp

The supported backends are http, chromedp, and bidi. Backend options, request headers, and cookies can be supplied when necessary:

hister import browser 
  --backend chromedp 
  --backend-option exec_path=/usr/bin/chromium 
  --proxy http://127.0.0.1:8080 
  --header "Accept-Language=en" 
  --cookie "session=abc; Domain=example.com"

The --backend-option, --header, and --cookie flags can be repeated. Use --proxy with an http:// or socks5:// URL. Cookies use Set-Cookie syntax and require a Domain attribute. See Website Crawler for all crawler settings and backend limitations.

Automated requests can be rejected by bot protection, expired sessions, removed pages, or network failures. Failed URLs remain visible through hister crawl errors, but resuming the job does not retry them. Export those URLs into a new URL input job when you want to retry them. See Retrying Failed URLs.

Importing from Linkding

Copy the API token from the Linkding settings page, then store it in the environment before running the import:

export HISTER_IMPORT_LINKDING_TOKEN='your-linkding-token'
hister import linkding https://linkding.example.com

You can use --api-token as a temporary override. The Linkding API token is separate from the global --token flag, which authenticates with the destination Hister server. Prefer the environment variable so the Linkding token does not appear in shell history or process listings.

Incremental Linkding Imports

Every imported Linkding document receives source: linkding metadata. Hister searches for metadata.source:linkding and reads the newest imported document timestamp before calling Linkding. If a previous import exists, the importer supplies that timestamp through the modified_since filter for both active and archived bookmarks. Otherwise, it requests every bookmark.

Deleted Linkding bookmarks are not removed from Hister during an incremental import.

Linkding Data Mapping

Linkding valueHister value
URLNormalized document URL
TitleTitle
Description, notes, and downloaded page contentSearchable text
Added dateAdded timestamp
Modification dateUpdated timestamp
FaviconDocument favicon
Tags, archive state, unread state, sharing, and IDDocument metadata
Archive snapshot and preview image URLsDocument metadata

Records without a URL are skipped because every Hister document requires a URL. Active and archived pagination and batch submission are automatic.

Linkding stores bookmark metadata rather than complete copies of linked pages. Hister therefore downloads every bookmarked page using the configured crawler backend and combines its extracted content with the stored description and notes.

Consult the Linkding API documentation when troubleshooting API access.

Importing from Linkwarden

Create an API token in Linkwarden, then store it in the environment before running the import:

export HISTER_IMPORT_LINKWARDEN_TOKEN='your-linkwarden-token'
hister import linkwarden https://links.example.com

You can use --api-token as a temporary override. The Linkwarden API token is separate from the global --token flag, which authenticates with the destination Hister server. Prefer the environment variable so the Linkwarden token does not appear in shell history or process listings.

Incremental Linkwarden Imports

Every imported Linkwarden document receives source: linkwarden metadata. Before requesting Linkwarden records, Hister searches for metadata.source:linkwarden, sorts the results by update date, and reads the newest document’s updated timestamp.

When a previous result exists, the importer adds an after: filter to the Linkwarden search request so only newer records are fetched. When no previous result exists, it performs a complete import. Repeating the command therefore continues from the most recent Linkwarden import automatically.

Linkwarden Data Mapping

Linkwarden valueHister value
URLNormalized document URL
NameTitle
Description and extracted text contentSearchable text
Import date, then creation dateAdded timestamp
Update dateUpdated timestamp
Tags, collection, source type, and IDDocument metadata

Records without a URL are skipped because every Hister document requires a URL. Pagination and batch submission are automatic.

If a Linkwarden URL record has no extracted text content, Hister downloads the page and extracts its contents before importing it. The configured crawler backend is used for these downloads. The crawler is initialized only when missing content is encountered and is reused for the rest of the import.

Importing from Karakeep

Karakeep was formerly named Hoarder. Create an API key in Karakeep, then store it in the environment before running the import:

export HISTER_IMPORT_KARAKEEP_TOKEN='your-karakeep-token'
hister import karakeep https://karakeep.example.com

You can use --api-token as a temporary override. The Karakeep API token is separate from the global --token flag used for the destination Hister server.

Incremental Karakeep Imports

Every imported Karakeep document receives source: karakeep metadata. Hister searches for metadata.source:karakeep and reads the newest imported document timestamp before calling Karakeep. If a previous import exists, the importer uses Karakeep search with an after: date. Otherwise, it requests every bookmark.

Karakeep applies the after: search qualifier to the bookmark creation date. A bookmark created before the checkpoint and edited afterward might therefore require a complete import to refresh it.

Karakeep Data Mapping

Karakeep valueHister value
Link URL or source URLNormalized document URL
Bookmark title, content title, or filenameTitle
Note, summary, description, and contentSearchable text
Creation dateAdded timestamp
Modification dateUpdated timestamp
Stored faviconDocument favicon
Tags, statuses, source, assets, and IDDocument metadata

For link bookmarks, Hister extracts the stored Karakeep HTML when it is available. If stored HTML is absent or cannot be extracted, Hister downloads the page with the selected crawler backend. Text and asset bookmarks use their stored content when they have a source URL.

Text and asset bookmarks without a source URL are skipped because every Hister document requires a URL. Pagination and batch submission are automatic.

Consult the Karakeep API documentation when troubleshooting API access.

Importing from Shaarli

Copy the API secret from the Shaarli administration page, then store it in the environment before running the import:

export HISTER_IMPORT_SHAARLI_SECRET='your-shaarli-api-secret'
hister import shaarli https://shaarli.example.com

You can use --api-token as a temporary override. For Shaarli, this option accepts the API secret from the administration page. Hister uses the secret to generate a short lived HS512 JWT for each API request. The secret itself is not sent to Shaarli. The global --token flag remains the access token for the destination Hister server.

Incremental Shaarli Imports

Every imported Shaarli document receives source: shaarli metadata. Hister searches for metadata.source:shaarli and reads the newest imported document timestamp before calling Shaarli.

If a previous import exists, Hister requests Shaarli history since that timestamp and retrieves the current value of every created or updated Shaare. Repeated events for the same Shaare are combined. Deleted Shaares are ignored because an import does not remove existing Hister documents. Without a previous result, Hister requests every Shaare.

Shaarli Data Mapping

Shaarli valueHister value
Link URL or text note permalinkNormalized document URL
TitleTitle
Description and downloaded page contentSearchable text
Creation dateAdded timestamp
Update dateUpdated timestamp
Tags, privacy, short URL, note status, and IDDocument metadata

Shaarli stores bookmark descriptions rather than complete copies of linked pages. Hister therefore downloads every ordinary bookmark with the configured crawler backend and combines its extracted content with the stored description. Text notes use their description directly and keep a stable Shaarli permalink, so they are not downloaded.

Pagination and batch submission are automatic. Consult the Shaarli API documentation and Shaarli REST API authentication guide when troubleshooting API access.

Importing from wallabag

Obtain an OAuth access token from wallabag, then store it in the environment before running the import:

export HISTER_IMPORT_WALLABAG_TOKEN='your-wallabag-access-token'
hister import wallabag https://wallabag.example.com

You can use --api-token as a temporary override. The wallabag access token is separate from the global --token flag, which authenticates with the destination Hister server. Prefer the environment variable so the source token does not appear in shell history or process listings.

Incremental wallabag Imports

Every imported wallabag document receives source: wallabag metadata. Hister searches for metadata.source:wallabag and reads the newest imported document timestamp before calling wallabag. If a previous import exists, Hister supplies that timestamp through the wallabag since filter and requests entries in ascending update order. Otherwise, it requests every entry.

Deleted wallabag entries are not removed from Hister during an incremental import.

wallabag Data Mapping

wallabag valueHister value
URLNormalized document URL
TitleTitle
Stored article HTML, or downloaded page contentSearchable text
Creation dateAdded timestamp
Update dateUpdated timestamp
Tags, authors, status values, reading time, and source IDDocument metadata

Hister extracts the article HTML already stored by wallabag and preserves it for offline previews. If the stored content is empty or cannot be extracted, Hister downloads the original URL with the selected crawler backend. Pagination and batch submission are automatic.

Consult the wallabag OAuth documentation and wallabag API methods when troubleshooting API access.

Service Import Options

The following options apply to Linkding, Linkwarden, Karakeep, Shaarli, and wallabag imports:

Service imports preserve favicon data supplied by the source. When it is absent, Hister tries the favicon URL discovered while extracting the linked page, or the conventional /favicon.ico URL when no page icon is available. A favicon download failure does not stop the import.

FlagPurpose
--api-token TOKENOverride the source service credential for this invocation
--backend BACKENDDownload missing content with http, chromedp, or bidi
--backend-option KEY=VALUESet an option for the selected crawler backend
--proxy URLRoute content downloads through an HTTP or SOCKS5 proxy
--header KEY=VALUEAdd a request header when downloading missing content
--cookie COOKIEAdd a cookie when downloading missing content
--skip-existingKeep documents whose normalized URL already exists in Hister
--label LABELOverride the default service source label
--batch-size NSubmit from 1 through 100 documents per request
--start-date YYYY-MM-DDImport documents added on or after the date
--end-date YYYY-MM-DDImport documents added on or before the date
--globalImport for all users when authenticated as an administrator
--user-id IDImport for one user when authenticated as an administrator

For example:

hister import linkwarden https://links.example.com 
	--backend chromedp 
	--backend-option exec_path=/usr/bin/chromium 
	--skip-existing 
  --start-date 2024-01-01 
  --batch-size 25

Linkwarden provides /api/v1/search and Bearer token authentication. Consult the Linkwarden API documentation when troubleshooting API access.