IntegrationsCapabilities
Discovery
Selectors and resource browsing — populate dropdowns and let users pick resources (mailboxes, channels, spreadsheets) from your vendor.
For vendors where users need to browse and select resources. Provides selectors for dropdowns and resource discovery for system-mode selection.
Define the capability
import { defineCapabilityDiscovery } from "@scrydon/sdk-authoring/integrations/define";
const discoveryCapability = defineCapabilityDiscovery({
selectors: [
{
key: "acme.channels",
label: "Channels",
async fetchOptions({ accessToken, query, context }) {
const response = await fetch("https://api.example.com/channels", {
headers: { Authorization: `Bearer ${accessToken}` },
});
const data = await response.json();
return data.channels.map((ch: any) => ({ id: ch.id, label: ch.name }));
},
// Optional — show label for already-selected IDs
async fetchDetail({ accessToken, detailId, context }) {
const response = await fetch(
`https://api.example.com/channels/${detailId}`,
{ headers: { Authorization: `Bearer ${accessToken}` } },
);
if (!response.ok) return null;
const ch = await response.json();
return { id: ch.id, label: ch.name };
},
},
],
resourceDiscovery: {
async discover(params) {
const response = await fetch(
`https://api.example.com/resources?q=${params.query ?? ""}`,
{ headers: { Authorization: `Bearer ${params.accessToken}` } },
);
const data = await response.json();
return data.resources.map((r: any) => ({
id: r.id,
name: r.name,
type: r.type,
}));
},
},
});Selector methods
| Method | Required | Purpose |
|---|---|---|
fetchOptions | yes | Populate the dropdown — returns all matching options |
fetchDetail | no | Resolve a single item by ID — returns one option or null |
fetchOptions fires when the user opens the dropdown — receives accessToken, optional query, and a context record (credential ID, domain, team ID).
fetchDetail fires when the UI needs to display a label for an already-stored value (e.g., "Marketing Team Chat" instead of a raw ID on the canvas). Without it, the UI falls back to the raw ID.
Implement fetchDetail when your vendor supports efficient single-item lookups — most REST APIs do (GET /channels/{id}).
Interface
interface SelectorProviderConfig {
key: string;
label: string;
fetchOptions(params: {
accessToken: string;
query?: string;
context?: Record<string, string>;
}): Promise<Array<{ id: string; label: string; icon?: string }>>;
fetchDetail?(params: {
accessToken: string;
detailId: string;
context?: Record<string, string>;
}): Promise<{ id: string; label: string; icon?: string } | null>;
}