Triggo Documentation
SDK

Properties

Reference for the Property system — 17 property types for declaring typed inputs on actions and triggers.

Properties

The Property namespace provides 17 factory methods for declaring typed input fields on actions and triggers. Each returns a frozen PropertyDefinition that describes the field's type, label, validation, and default value.

import { Property } from "@triggo/connector-sdk";

Base Config

All property types share these common config fields:

FieldTypeRequiredDescription
displayNamestringYesLabel shown in the UI.
descriptionstringNoHelp text describing the field.
requiredbooleanYesWhether the field must be provided.
defaultValuevariesNoDefault value if the user does not provide one.

Property Types

Property.ShortText

Single-line text input.

Property.ShortText({
  displayName: "Name",
  description: "The recipient's name.",
  required: true,
})

Default value type: string

Property.LongText

Multi-line text input.

Property.LongText({
  displayName: "Message Body",
  description: "The full message content. Supports multiple lines.",
  required: true,
})

Default value type: string

Property.Number

Numeric input.

Property.Number({
  displayName: "Quantity",
  description: "Number of items.",
  required: true,
  defaultValue: 1,
})

Default value type: number

Property.Checkbox

Boolean toggle.

Property.Checkbox({
  displayName: "Send Notification",
  description: "Whether to send an email notification.",
  required: false,
  defaultValue: false,
})

Default value type: boolean

Property.DateTime

ISO 8601 date-time string input.

Property.DateTime({
  displayName: "Due Date",
  description: "Task deadline in ISO 8601 format.",
  required: false,
})

Default value type: string (format: date-time)

Property.Array

Array of values.

Property.Array({
  displayName: "Tags",
  description: "List of tags to apply.",
  required: false,
  defaultValue: [],
})

Default value type: readonly unknown[]

Property.Object

Arbitrary key-value object.

Property.Object({
  displayName: "Metadata",
  description: "Custom key-value pairs.",
  required: false,
  defaultValue: {},
})

Default value type: Record<string, unknown>

Property.SecretText

Sensitive text input. The value is masked in the UI and encrypted at rest.

Property.SecretText({
  displayName: "Webhook Secret",
  description: "HMAC secret for signature verification.",
  required: true,
})

Default value type: string (no defaultValue — secrets should not have defaults)

Property.OAuth2

OAuth2 credential reference. Used internally by the auth system.

Property.OAuth2({
  displayName: "OAuth2 Connection",
  description: "Select an OAuth2 connection.",
  required: true,
})

Default value type: Record<string, unknown>

Property.Dropdown

Static dropdown with predefined options.

Property.Dropdown({
  displayName: "Priority",
  description: "Task priority level.",
  required: true,
  defaultValue: "medium",
  options: [
    { label: "Low", value: "low" },
    { label: "Medium", value: "medium" },
    { label: "High", value: "high" },
  ],
})

Default value type: string

The options array contains DropdownOption objects:

interface DropdownOption {
  readonly label: string;  // Shown in the UI
  readonly value: string;  // Stored value passed to run()
}

Dropdown options are included in the auto-generated JSON Schema as an enum constraint.

Property.DynamicDropdown

Dropdown whose options are loaded at runtime from an API call.

Property.DynamicDropdown({
  displayName: "Pipeline",
  description: "Select a pipeline to reference.",
  required: true,
  refreshers: ["workspace_id"],
  options: async (context) => {
    const auth = context.auth as { secret: string };
    const workspaceId = context.values?.["workspace_id"] as string | undefined;

    if (!workspaceId) {
      return {
        disabled: true,
        placeholder: "Select a workspace first",
        options: [],
      };
    }

    const response = await fetch(
      `https://api.example.com/workspaces/${workspaceId}/pipelines`,
      { headers: { Authorization: `Bearer ${auth.secret}` } },
    );
    const pipelines = (await response.json()) as Array<{ id: string; name: string }>;

    return {
      disabled: false,
      options: pipelines.map((p) => ({ label: p.name, value: p.id })),
    };
  },
})

DynamicDropdown Config

FieldTypeRequiredDescription
optionsDynamicDropdownResolverYesAsync function that returns dropdown state.
refreshersreadonly string[]NoProp names that trigger a re-fetch when their values change.

DynamicDropdownResolver

type DynamicDropdownResolver = (
  context: DynamicDropdownResolverContext,
) => Promise<DynamicDropdownState>;

interface DynamicDropdownResolverContext {
  readonly auth: unknown;
  readonly values?: Record<string, unknown>;
}

interface DynamicDropdownState {
  readonly disabled: boolean;
  readonly placeholder?: string;
  readonly options: readonly DropdownOption[];
}

Return { disabled: true } with a placeholder when a dependent field has not been filled yet.

Property.MultiSelect

Static multi-choice dropdown. The UI renders a searchable list with checkmarks and chip-rendered selections.

Property.MultiSelect({
  displayName: "Channels",
  description: "Slack channels to post to.",
  required: true,
  options: [
    { label: "General", value: "general" },
    { label: "Alerts", value: "alerts" },
  ],
});

Default value type: readonly string[]

Property.MultiSelectDynamic

Runtime-resolved multi-choice dropdown. Reuses the same DynamicDropdownResolver contract as Property.DynamicDropdown — returns { disabled, placeholder, options }.

