Skip to main content

Official Python SDK for Ujex Postbox — email-for-AI-agents with built-in prompt-injection scoring, auth verdicts, and plus-addressed task threading.

Project description

ujex-postbox

The Python SDK for Ujex Postbox — email for AI agents.

pip install ujex-postbox

30-second demo

from ujex_postbox import PostboxClient, plus_address

client = PostboxClient(device_key="ap_live_...", agent_id="agent-hello")

# Send
resp = client.send(
    to=["alice@vendor.com"],
    subject="Re: invoice",
    body="On it — sending by Friday.",
    require_human=True,
)
print(resp.id, resp.status, resp.quota_remaining)

# Plus-address a per-task inbox (no new inbox needed)
addr = plus_address("agent-hello@in.ujex.dev", task_id="proj-42-abc")
# -> agent-hello+proj-42-abc@in.ujex.dev

# Read an inbound message
m = client.read_message(agent_id="agent-hello", message_id="msg_01...")
print(m.pi_score, m.pi_reasons, m.auth_verdict.dkim, m.plus_task_id)

Why not AgentMail / SES / SendGrid?

Postbox surfaces Ujex's agent-specific signals as first-class fields:

Field What it gives you
m.pi_score / m.pi_reasons Gemini-scored prompt-injection risk on every inbound, 0-1.
m.auth_verdict.dkim/spf/dmarc RFC 5321/7208/7489 verdicts — bool per message, no parsing SPF strings yourself.
m.plus_task_id Task id automatically extracted from the plus-address.
resp.quota_remaining Per-agent monthly budget remaining in USD-equivalent units.
require_human=True on send Returns waiting_approval; the outbound message dispatches after app/dashboard approval.

API

Method Purpose
PostboxClient.send(to, subject, body, thread_key?, idempotency_key?, require_human?) Send an email. Returns SendResult.
PostboxClient.list_messages(agent_id, direction?, limit?, since?) List inbound or outbound messages. Returns list[Message].
PostboxClient.read_message(agent_id, message_id) Full message with body + verdicts.
PostboxClient.list_inboxes(agent_id?) Provisioned inboxes.
plus_address(base_inbox, task_id) Build base+task@domain.
parse_plus_address(addr) {base, task_id, domain} or None.
verify_signature(raw_body, signature, secret) Timing-safe HMAC-SHA256 check on an inbound webhook.
parse_inbound_event(raw_body) Raw bytes/dict → InboundEvent.

An AsyncPostboxClient mirrors the same surface on httpx.AsyncClient.

Retries

Retries automatically on 429 and 5xx with exponential backoff and respect for Retry-After. Default max 3 retries. Tune with PostboxClient(max_retries=…).

Webhook verification

from ujex_postbox import verify_signature, parse_inbound_event

ok = verify_signature(
    raw_body=request.body,                      # bytes
    signature=request.headers["x-ujex-signature"],
    secret=os.environ["POSTBOX_INGEST_SECRET"],
)
if not ok:
    return Response(status=401)
event = parse_inbound_event(request.body)
if event.injection_score.score > 0.7:
    # flag for review, don't let the agent process it yet
    quarantine(event)

Framework integrations

Each adapter is an opt-in install that raises a clear ImportError with install instructions if the framework isn't present.

LangChain

pip install 'ujex-postbox[langchain]'
from ujex_postbox import PostboxClient
from ujex_postbox.integrations.langchain import postbox_tools

client = PostboxClient(device_key="ap_live_...", agent_id="agent-hello")
tools = postbox_tools(client, agent_id="agent-hello")
# hand `tools` to any LangChain agent / graph

LlamaIndex

pip install 'ujex-postbox[llamaindex]'
from ujex_postbox import PostboxClient
from ujex_postbox.integrations.llamaindex import postbox_tools

client = PostboxClient(device_key="ap_live_...", agent_id="agent-hello")
tools = postbox_tools(client, agent_id="agent-hello")

CrewAI

pip install 'ujex-postbox[crewai]'
from ujex_postbox import PostboxClient
from ujex_postbox.integrations.crewai import postbox_tools

client = PostboxClient(device_key="ap_live_...", agent_id="agent-hello")
send_tool, read_tool, list_tool = postbox_tools(client, agent_id="agent-hello")

Core loop

Use Python for the Postbox edge of the golden path: send/receive agent mail, request human approval with require_human=True, and inspect prompt-injection signals on inbound messages. Recall memory and owner-scoped Audit are available through the dashboard, CLI, and TypeScript client while the Python SDK remains Postbox-focused.

No account yet?

Free tier: 100 sends/month plus approvals, audit, and Recall memory, no card. Sign up at ujex.dev.

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ujex_postbox-0.1.0.tar.gz (20.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ujex_postbox-0.1.0-py3-none-any.whl (26.0 kB view details)

Uploaded Python 3

File details

Details for the file ujex_postbox-0.1.0.tar.gz.

File metadata

  • Download URL: ujex_postbox-0.1.0.tar.gz
  • Upload date:
  • Size: 20.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for ujex_postbox-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a5f17efb8a97197e6dab7a56f894e1f42ef802b931d3cccdde9c87430aa2a27c
MD5 00363b8f77a9eaa16696f19d7ac5af34
BLAKE2b-256 646621217675903791b7edc29a608963e198668f9536d7dbf21875a1866eb108

See more details on using hashes here.

File details

Details for the file ujex_postbox-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ujex_postbox-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 26.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for ujex_postbox-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 98445f2a2d580a537acc3c08ce06e8f08cb1f4013cc4407abe0b0b05ca0dc0b5
MD5 47d499e76d63cd002138a7d061080fd1
BLAKE2b-256 e13356da5b361ba3f66987cb9db1350889f83abf0ab3a7d4dd325fa9de78b3c8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page