# One gateway for channels, calendars, and your APIs.

Channels share one data plane: one contact identity, one conversation history, durable delivery for async sends. Agents book on a native calendar, call your APIs over HTTP, and can run on your own model keys.

## What it does

### One adapter and one webhook per channel

Inbound messages normalize at the edge into one canonical shape and run one pipeline: dedup, identity, middleware, conversation, brain, persist, deliver. Adding a channel touches one adapter file and one webhook route. Nothing else changes.

- Web chat, SMS, and voice share one data plane
- Inbound dedup keys on the provider message id
- The agent brain never sees channel-specific payloads
- Voice keeps its low-latency loop on the same data plane

### One contact record across every channel

Identity resolution maps each channel address to one contact before the agent runs. A caller who texts later is the same contact with the same history, and a web chat visitor links up once they share a phone or email, so agents answer with context instead of starting over.

- Phone, email, and visitor ids resolve to one contact
- A caller who later texts lands in the same contact
- Blocklist checks run before anything is persisted

### Deliveries that survive provider outages

Async sends queue in a durable outbox instead of firing and forgetting. A minutely cron claims pending rows atomically and retries failures with exponential backoff. Exhausted or non-retryable sends are marked failed with the provider error attached to the message.

- Retries back off from 30 seconds to 1 hour
- 5 delivery attempts by default
- Stuck deliveries sweep back to pending after 2 minutes
- Failed sends keep the provider error on the message

### A calendar that owns its bookings

The native calendar is the system of record: working hours, buffers, lead time, booking horizon, seats per slot, blackout dates. Assistants check real availability and write bookings directly. External sync is write-behind: a failure marks the booking, never blocks it.

- 4 booking tools seeded into every new assistant
- Buffers, lead time, horizon, and seats per slot
- Per-booking sync status: synced, failed, skipped
- A failed backfill re-drives with one API call

### Agents that call your APIs

Custom tools give agents HTTP access to your systems mid-conversation: URL, method, headers, and JSON-Schema parameters, with variable substitution across URL, query, headers, and body, and an SSRF guard that blocks private-network URLs. One tool definition serves voice and chat.

- Define URL, method, headers, and parameters
- Variables substitute into URL, query, headers, and body
- An SSRF guard blocks private-network URLs
- Voice and chat share the same tool registry

### Keys stored server-side, shown once

Bring your own model keys for OpenAI, Anthropic, or OpenRouter; they are stored server-side and read back only as masked hints. Platform API keys are scoped read-only, read-write, or admin, hashed with SHA-256, and shown once at creation.

- Key reads return a masked hint, never the raw key
- sk_test_ and sk_live_ keys per environment
- Revoke a key with one API call
- Turns on your own keys carry no platform LLM charge

## Under the hood

- **PIPELINE:** Dedup, identity, middleware, conversation, brain, persist, deliver. One canonical message shape for every channel
- **CHANNELS:** Web chat, SMS, and voice today. A new channel is one adapter file plus one webhook route
- **OUTBOX:** Durable queue, atomic claims, retries backing off 30s to 1h, 5 attempts by default, stuck-claim sweep
- **CALENDAR:** Native system of record. External sync is write-behind and never owns the booking ids
- **TOOLS:** HTTP tools: URL, method, headers, JSON-Schema parameters, variable substitution, SSRF guard on tool URLs
- **BYOK:** OpenAI, Anthropic, and OpenRouter keys stored server-side, read back only as masked hints
- **KEYS:** Scoped read-only, read-write, or admin. SHA-256 hashed, shown once, sk_live_ and sk_test_ per environment

## FAQ

**How do you add a channel without rebuilding the pipeline?**

Each channel is two pieces: an adapter that renders and sends outbound messages, and a webhook route that parses the provider payload into a canonical envelope. Identity, conversations, the agent brain, and delivery retries are shared, so nothing else changes when a channel is added.

**What happens when a provider has an outage?**

Outbound messages sit in a durable queue, not a fire-and-forget API call. Retries back off from 30 seconds to an hour across 5 attempts, and a minutely cron sweeps stuck deliveries. Calendar bookings write to the native calendar first, so an integration outage never blocks a live booking.

**Does Assistable sync with my CRM or external calendar?**

The native calendar is the system of record, so a booking never depends on an external system. Calendar sync is write-behind: each booking records its own sync status and error, and a failed sync re-drives with one API call. For CRMs and other systems, agents call your APIs directly through HTTP tools during a conversation.

**Can I bring my own model keys?**

Yes. Connect OpenAI, Anthropic, or OpenRouter keys in settings; they are stored server-side and read back only as masked hints. Turns on your own keys are not metered as platform LLM usage. Platform pricing stays usage-based: $0.02 per message, $0.07/min voice, free pay-as-you-go signup.

**How are sandbox and production kept apart?**

Environments are stamped through the stack: conversations, calendars, and tools carry an environment column, and API keys are prefixed sk_test_ or sk_live_ per environment. You can exercise the full pipeline in sandbox before pointing production traffic at it.

---
Source: https://www.assistable.ai/platform/integrations