# Sendlet > Sendlet lets a person give an AI agent permission to email specific, pre-approved people. Each permission is a secret URL that sends to exactly one recipient. You need an endpoint URL from the person you work for. It looks like: https://sendlet.email/to/sam-k7F2x9Qa4mB8nR1vT6yZ3c ## Send an email POST JSON to the endpoint URL: POST https://sendlet.email/to/sam-k7F2x9Qa4mB8nR1vT6yZ3c Content-Type: application/json {"subject": "Short summary", "body": "Message text. Markdown is supported."} - subject: required, up to 200 characters, one line. Alias: title. - body: required, up to 50,000 characters, plain text or Markdown. Aliases: message, text, content. - idempotency_key: optional, up to 100 of A-Z a-z 0-9 _ . : - ; makes retries safe. Also accepted as an Idempotency-Key header. Also accepted: application/x-www-form-urlencoded with the same fields, or text/plain / text/markdown where the first line is the subject and the rest is the body. ## Attach files and images Add an "attachments" array with each file's name and base64 content: {"subject": "Floor plan", "body": "Here it is:\n\n![Floor plan](plan.png)", "attachments": [{"filename": "plan.png", "content": "iVBORw0KGgo..."}]} Or POST multipart/form-data, which curl sends with -F: curl -F subject="Floor plan" -F body="![Floor plan](plan.png)" -F file=@plan.png https://sendlet.email/to/sam-k7F2x9Qa4mB8nR1vT6yZ3c - Up to 10 files and 5 MB in total per email; 50 MB per account per day. - Allowed types, by extension: png, jpg, jpeg, gif, webp, pdf, txt, csv, md, json, ics, docx, xlsx, pptx, odt, ods. The content must match the extension. - To show an attached image inside the message, reference its file name as a Markdown image: ![Description](plan.png). Other attachments appear as files. - Images from web URLs are not loaded; they show as their alt text. Attach the image instead. ## Approval Some endpoints hold every email until the owner approves it. The send is still accepted (202), with "awaiting_approval": true; nothing reaches the recipient until they approve. Don't resend it. ## Check what happened to a send GET https://sendlet.email/to/sam-k7F2x9Qa4mB8nR1vT6yZ3c/sends/snd_… Returns the overall status (awaiting_approval, rejected, queued, sent, partly_sent or failed) and one line per recipient (by label), e.g. sent, bounced or skipped, with a short explanation. ## MCP Every endpoint is also a Model Context Protocol server: replace /to/ with /mcp/ in the URL. https://sendlet.email/mcp/sam-k7F2x9Qa4mB8nR1vT6yZ3c It uses the Streamable HTTP transport and offers three tools: send_email (subject and body; optional attachments and idempotency_key), endpoint_info (who it emails and what's left today) and get_send_status (what happened to a send). In Claude, add it as a custom connector; in Claude Code: claude mcp add --transport http sendlet . ## Groups Some URLs send to a group rather than one person. The GET description says so and how many people will receive it. Each member gets their own copy (nobody sees the others' addresses), and each copy counts towards the daily limit. The 202 response then includes `"recipients": 3`, the number of people emailed. ## Check an endpoint before sending GET the endpoint URL. It returns Markdown instructions by default, or JSON with `Accept: application/json`, including how many emails are left today. GET never sends (unless the owner enabled GET-send mode and you add `send=yes`). ## Responses - 202 Accepted: queued. `{"sent": true, "id": "snd_…", "to": "Sam (personal)", "remaining_today": 16}` - 200 OK: a duplicate of a send in the last 10 minutes (same idempotency key or same content); nothing new was sent. Includes `"duplicate": true`. - 400: a field is missing or invalid. Read `hint` for a corrected request. - 404: unknown URL. Check it was copied in full. - 409: the recipient hasn't accepted yet, declined, or unsubscribed, or nobody in the group can receive yet. Don't retry 409s in a loop. - 410: the endpoint was revoked. - 413: the request is over 8 MB. - 415: unsupported Content-Type. - 429: a rate or daily limit was reached. Wait for `Retry-After` seconds. - 503: the service is busy. Retry after `Retry-After` seconds. Errors are RFC 9457 problem details with an extra `hint` field showing a corrected request. ## More - OpenAPI description: https://sendlet.email/openapi.json