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:
| Field | Type | Required | Description |
|---|---|---|---|
displayName | string | Yes | Label shown in the UI. |
description | string | No | Help text describing the field. |
required | boolean | Yes | Whether the field must be provided. |
defaultValue | varies | No | Default 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
| Field | Type | Required | Description |
|---|---|---|---|
options | DynamicDropdownResolver | Yes | Async function that returns dropdown state. |
refreshers | readonly string[] | No | Prop 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
| Field | Type | Required | Description |
|---|---|---|---|
search | SearchResolver | Yes | Async function invoked with the user's query. |
refreshers | readonly string[] | No | Prop names whose changes invalidate the cache. |
placeholder | string | No | Placeholder text for the search input. |
idLabel | string | No | Label 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
| Field | Type | Required | Description |
|---|---|---|---|
allowedMimeTypes | readonly string[] | No | MIME 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
| Field | Type | Required | Description |
|---|---|---|---|
displayName | string | Yes | Used as the node-local identifier only; not rendered. |
markdown | string | Yes | Markdown body. Sanitized to bold, italic, inline code, and links; <script>, <img>, and event handlers are stripped. |
variant | "info" | "warning" | "success" | No | Optional 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 Type | JSON 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" } |
| MarkdownNotice | omitted from schema |