Endpoints

Complete reference for all mail-catcher API endpoints.

All endpoints are served from your API base URL (printed during deployment). Protected endpoints require a Bearer token.

Public endpoints

GET /health

Health check. No authentication required.

Response 200 OK

{
  "status": "ok",
  "timestamp": 1710000000000
}

GET /version

Returns the API version. No authentication required.

Response 200 OK

{
  "version": "0.1.0",
  "apiVersions": ["v1"]
}

GET /openapi.json

Returns the OpenAPI specification. No authentication required.

GET /docs

Interactive API documentation powered by Scalar. No authentication required.


Email endpoints

All email endpoints require authentication and are prefixed with /v1.

GET /v1/emails

List emails for a specific inbox. Returns emails sorted newest first.

Query parameters

ParameterRequiredDefaultDescription
inboxyes-Inbox name (local part of the email address, before @). Valid characters: a-z 0-9 . _ -
limitno50Results per page (1100)
cursorno-Pagination cursor from a previous response
waitnofalse"true" to enable long-polling
timeoutno28Max wait time in seconds for long-poll (128)
senderno-Filter by sender (substring match)
subjectno-Filter by subject (substring match)
receivedAfterno-Timestamp or ISO date
receivedBeforeno-Timestamp or ISO date
hasAttachmentsno-"true" or "false"

Response 200 OK

{
  "emails": [
    {
      "messageId": "abc123@mail.example.com",
      "inbox": "test",
      "sender": "sender@example.com",
      "recipient": "test@receive.yourdomain.com",
      "subject": "Verify your account",
      "body": "Click the link to verify...",
      "htmlBody": "<p>Click the link to verify...</p>",
      "attachments": [
        {
          "filename": "invoice.pdf",
          "contentType": "application/pdf",
          "size": 24680,
          "url": "/v1/emails/abc123@mail.example.com/attachments/invoice.pdf"
        }
      ],
      "receivedAt": 1710000000000,
      "rawUrl": "/v1/emails/abc123@mail.example.com/raw"
    }
  ],
  "nextCursor": "2024-03-10T00:00:00.000Z#abc123",
  "hasMore": true
}

Response fields

FieldTypeDescription
emailsarrayList of email objects
emails[].messageIdstringUnique email identifier (from Message-ID header)
emails[].inboxstringInbox name (lowercase)
emails[].senderstringSender email address
emails[].recipientstringRecipient email address
emails[].subjectstringEmail subject line
emails[].bodystringPlain text body
emails[].htmlBodystringHTML body
emails[].attachmentsarrayAttachment metadata
emails[].receivedAtnumberUnix timestamp in milliseconds
emails[].rawUrlstringRelative URL to the raw .eml file
nextCursorstring | undefinedCursor for the next page
hasMorebooleanWhether more results exist

Long-polling

When wait=true, the API polls DynamoDB with exponential backoff (starting at 500ms, doubling to max 10s) until emails arrive or the timeout is reached. If no emails arrive, the response contains an empty emails array.

curl -H "Authorization: Bearer $TOKEN" \
  "$API_URL/v1/emails?inbox=test&wait=true&timeout=15"

Pagination

Pass nextCursor from the previous response as cursor:

curl -H "Authorization: Bearer $TOKEN" \
  "$API_URL/v1/emails?inbox=test&limit=10&cursor=2024-03-10T00:00:00.000Z%23abc123"

GET /v1/emails/:messageId

Retrieve a single email by its message ID.

Response 200 OK, same email object shape as the list endpoint.

Errors

StatusError Code
401UNAUTHORIZED
404NOT_FOUND

DELETE /v1/emails/:messageId

Delete a single email and all its attachments.

Response 200 OK

{
  "deleted": true,
  "messageId": "abc123@mail.example.com"
}

This removes the DynamoDB record, the raw .eml from S3, and all attachment files from S3.

Errors

StatusError Code
401UNAUTHORIZED
404NOT_FOUND

DELETE /v1/emails

Bulk delete all emails in an inbox.

Query parameters

ParameterRequiredDescription
inboxyesInbox name to clear

Response 200 OK

{
  "deleted": 42
}

Deletes are batched in groups of 25 with exponential backoff for reliability.

Errors

StatusError Code
400MISSING_INBOX
400INVALID_INBOX
401UNAUTHORIZED

GET /v1/emails/:messageId/raw

Download the raw .eml file.

Response 302 Found, redirects to a pre-signed S3 URL valid for 15 minutes.

curl -L -H "Authorization: Bearer $TOKEN" \
  "$API_URL/v1/emails/abc123@mail.example.com/raw" -o email.eml

Errors

StatusError Code
401UNAUTHORIZED
404NOT_FOUND

GET /v1/emails/:messageId/attachments/:filename

Download a specific attachment.

Response 302 Found, redirects to a pre-signed S3 URL valid for 15 minutes.

Errors

StatusError Code
401UNAUTHORIZED
404NOT_FOUND

Search Documentation

Search through the docs