Integration Contract
Define a valid manifest, connect each capability and action to a real hook, and return safe authentication, sync, and fulfillment results.
On this page
The registry fails fast on an invalid manifest
const manifest = {
key: 'acme-tickets',
version: '1.0.0',
provider: { name: 'tickets.acme.example' },
displayName: 'Acme Tickets',
description: 'Import events and fulfill ticket purchases.',
capabilities: [
'account', 'groups', 'events', 'ticket_inventory',
'ticket_fulfillment', 'manual_sync', 'scheduled_sync',
],
fulfillment: { retrySafety: 'manual_reconciliation' },
auth: {
methods: [{
key: 'token',
label: 'Access token',
flow: 'token',
fields: [{
name: 'token', label: 'Access token', type: 'token', required: true,
}],
}],
},
catalog: { authType: 'token', enabledByDefault: false },
actions: { refresh: true, configure: false, disconnect: true },
};| Field | Requirement |
|---|---|
key | Unique lowercase kebab-case registry key used in code paths and URLs. |
version | Semantic version describing the adapter contract. |
provider.name | Stable non-empty name used to resolve the existing Provider catalog row. |
displayName | User-facing provider name. |
description | Safe user-facing purpose; do not expose operational details or credentials. |
capabilities | Unique supported values that exactly match implemented hooks. |
auth.methods | At least one valid direct, token, challenge, or OAuth method. |
Capabilities declare dependencies; actions declare controls
| Declaration | Contract |
|---|---|
account | getAccount is mandatory for every connection. |
groups | listGroups; use a stable synthetic group only when the provider has none. |
events | groups plus listEvents. |
ticket_inventory | listEvents embeds canonical ticket classes, prices, currency, and availability on each event. |
ticket_fulfillment | fulfillOrder with durable idempotency and reconciliation behavior. |
credential_refresh | refreshCredential and refreshable credential metadata. |
manual_sync | Allows an authenticated account refresh through the common sync service. |
scheduled_sync | Enrolls the adapter in the shared bounded scheduler; no provider-specific cron is required. |
Optional actions control the operator interface. Refresh must befalse unless manual_sync is declared. Configure must befalse unless a real configure() hook exists. Disconnect can expose the common owner-scoped operation and an optional provider revocation hook. A missing action means unavailable behavior, not a placeholder button.
- Use
actions.refresh: trueonly for the common manual-sync path. - Use
actions.configure: trueonly when configuration can be validated and applied through the adapter hook. - Use
actions.disconnect: trueto expose credential clearing and imported-resource deactivation; upstream revocation runs only when the adapter implements its optional disconnect hook, and historical records remain retained. - Use
sync.resourceConcurrencyfor bounded persistence tuning; the platform clamps it to 10.
Choose one of four authentication flows
| Flow | Typical use | Required hooks |
|---|---|---|
direct | Email/password or another one-step login. | authenticate |
token | A user-supplied or internal access token. | authenticate |
challenge | Phone or email verification code. | beginAuth and completeAuth |
oauth | Redirect or authorization challenge. | beginAuth and completeAuth |
Auth method keys use snake_case. Supported field types are email,password, tel, text, token, andurl, with optional required, minimum-length, pattern, and safe validation message metadata. Authentication hooks also receive the resolved Provider record so they can read protected application configuration.
Start securely
Validate the method and fields, then let the platform sign short-lived opaque auth state bound to the provider, method, owner, acting user, team account, fields, and upstream challenge.
Echo state unchanged
The client returns the opaque auth_state. It cannot replace the original subject or fields during completion.
Return a credential envelope
Return a required access token and optional expiry and refresh token, plus an optional canonical account and safe metadata.
Refresh only when declared
A credential-refresh adapter returns the same envelope shape from refreshCredential and distinguishes invalid credentials from transient provider failures.
Errors are typed, safe, and operationally useful
- Use a stable code, a safe public message, an appropriate status, and retryable only when repetition is safe.
- Never attach passwords, tokens, codes, cookies, authorization headers, full provider responses, signed URLs, or private buyer data to errors or raw logs.
- Treat every auth field, challenge, provider payload, webhook, and payment field as untrusted input.
- Scope all work to the platform-supplied user and resolved Provider; never trust ownership IDs returned by the provider or sent by a client.
- Apply application and edge/shared-store throttling to password, token, and verification-code attempts.
- Confirm the provider permits every official and private/organizer workflow before shipping it.
All clients use the common integration service
| Operation | Behavior |
|---|---|
| Authenticated catalog and manifest | Return provider presentation with explicit enabled and connection state while removing internal methods and Provider.config. |
| Anonymous app catalog | GET /integrations/public and /integrations/public/:provider return only enabled Provider identity, reviewed app metadata, public manifest fields, and the sanitized checkout_fee projection. |
| Start and complete authentication | Validate manifest fields, throttle attempts, bind signed state, persist credentials, fetch the canonical account, and run initial sync. |
| Manual account sync | Verify ownership of the Provider_Account, invoke the same adapter/persistence path, and return success, partial, or failed counts. |
| Disconnect | Attempt optional provider revocation, clear stored credentials, advance the connection generation, stop scheduled selection, hide groups, and mark imports unavailable while retaining history. |
| Scheduled sync and refresh | Lease eligible accounts through shared bounded queues and dispatch only capabilities declared by the resolved Provider integration. |
| Fulfillment | Enter through the integration service with the same purchase idempotency key; never call the adapter directly from payment, webhook, retry, or recovery code. |