Skip to content

jmluang/postara

Repository files navigation

Postara

Postara is a lightweight IMAP-to-HTTP gateway for product teams that need stable mailbox APIs without building and maintaining their own email ingestion layer.

It connects user-owned mailboxes, normalizes folders and messages into predictable JSON, and exposes scoped API keys for application access.

Status

Postara is in early development. The current public repository contains the backend service and the prebuilt app bundle used by the local workspace.

Local Development

Create a .env file with Postgres connection settings:

DATABASE_URL=postgresql://user:password@host:6543/postara
DIRECT_URL=postgresql://user:password@host:5432/postara
POSTARA_SECRETS_DIR=/absolute/path/to/postara/secrets

DATABASE_URL is used by the running service. DIRECT_URL is used for migrations.

Run locally:

scripts/run_local.sh

The app opens at http://127.0.0.1:18080/app.

Mailbox API Names

Each mailbox has a user-facing API name used in external mailbox routes:

/mailboxes/{mailbox_name}/messages

Mailbox API names are unique per user and may contain only letters, numbers, and hyphens:

gmail-primary
work-gmail-1
receipts

Spaces, underscores, slashes, and non-ASCII characters are rejected so external clients never need URL encoding for mailbox names.

Rename a mailbox API name from an authenticated user session:

curl -X PATCH \
  -H "Authorization: Bearer $POSTARA_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"gmail-primary"}' \
  http://127.0.0.1:18080/mailboxes/1/name

API Key Usage

Create API keys in the app, copy the raw key once, then use it with X-Api-Key.

Agent-specific instructions are available in:

Discover which mailboxes the API key can access:

curl -H "X-Api-Key: $POSTARA_API_KEY" \
  http://127.0.0.1:18080/mailboxes

The response includes api_path values that can be used directly:

{
  "mailboxes": [
    {
      "name": "gmail-primary",
      "email": "user@example.com",
      "provider": "gmail",
      "auth_type": "oauth2",
      "api_path": "/mailboxes/gmail-primary"
    }
  ]
}

List messages for a mailbox:

curl -H "X-Api-Key: $POSTARA_API_KEY" \
  http://127.0.0.1:18080/mailboxes/gmail-primary/messages?limit=12

Fetch one message:

curl -H "X-Api-Key: $POSTARA_API_KEY" \
  http://127.0.0.1:18080/mailboxes/gmail-primary/messages/{uid}

Auth Protection

Password login and registration use layered abuse protection:

  • durable aggregated failure buckets in the app database for hosted deployments
  • normalized email buckets and client-IP buckets
  • trusted proxy CIDR handling for CF-Connecting-IP and X-Forwarded-For
  • optional Cloudflare Turnstile challenges in hosted mode
  • emergency bypass via AUTH_EMERGENCY_BYPASS=true

Stable auth/security error codes include:

  • invalid_credentials
  • rate_limited
  • auth_challenge_required
  • auth_challenge_failed
  • registration_unavailable

Forwarded IP headers are trusted only when the immediate peer is inside trusted_proxy_cidrs / TRUSTED_PROXY_CIDRS.

Runtime Message Model

Messages are provider-backed runtime data. Postara does not persist provider message bodies, subjects, senders, recipients, snippets, attachment names, or message metadata in the app database.

Message list/detail endpoints pull from the connected provider on request. The provider remains the source of truth for seen; opening message detail does not mark a message read. Use the explicit mark-seen endpoint to change read state.

About

Self-hostable mailbox API gateway for AI agents.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages