API and MCP server

Base URL https://policies.biz59.net/api. JSON in and out. Interactive reference: /api/docs. For agents: llms.txt.

Sign up with an email code

The same account as the website sign-in. A new email is signed up on the second call.

curl -X POST https://policies.biz59.net/api/auth -H 'Content-Type: application/json' -d '{"email":"you@example.com"}'
# {"otp_sent": true, "expires_in_seconds": 600, "next": "Call auth again with the same email and the 6-digit otp..."}

curl -X POST https://policies.biz59.net/api/auth -H 'Content-Type: application/json' -d '{"email":"you@example.com","otp":"123456"}'
# {"session_key": "pols_...", "token_type": "Bearer", "expires_at": "...", "new_account": true}

curl https://policies.biz59.net/api/projects -H 'Authorization: Bearer pols_...'
Codes6 digits, 10 minutes, single use, 5 wrong tries end a code, 3 codes per email per 15 minutes
Session keyspols_..., 30 days; POST /api/auth/logout revokes one
API keyspol_live_..., from POST /api/keys; work wherever a session key works
Websitethe osec.one sign-in on this site works on the same routes

Routes

GET/api/public/policies/{id}.mdThe policy as raw markdown. No key. ?v=1.0 for an older version.
GET/api/public/policies/{id}The policy as JSON: markdown, version, theme, published versions. No key.
GET/api/page?pageid={id}The first version's route, unchanged (markdown is base64 when an appcode header is sent).
POST/api/public/consentsRecord accept / withdraw: {policy_id, subject, consent_key, action}. No sign-in; the project's consent key.
GET/api/public/consents/status?policy_id&subject&consent_key → accepted, accepted_version, needs_accept.
GET/api/templatesAll templates with their laws and [KEY] placeholders. /api/templates/{slug} for the text.
POST/api/authSign up / sign in with an email code; or swap an API key for a session key.
GET POST/api/projectsList / create projects. GET PUT DELETE /api/projects/{id}; POST /api/projects/{id}/consent-key rotates the key.
GET POST/api/policiesList (?project_id=) / create policies. GET PUT DELETE /api/policies/{id}.
POST/api/policies/from-template{project_id, template, values, publish} → a policy with the placeholders filled; missing_keys lists the rest.
GET POST/api/themesPage themes. PUT DELETE /api/themes/{id}.
GET/api/consentsConsent records (?project_id, policy_id, subject). /api/consents.csv for a CSV file.
GET POST/api/keysLong-lived pol_live_ API keys (max 10, shown once). DELETE /api/keys/{id}.
GET DELETE/api/accountThe account. GET /api/account/export downloads everything; DELETE ?confirm=<email> erases it all.

Show a policy

Link to https://policies.biz59.net/page?pageid=<id>. Readers can switch dark and light and print. Add &theme=dark to open dark, &v=1.0 for an older version. To collect consent on the page itself, add &subject=<your user id>&ck=<consent key>: it shows an "I agree" button, asks again after a new version, and posts a POLICIES_CONSENT message to the opener or parent frame.

// render it yourself
const md = await fetch("https://policies.biz59.net/api/public/policies/<id>.md").then(r => r.text());

MCP server

Streamable HTTP at https://policies.biz59.net/api/mcp (JSON-RPC 2.0, plain JSON replies). Sign in with the auth tool, then send the session key as a header. Function-calling schema for other agents: /api/mcp/schema.

{
  "mcpServers": {
    "policies": {
      "type": "http",
      "url": "https://policies.biz59.net/api/mcp",
      "headers": { "Authorization": "Bearer pols_..." }
    }
  }
}
curl -X POST https://policies.biz59.net/api/mcp -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_templates","arguments":{}}}'
authSign up or sign in (email → code → session key), or swap an API key.
list_templates / get_templateTemplates and their placeholders (no sign-in).
get_public_policyA published policy as readers see it (no sign-in).
list_projects / create_project / update_project / delete_projectProjects (one per website or app).
list_policies / get_policy / create_policy / update_policy / delete_policyPolicies; update_policy with is_active=true publishes.
create_policy_from_templateFill a template's placeholders and create the policy.
list_themes / create_theme / update_themePage themes: background colour or image, accent, font, width, dark/light.
list_consentsWho accepted which version, and when.
get_account / create_api_keyThe account and long-lived keys.