4-Tier Integration Model
Otesse integrations are built on a four-tier architecture that cleanly separates the global catalog of available services from organization-level activation, individual user authentication, and provider-specific resource management. This design ensures security, auditability, and flexibility as your integration needs grow.
The Four Tiers
Tier 1: Provider Catalog (Global)
The provider catalog defines what integrations are available on the platform. Each entry in the catalog is an IntegrationProvider record containing:
- Provider metadata — Name, description, logo URL, documentation link
- Authentication type — Whether the provider uses OAuth 2.0 or API key authentication
- OAuth configuration — Authorization URL, token URL, required scopes (for OAuth providers)
- Required credentials — JSON schema defining what credentials the provider needs (for API key providers)
- Category — Which category the provider belongs to (Payment, Communication, Mapping, AI, etc.)
The provider catalog is managed by platform administrators and is shared across all organizations. Individual organizations cannot add providers to the catalog — they can only activate providers that already exist.
Tier 2: Tenant Instance (Per-Organization)
When an organization activates a provider, a IntegrationInstance is created. This record represents the organization's relationship with the provider:
| Field | Description |
|---|---|
| Organization ID | Which organization activated this provider |
| Provider ID | Which provider was activated |
| Status | Current connection status (pending, connected, error, revoked, suspended) |
| Environment | Production or sandbox |
| Enabled | Whether the instance is currently active |
| Last Connected | Timestamp of the last successful connection |
| Configuration | Provider-specific settings |
Each organization can have at most one instance per provider. If an organization disconnects and later reconnects, the existing instance is reused (status updated from "revoked" to "pending").
Tier 3: User Connection (Per-User)
Each user who authenticates with an integration gets their own IntegrationConnection record. This record owns the encrypted credentials:
| Field | Description |
|---|---|
| Connection Name | Display name (e.g., "Stripe - Nathaniel") |
| Instance ID | Which organization instance this connection belongs to |
| User ID | Which user authenticated |
| Status | Connection health (pending, connected, error, expired, revoked) |
| Connected At | When the connection was successfully established |
| Metadata | Authentication details (grant type, scopes, auth type) |
Multiple users in the same organization can have their own connections to the same instance. The instance status reflects the best connection status — if any user is connected, the instance is considered connected.
Tier 4: Integration Resource (Per-Instance)
Resources are provider-specific manageable items that belong to an instance. Not all providers have resources — only those that expose configurable items:
| Resource Type | Provider | Description |
|---|---|---|
| Sender Email | Postmark | Email addresses used for sending (e.g., hello@otesse.com) |
| Phone Number | Quo (OpenPhone) | Phone numbers for SMS messaging |
| Webhook URL | Stripe | Webhook endpoint URLs for receiving payment events |
| Model Preference | Anthropic | AI model selection (e.g., Claude Opus, Claude Sonnet) |
Resources are managed through the Connected Apps drawer, where administrators can add, edit, delete, and set defaults for each resource type.
How the Tiers Relate
Provider Catalog (global)
└── Instance (org activates provider)
├── Connection (user authenticates)
│ └── Credential (encrypted tokens/keys)
└── Resource (manageable items: emails, phone numbers)
Example flow: Postmark is a provider in the catalog (Tier 1). When Otesse enables Postmark, an instance is created (Tier 2). When Nathaniel enters the Postmark API key, a connection is created with encrypted credentials (Tier 3). Nathaniel then adds sender email addresses like hello@otesse.com and support@otesse.com as resources on the instance (Tier 4).
Integration Categories
Providers are organized into categories for browsing in the catalog:
| Category | Code | Example Providers |
|---|---|---|
| Payment | payment | Stripe, Square, PayPal |
| Accounting | accounting | QuickBooks, Xero, FreshBooks |
| Communication | communication | Postmark, Twilio, Quo (OpenPhone) |
| Marketing | marketing | Mailchimp, SendGrid, HubSpot Marketing |
| Scheduling | scheduling | Google Calendar, Calendly |
| CRM | crm | Salesforce, HubSpot CRM |
| Storage | storage | Google Drive, Dropbox |
| Analytics | analytics | Google Analytics, Mixpanel |
Categories help administrators find the right integration quickly. The All Integrations tab displays provider cards grouped by category with search and filter capabilities.
Connection Status Values
Both instances and connections track their status using a shared set of status codes:
| Status | Meaning | Used By |
|---|---|---|
pending | Created but not yet authenticated | Instance, Connection |
connected | Active and healthy | Instance, Connection |
error | Last health check or auth attempt failed | Instance, Connection |
revoked | User or admin explicitly disconnected | Instance, Connection |
expired | OAuth token expired and refresh failed | Connection only |
suspended | Admin disabled the integration | Instance only |
Understanding these statuses helps administrators diagnose connection issues. A "connected" instance with an "expired" connection means the user's tokens need refreshing, while an "error" instance means the last health check failed for all connections.
On this page