MOLTED EMAIL

Batch Operations

Send, simulate, classify, and get recommendations for up to 500 recipients in a single request.

Batch endpoints let you process multiple items in a single API call -- up to 500 per request. Each item is evaluated independently with full policy enforcement.

Batch send

Send email to up to 500 recipients in one request. Each recipient gets their own policy evaluation and deduplication check.

molted send batch --template <id> --recipients '<json>' [--mailbox <id>] [--stdin]

Options

FlagTypeRequiredDescription
--templatestringYesTemplate ID to use for all recipients.
--recipientsstringNoJSON array of recipient objects (required unless using --stdin).
--mailboxstringNoMailbox ID to send from.
--stdinflagNoRead recipients JSON from stdin instead of --recipients.

Recipient format

Each recipient object has three fields:

[
  { "email": "alice@example.com", "dedupeKey": "promo-alice", "payload": { "name": "Alice" } },
  { "email": "bob@example.com", "dedupeKey": "promo-bob", "payload": { "name": "Bob" } }
]
FieldTypeRequiredDescription
emailstringYesRecipient email address.
dedupeKeystringYesUnique key to prevent duplicate sends.
payloadobjectNoTemplate variables for this recipient.

Example

molted send batch --template campaign-march \
  --recipients '[{"email":"alice@example.com","dedupeKey":"march-alice","payload":{"name":"Alice"}},{"email":"bob@example.com","dedupeKey":"march-bob","payload":{"name":"Bob"}}]'

Using stdin (useful for large recipient lists):

cat recipients.json | molted send batch --template campaign-march --stdin
POST https://api.molted.email/v1/agent/batch/request-send

Requires Bearer authentication.

Parameters

FieldTypeRequiredDescription
tenantIdstringYesYour tenant identifier.
templateIdstringYesTemplate ID to use for all recipients.
sendsarrayYesArray of recipient objects (max 500).
sends[].recipientEmailstringYesRecipient email address.
sends[].dedupeKeystringYesUnique key to prevent duplicate sends.
sends[].payloadobjectNoTemplate variables for this recipient.
sends[].sendReasonstringNoAnnotate why the agent is sending (for audit trails).
mailboxIdstringNoMailbox ID to send from.
humanizebooleanNoApply AI humanization to email content.

Example

curl
curl -X POST https://api.molted.email/v1/agent/batch/request-send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_abc123",
    "templateId": "campaign-march",
    "sends": [
      {
        "recipientEmail": "alice@example.com",
        "dedupeKey": "march-alice",
        "payload": { "name": "Alice" }
      },
      {
        "recipientEmail": "bob@example.com",
        "dedupeKey": "march-bob",
        "payload": { "name": "Bob" }
      }
    ]
  }'

Response

{
  "batchId": "batch_abc123",
  "total": 2,
  "queued": 1,
  "blocked": 1,
  "results": [
    { "recipientEmail": "alice@example.com", "requestId": "req_001", "status": "queued" },
    { "recipientEmail": "bob@example.com", "requestId": "req_002", "status": "blocked", "reason": "suppressed" }
  ]
}
FieldTypeDescription
batchIdstringUnique identifier for this batch.
totalnumberTotal number of recipients in the batch.
queuednumberNumber of sends that passed policy and are queued for delivery.
blockednumberNumber of sends blocked by the policy engine.
resultsarrayPer-recipient results with status (queued, blocked, or error) and optional reason.

Each item gets its own result -- some may be queued while others are blocked.

Simulate batch

Dry-run a batch send to check policy decisions without delivering. Use this to verify which recipients would be allowed before committing to a real send.

molted send simulate-batch --template <id> --recipients '<json>'

Options

FlagTypeRequiredDescription
--templatestringYesTemplate ID to simulate against.
--recipientsstringYesJSON array of email strings or recipient objects.

The recipients flag accepts either plain email strings or full {email, dedupeKey, payload} objects. For simulation, only the email address is used.

Example

molted send simulate-batch --template campaign-march \
  --recipients '["alice@example.com", "bob@example.com"]'
POST https://api.molted.email/v1/agent/simulate-batch

Requires Bearer authentication.

Parameters

FieldTypeRequiredDescription
tenantIdstringYesYour tenant identifier.
templateIdstringYesTemplate ID to simulate against.
recipientEmailsstring[]YesArray of recipient email addresses (max 500).

Example

curl
curl -X POST https://api.molted.email/v1/agent/simulate-batch \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_abc123",
    "templateId": "campaign-march",
    "recipientEmails": ["alice@example.com", "bob@example.com"]
  }'

Response

{
  "total": 2,
  "wouldAllow": 1,
  "wouldBlock": 1,
  "results": [
    { "recipientEmail": "alice@example.com", "wouldAllow": true },
    { "recipientEmail": "bob@example.com", "wouldAllow": false, "reason": "fatigue_limit", "cooldownExpiresAt": "2025-03-15T14:30:00Z" }
  ]
}
FieldTypeDescription
totalnumberTotal recipients evaluated.
wouldAllownumberNumber that would pass policy.
wouldBlocknumberNumber that would be blocked.
results[].wouldAllowbooleanWhether this recipient would pass policy checks.
results[].reasonstringWhy the recipient would be blocked (only present when wouldAllow is false).
results[].cooldownExpiresAtstringWhen the cooldown expires, if applicable.

Batch next-best-action

Get recommendations for up to 500 contacts at once.

There is no dedicated CLI command for batch next-best-action. Use the API directly.

POST https://api.molted.email/v1/agent/batch/next-best-action

Requires Bearer authentication.

Parameters

FieldTypeRequiredDescription
tenantIdstringYesYour tenant identifier.
contactEmailsstring[]YesArray of contact email addresses (max 500).

Example

curl
curl -X POST https://api.molted.email/v1/agent/batch/next-best-action \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_abc123",
    "contactEmails": ["alice@example.com", "bob@example.com"]
  }'

Response

{
  "results": [
    { "contactEmail": "alice@example.com", "recommendation": "nudge", "reasoning": "No reply in 5 days" },
    { "contactEmail": "bob@example.com", "recommendation": "wait", "reasoning": "Recent send 2 hours ago" }
  ]
}

Batch classify intent

Classify up to 500 inbound messages at once.

There is no dedicated CLI command for batch classify intent. Use the API directly.

POST https://api.molted.email/v1/agent/batch/classify-intent

Requires Bearer authentication.

Parameters

FieldTypeRequiredDescription
tenantIdstringYesYour tenant identifier.
messagesarrayYesArray of message objects to classify (max 500).
messages[].subjectstringYesThe email subject line.
messages[].bodyTextstringYesThe plain text body of the email.

Example

curl
curl -X POST https://api.molted.email/v1/agent/batch/classify-intent \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_abc123",
    "messages": [
      { "subject": "Re: Partnership proposal", "bodyText": "Sure, let'\''s set up a call next week" },
      { "subject": "Re: Your offer", "bodyText": "We already have a vendor for this, not interested" }
    ]
  }'

Response

{
  "results": [
    { "intent": "interested", "confidence": 0.94, "suggestedAction": "notify_owner" },
    { "intent": "objection", "confidence": 0.88, "suggestedAction": "escalate" }
  ]
}

Limits

All batch endpoints accept a maximum of 500 items per request. Requests exceeding this limit are rejected with a 400 Bad Request response.

  • Sending Email -- single-recipient send with full policy trace
  • Policy Simulation -- understand how the policy engine evaluates sends
  • Templates -- manage the templates referenced in batch sends
  • Errors -- all possible block reasons and error codes