Set up with the CLI
Create a workspace, endpoint, bindings, and routes from the command line, or apply them all from one YAML file.
This guide sets up the same email-to-webhook path as the Quickstart, using the agentowl CLI instead of the dashboard. It works against the hosted API or a self-hosted Worker.
Before you start
Sign in to the CLI:
# Hosted: browser sign-in
agentowl login
# Or with an API key from Settings → API Keys
agentowl login --token aok_... --url https://api.agentowl.devCheck the connection:
agentowl whoami
agentowl version1. Create a tenant
Tenants (called workspaces in the dashboard) are the top-level isolation boundary. Every binding, endpoint, route, and policy belongs to exactly one tenant. Any signed-in account can create tenants up to its plan limit; the Free plan allows one.
agentowl tenant create acme --display-name "Acme Corp"If you created a workspace during dashboard onboarding, skip this step and use its workspace ID wherever these commands take a tenant.
Output:
tenant_id t_abc123...
slug acme
display_name Acme Corp
status active
created_at 2026-03-24T12:00:00ZPreview without creating:
agentowl tenant create acme --display-name "Acme Corp" --dry-runList all tenants:
agentowl tenant list2. Create an endpoint
An endpoint is where inbound messages are delivered. The most common type is a webhook — a URL in your application that receives POST requests with the normalized event payload.
agentowl endpoint create webhook my-webhook https://app.acme.com/hooks/inbound \
--tenant acmeOther endpoint types: agent-runtime, queue, sip, email-forward, hosted-page, dead-letter, and voice-runtime (hands inbound calls to an external voice-agent runtime over Telnyx media streaming; see the CLI reference for --runtime-url and --stream-token-secret-ref).
List endpoints:
agentowl endpoint list --tenant acme3. Bind a communication channel
Bindings connect a communication identity (email address, phone number) to a tenant. Once bound and provisioned, inbound messages to that identity flow through AgentOwl.
Bind an email address
agentowl email bind acme support@acme.agentowl.dev --provider smtpAddresses on your workspace subdomain (<name>@<workspace>.agentowl.dev) are received by AgentOwl's SMTP server, so use --provider smtp for them. Custom-domain receiving uses operator-configured SMTP address mappings; see Email.
Bind an SMS number
Phone bindings require an active paid plan. Choose an available number in Admin, then configure its destination for your workspace. SMS and MMS are in preview; sending business messages from US local numbers requires messaging registration and approval. If number setup is unavailable for your account, contact support@agentowl.dev. These commands also serve self-hosted operators with configured provider credentials. Sandbox billing does not enable production phone provisioning.
agentowl messaging bind acme --number +15551234567 --capability smsAuto-assign an SMS number
agentowl messaging bind acme --capability sms voiceWhen no --number is specified, AgentOwl requests an auto-assigned number from the provider.
Import an existing phone number
agentowl messaging import-number acme +15559876543 --capability sms voiceList all bindings for a tenant:
agentowl email inspect <binding_id>
agentowl messaging inspect <binding_id>4. Create a route
Routes connect bindings to endpoints. When an inbound message arrives on a binding, the route determines which endpoint receives it.
agentowl route create \
--tenant acme \
--binding <binding_id> \
--endpoint <endpoint_id> \
--priority 100Lower priority numbers are evaluated first. New routes use the dead-letter fallback policy; change it with agentowl route update <route_id> --fallback drop|quarantine|dead-letter.
List routes:
agentowl route list --tenant acme5. Publish the runtime config
After creating your bindings, endpoints, and routes, publish the runtime configuration so the ingress workers can use it:
agentowl config publish acmeThis snapshots the current desired state and distributes it to KV for all ingress workers. Nothing goes live until you publish.
In the dashboard, this is the Activate routing step of Guided Setup. Run agentowl config diff acme to see unpublished changes.
6. Verify with doctor
Run a health check to confirm everything is correctly configured:
agentowl doctor acmeThis checks API connectivity, tenant status, published config, and provider drift.
Declarative configuration (apply)
Instead of running individual commands, you can define your entire configuration in a YAML file and apply it in one step.
Create acme.yaml:
tenant:
slug: acme
display_name: "Acme Corp"
endpoints:
- name: main-webhook
type: webhook
config:
url: https://app.acme.com/hooks/inbound
bindings:
- address_or_number: support@acme.agentowl.dev
provider: smtp
channels:
- email
capabilities:
- email
- address_or_number: "+15551234567"
provider: telnyx
channels:
- sms
capabilities:
- sms
routes:
- binding_address: support@acme.agentowl.dev
endpoint_name: main-webhook
priority: 100
fallback_policy: dead-letter
- binding_address: "+15551234567"
endpoint_name: main-webhook
priority: 100
fallback_policy: dead-letterValidate
agentowl validate -f acme.yamlPreview changes
agentowl plan -f acme.yamlApply
agentowl apply -f acme.yaml --auto-approveThis creates the tenant (if needed), endpoints, bindings, routes, and publishes the runtime config.
What's next
- Event format — what your webhook receives
- Policies — allow, deny, and quarantine senders
- CLI Reference — every command and flag