11
HTTP REST API
Scott E. Graves edited this page 2025-08-14 20:02:34 -05:00

HTTP REST API

Authentication

The Repertory HTTP REST API uses hashed passwords for authentication.

Before making requests to any protected endpoint, hash your password using BLAKE2b-384 and provide it according to the API's authentication requirements.

Example in C++:

auto create_password_hash(std::string_view password) -> std::string {
    return utils::collection::to_hex_string(
        utils::hash::create_hash_blake2b_384(password));
}

Example hash for the password repertory:

55427d3dfdce97ef391db56aaf63a3726266777b46df1fa6dbc492093491e7605bd39cf6a88d6ccf4499b9d0de7f78c6

This document reflects the API exactly as implemented in the server code.

  • Bind Address: 127.0.0.1
  • Base Path: /api/v1/
  • Auth: HTTP Basic Auth on every request
  • Content-Type: JSON for successful responses that include bodies; some endpoints return no body on success.
  • Status Codes:
    • 200 OK on success
    • 401 Unauthorized when Basic Auth fails (no JSON body is set by the handler)
    • 404 Not Found for some resource misses (e.g., pin/unpin when path not found)
    • 500 Internal Server Error on unhandled exceptions (JSON body with path and error provided by exception handler)

The server listens on 127.0.0.1:<API_PORT>, where <API_PORT> comes from your runtime configuration (config.json).

🔑 Authentication Configuration

The ApiUser, ApiPassword, and ApiPort settings are stored in your config.json file.
These values are read directly by the server at startup.

Example config.json snippet:

{
  "ApiPassword": "",
  "ApiPort": 10000,
  "ApiUser": "repertory"
}
  • ApiUser → Username for API authentication
  • ApiPassword → Plaintext password (hashed internally during requests)
  • ApiPort → Port number the API server listens on

Endpoints

GET /api/v1/get_config

Return the full (cleaned) configuration JSON for the running mount.

  • Query params: none
  • Response: 200 OK with JSON body (cleaned by clean_json_config); otherwise an error code.
  • Body (success): JSON representing the current config.

Example:

curl -u USER:PASS "http://127.0.0.1:PORT/api/v1/get_config"

GET /api/v1/get_config_value_by_name

Return a single configuration value by key.

  • Query params:
    • name (string, required) — key path, e.g. S3Config.Bucket
  • Response: 200 OK with JSON body; otherwise an error code.
  • Body (success):
    { "value": <clean_json_value> }
    

Example:

curl -u USER:PASS \
  "http://127.0.0.1:PORT/api/v1/get_config_value_by_name?name=S3Config.Bucket"

POST /api/v1/set_config_value_by_name

Set a single configuration value by key.

  • Form params (application/x-www-form-urlencoded):
    • name (string, required)
    • value (string, required)
  • Response: 200 OK with JSON body; otherwise an error code.
  • Body (success):
    { "value": <clean_json_value> }
    

Example:

curl -u USER:PASS -X POST \
  -d "name=HostConfig.ApiPort" \
  -d "value=9981" \
  "http://127.0.0.1:PORT/api/v1/set_config_value_by_name"

POST /api/v1/unmount

Request a clean unmount of the running mount.

  • Params: none
  • Response: 200 OK with no body on success (event unmount_requested is raised internally).
  • Body (success): empty

Example:

curl -u USER:PASS -X POST "http://127.0.0.1:PORT/api/v1/unmount"

GET /api/v1/get_directory_items

List items for a given directory path in the API namespace.

  • Query params:
    • api_path (string, required)
  • Response: 200 OK with JSON body; 404 if path not found is handled by lower layers, otherwise 500 on error.
  • Body (success):
    { "items": <fm_.get_directory_items(api_path)> }
    

Example:

curl -u USER:PASS \
  "http://127.0.0.1:PORT/api/v1/get_directory_items?api_path=/"

GET /api/v1/get_drive_information

