Getting Started
Sentio is an email inbox API for AI agents: a complete SMTP server and REST API in Rust, dual-licensed MIT or Apache-2.0, that you run yourself. This page gets one running. The repository is the source of truth for everything here.
Quick Start With Docker
The compose stack brings up Sentio and every service it depends on: PostgreSQL, Redis, NATS/JetStream, MinIO, ClamAV and rspamd. You need Docker Engine 24+ with the Compose plugin, about 4 GB of RAM and 8 GB of disk.
git clone https://github.com/truespar/sentio.git
cd sentio
docker compose up -dThat pulls a prebuilt image, ghcr.io/truespar/sentio, published for linux/amd64 and linux/arm64, so there is nothing to compile. Pin a version with SENTIO_TAG=1.2.3 docker compose up -d.
To build from your own checkout instead, which is a release build of the whole workspace and takes a while:
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --buildMigrations run once, then the server starts:
docker compose logs -f sentio-migrate # schema + bootstrap tenant
docker compose logs -f sentio # the server
curl localhost:8080/health/ready
# {"status":"ok","database":"ok","kv":"ok"}Bootstrap Credentials
Migration 007 seeds one admin tenant and one API key.
| What | Value |
|---|---|
| Tenant ID | 00000000-0000-0000-0000-000000000001 |
| API key | sentio_bootstrap_admin_CHANGE_ME |
Rotate this before the host sees anything untrusted. The bootstrap key carries wildcard (*) scope. Create a replacement with POST /v1/tenants/{id}/api-keys, then delete the bootstrap key.
Building From Source
Sentio builds with stable Rust. Compile-time-checked SQL is served from the committed .sqlx/ cache, so no database is needed to build.
git clone https://github.com/truespar/sentio.git
cd sentio
cargo build --release # binary at target/release/sentio-smtpCreate the database, apply migrations, and run. The binary embeds its migrations and applies them in order:
sudo -u postgres createuser --pwprompt sentio
sudo -u postgres createdb --owner=sentio sentio
./target/release/sentio-smtp --config config/default.toml migrate
./target/release/sentio-smtp --config /etc/sentio/sentio.toml serveAt minimum set server.hostname, database.url and the [storage] credentials. See Configuration.
Binding ports below 1024 needs the capability rather than root:
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/sentio-smtpA systemd unit ships at deploy/sentio-smtp.service. Read its Requires= and After= lines before enabling it: they assume the supporting services run on the same host.
Ports
| Port | Purpose | Notes |
|---|---|---|
| 25 | SMTP (MX) | Inbound mail from other servers |
| 465 | SMTPS | Implicit TLS; only binds when certificates are present |
| 587 | Submission | STARTTLS |
| 8080 | REST API | Also serves /openapi.json |
The API Documents Itself
Two endpoints are live as soon as the server starts.
| Endpoint | What it is |
|---|---|
/docs | Interactive reference with a built-in request client. Set the bearer token once and you can exercise the whole API from the browser. |
/openapi.json | The OpenAPI 3.1 document: 116 operations across 85 paths. |
/docs loads its front-end assets from a CDN, so the browser opening it needs outbound internet access. Where that is blocked the page renders blank; use /openapi.json with your own tooling instead.
A generated copy is committed at docs/openapi.json, so you can read the API or generate a client without starting anything:
cargo run -- openapi > openapi.json # from source
docker compose exec sentio sentio-smtp openapi # from the container
npx @openapitools/openapi-generator-cli generate \
-i docs/openapi.json -g typescript-fetch -o ./clientEvery /v1/** route takes a bearer token:
Authorization: Bearer <your-api-key>Next
- Agent Inboxes gives an agent its own address, which is what Sentio is for.
- Sending Mail covers domain verification and the send endpoints.
- Deliverability is the half that is not software, and the usual reason self-hosted mail lands in spam.