Docs
Server API
Everything the SDKs, the report widget and the generator send goes to https://api.hlpd.uk. These are its public endpoints and what they expect.
SDK API
Requests to / carry the app's SDK key and identify the bundle and device:
Authorization: Bearer hk_…
X-Hlpd-Bundle: drink-ios
X-Hlpd-Bundle-Version: 2026.10.12-1
X-Hlpd-Device: 7fQ2kLp9Xc3mVb8N| Endpoint | Purpose |
|---|---|
POST / | OpenAI-style chat completions for the on-device agent, within the app's daily, monthly and per-device limits |
POST / | Analytics events as {"events": [...]}, at most 200 per request |
GET / | Topic order and service-notice pins, optionally for one screen, with ETag support |
GET / | The live published manifest for over-the-air updates, or 204 when none is live |
GET / | One bundle file by content hash |
Event types are topic_view, search, walkthrough_start, walkthrough_complete, chat_question, feedback, suggestion_shown, suggestion_opened and report_filed.
The chat agent runs on the device and the API only gates the language model. The agent uses plain tool calling with search_topics, get_topic, show_topic, show_walkthrough and escalate, with at most 6 tool rounds and 600 tokens per completion.
Reports and tickets
Reports and feature requests are sent as multipart/ to POST /:
| Field | Notes |
|---|---|
project_id | The public project id, brp_… |
title | Required |
kind | bug (default) or feature |
body | The description |
client_id | The device id. Required when attaching files |
classification_level | low, medium (default) or high |
metadata | A JSON object as a string, such as the screen, app version and topics viewed |
attachments | Images, up to 4 files of 5 MB each |
curl https://api.hlpd.uk/api/reports \
-F project_id=brp_your_project \
-F title="Reminders won't stop" \
-F kind=bug \
-F body="They keep buzzing after 10pm." \
-F client_id=7fQ2kLp9Xc3mVb8N \
-F 'metadata={"screen_name": "Settings"}'The response identifies the ticket. reply_token is only returned when the app has public ticket status turned on; keep it to read and reply to the thread.
{
"id": "…",
"ticket_id": "…",
"ticket_url": "https://api.hlpd.uk/tickets/…",
"client_id": "7fQ2kLp9Xc3mVb8N",
"kind": "bug",
"status": "received",
"classification_level": "medium",
"status_visible": true,
"can_reply": true,
"reply_token": "…"
}| Endpoint | Purpose |
|---|---|
GET / | Ticket status and public messages |
POST / | Reply as the reporter with {"reply_token": "…", "body": "…"} |
POST / | Register for reply pushes with {"reply_token": "…", "platform": "apns", "token": "…"}; platform is apns or fcm |
POST / | Stop reply pushes |
GET / | The hosted report form |
GET / | The hosted ticket status page |
When an app has allowed origins, browser requests must come from one of them.
Owner API
The admin, the native admin app and the generator use owner endpoints under /. Native apps and command-line tools open a bearer session, valid for 30 days, with POST / and {"email": "…", "password": "…"}. Coding agents can create an account and first app with POST /; see For coding agents.
| Endpoint | Purpose |
|---|---|
GET / | Your apps |
POST / | Create an app within your plan's app limit |
PATCH / | Bundle id, quotas and store text |
POST / | Create an SDK key |
DELETE / | Revoke an SDK key |
POST / | Upload a bundle as a gzipped tar |
GET / | List uploaded bundles |
PUT / | Choose the live bundle version |
GET / | Chat usage against the app's limits |
GET / | Help analytics; topics and gaps sit alongside it |
GET / | Service-notice pins; PUT replaces them, with ETag |
GET / | Reports across your apps |
GET / reports whether the server is up.
Accounts and email
Owners sign in with an email address and a password. When an account is created, hlpd sends a verification email. The account works straight away; upgrading to a paid plan needs a verified email address.
| Endpoint | Purpose |
|---|---|
POST / | Create an account and first app with {"email": "…", "password": "…", "project": "…"}; see For coding agents |
POST / | Verify the email address with {"token": "…"} from the verification email |
POST / | Send the signed-in owner's verification email again |
POST / | Send a password reset email with {"email": "…"} |
POST / | Set a new password with {"token": "…", "password": "…"} from the reset email |
Run your own server
The server is a FastAPI app with one SQLite database. To deploy it to a Linux host running Caddy:
- Copy
deploy/toenv.example /on the host and fill it in.opt/ hlpd/ server/ .env - Point the API domain at the host. Caddy obtains the certificate.
- Run
deploy/, and again after every change.server.sh user@host
At startup the server creates two accounts if they are missing: a super-admin from HLPD_ADMIN_EMAIL and HLPD_ADMIN_PASSWORD, and an owner from HLPD_OWNER_EMAIL and HLPD_OWNER_PASSWORD.
Verification and password reset emails use these settings:
| Variable | Purpose |
|---|---|
HLPD_MAIL_BACKEND | log writes each email to the server log instead of sending it; ses sends it through Amazon SES |
HLPD_MAIL_FROM | Sender address, which must be a verified SES identity when sending through SES |
HLPD_MAIL_REPLY_TO | Reply-to address |
AWS_REGION | The SES region |
With ses, also provide AWS credentials allowed to send through SES, such as AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
Data lives in the service user's ~/: the SQLite database, uploads and bundle objects.