Skip to main content
The Synthetiq Services Framework is how external APIs — GitHub, Slack, Shopify, LLM providers, databases, and any other service — are integrated into Synthetiq apps. Each service is a module that defines its authentication requirements and exposes typed tools. The platform handles everything else: OAuth flows, credential storage, token refresh, and per-user authentication.

What a service is

A service is a self-contained module that wraps an external API. It declares:
  • Authentication type — OAuth2, custom credentials, or none
  • Configuration settings — admin-level settings like base URLs or feature flags
  • Tools — typed functions that call the external API, each with input/output schemas
At runtime, the framework hydrates the service with the authenticated user’s credentials and the admin’s configuration — the service code never stores, fetches, or manages credentials directly.

Why the framework manages credentials

In traditional integrations, every application must implement OAuth flows, token storage, refresh logic, and secret management. This creates problems at scale and is especially problematic when AI agents are building the integrations:
ConcernTraditional approachSynthetiq Services Framework
OAuth flowsEach app implements authorization, callback, token exchangeFramework handles the full OAuth lifecycle
Token storageStored in env vars, databases, or config files per appFramework stores per-user credentials, isolated from app code
Token refreshEach app implements refresh logic, handles expiryAutomatic refresh at request time
System-wide vs per-user authEach app builds multi-user credential managementBuilt-in per-user and system-wide credential models
AI agent accessAgent must manage API keys and tokensAgent calls typed tools, credentials are invisible

Three-tier architecture

Apps call services in their backend routes and workflows via generated, typed service clients. App code does not manage authentication or credentials. At call time, the framework handles credential hydration based on the current user’s authenticated context. It manages OAuth flows for connecting users to services, and can control access to specific services and tools. The service layer contains the service’s configuration (auth type, settings schema) and its implementation code (the actual API calls).
┌────────────────────────────────────────────────────┐
│  Application Layer                                 │
│  Apps consume services via generated clients       │
├────────────────────────────────────────────────────┤
│  Framework Layer                                   │
│  Credential hydration, auth flows, access control  │
├────────────────────────────────────────────────────┤
│  Service Layer                                     │
│  Individual services with API-specific logic       │
└────────────────────────────────────────────────────┘

Example: Slack integration

1. User connects — The app’s settings page includes a connection panel. The user clicks “Connect Slack” and the framework handles the full OAuth flow, storing their credentials securely. 2. App calls the service — A backend route calls the generated client with no auth code:
const channels = await slackClient.listChannels();
3. Framework hydrates credentials — The framework resolves the current user from the app’s auth context, fetches their stored Slack credentials, and injects them into the service. 4. Service executes — The Slack service receives the authenticated context and makes the API call to Slack’s conversations.list endpoint, returning the results to the app.

Next steps