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_...'| Codes | 6 digits, 10 minutes, single use, 5 wrong tries end a code, 3 codes per email per 15 minutes |
| Session keys | pols_..., 30 days; POST /api/auth/logout revokes one |
| API keys | pol_live_..., from POST /api/keys; work wherever a session key works |
| Website | the osec.one sign-in on this site works on the same routes |
Routes
| GET | /api/public/policies/{id}.md | The 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/consents | Record 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/templates | All templates with their laws and [KEY] placeholders. /api/templates/{slug} for the text. |
| POST | /api/auth | Sign up / sign in with an email code; or swap an API key for a session key. |
| GET POST | /api/projects | List / create projects. GET PUT DELETE /api/projects/{id}; POST /api/projects/{id}/consent-key rotates the key. |
| GET POST | /api/policies | List (?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/themes | Page themes. PUT DELETE /api/themes/{id}. |
| GET | /api/consents | Consent records (?project_id, policy_id, subject). /api/consents.csv for a CSV file. |
| GET POST | /api/keys | Long-lived pol_live_ API keys (max 10, shown once). DELETE /api/keys/{id}. |
| GET DELETE | /api/account | The 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":{}}}'| auth | Sign up or sign in (email → code → session key), or swap an API key. |
| list_templates / get_template | Templates and their placeholders (no sign-in). |
| get_public_policy | A published policy as readers see it (no sign-in). |
| list_projects / create_project / update_project / delete_project | Projects (one per website or app). |
| list_policies / get_policy / create_policy / update_policy / delete_policy | Policies; update_policy with is_active=true publishes. |
| create_policy_from_template | Fill a template's placeholders and create the policy. |
| list_themes / create_theme / update_theme | Page themes: background colour or image, accent, font, width, dark/light. |
| list_consents | Who accepted which version, and when. |
| get_account / create_api_key | The account and long-lived keys. |