Scrydon
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

MethodRequiredPurpose
fetchOptionsyesPopulate the dropdown — returns all matching options
fetchDetailnoResolve 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>;
}
On this page

On this page