Documentation navigation

What the MarkRelay Agent Skill Does

The reference for the skill your deployment serves and the HTTP API behind it: what an agent can do with a mailbox, how it should work through one, and the rules it follows. Written for developers building their own agents, and for anyone who wants to know what the skill will do before installing it.

Just want to set it up? Install it in Claude Code, Codex, OpenClaw, Hermes or Pi.

What each deployment serves

PathWhat it is
/skills/SKILL.mdThe skill, named markrelay-mail, in the open Agent Skills format, written for this deployment's API URL.
/llms.txtConcise API instructions for an agent's context.
/openapi/openapi.jsonThe OpenAPI 3.1 document, for SDKs and tools.
/openapi/docsInteractive API documentation.

The agent needs two values. MARKRELAY_API_URL is the complete API endpoint, including /openapi/v1; MARKRELAY_API_KEY is a personal key starting with sk-. The skill and llms.txt repeat the exact URL for their deployment, so agents do not have to guess it.

What an agent can do

  • Discover mailboxes available to its API key.
  • Send email with Markdown and personalization variables.
  • Triage inboxes by folder, unread state, sender, subject, and date.
  • Read and organize messages without relying on browser automation.
  • Reply and forward while preserving conversation context.
  • Upload and download files through reusable upload IDs, or link larger uploaded files by URL.

How the key limits the agent

A key reaches only what its owner can open, narrowed to the scope chosen for it. With Specific mailboxes scope, everything else is invisible to the agent, in listings and in direct requests.

agent — zsh
# The agent's key was created for agent@acme.com only
$curl -H "Authorization: Bearer $MARKRELAY_API_KEY" "$MARKRELAY_API_URL/mailboxes"
{"items":[{"id":"mb_agent","address":"agent@acme.com","displayName":"Acme Triage Agent"}]}
# Another team's mailbox is invisible to it
$curl -H "Authorization: Bearer $MARKRELAY_API_KEY" "$MARKRELAY_API_URL/emails?mailbox=support@acme.com"
{"code":"not_found","message":"Mailbox not found"}
# Its own mail: read, then reply in the same thread
$curl -H "Authorization: Bearer $MARKRELAY_API_KEY" "$MARKRELAY_API_URL/emails?mailbox=agent@acme.com&folder=inbox"
{"items":[{"id":"b68419a2-…","subject":"Reset my password please","from":{"name":"Sam Patel",…}}, …]}
$curl -X POST -H "Authorization: Bearer $MARKRELAY_API_KEY" -H "Content-Type: application/json" \ "$MARKRELAY_API_URL/emails/b68419a2-…/reply" -d '{"text":"Hi Sam, I have sent a fresh reset link…"}'
{"id":"528a8469-74ee-4dc4-8023-0d3882699ad2"}
A key scoped to agent@acme.com: its own mail is readable, another team's mailbox is not found.

Example workflow

  1. Call GET /mailboxes and choose the configured address.
  2. List unread Inbox messages.
  3. Fetch full detail for the next conversation.
  4. Classify it, draft a reply, or send it to a human review queue.
  5. Reply and then update the message state.

Monitor a mailbox safely

For periodic checks, use an external scheduler and query with an inclusive dateFrom checkpoint. Keep a short overlap window, follow every cursor page, and deduplicate by the opaque message ID before advancing the checkpoint. Do not use read=false as an incremental-sync cursor: another client may mark new mail as read first. To react the moment mail arrives instead, use signed webhooks.

Recommended guardrails

  • Use a dedicated key and mailbox for each agent workflow.
  • Require human approval for sensitive or high-value replies.
  • Validate recipients and attachments before sending.
  • Never automatically retry an ambiguous send, reply, or forward; these operations are not idempotent.
  • Move mail to trash by default because the DELETE endpoint is permanent.
  • Treat received HTML and attachments as untrusted, and uploaded file URLs as public bearer capabilities.
  • Rotate keys and review mailbox access regularly.

Related: AI agents setup and the complete Email API guide.