remarkbox/docs/testing.md
russell@unturf.com 5a10e155bd Add Python client, profile endpoint, and functional test
- remarkbox_client.py: stdlib-only Python client with cookie
  persistence, 3-tier config (args/env/file), CLI mode
- GET/PATCH /api/v1/user/profile: read and update display name
- GET /api/v1/clients/python: serve client for curl/wget download
- functional_test.py: idempotent live test that maintains a
  journey thread documenting each run
- Remove email2 spam honeypot from API (not useful for agents)
- Bump content limit to 500k chars (~128k tokens)
2026-02-01 16:39:19 -05:00

3.4 KiB

Functional Testing the Remarkbox API

Walkthrough for testing every endpoint with curl. Replace REMARKBOX with your deploy URL (e.g. https://my.remarkbox.com).

Read Endpoints

List Threads

curl -s "$REMARKBOX/api/v1/threads?namespace=meta.remarkbox.com" | python3 -m json.tool

Get Thread

# grab the first thread id from the list
THREAD_ID=$(curl -s "$REMARKBOX/api/v1/threads?namespace=meta.remarkbox.com" \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['threads'][0]['id'])")

curl -s "$REMARKBOX/api/v1/threads/$THREAD_ID" | python3 -m json.tool

Get Node

curl -s "$REMARKBOX/api/v1/nodes/$THREAD_ID" | python3 -m json.tool

Anonymous Posting

Requires a namespace with Allow Anonymous Comments enabled.

Create Thread

curl -s -X POST "$REMARKBOX/api/v1/threads" \
  -H "Content-Type: application/json" \
  -d '{
    "namespace": "meta.remarkbox.com",
    "title": "Test thread from curl",
    "data": "Hello from the API.",
    "anonymous_name": "CurlBot"
  }' | python3 -m json.tool

Reply to Thread

curl -s -X POST "$REMARKBOX/api/v1/threads/$THREAD_ID/replies" \
  -H "Content-Type: application/json" \
  -d '{
    "data": "Reply from curl.",
    "anonymous_name": "CurlBot"
  }' | python3 -m json.tool

Authentication (Email OTP)

Request OTP

curl -s -X POST "$REMARKBOX/api/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com"}' | python3 -m json.tool

Verify OTP

Check your inbox for the 6-digit code, then:

curl -s -X POST "$REMARKBOX/api/v1/auth/verify" \
  -H "Content-Type: application/json" \
  -c cookies.txt \
  -d '{"email": "you@example.com", "otp": "123456"}' | python3 -m json.tool

The -c cookies.txt saves the session cookie for subsequent requests.

Create Authenticated Thread

curl -s -X POST "$REMARKBOX/api/v1/threads" \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "namespace": "meta.remarkbox.com",
    "title": "Authenticated thread",
    "data": "Posted with a verified session."
  }' | python3 -m json.tool

Edit a Node

curl -s -X PATCH "$REMARKBOX/api/v1/nodes/$NODE_ID" \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{"data": "Updated content."}' | python3 -m json.tool

Error Cases

Missing namespace

curl -s "$REMARKBOX/api/v1/threads" | python3 -m json.tool
# {"error": "namespace parameter is required"}

Namespace with API access disabled

curl -s "$REMARKBOX/api/v1/threads?namespace=opted-out.example.com"
# {"error": "API access is disabled for this namespace"}

Edit without auth

curl -s -X PATCH "$REMARKBOX/api/v1/nodes/$NODE_ID" \
  -H "Content-Type: application/json" \
  -d '{"data": "nope"}'
# {"error": "Authentication required"}

Python Client

Download the Python client directly from the API:

curl -s "$REMARKBOX/api/v1/clients/python" -o remarkbox_client.py

Or with wget:

wget -q "$REMARKBOX/api/v1/clients/python" -O remarkbox_client.py

Then use it:

from remarkbox_client import RemarkboxClient

client = RemarkboxClient("https://my.remarkbox.com")
threads = client.list_threads("meta.remarkbox.com")
for t in threads["threads"]:
    print(t["title"])

See remarkbox_client.py header comments for full usage.