Return mount/drive summary.

  • Query params: none
  • Response: 200 OK with JSON body.
  • Body (success):
    {
      "cache_space_used": <bytes>,
      "drive_space_total": <bytes>,
      "drive_space_used": <bytes>,
      "item_count": <integer>
    }
    

Example:

curl -u USER:PASS "http://127.0.0.1:PORT/api/v1/get_drive_information"

GET /api/v1/get_open_files

Return the set of currently open files tracked by the file manager.

  • Query params: none
  • Response: 200 OK with JSON body.
  • Body (success):
    {
      "items": [
        { "path": "<api_path>", "count": <open_count> },
        ...
      ]
    }
    

Example:

curl -u USER:PASS "http://127.0.0.1:PORT/api/v1/get_open_files"

GET /api/v1/get_pinned_files

Return the set of currently pinned files.

  • Query params: none
  • Response: 200 OK with JSON body.
  • Body (success):
    { "items": <provider_.get_pinned_files()> }
    

Example:

curl -u USER:PASS "http://127.0.0.1:PORT/api/v1/get_pinned_files"

GET /api/v1/pinned_status

Return the pinned status for a single file.

  • Query params:
    • api_path (string, required)
  • Response: 200 OK with JSON body; 500 if provider query fails (internal error handling).
  • Body (success):
    { "pinned": true | false }
    

Example:

curl -u USER:PASS \
  "http://127.0.0.1:PORT/api/v1/pinned_status?api_path=/media/movie.mkv"

POST /api/v1/pin_file

Pin a file so it remains cached/available locally.

  • Form params (application/x-www-form-urlencoded):
    • api_path (string, required)
  • Response: 200 OK with no body if the file existed and was pinned; 404 Not Found if the path is not a file; 500 on provider error.
  • Body (success): empty

Example:

curl -u USER:PASS -X POST \
  -d "api_path=/media/movie.mkv" \
  "http://127.0.0.1:PORT/api/v1/pin_file"

POST /api/v1/unpin_file

Unpin a file.

  • Form params (application/x-www-form-urlencoded):
    • api_path (string, required)
  • Response: 200 OK with no body if the file existed and was unpinned; 404 Not Found if the path is not a file; 500 on provider error.
  • Body (success): empty

Example:

curl -u USER:PASS -X POST \
  -d "api_path=/media/movie.mkv" \
  "http://127.0.0.1:PORT/api/v1/unpin_file"

Authentication & Errors

  • Auth check happens before routing; failed auth returns 401 Unauthorized (no JSON body set in that path).
  • Exceptions inside handlers return 500 with a JSON body:
    {
      "path": "/api/v1/<method>",
      "error": "<message or 'unknown error'>"
    }
    

Conventions & Notes

  • api_path is normalized before use.
  • Pin/unpin also raise events (file_pinned / file_unpinned) on success.
  • unmount raises unmount_requested and returns immediately; actual unmount is asynchronous relative to the HTTP request.

🖥️ Example Usage with curl

Hash your password

The API requires the password to be hashed with BLAKE2b-384 before sending.

Example in Linux/macOS (requires b2sum from coreutils):

echo -n "mypassword" | b2sum -l 384 | awk '{print $1}'

Example in Python:

import hashlib
print(hashlib.blake2b(b"mypassword", digest_size=48).hexdigest())

Make an authenticated request

Example: List directory items in /myfolder

curl -u "repertory:$(echo -n 'mypassword' | b2sum -l 384 | awk '{print $1}')"      "http://localhost:10000/api/v1/get_directory_items?api_path=/myfolder"

Example: Pin a file

curl -X POST -u "repertory:$(echo -n 'mypassword' | b2sum -l 384 | awk '{print $1}')"      "http://localhost:10000/api/v1/pin_file?api_path=/docs/file1.txt"

Example: Unmount

curl -X POST -u "repertory:$(echo -n 'mypassword' | b2sum -l 384 | awk '{print $1}')"      "http://localhost:10000/api/v1/unmount"