operations

Limits and Security

Current product caps, storage limits, and auth protections enforced by Spinupmail.

This page collects the current limits reflected in the README and backend defaults. Some of these values are fixed product caps, while others are runtime settings you can override in wrangler.toml.

Product caps

These limits are part of the current Spinupmail product behavior.

LimitCurrent value
Organizations per user3, configurable in backend auth setup
Members per organization10, configurable in backend auth setup
Addresses per organization100 by default, configurable with MAX_ADDRESSES_PER_ORGANIZATION
Stored emails per address100 by default, configurable with MAX_RECEIVED_EMAILS_PER_ADDRESS
Stored emails per organization1000 by default, configurable with MAX_RECEIVED_EMAILS_PER_ORGANIZATION

If an organization reaches its address cap, new address creation is blocked until the limit is raised or existing addresses are removed.

The organization and membership caps are currently set in the Better Auth organization plugin configuration rather than exposed as wrangler.toml variables.

GET /api/domains exposes the live maxReceivedEmailsPerAddress and maxReceivedEmailsPerOrganization values so clients can stay aligned with the currently deployed limits.

Email and attachment limits

These settings control how much inbound mail Spinupmail accepts and stores.

VariableDefault
EMAIL_MAX_BYTES524288 bytes for the raw inbound message
EMAIL_BODY_MAX_BYTES524288 bytes persisted per email body in D1
EMAIL_ATTACHMENT_MAX_BYTES10485760 bytes per attachment
EMAIL_ATTACHMENT_MAX_TOTAL_BYTES_PER_ORGANIZATION104857600 bytes total per organization
EMAIL_ATTACHMENTS_ENABLEDtrue
MAX_RECEIVED_EMAILS_PER_ADDRESS100 stored emails per inbox by default
MAX_RECEIVED_EMAILS_PER_ORGANIZATION1000 stored emails across the organization by default

Oversized message bodies are dropped before D1 persistence to avoid write failures. Oversized attachments are skipped, and new attachments are also skipped once an organization would exceed its total attachment quota.

For inbox retention, Spinupmail enforces both limits together:

  • The configured address policy (maxReceivedEmailCount) cannot exceed MAX_RECEIVED_EMAILS_PER_ADDRESS.
  • If an address does not store its own override, inbound processing falls back to the current MAX_RECEIVED_EMAILS_PER_ADDRESS default.
  • The total number of stored emails across all inboxes in the org cannot exceed MAX_RECEIVED_EMAILS_PER_ORGANIZATION.

Storage and raw email toggles

The default posture is intentionally conservative.

VariableDefaultEffect
EMAIL_STORE_HEADERS_IN_DBfalsePersist full header JSON in D1
EMAIL_STORE_RAW_IN_DBfalsePersist raw MIME in D1
EMAIL_STORE_RAW_IN_R2falsePersist raw MIME in private R2

Auth and API rate limits

Spinupmail applies both Better Auth throttling and API key throttling.

ControlCurrent default
API_KEY_RATE_LIMIT_WINDOW60 seconds
API_KEY_RATE_LIMIT_MAX120 requests
AUTH_RATE_LIMIT_WINDOW60 seconds
AUTH_RATE_LIMIT_MAXOptional override, otherwise Better Auth default
AUTH_CHANGE_EMAIL_RATE_LIMIT_WINDOW3600 seconds
AUTH_CHANGE_EMAIL_RATE_LIMIT_MAX2

API key throttling also covers Better Auth runtime checks on /get-session and /organization/get-full-organization, not just the application endpoints.

Integration dispatch limits

Integration dispatches are also protected by organization-level caps and queue retry controls.

ControlCurrent default
MAX_INTEGRATIONS_PER_ORGANIZATION3
MAX_INTEGRATION_DISPATCHES_PER_ORGANIZATION_PER_DAY100
INTEGRATION_QUEUE_RETRY_WINDOW_SECONDS21600 seconds
INTEGRATION_QUEUE_BASE_DELAY_SECONDS30 seconds
INTEGRATION_QUEUE_MAX_DELAY_SECONDS1800 seconds
INTEGRATION_QUEUE_JITTER_SECONDS10 seconds

Dispatches run asynchronously through the integration queue and retry with backoff inside the configured retry window.

Verification resend throttling

Email verification resend is also guarded by backend constants:

ControlCurrent value
Cooldown between resend attempts60 seconds
IP window300 seconds
Max resend attempts per IP window5

Retrieval boundaries

Attachments and raw-email downloads are never public. Access requires organization membership:

  • Session-based requests use the active organization in the current user session.
  • API key requests must include X-Org-Id.
  • Attachment downloads use GET /api/emails/:id/attachments/:attachmentId.
  • Raw downloads use GET /api/emails/:id/raw when raw storage is enabled.