Creating an API Key
Malleable issues two flavors of key, both prefixed mk_live_ followed by 32 bytes of base64url randomness. Personal integration keys live in the agent_api_keys table and are managed from the dashboard's Bring your agents section. Per-client embed keys live in customer_api_keys and are managed from the contact slide-over on a contact record.
Both key types are reveal-once. The full token is shown exactly one time (at the moment of creation) inside an amber callout that reads "Copy this key now, it will not be shown again". After you dismiss that panel, only the preview survives. The preview is the first 12 characters plus the last 4, joined by an ellipsis, e.g. mk_live_aB3x...9zQk. The server never stores the plaintext: the database row holds a SHA-256 hash in key_hash and the truncated key_preview for display.
Personal keys (for your own agent / CLI)
POST /api/integration-keys
{
"name": "Claude Desktop",
"scopes": ["calendar:read", "calendar:write", "tasks:read"]
}
200 OK
{
"key": {
"id": "...",
"name": "Claude Desktop",
"keyPrefix": "mk_live_aB3x...9zQk",
"scopes": ["calendar:read", "calendar:write", "tasks:read"],
"plaintext": "mk_live_aB3xKp...full token shown ONCE..."
}
}Per-contact embed keys (for a client's widget)
Open a contact, expand Embed keys, click Generate new key. The default scope set is ['embed:client'], which authorizes the embed chat and booking endpoints. Each contact can hold many keys; revoked keys remain in the list, line-through, for audit traceability.