API, MCP & webhooks

Connect SchlüsselBot securely to your software and AI assistant.

Connect Claude or ChatGPT via MCP, or integrate SchlüsselBot using the Business API. You can send messages securely, check their status and withdraw a pending send. Webhooks reliably notify your software of important status changes.

Download OpenAPI 3.1AI product knowledgeRights & copyright
Granular rights Each key receives only the scopes actually required by its application.
Browser-enabled Up to ten exact HTTPS origins can be granted CORS access per key.
Reliable events Webhooks are first queued and automatically retried with controlled handling in case of errors.

Quick start

Create a key in your account under Interface & Webhooks. It will be displayed in full only once. SchlüsselBot stores only its checksum.

curl -X POST https://schluesselbot.de/v1/messages \
  -H "Authorization: Bearer sb_live_XXXXXXXX_…" \
  -H "Idempotency-Key: auftrag-4711-versand-1" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient_email": "empfaenger@firma.de",
    "message": "Zugang: kunde42 / T7!kq2wZ",
    "ttl_hours": 48,
    "sender_name": "Kanzlei Weber"
  }'

For server-to-server calls, the Bearer token is sufficient. External browser applications additionally require an origin approved by the key, for example https://portal.firma.de.

Important for browser applications: CORS prevents calls from unapproved websites, but does not make a JavaScript-built API key secret. Use a narrowly scoped key and protect the application against XSS. For publicly distributed frontend JavaScript, using a dedicated backend as intermediary is the more secure architecture.

MCP for Claude and ChatGPT

SchlüsselBot provides a remote MCP server using Streamable HTTP. In your account, under AI connections, API & webhooks, create a dedicated MCP connection that you can revoke at any time. The simplest setup uses just one link, which you enter as a custom server in Claude, ChatGPT or another compatible MCP client:

https://schluesselbot.de/mcp/sb_mcp_EXAMPLE_<secret>

The example is intentionally not a valid connection. Use only the complete link shown once in your account.

Alternative using an Authorization header

If your client supports custom headers, you can store the server address and secret separately. The MCP key belongs in the Bearer header of every request, never in a query string such as ?token=….

Server:        https://schluesselbot.de/mcp
Transport:     Streamable HTTP
Authorization: Bearer sb_mcp_EXAMPLE_<secret>
ToolFunction
connection_statusCheck the connection and available features without loading content
search_contactsSearch your own encrypted contacts
list_recent_sendsList metadata and status for your recent sends
get_message_statusCheck the status of one of your sends
send_secure_messageSend a secure text message
withdraw_messagePermanently withdraw one of your pending sends
Security boundary of convenient sending: A message you ask an AI assistant to send is first processed by that provider and then briefly reaches SchlüsselBot as plaintext. SchlüsselBot encrypts it in memory for one-time retrieval, but this workflow is not zero-knowledge. For content that neither the AI provider nor SchlüsselBot should technically be able to see, do not use MCP. Use secure sending in the browser and share the secret link yourself.

MCP cannot read secure inbox contents or received messages, modify contacts or attach files. Sent message content also cannot be retrieved later via MCP. The connection link is an access key: enter it directly in the connector settings, do not send it in a chat message and revoke it immediately in your account if it is exposed. SchlüsselBot stores only a checksum of the secret and masks MCP credentials in its web server logs.

Permissions

ScopeAllowed
messages:sendSend messages and already client-side encrypted attachments
messages:readCheck the status of your own API dispatch
messages:withdrawPermanently block and remove an outstanding, own message
contacts:readRead and search your own contacts
contacts:writeCreate, edit, and delete your own contacts

Messages

POST/v1/messagesScope messages:send

/v1/send remains available as a compatible alias. When using automated retries, always use a unique Idempotency-Key. The same key with identical content returns the same response within 24 hours; different content results in HTTP 409.

Two encryption paths: With message, the plaintext briefly reaches the SchlüsselBot memory and is encrypted there. For provider blindness, your application encrypts itself, sends ciphertext, and distributes the key separately using delivery_mode: "separate". A transmitted fragment enables automatic email delivery, but still reaches the server.
FieldRequiredContent
recipient_emailyesRecipient address
messagealternativePlain text up to 256 KB, encrypted on server side in storage
ciphertextalternativeBase64: 12-byte nonce + AES-256-GCM ciphertext + 16-byte tag
fragmentfor automatic delivery32-byte key as 43-character base64url without padding
attachment_ciphertextnoAlready encrypted file container, up to 100 MB of raw data
delivery_modenoautomatic or separate
ttl_hoursno1 to 168; Business default: 168 (7 days)
sender_namenoDisplay name up to 80 characters
personal_notenoEmail note up to 500 characters; external links are removed
notify_emailnoE-Mail for delivery confirmation after retrieval
{
  "id": "8f3c…",
  "link": "https://schluesselbot.de/r/8f3c…#kQ2…",
  "expires_at": "2026-08-20T09:00:00+00:00",
  "modus": "encrypted by the server",
  "delivery": "automatic",
  "mail_sent": true,
  "has_attachment": false
}
GET/v1/messages/{id}Scope messages:read

Returns ready , consumed , withdrawn , expired , or unknown if the safe cannot currently be verified. A failure is never falsely reported as a retrieval.

DELETE/v1/messages/{id}Scope messages:withdraw

First permanently locks the transaction and then removes it from the vault. If physical deletion temporarily fails, the message remains inaccessible and cleanup will automatically be retried.

Contacts

Contact names and email addresses are encrypted in the database using AES-256-GCM. API responses are not cached.

MethodPathScopeFunction
GET/v1/contacts?q=&cursor=&limit=contacts:readSearch and list page by page, up to 100 per page
POST/v1/contactscontacts:write{"name":"Anna","email":"anna@example.de"}
GET/v1/contacts/{id}contacts:readLoad single contact
PATCH/v1/contacts/{id}contacts:writeName or address partially changed
DELETE/v1/contacts/{id}contacts:writeDelete contact

Webhooks

Selectable events: created, consumed, withdrawn, expired, and delivery_failed. SchlüsselBot permanently stores each event prior to the first delivery attempt. An HTTP 2xx response is expected within five seconds. In case of failure, up to eight retries will occur over approximately three days: after 1 minute, 5 minutes, 15 minutes, 1 hour, and then at increasing intervals.

{
  "api_version": "v1",
  "event_id": "consumed:8f3c…",
  "event": "consumed",
  "zeit": "2026-08-19T10:12:33+00:00",
  "daten": {"id": "8f3c…", "mit_anhang": false}
}
X-SchluesselBot-Event: consumed
X-SchluesselBot-Event-Id: consumed:8f3c…
X-SchluesselBot-Delivery: wd_…
X-SchluesselBot-Signature: sha256=<HMAC-SHA256 des unveränderten Roh-Rumpfs>

Verify the signature over the unmodified request body and process event_id idempotently. The secret is shown once upon creation and stored separately by SchlüsselBot, AES-256-GCM encrypted.

// PHP
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $webhookSecret);
if (!hash_equals($expected, $_SERVER['HTTP_X_SCHLUESSELBOT_SIGNATURE'] ?? '')) {
    http_response_code(401); exit;
}

Webhook targets must be publicly reachable, HTTPS, and without redirection. Private, loopback, link-local, documentation, and Tailscale/CGNAT networks are blocked; the resolved public IP is permanently fixed for the actual connection setup.

Errors and limitations