Property.MultiSelectDynamic({
  displayName: "Tags",
  description: "Tags to apply to the new deal.",
  required: false,
  options: async ({ auth }) => ({
    disabled: false,
    options: await fetchTags(auth),
  }),
  refreshers: ["connectionId"],
});

Default value type: readonly string[]

Property.KeyValue

Free-form map of string keys to string values. The UI renders as key/value rows with an add button; each value cell supports {{mentions}} when upstream nodes are present. Rows with empty keys are dropped from the emitted record.

Property.KeyValue({
  displayName: "Custom Headers",
  description: "Additional HTTP headers to attach to the request.",
  required: false,
  keyPlaceholder: "Header name",
  valuePlaceholder: "Header value",
});

Default value type: Readonly<Record<string, string>>

Property.ResourceLocator

Dual-mode picker for large, searchable resources where listing every option upfront isn't feasible (e.g. Notion pages, HubSpot deals, Google Drive files). The UI exposes a Search tab backed by a debounced async resolver and a Paste ID tab for users who already know the identifier.

Property.ResourceLocator({
  displayName: "Notion Page",
  description: "Page to append the new block to.",
  required: true,
  idLabel: "Page ID",
  placeholder: "Search pages…",
  refreshers: ["connectionId"],
  search: async ({ auth, query, cursor }) => {
    const resp = await fetch(`https://api.notion.com/v1/search`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${(auth as { token: string }).token}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        query,
        start_cursor: cursor,
        filter: { property: "object", value: "page" },
      }),
    });
    const data = (await resp.json()) as {
      results: Array<{ id: string; properties: { title: { title: { plain_text: string }[] } } }>;
      next_cursor?: string;
    };
    return {
      items: data.results.map((r) => ({
        label: r.properties.title.title[0]?.plain_text ?? r.id,
        value: r.id,
      })),
      nextCursor: data.next_cursor,
    };
  },
});

ResourceLocator Config

FieldTypeRequiredDescription
searchSearchResolverYesAsync function invoked with the user's query.
refreshersreadonly string[]NoProp names whose changes invalidate the cache.
placeholderstringNoPlaceholder text for the search input.
idLabelstringNoLabel for the "Paste ID" tab input.

SearchResolver

type SearchResolver = (
  context: SearchResolverContext,
) => Promise<SearchResolverResult>;

interface SearchResolverContext {
  readonly auth: unknown;
  readonly query: string;
  readonly cursor?: string;
  readonly values?: Record<string, unknown>;
}

interface SearchResolverResult {
  readonly items: readonly { label: string; value: string }[];
  readonly nextCursor?: string;
}

The canvas inspector debounces queries by 200 ms and calls the connection.searchResource tRPC endpoint, which is rate-limited to 200 requests per minute per user. Return nextCursor to enable paginated scrolling; omit it when the result set is complete.

Default value type: string (the resource ID)

Property.File

Accepts a URL string or a template mention ({{step1.fileUrl}}) that resolves to one at runtime. The UI shows the resolved preview when the value is a literal URL and an "Upload from device" button that is disabled — direct uploads are coming soon.

Property.File({
  displayName: "Attachment",
  description: "Public URL of the file to attach.",
  required: true,
  allowedMimeTypes: ["image/png", "image/jpeg", "application/pdf"],
});

File Config

FieldTypeRequiredDescription
allowedMimeTypesreadonly string[]NoMIME types the connector accepts. Used for client-side validation hints only; runtime validation is the connector's responsibility.

Default value type: string (URL or mention)

Property.MarkdownNotice

Render-only help text that does not carry a value. The property is excluded from the generated JSON Schema and is never passed to run(). Use it inside inspectors to show scope warnings, setup instructions, or gotchas near related fields.

Property.MarkdownNotice({
  displayName: "oauth_scope_notice",
  markdown:
    "This action requires the `drive.file` scope. **Reconnect** the integration if you added it after authorization.",
  variant: "warning",
});

MarkdownNotice Config

FieldTypeRequiredDescription
displayNamestringYesUsed as the node-local identifier only; not rendered.
markdownstringYesMarkdown body. Sanitized to bold, italic, inline code, and links; <script>, <img>, and event handlers are stripped.
variant"info" | "warning" | "success"NoOptional Alert frame. When omitted the notice renders inline without a frame.

MarkdownNotice is the only property type with no required field — it is always non-interactive.

Default value type: n/a (no value emitted)

JSON Schema Generation

All properties are automatically converted to JSON Schema via propertiesToJsonSchema(). The resulting schema is attached to the action/trigger definition as inputSchema and used by the AI system during pipeline generation.

Property TypeJSON Schema Type
ShortText{ type: "string" }
LongText{ type: "string" }
Number{ type: "number" }
Checkbox{ type: "boolean" }
DateTime{ type: "string", format: "date-time" }
Array{ type: "array" }
Object{ type: "object" }
SecretText{ type: "string" }
OAuth2{ type: "object" }
Dropdown{ type: "string", enum: [...] }
DynamicDropdown{ type: "string" }
MultiSelect{ type: "array", items: { type: "string" } }
MultiSelectDynamic{ type: "array", items: { type: "string" } }
KeyValue{ type: "object", additionalProperties: { type: "string" } }
ResourceLocator{ type: "string" }
File{ type: "string", format: "uri" }
MarkdownNoticeomitted from schema

On this page