TrekMail TrekMail

Safety Rails and Delete Intents

How two-step delete intents, rate limits, and audit logging protect against accidental data loss.

Article details

Type, difficulty, plans, and last updated info.

Type
Reference
Difficulty
Intermediate
Plans
Starter · Pro · Agency
Last updated
Apr 29, 2026

The TrekMail API is designed to prevent accidental data loss. Destructive operations require multiple confirmation steps, rate limits prevent bulk mistakes, and every action is logged.

Two-step delete (delete intents)

Mailbox deletion and domain deletion are the most impactful destructive operations in the API. It uses a two-step process:

Step 1: Create a delete intent

POST /api/v1/mailboxes/{id}:delete-intent

This creates a time-limited intent that describes what will be deleted. The response includes:

  • Risk flags — warnings about forwarding rules, aliases, or active migrations that will be affected.
  • Expiration — the intent expires after 10 minutes. After that, you must create a new one.
  • Confirm URL — the URL to call for Step 2.

No data is deleted at this stage.

Step 2: Confirm the intent

POST /api/v1/delete-intents/{id}:confirm
Headers: X-Confirm-Delete: true

This executes the deletion. The mailbox is marked as deleting, email data is queued for removal, and the address is retired so it cannot be reused.

The X-Confirm-Delete: true header is required as an additional safety check.

Risk flags

When you create a delete intent, the API checks for conditions that might indicate you do not want to proceed:

Flag Meaning
has_active_forwarding The mailbox has forwarding enabled — other addresses depend on it.
has_aliases Virtual aliases route email to this mailbox.
has_active_migration A migration is currently importing email into this mailbox.

Review these flags before confirming. The API does not block confirmation based on risk flags — they are informational only.

Rate limits on destructive operations

Destructive operations have two layers of rate limiting beyond the standard per-minute API rate limit:

  • Daily limit per token — Each token can confirm a limited number of delete intents per day.
  • Cooldown between confirms — After confirming one delete, there is a short cooldown before the next confirmation is accepted.

Both return 429 Too Many Requests with a Retry-After header when triggered.

MCP destructive operations gate

The MCP server adds another layer. Delete tools are disabled by default and require the TREKMAIL_ALLOW_DESTRUCTIVE=true environment variable.

With destructive operations disabled:

  • create_delete_intent returns an error explaining how to enable it.
  • confirm_delete_intent returns an error explaining how to enable it.
  • delete_cloudflare_token returns an error explaining how to enable it.

All other tools (read, create, forwarding, invites) work regardless of this setting.

Idempotency

All mutating API requests (POST, PUT) require an Idempotency-Key header. This prevents duplicate operations when requests are retried:

Idempotency-Key: create-mailbox-alice-2024
  • Same key + same body = replayed response (no side effects).
  • Same key + different body = 409 Conflict.
  • Different tokens use independent key spaces.

The MCP server generates deterministic idempotency keys automatically from sha256(tool_name + params), so agent retries are always safe.

Sending safety gates

Email sending through the MCP server has its own dual-gate safety design, similar to the destructive operations gate but with two independent checks:

Gate 1: Environment gate

Set TREKMAIL_ALLOW_SENDING=true in the MCP server environment to enable the send_message tool. Without this variable (or with it set to false), the tool returns an error explaining how to enable sending.

Gate 2: Per-call confirmation

Even with the environment gate enabled, each send_message call must include confirm_send=true as a parameter. Without it, the tool returns an error asking the agent to confirm.

Why two gates?

The environment gate is set once by the administrator who configures the MCP server. The per-call gate requires the agent to actively decide to send on every individual email. Neither gate alone is sufficient — both must pass before any email leaves the server.

This prevents accidental sends from agents that explore available tools without understanding their consequences. An agent can list and read messages freely (with a message token), but it cannot send unless both safety gates are satisfied.

Migration safety gates

Email migration through the MCP server has its own safety gates, similar to sending and destructive operations.

Migration environment gate

Set TREKMAIL_ALLOW_MIGRATION=true in the MCP server environment to enable migration write tools (start_migration, retry_migration, delete_migration). Without this variable, these tools return an error explaining how to enable them.

