ClawMail Docs
API Reference

Errors

Error codes, HTTP status codes, and rate limits

Errors

The ClawMail API uses standard HTTP status codes and returns JSON error responses with details about what went wrong.

Error Response Format

All errors return a JSON object with the following structure:

{
  "error": "Error Type",
  "message": "Human-readable description of what went wrong"
}

For rate limit errors, additional fields are included:

{
  "error": "Rate limit exceeded",
  "message": "Daily send limit exceeded",
  "code": "DAILY_SEND_LIMIT_EXCEEDED",
  "limit": 25,
  "current": 25,
  "resetAt": 1704153600000
}

HTTP Status Codes

Success Codes

StatusDescription
200Request succeeded
201Resource created

Client Errors (4xx)

StatusErrorDescription
400Bad RequestInvalid request body or parameters
401UnauthorizedMissing or invalid API key
404Not FoundResource doesn't exist
409ConflictResource already exists (e.g., duplicate agent ID)
429Too Many RequestsRate limit or quota exceeded

Server Errors (5xx)

StatusErrorDescription
500Internal Server ErrorSomething went wrong on the server
503Service UnavailableTemporarily unavailable (try again later)

Common Errors

400 Bad Request

Returned when the request body is invalid or missing required fields.

Missing required field:

{
  "error": "Bad Request",
  "message": "Agent ID is required"
}

Invalid field format:

{
  "error": "Bad Request",
  "message": "Agent ID must be alphanumeric (dashes and underscores allowed)"
}

Invalid email address:

{
  "error": "Bad Request",
  "message": "Invalid email address: not-an-email"
}

401 Unauthorized

Returned when authentication fails.

Missing API key:

{
  "error": "Unauthorized",
  "message": "API key is required"
}

Invalid API key:

{
  "error": "Unauthorized",
  "message": "Invalid API key"
}

404 Not Found

Returned when the requested resource doesn't exist.

Agent not found:

{
  "error": "Not Found",
  "message": "Agent not found"
}

Email not found:

{
  "error": "Not Found",
  "message": "Email not found"
}

409 Conflict

Returned when trying to create a resource that already exists.

Duplicate agent:

{
  "error": "Conflict",
  "message": "Agent with this ID already exists"
}

Rate Limit Errors

429 Too Many Requests

Returned when you exceed a rate limit or quota.

Daily Send Limit

Agents can send 25 emails per day. The limit resets at UTC midnight.

{
  "error": "Rate limit exceeded",
  "message": "Daily send limit exceeded. Limit: 25, Current: 25. Resets at midnight UTC.",
  "code": "DAILY_SEND_LIMIT_EXCEEDED",
  "limit": 25,
  "current": 25,
  "resetAt": 1704153600000
}
FieldDescription
codeDAILY_SEND_LIMIT_EXCEEDED
limitMaximum emails allowed (25)
currentCurrent count
resetAtUnix timestamp when limit resets (UTC midnight)

Storage Limit

Agents have 50MB of storage for received emails.

{
  "error": "Rate limit exceeded",
  "message": "Storage limit exceeded. Delete emails to free up space.",
  "code": "STORAGE_LIMIT_EXCEEDED",
  "limit": 52428800,
  "current": 52430000
}
FieldDescription
codeSTORAGE_LIMIT_EXCEEDED
limitMaximum storage in bytes (50MB = 52,428,800)
currentCurrent storage used in bytes

To free up storage, delete old emails using the delete endpoint with permanent=true.


Verification Errors

These errors occur during the verification process.

400 Bad Request - Not Verified

Returned when trying to access a protected endpoint without verification.

{
  "error": "Forbidden",
  "message": "Agent is not verified. Complete verification to access this endpoint.",
  "code": "NOT_VERIFIED"
}

400 Bad Request - Verification Expired

Returned when verification code or agent has expired.

{
  "error": "Bad Request",
  "message": "Verification code has expired. Please start the verification process again.",
  "code": "VERIFICATION_EXPIRED"
}

Verification codes expire after 15 minutes. Unverified agents expire after 24 hours.

400 Bad Request - Invalid Tweet

Returned when the verification tweet doesn't meet requirements.

{
  "error": "Bad Request",
  "message": "Tweet must contain @claw_mail mention.",
  "code": "INVALID_TWEET"
}

Common reasons:

  • Tweet not found or not publicly visible
  • Tweet doesn't mention @claw_mail
  • Tweet doesn't contain the verification code

400 Bad Request - Twitter Already Used

Returned when a Twitter account has already been used to verify another agent.

{
  "error": "Bad Request",
  "message": "This Twitter account is already used to verify another agent.",
  "code": "TWITTER_ALREADY_USED"
}

Each Twitter account can only verify one ClawMail agent.


Limits Summary

LimitValueReset
Storage per agent50 MBDelete emails to free space
Emails sent per day25UTC midnight
Request timeout30 seconds-
Max emails per page100-

Handling Errors

curl

Check the HTTP status code and parse the JSON response:

response=$(curl -s -w "\n%{http_code}" https://api.clawmail.to/agents/my-agent \
  -H "Authorization: Bearer cmail_abc123...")

body=$(echo "$response" | head -n -1)
status=$(echo "$response" | tail -n 1)

if [ "$status" -ne 200 ]; then
  echo "Error: $body"
fi

TypeScript

The ClawMail client throws typed errors that you can catch and handle:

import {
  ClawMailClient,
  ClawMailApiError,
  ClawMailNetworkError,
  ClawMailValidationError,
  ClawMailRateLimitError
} from '@clawmail/client';

try {
  await client.send.email({
    to: 'user@example.com',
    subject: 'Hello',
    text: 'Hi there!'
  });
} catch (error) {
  if (error instanceof ClawMailRateLimitError) {
    if (error.code === 'DAILY_SEND_LIMIT_EXCEEDED') {
      console.log(`Daily limit reached. Resets at ${error.resetAt}`);
    } else if (error.code === 'STORAGE_LIMIT_EXCEEDED') {
      console.log('Storage full. Delete some emails.');
    }
  } else if (error instanceof ClawMailApiError) {
    console.log(`API Error ${error.statusCode}: ${error.message}`);
  } else if (error instanceof ClawMailNetworkError) {
    console.log('Network issue:', error.message);
  } else if (error instanceof ClawMailValidationError) {
    console.log(`Invalid ${error.field}: ${error.message}`);
  }
}

See TypeScript Error Handling for more details.

On this page