Concepts

Core concepts behind OneShotMail -- addresses, modes, TTL, labels, credits, and the one-shot guarantee.

Addresses

An address is the fundamental unit in OneShotMail. Each address is a randomly generated, cryptographically unique email address. Receive addresses use @in.oneshotemail.com, send addresses use @out.oneshotemail.com:

abc123xyz789def456@in.oneshotemail.com   # receive mode
abc123xyz789def456@out.oneshotemail.com  # send mode

The local part (before the @) is a 20-character base62 string generated using secrets.token_urlsafe. It cannot be guessed or enumerated.

When you create an address, you get back an address ID (the same as the local part) that you use for all subsequent operations — checking status, retrieving the email, or deleting the address.

Modes

Every address operates in exactly one of two modes:

Receive mode

The default. A receive-mode address waits for exactly one inbound email.

Lifecycle: waiting —> received —> expired

  • waiting — The address exists and is ready to accept an email. No email has arrived yet.
  • received — An email has been delivered. The email content is available via the API. Only the first email is kept; subsequent emails to the same address are silently discarded.
  • expired — The TTL has elapsed. The address and all associated data (email content, attachments) have been permanently deleted.

Send mode

A send-mode address sends exactly one outbound email and then self-destructs.

Lifecycle: pending —> sent —> expired

  • pending — The address has been created and the email is queued for sending.
  • sent — The email has been accepted by SES for delivery. Delivery status (delivered, bounced, complained) is tracked in the address metadata.
  • expired — The TTL has elapsed and the address record has been cleaned up.

Send mode costs more credits than receive mode because it incurs SES sending costs and requires domain reputation management.

TTL (Time-to-Live)

Every address has a TTL that determines how long it exists before auto-deletion. You set the TTL when creating the address:

# Lives for 5 minutes
addr = oneshot.create(ttl_seconds=300)

# Lives for 1 hour (the default)
addr = oneshot.create(ttl_seconds=3600)

TTL limits depend on your plan:

PlanMax TTL
Free1 hour
Solo12 hours
Team24 hours
EnterpriseCustom
Max24 hours

When the TTL expires:

  1. The address stops accepting email.
  2. The address record and all email data are permanently deleted.
  3. There is no recovery.

The One-Shot Guarantee

This is the defining feature of OneShotMail. Each address accepts exactly one email. When the first email arrives:

  1. The address status changes from waiting to received.
  2. The email is stored.
  3. All subsequent emails to that address are silently discarded.

This guarantee is what makes OneShotMail perfect for automated testing. Each test gets its own isolated address. There is no cross-contamination between test runs, no leftover emails from previous executions, and no race conditions from shared inboxes.

If an address is in received status and another email arrives for it, the second email is dropped without any bounce message. The sender receives no indication that the email was discarded. This prevents information leakage about which addresses exist.

Labels

Labels are optional, user-defined strings you attach to addresses when creating them. They are the primary mechanism for organizing and bulk-managing addresses in test suites.

# Tag addresses with the CI run ID
run_id = os.environ.get("CI_RUN_ID", "local")

addr1 = oneshot.create(label=f"ci-{run_id}")
addr2 = oneshot.create(label=f"ci-{run_id}")
addr3 = oneshot.create(label=f"ci-{run_id}")

# After the test run, clean up all addresses in one call
oneshot.delete_by_label(f"ci-{run_id}")

Labels support filtering in the list endpoint:

# Find all addresses from this test run
addresses = oneshot.list(label=f"ci-{run_id}")

Best practices for labels:

  • CI/CD runs: Use the build ID, commit SHA, or run number. Example: ci-run-a1b2c3d4.
  • Test suites: Use the test class or feature name. Example: signup-flow.
  • Manual testing: Use a descriptive name. Example: debug-invoice-email.
  • Cleanup: Always call delete_by_label() in your test teardown or CI cleanup step.

Credits

OneShotMail uses a credit system for usage beyond your plan’s monthly allocation.

How billing works (in order)

  1. Monthly allocation — Your plan includes a set number of receive and send operations per month. These are used first.
  2. Credit balance — If your monthly allocation is exhausted, credits are consumed instead. 1 credit = 1 receive address creation. Send operations consume more credits (see your plan details).
  3. Quota exceeded — If both your allocation and credits are exhausted, the API returns a 402 error with a link to upgrade or purchase more credits.

Purchasing credits

Credits are sold in packs and are available on every plan at the same price. Credits are always more expensive per address than your plan allocation, so if you’re buying credits regularly, upgrading your plan saves money. See Billing & Usage for full pricing.

Credits expire 12 months after purchase. Unused credits carry over between billing cycles (they do not reset monthly).

Credit costs by operation

OperationCredit cost
Create (receive)1 credit
Create + send2 credits

API Keys

Your API key is the credential used to authenticate all API requests. It has the format:

osm_live_aBcDeFgHiJkLmNoPqRsT...

Key facts about API keys:

  • Shown once. When you register or regenerate your key, you see it exactly once. Store it securely.
  • Stored as a hash. OneShotMail stores only a bcrypt hash of your key. We cannot retrieve it for you.
  • Prefix-indexed. The first 8 characters are stored separately for fast lookup. The osm_live_ prefix identifies it as a live key.
  • Environment variable. All SDKs and the CLI read from the ONESHOT_API_KEY environment variable by default.
  • One key per account. Regenerating your key invalidates the previous one immediately.

Plans

PlanReceive/moSend/moMax email sizeMax TTLRate limit
Free2551 MB1 hour5 rps
Solo10,0001,00010 MB12 hours50 rps
Team100,00010,00025 MB24 hours200 rps
Enterprise500,00050,00050 MB24 hours500 rps
Max1,000,000100,00050 MB24 hours1,000 rps

See the Billing guide for full details on plans, credits, and the free tier queue.