Integration SDK v1 Contract
AutoFlow launch freezes the Tier 1 connector surface as v1. New connector work should target these lifecycle hooks, auth abstractions, error semantics, and health reporting rules without needing ad hoc clarification.
Covered connectors
- Slack
- HubSpot
- Stripe
- Gmail
- Linear
- Sentry
- Microsoft Teams
- Jira ticket-sync
Lifecycle hooks
Tier 1 services expose a common execution lifecycle. OAuth-based connectors must support auth flow initialization and completion; all connectors must support connection testing, health reporting, listing active connections, and revocation.
type Tier1OAuthStartResult = {
authUrl: string;
state: string;
expiresInSeconds: number;
codeVerifier?: string; // PKCE connectors only
};
interface Tier1ConnectorLifecycle<CredentialPublic, Health> {
beginOAuth(userId: string): Tier1OAuthStartResult;
completeOAuth(params: { code: string; state: string }): Promise<CredentialPublic>;
connectApiKey(params: { userId: string; apiKey?: string; accessToken?: string }): Promise<CredentialPublic>;
listConnections(userId: string): Promise<CredentialPublic[]> | CredentialPublic[];
testConnection(userId: string): Promise<Record<string, string | undefined>>;
health(userId: string): Promise<Health>;
disconnect(userId: string, credentialId: string): Promise<boolean> | boolean;
}Auth abstractions
Each connector stores a provider-specific public connection shape, but the shared contract freezes the common fields: id, userId, authMethod,tokenMasked, createdAt, and optional revokedAt.
interface Tier1ConnectionPublic<TAuthMethod extends string, TMetadata> {
id: string;
userId: string;
authMethod: TAuthMethod;
tokenMasked: string;
createdAt: string;
revokedAt?: string;
} & TMetadata
// Examples:
// Slack -> { scopes, teamId, teamName? }
// Gmail -> { scopes, emailAddress }
// Stripe -> { scopes, accountId, accountName?, accountEmail?, livemode }Error contract and retry classification
Tier 1 connectors and Jira ticket-sync share the same error taxonomy. This taxonomy is the launch contract and should not change without a major version bump.
auth: invalid credentials, revoked scopes, forbidden accessrate-limit: provider throttling and429responsesschema: malformed request payloads and permanent4xxerrorsnetwork: transport failure before a usable responseupstream: transient provider-side failures and retriable5xxerrors
Automatic retries are allowed only for rate-limit, network, andupstream. Auth and schema failures fail fast.
Retry budgets and recovery expectations for each Tier 1 connector are documented in docs/integrations/tier1-retry-policy.md.
Health reporting interface
All Tier 1 connectors surface the same health envelope so QA, dashboards, and operational runbooks can rely on one shape.
interface Tier1ConnectionHealth<TAuthMethod extends string, TMetadata> {
status: "ok" | "degraded" | "down";
checkedAt: string; // ISO-8601
authMethod?: TAuthMethod;
tokenRefreshStatus?: "not_applicable" | "healthy" | "failed";
details: {
auth: boolean;
apiReachable: boolean;
rateLimited: boolean;
errorType?: "auth" | "rate-limit" | "schema" | "network" | "upstream";
message?: string;
};
} & TMetadataExamples
Start an OAuth flow:
POST /api/integrations/slack/oauth/start
Authorization: Bearer <user-jwt>
{
"authUrl": "https://slack.com/oauth/v2/authorize?...",
"state": "slack_pkce_state",
"expiresInSeconds": 600,
"codeVerifier": "pkce_verifier"
}Consume a health response:
GET /api/integrations/stripe/health
{
"status": "degraded",
"checkedAt": "2026-04-28T14:05:12.001Z",
"authMethod": "oauth2",
"accountId": "acct_123",
"details": {
"auth": true,
"apiReachable": true,
"rateLimited": true,
"errorType": "rate-limit",
"message": "Stripe API rate limit exceeded"
}
}Version migration policy:
v1 -> v2 rules 1. Additive fields or new endpoints may ship in minor releases. 2. Renaming or removing contract fields requires a major version bump. 3. Every breaking change must ship with migration notes and updated examples. 4. Tier 1 contract tests must pass before a new major version is published.
Verification: Tier 1 contract tests live in src/integrations/shared/tier1Contract.test.ts.