One-Shot Sending Guide

How to send one-shot emails from disposable addresses for testing inbound email processing.

Why one-shot sending?

Most disposable email services only handle receiving. OneShotMail lets you send a single email from a temporary address too. This is critical for testing:

  • Inbound email processing — Your app parses incoming emails (invoices, support tickets, form submissions). Send a test email and verify it was parsed correctly.
  • Email-to-X integrations — Systems that trigger actions from inbound email (create a ticket, process an order, update a CRM record).
  • Webhook verification — Third-party services that send email as part of an integration flow.
  • OTP testing — Send an email containing a known OTP code to test your app’s extraction logic.

How it works

  1. You call send() with the destination, subject, body, and optional attachments.
  2. OneShotMail creates a temporary address, composes the email, and sends it via Amazon SES.
  3. The email is sent from {random_id}@out.oneshotemail.com.
  4. The temporary address auto-deletes after the TTL expires.
  5. There is no reply-to persistence — the address is disposable.

Code examples

Python

import oneshot

# Simple text email
result = oneshot.send(
    to="intake@myapp.com",
    subject="Test support ticket",
    text_body="Hi, I need help with order #12345.",
    label="test-inbound",
)
print(f"Sent from: {result.address}")
print(f"Status: {result.status}")  # "sent"

# HTML email with attachment
with open("invoice.pdf", "rb") as f:
    pdf_bytes = f.read()

result = oneshot.send(
    to="invoices@myapp.com",
    subject="Invoice #9876",
    text_body="Please find the invoice attached.",
    html_body="<p>Please find the invoice attached.</p>",
    attachments=[
        ("invoice.pdf", "application/pdf", pdf_bytes),
    ],
    ttl_seconds=600,
    label="test-invoice",
)

Go

addr, err := client.Send(ctx, &oneshot.SendOptions{
    To:       "intake@myapp.com",
    Subject:  "Test support ticket",
    TextBody: "Hi, I need help with order #12345.",
    Label:    "test-inbound",
})
if err != nil {
    log.Fatal(err)
}
fmt.Println("Sent from:", addr.Address)

Ruby

result = client.send(
  to: "intake@myapp.com",
  subject: "Test support ticket",
  text_body: "Hi, I need help with order #12345.",
  label: "test-inbound"
)
puts "Sent from: #{result['address']}"

JavaScript / TypeScript

const result = await client.send({
  to: "intake@myapp.com",
  subject: "Test support ticket",
  textBody: "Hi, I need help with order #12345.",
  label: "test-inbound",
});
console.log(`Sent from: ${result.address}`);

Java

Address result = client.send(
    "intake@myapp.com",
    "Test support ticket",
    "Hi, I need help with order #12345.",
    null,  // htmlBody
    300    // ttlSeconds
);
System.out.println("Sent from: " + result.address);

Testing inbound email processing — full example

Here is a complete test that sends an email to your app and verifies it was processed correctly:

import oneshot
import requests

def test_invoice_email_processing():
    # 1. Send a test invoice email to your app's intake address
    result = oneshot.send(
        to="invoices@myapp.com",
        subject="Invoice #TEST-001",
        text_body="Amount: $150.00\nDue: 2026-04-01",
        html_body="""
        <h1>Invoice #TEST-001</h1>
        <table>
          <tr><td>Amount:</td><td>$150.00</td></tr>
          <tr><td>Due:</td><td>2026-04-01</td></tr>
        </table>
        """,
        attachments=[
            ("invoice.pdf", open("fixtures/invoice.pdf", "rb").read()),
        ],
        label="test-invoice-processing",
    )

    # 2. Wait for your app to process the email
    import time
    time.sleep(5)  # Give your app time to process

    # 3. Verify the invoice was created in your system
    response = requests.get(
        "http://localhost:3000/api/invoices",
        params={"reference": "TEST-001"},
    )
    assert response.status_code == 200
    invoice = response.json()[0]
    assert invoice["amount"] == 150.00
    assert invoice["status"] == "pending"

Attachments

Send mode supports file attachments. Each attachment requires:

  • filename — The file name as it will appear to the recipient.
  • content_type — MIME type (e.g., application/pdf, image/png).
  • content — The file bytes (SDKs handle base64 encoding).

Attachment limits by plan

PlanMax email sizeMax single attachmentMax attachments
Free1 MB500 KB2
Solo10 MB5 MB5
Team25 MB15 MB10
Enterprise50 MB35 MB20
Max50 MB35 MB20

Deliverability

Emails are sent via Amazon SES from the out.oneshotemail.com domain, which has:

  • DKIM signing configured.
  • SPF records allowing SES to send on behalf of the domain.
  • DMARC policy set to v=DMARC1; p=none (monitoring mode).

Deliverability tips

  • Send to your own domains. OneShotMail sending is designed for testing, not marketing. Send to addresses you control.
  • Check spam folders. Some email providers may flag emails from unfamiliar domains. Allowlist out.oneshotemail.com in your test environment.
  • Monitor bounce rates. If your test destination addresses are invalid, bounces accumulate against the sending domain’s reputation.

Bounce tracking

After sending, you can check the delivery status by fetching the address:

addr = oneshot.get(result.id)
print(addr.status)  # "sent"
# Delivery status updates are available in the address metadata
# after SES processes the delivery notification

Pricing

Send operations cost 2 credits (vs 1 credit for receive). This reflects the additional cost of SES sending and domain reputation management. See the Billing guide for details.