cancel_migration is always available regardless of this setting — it is a safety operation that must always be accessible to stop a runaway migration.

Read-only migration tools (list_migrations, get_migration) work without any gates. test_migration_connection requires TREKMAIL_ALLOW_MIGRATION=true because it makes outbound IMAP connections.

Migration per-call confirmation

Each migration write tool requires a confirmation parameter:

  • start_migration requires confirm_start=true
  • cancel_migration requires confirm_cancel=true
  • retry_migration requires confirm_retry=true

Without the confirmation parameter, the tool returns an error asking the agent to confirm.

Server-wide concurrency limit

The API enforces a global limit on simultaneous migrations (default: 20). When the limit is reached, new migration requests return 503 with migration_capacity_reached and retryable: true. This protects server resources when many accounts migrate simultaneously.

Audit logging

Every mutating API action is recorded in the audit log, visible under AI Agents & API → Audit Log in the dashboard. Events include:

  • Token created / revoked — who created or revoked an ops token, and when.
  • Message token created / revoked — who created or revoked a message token.
  • Intent created — a delete intent was created for a specific mailbox.
  • Intent confirmed — the deletion was confirmed and executed.
  • Delete executed — the mailbox was marked for removal.
  • Delete failed — the deletion could not be completed.
  • Intent expired — an unconfirmed intent expired after 10 minutes.
  • Mailbox created — a new mailbox was provisioned via the API.
  • Invite created — a mailbox setup invite was sent.
  • Forwarding updated — forwarding rules were changed for a mailbox.
  • DNS recheck triggered — a DNS verification was requested for a domain.
  • Migration started — an email migration was initiated via the API.
  • Migration cancelled — a running migration was cancelled.
  • Migration retried — a failed or cancelled migration was retried.
  • Migration deleted — a migration record was deleted.
  • Message read — messages were listed or read via the Message API.
  • Message sent — an email was sent via the Message API.
  • Message send failed — an email send attempt failed.
  • Message flags updated — message flags (read/unread, starred) were changed.
  • Message deleted — a message was deleted from a mailbox folder.
  • Message moved — a message was moved between folders.
  • Domain created — a domain was added via the API.
  • Domain deleted — a domain was removed via the API.
  • Ticket created — a support ticket was opened via the API.
  • Ticket replied — a reply was posted to a ticket.
  • Ticket closed — a ticket was closed via the API.
  • SMTP configured — SMTP settings were updated.
  • SMTP connection deleted — a custom SMTP connection was removed.
  • SMTP test queued — an SMTP connection test was started.
  • Cloudflare token deleted — a stored Cloudflare token was removed via the API.

All message API events — reads, sends, flag updates, deletes, and moves — are fully logged. A scheduled cleanup command (api:prune-audit-events) removes records older than 90 days to manage table growth.

Each event records the token used, the resource affected, the IP address, and a request ID.

Filter the audit log by event type, token, or date range to investigate specific activity.

Quick fixes

  • Intent expired before confirmation: Create a new delete intent. Intents expire after 10 minutes.
  • "Missing confirm header": Add the X-Confirm-Delete: true header to the confirmation request.
  • 429 on delete confirmation: You hit the daily limit or cooldown. Wait for the Retry-After period.
  • MCP agent says delete tools are disabled: Set TREKMAIL_ALLOW_DESTRUCTIVE=true in the MCP server environment variables.
  • MCP agent says "Sending is disabled": Set TREKMAIL_ALLOW_SENDING=true in the MCP server environment variables.
  • MCP agent says "Send not confirmed": The agent must pass confirm_send=true as a parameter on each send_message call.
  • MCP agent says migration tools are disabled: Set TREKMAIL_ALLOW_MIGRATION=true in the MCP server environment variables.
  • 503 "migration_capacity_reached": Too many migrations are running server-wide. Wait a few minutes and retry.
  • 409 "active migration running": Cancel or wait for the existing migration to finish before starting a new one.

Related articles

Jump to nearby guides that continue the workflow.

We use cookies for essential functionality. No ads, no ad tracking.

or
or

Reset email sent

If an account exists for this email, we've sent password reset instructions.

By continuing, you agree to TrekMail's Terms and Privacy Policy.