{
  "schema_version": "2025-03-26",
  "name": "Kepeink Management API",
  "base_url": "https://manage.kepeink.hu",
  "auth": {
    "type": "bearer",
    "header": "Authorization",
    "token_prefix": "kpm_",
    "notes": "Machine API keys are non-expiring and inherit the user's workspace role at creation time."
  },
  "tools": [
    {
      "name": "get_me",
      "method": "GET",
      "path": "/api/v1/me",
      "description": "Read the current user, active workspace, role, billing state, and feature flags.",
      "annotations": { "title": "Get current account", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "list_workspaces",
      "method": "GET",
      "path": "/api/v1/workspaces",
      "description": "List workspaces available to the current user.",
      "annotations": { "title": "List workspaces", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "create_workspace",
      "method": "POST",
      "path": "/api/v1/workspaces",
      "description": "Create a new workspace and browser session.",
      "annotations": { "title": "Create workspace", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": false }
    },
    {
      "name": "switch_workspace",
      "method": "POST",
      "path": "/api/v1/workspaces/switch",
      "description": "Create a browser session pinned to another accessible workspace.",
      "annotations": { "title": "Switch workspace", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "list_tunnels",
      "method": "GET",
      "path": "/api/v1/tunnels",
      "description": "List tunnels in the active workspace.",
      "annotations": { "title": "List tunnels", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "create_tunnel",
      "method": "POST",
      "path": "/api/v1/tunnels",
      "description": "Create a tunnel. Body { target } plus optional backend_mode (proxy|static|ssh, default proxy). The server allocates the public hostname — do not send one; the sni field is an operator-only override. tls_mode must be omitted or 'terminated'; end-to-end TLS has its own endpoint. The response carries the first agent_token in plaintext, returned once and never again.",
      "annotations": { "title": "Create tunnel", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": false }
    },
    {
      "name": "get_tunnel",
      "method": "GET",
      "path": "/api/v1/tunnels/{id}",
      "description": "Read one tunnel in the active workspace.",
      "annotations": { "title": "Get tunnel", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "update_tunnel",
      "method": "PATCH",
      "path": "/api/v1/tunnels/{id}",
      "description": "Update a tunnel's target or backend_mode (proxy|static|ssh). Send only the fields that change. tls_mode must be omitted or 'terminated' — passthrough is rejected here and has its own endpoint. Use toggle_tunnel for enable/disable.",
      "annotations": { "title": "Update tunnel", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "delete_tunnel",
      "method": "DELETE",
      "path": "/api/v1/tunnels/{id}",
      "description": "Retire a tunnel from the active workspace.",
      "annotations": { "title": "Delete tunnel", "readOnlyHint": false, "destructiveHint": true, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "list_tunnel_tokens",
      "method": "GET",
      "path": "/api/v1/tunnels/{id}/tokens",
      "description": "List agent tokens for a tunnel.",
      "annotations": { "title": "List tunnel tokens", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "issue_tunnel_token",
      "method": "POST",
      "path": "/api/v1/tunnels/{id}/tokens",
      "description": "Issue a new one-time agent token for a tunnel.",
      "annotations": { "title": "Issue tunnel token", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": false }
    },
    {
      "name": "revoke_tunnel_token",
      "method": "DELETE",
      "path": "/api/v1/tunnels/{id}/tokens/{token_id}",
      "description": "Revoke an agent token for a tunnel.",
      "annotations": { "title": "Revoke tunnel token", "readOnlyHint": false, "destructiveHint": true, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "list_access_tokens",
      "method": "GET",
      "path": "/api/v1/sessions",
      "description": "List browser sessions and machine API keys owned by the current user.",
      "annotations": { "title": "List access tokens", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "create_api_key",
      "method": "POST",
      "path": "/api/v1/api-keys",
      "description": "Create a non-expiring machine API key with the current user's active workspace role. Browser-session only.",
      "annotations": { "title": "Create API key", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": false }
    },
    {
      "name": "revoke_access_token",
      "method": "DELETE",
      "path": "/api/v1/sessions/{token_id}",
      "description": "Revoke a browser session or machine API key owned by the current user.",
      "annotations": { "title": "Revoke access token", "readOnlyHint": false, "destructiveHint": true, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "list_audit",
      "method": "GET",
      "path": "/api/v1/audit",
      "description": "List audit events visible to the current user.",
      "annotations": { "title": "List audit events", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "list_billing_products",
      "method": "GET",
      "path": "/api/v1/billing/products",
      "description": "List what is for sale, as { one_time, subscriptions }. Entries with credit_bytes or entitlement_days above zero are credit tiers that top up transferable bytes and validity. Entries carrying grants_feature (e.g. e2e_tls) are feature add-ons: they unlock a workspace capability, carry no credit, and move no traffic. feature_granted true means this workspace already holds that capability.",
      "annotations": { "title": "List billing products", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": true }
    },
    {
      "name": "create_checkout",
      "method": "POST",
      "path": "/api/v1/billing/checkouts",
      "description": "Create a hosted checkout URL for a product (hosted by Creem). Requires owner role.",
      "annotations": { "title": "Create checkout", "readOnlyHint": false, "destructiveHint": true, "idempotentHint": false, "openWorldHint": true }
    },
    {
      "name": "redeem_code",
      "method": "POST",
      "path": "/api/v1/billing/codes/redeem",
      "description": "Owner-only. Redeem a credit, feature, or access code against the active workspace. Body { code }. Returns { applied: { credit_bytes?, entitlement_days?, features? }, new_balance_bytes? }. Invalid, expired, exhausted, revoked, and wrong-email codes each return a specific 4xx — do not retry variations of a rejected code.",
      "annotations": { "title": "Redeem a code", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": false }
    },
    {
      "name": "activate_free_trial",
      "method": "POST",
      "path": "/api/v1/free-trial/activate",
      "description": "Human-only free-trial activation requiring reCAPTCHA Enterprise.",
      "annotations": { "title": "Activate free trial", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": true, "_humanRequired": true }
    },
    {
      "name": "get_legal_current",
      "method": "GET",
      "path": "/api/v1/legal/current",
      "description": "Read current legal versions and acceptance state.",
      "annotations": { "title": "Get legal state", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "accept_legal",
      "method": "POST",
      "path": "/api/v1/legal/accept",
      "description": "Record ToS and privacy acceptance for the current user.",
      "annotations": { "title": "Accept legal terms", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "submit_takedown",
      "method": "POST",
      "path": "/api/public/takedown",
      "description": "Submit a public, email-verified takedown report.",
      "annotations": { "title": "Submit takedown report", "readOnlyHint": false, "destructiveHint": true, "idempotentHint": false, "openWorldHint": true }
    },
    {
      "name": "toggle_tunnel",
      "method": "POST",
      "path": "/api/v1/tunnels/{id}/enabled",
      "description": "Enable or disable a tunnel without changing its configuration. Body {\"enabled\": true|false}.",
      "annotations": { "title": "Toggle tunnel", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "get_agent_release",
      "method": "GET",
      "path": "/api/v1/agent-release",
      "description": "Read the current agent release version and download URLs.",
      "annotations": { "title": "Get agent release", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "list_custom_domains",
      "method": "GET",
      "path": "/api/v1/custom-domains",
      "description": "List custom domains in the active workspace.",
      "annotations": { "title": "List custom domains", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "create_custom_domain",
      "method": "POST",
      "path": "/api/v1/custom-domains",
      "description": "Create a custom domain and start DNS verification.",
      "annotations": { "title": "Create custom domain", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": false }
    },
    {
      "name": "get_custom_domain",
      "method": "GET",
      "path": "/api/v1/custom-domains/{id}",
      "description": "Read one custom domain, including verification and certificate status.",
      "annotations": { "title": "Get custom domain", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "verify_custom_domain",
      "method": "POST",
      "path": "/api/v1/custom-domains/{id}/verify",
      "description": "Re-check DNS verification for a pending custom domain.",
      "annotations": { "title": "Verify custom domain", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": true, "openWorldHint": true }
    },
    {
      "name": "update_custom_domain",
      "method": "PATCH",
      "path": "/api/v1/custom-domains/{id}",
      "description": "Update custom domain configuration.",
      "annotations": { "title": "Update custom domain", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "retry_custom_domain_certificate",
      "method": "POST",
      "path": "/api/v1/custom-domains/{id}/retry-certificate",
      "description": "Retry certificate issuance for a custom domain after a prior failure.",
      "annotations": { "title": "Retry custom domain certificate", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": true, "openWorldHint": true }
    },
    {
      "name": "delete_custom_domain",
      "method": "DELETE",
      "path": "/api/v1/custom-domains/{id}",
      "description": "Remove a custom domain from the active workspace.",
      "annotations": { "title": "Delete custom domain", "readOnlyHint": false, "destructiveHint": true, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "get_tunnel_access",
      "method": "GET",
      "path": "/api/v1/tunnels/{id}/access",
      "description": "Read a tunnel's basic-auth/MFA access-gate policy.",
      "annotations": { "title": "Get tunnel access policy", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "update_tunnel_access",
      "method": "PUT",
      "path": "/api/v1/tunnels/{id}/access",
      "description": "Replace a tunnel's access-gate policy. Body {\"mfa_enabled\": true|false}. Enabling MFA requires at least one access user with a TOTP secret already configured.",
      "annotations": { "title": "Update tunnel access policy", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "create_tunnel_access_user",
      "method": "POST",
      "path": "/api/v1/tunnels/{id}/access/users",
      "description": "Add a basic-auth access user to a tunnel's access gate. Body {\"username\": \"...\", \"password\": \"...\", \"totp_secret_b32\": \"...\"}.",
      "annotations": { "title": "Create tunnel access user", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": false }
    },
    {
      "name": "update_tunnel_access_user",
      "method": "PATCH",
      "path": "/api/v1/tunnels/{id}/access/users/{access_user_id}",
      "description": "Update a tunnel access user's username or password.",
      "annotations": { "title": "Update tunnel access user", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "delete_tunnel_access_user",
      "method": "DELETE",
      "path": "/api/v1/tunnels/{id}/access/users/{access_user_id}",
      "description": "Disable a tunnel access user.",
      "annotations": { "title": "Delete tunnel access user", "readOnlyHint": false, "destructiveHint": true, "idempotentHint": true, "openWorldHint": false }
    },
    {
      "name": "request_account_delete",
      "method": "POST",
      "path": "/api/v1/account/delete/request",
      "description": "Request a 6-digit account deletion code by email. Browser session required; kpm_ machine bearer tokens receive 403 Forbidden. Returns {\"challenge_id\":\"...\"} with HTTP 202.",
      "annotations": { "title": "Request account deletion", "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": true, "_humanRequired": true }
    },
    {
      "name": "confirm_account_delete",
      "method": "POST",
      "path": "/api/v1/account/delete",
      "description": "Confirm account deletion with body {\"challenge_id\":\"...\",\"code\":\"123456\"}. Browser session required; kpm_ machine bearer tokens receive 403 Forbidden. Returns 204 No Content.",
      "annotations": { "title": "Confirm account deletion", "readOnlyHint": false, "destructiveHint": true, "idempotentHint": false, "openWorldHint": false, "_humanRequired": true }
    },
    {
      "name": "export_account",
      "method": "GET",
      "path": "/api/v1/account/export",
      "description": "Download all account data as an application/json attachment. Browser session required; kpm_ machine bearer tokens receive 403 Forbidden. Rate-limited to 2/hour per user, then 429.",
      "annotations": { "title": "Export account data", "readOnlyHint": true, "destructiveHint": false, "idempotentHint": false, "openWorldHint": false, "_humanRequired": true }
    }
  ]
}
