Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions content/_getting-started/actions-and-triggers-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
title: Understanding Actions and Triggers
layout: article
section: Tutorials
order: 3
description: What the standard actions and triggers you see in most components mean, why they're named the way they are, and how to pick between them when building a flow.
category: actions-and-triggers
---

If you've opened a few different components on the platform, you've probably noticed the same handful of names keep coming back: **Upsert Object**, **Lookup Objects**, **Delete Object By ID**, **Get New and Updated Objects Polling**, **Make Raw Request**. That's not an accident, and it's not a lack of imagination — it's a deliberate design choice, and understanding it will save you time in every flow you build afterwards.

This article explains what that choice is, why it looks the way it does, and gives you a starting point for picking the right action or trigger. Two follow-up articles go deeper on each side: [Choosing a Trigger](choosing-a-trigger) and [Choosing an Action](choosing-an-action).

> New to the terms "action" and "trigger" themselves? Start with the [Integration Component Overview](/getting-started/integration-component) — this article assumes you know that a trigger starts a flow and an action consumes what the trigger (or a previous action) produced.

## Why the same few names keep showing up

A connector built by a competitor for, say, Salesforce might expose an action literally called "Create Invoice" and another called "New Lead." That reads nicely, but it only exists because someone wrote code specifically for the `Invoice` object and specifically for the `Lead` object. The moment you need a third object — `Opportunity`, or a custom object your team added last month — that connector either doesn't support it, or a developer has to ship an update.

Our components are built differently, most of them on top of [Open Integration Hub](https://openintegrationhub.org), an API-driven approach where the component doesn't hard-code which object it works with. Instead it exposes one **Upsert Object** action, and you tell it which object — Invoice, Lead, Opportunity, or anything else the connected system exposes — through a configuration field. The trade-off is right there in the name: **Upsert Object** is less immediately readable than **Create Invoice**, but it works with every object the API has, today and after you add a custom one next year, with nothing to wait on from us.

Once you know this, the naming stops looking vague and starts looking like a pattern:

* the **verb** (`Upsert`, `Lookup`, `Delete`, `Get New and Updated`) tells you what happens
* the **noun** (`Object`) is a placeholder you fill in yourself, in the action's or trigger's configuration
* a small number of connectors — the ones tied to a schema-less API, like [Airtable](/components/airtable) or a plain [REST API](/components/rest-api) component — use `Row`, `Record`, or `Resource` in place of `Object`, but the same logic applies

## The standard vocabulary

Across the platform's components, most of what you'll build a flow from boils down to this set. You will not find every one of these in every component — a component only exposes the operations its underlying API actually supports — but if a component has actions or triggers at all, they are very likely drawn from this list.

| You want to... | Look for a trigger or action named... | Type |
|---|---|---|
| Start a flow when a record is created or changed, and the system has to be asked periodically | **Get New and Updated Objects (Polling)** | Trigger |
| Start a flow the instant something happens, pushed by the external system | **Webhook** | Trigger |
| Start a flow the instant something happens, via a live subscription to the source system's event stream | **Subscribe to Events** (and similar) | Trigger |
| Create a record, or update it if a matching one already exists | **Upsert Object** | Action |
| Create a new record only | **Create Object** | Action |
| Change a record you already have the ID for | **Update Object** | Action |
| Fetch one specific record | **Lookup Object (By ID)** | Action |
| Fetch a list of records matching some criteria | **Lookup Objects (plural)** | Action |
| Remove a record | **Delete Object (By ID)** | Action |
| Do something the standard actions above don't cover | **Make Raw Request** | Action |

The last row matters: **Make Raw Request** (sometimes called **Raw Request** or, for GraphQL APIs, **Execute Mutation**) is the escape hatch. It sends a direct call to the connected system's API and hands you the raw response. It's more work to configure, but it means you're never stuck if your use case doesn't fit one of the friendlier actions above — reach for it deliberately, not as your first choice. [Choosing an Action](choosing-an-action) covers when it actually makes sense.

## The dropdown is doing the work

Here is the piece that makes the generic naming workable in practice: every one of these actions and triggers has a configuration field — usually called **Object Type**, **Object**, or **Table** — where you pick the specific thing you want to work with, populated live from your own connected account.

That single dropdown is the difference between an abstract-sounding **Upsert Object** and a concrete result. Pick `Invoice` in that field, and the action becomes, in effect, "create or update an invoice." Pick `Contact`, and it becomes "create or update a contact." The action's name in the component list stays generic on purpose — so it can be reused for any object — but what it *does* in your flow is exactly as specific as what you configure.

Practically, this means:

1. Drag in the action or trigger by its generic name.
2. Open its configuration and set the **Object Type** (or equivalent) field first — most of the other fields on the step depend on it.
3. The input and output fields will update to match the object you picked, often pulling the real field list straight from the connected system.

## Where to go from here

* [Choosing a Trigger](choosing-a-trigger) — a closer look at polling, webhooks, and real-time streams, and how to tell which one a given component offers.
* [Choosing an Action](choosing-an-action) — a decision guide for picking between Create, Update, Upsert, Lookup, Delete, and Raw Request.
* [Creating a Basic Integration Flow](first-flow) — if you haven't built a flow at all yet, start there first.
* Each component's own documentation page (for example, [Salesforce](/components/salesforce), [Microsoft Dynamics Business Central](/components/microsoft-dynamics-business-central), [Shopify Admin](/components/shopify-admin-v2)) lists exactly which of these actions and triggers it supports, plus any configuration fields specific to that system.

## Related links

- [Integration Component Overview](/getting-started/integration-component)
- [Integration Flow Overview](/getting-started/integration-flow)
- [Creating a Basic Integration Flow](first-flow)
- [Understanding Data Sample](/guides/data-sample-overview)
- [Mapping Data](/guides/mapping-data)
66 changes: 66 additions & 0 deletions content/_getting-started/choosing-a-trigger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: Choosing a Trigger
layout: article
section: Tutorials
order: 4
description: A practical guide to the trigger types you'll find across components — polling, webhooks, and real-time flows — and how to decide between them.
category: actions-and-triggers
---

Every flow starts with a trigger. Before you pick a component, it helps to know that almost every trigger on the platform is one of three kinds, regardless of which system it connects to. This article walks through each, and gives you a way to decide which one your flow needs.

> This article assumes you've read [Understanding Actions and Triggers](actions-and-triggers-overview) first.

## The three kinds of trigger

| Kind | Typical name | How it starts your flow | Delay |
|---|---|---|---|
| Polling | **Get New and Updated Objects (Polling)** | The platform asks the connected system, on a schedule, "anything new or changed since last time?" | Minutes, depending on your polling interval |
| Webhook | **Webhook** / **Webhook Subscription** | The connected system pushes a notification to the platform the moment something happens | Seconds |
| Event subscription | **Subscribe to Events**, **Subscribe to Platform Events**, **Subscribe to PubSub**, and similar | The flow keeps a live subscription to the connected system's event stream | Near-instant; whether it needs a real-time flow depends on the trigger — see below |

### Polling triggers

A polling trigger — usually named **Get New and Updated Objects (Polling)** — checks the connected system on an interval you configure (for example, every 15 minutes) and starts your flow once for every record that's new or has changed since the last check. It's the most widely available trigger type, because it only requires the connected system to have a normal read API — it doesn't need the system to support webhooks or streaming at all.

Use a polling trigger when:

* the connected system doesn't offer webhooks for the object you care about
* a delay of a few minutes between something happening and your flow reacting is acceptable
* you want the simplest, most predictable setup — polling triggers rarely need anything configured on the *other* system's side, only here

Keep in mind: a shorter polling interval means faster reactions but more API calls to the connected system, which can run into that system's rate limits. Match the interval to how time-sensitive the flow actually is, not to the shortest interval available.

### Webhook triggers

A webhook-based trigger — often just named **Webhook**, sometimes **Webhook Subscription** — takes the opposite approach: instead of asking, it waits. The connected system calls a URL the platform gives you the moment a relevant event happens, and that call starts your flow immediately. This is faster than polling and puts less load on the connected system, but it requires that system to support sending webhooks, and usually a one-time setup step (registering the webhook URL) either automatically by the component or manually in the connected system's settings.

Use a webhook trigger when:

* the component and the connected system both support it for the event you need
* near-real-time reaction matters for the use case (order placed, ticket created, payment received)

See the [Webhook Overview](webhooks-overview) and [Creating a webhook flow](webhooks-flow) for a full walkthrough of setting one up.

### Event subscription triggers

A growing number of components offer a trigger that subscribes directly to a live event stream from the source system — look for names like **Subscribe to Events**, **Subscribe to Platform Events**, or **Subscribe to PubSub**. Not all of them require a [real-time flow](/guides/realtime-flows): some keep a persistent subscription open and run perfectly well in an ordinary flow, while others genuinely need the real-time flow mode to keep that connection alive. Which one you have is usually spelled out right in the trigger's own name (for example, Salesforce's **Subscribe to platform events (Realtime flows only)**) — check the trigger's name and the component's documentation page rather than assuming either way.

Use an event subscription trigger when:

* the connected system exposes an event-streaming API (platform events, pub/sub, CDC streams) for what you need
* if the trigger's name indicates it needs a real-time flow, you're already using one or are prepared to set one up

## Quick decision guide

1. **Does the component offer a Webhook trigger for what you need, and can you register it?** Use it — it's the best combination of speed and simplicity for most flows.
2. **Do you need near-instant reaction?** Look for an event subscription trigger such as Subscribe to Events or Subscribe to Platform Events, and check its name for whether it requires a real-time flow.
3. **Otherwise, use the polling trigger** and set the interval to match how time-sensitive the flow actually is.

## Related links

- [Understanding Actions and Triggers](actions-and-triggers-overview)
- [Choosing an Action](choosing-an-action)
- [Webhook Overview](webhooks-overview)
- [Creating a webhook flow](webhooks-flow)
- [Building real-time flows](/guides/realtime-flows)
71 changes: 71 additions & 0 deletions content/_getting-started/choosing-an-action.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
title: Choosing an Action
layout: article
section: Tutorials
order: 5
description: A decision guide for the standard actions you'll find across components — Create, Update, Upsert, Lookup, Delete, and Raw Request — and when to reach for each.
category: actions-and-triggers
---

Once a trigger has started your flow, actions are the steps that do something with the data — usually writing it into another system, or fetching more data from one. Most components draw from the same small set of actions. This article walks through each one and when to use it.

> This article assumes you've read [Understanding Actions and Triggers](actions-and-triggers-overview) first.

## Start with the Object Type field

Whichever action you pick, the first thing to configure is almost always which kind of record it applies to — a field usually named **Object Type**, **Object**, or **Table**, and populated live from your connected account. Set this first: the rest of the action's fields (which data it expects as input, which fields it returns as output) are generated from whatever you choose here, so they won't be right — or won't appear at all — until it's set.

## Writing data: Create, Update, or Upsert?

| Action | Does | Needs |
|---|---|---|
| **Create Object** | Always makes a new record | Just the field values for the new record |
| **Update Object** | Changes a record that already exists | The record's ID (or another unique identifier), plus the fields to change |
| **Upsert Object** | Creates a new record, *or* updates a matching one if it finds it | A field to match on (an ID, an external ID, or another unique field) |

If you already know for certain whether the record exists — for instance, you just created it two steps earlier in the same flow and have its ID — **Create** or **Update** is the more direct choice. If you don't know, and the flow needs to work correctly either way (a very common case: "sync this contact, whether or not we've seen them before"), **Upsert Object** is built for exactly that, and saves you from having to do a Lookup first just to decide.

## Reading data: Lookup Object vs. Lookup Objects

Components consistently distinguish singular from plural in this pair, so read the title carefully:

* **Lookup Object (By ID)** — fetches exactly one record, by an ID or another value that uniquely identifies it. Use it when you know precisely which record you want.
* **Lookup Objects (plural)** — fetches a list of records matching some criteria (a filter, a search field, sometimes a full query). Use it when you need several records, or when you don't have a unique identifier to search by.

Some components additionally expose a direct query action — for example **Query** or **Bulk Query** on Salesforce, running a SOQL statement — for cases where a simple field-match lookup isn't expressive enough.

## Removing data: Delete Object

**Delete Object** (sometimes **Delete Object By ID**) removes a single record, identified the same way as **Lookup Object** — usually by ID. There's no "bulk delete" equivalent in most components beyond running this once per record; if you need to remove many records, feed a list into this action from an earlier step in the flow.

## When none of the above fits: Make Raw Request

**Make Raw Request** (also seen as **Raw Request**, or **Execute Mutation** on GraphQL-based components) sends a request directly to the connected system's API, exactly as you construct it, and returns the raw response. Nothing about the object model or field mapping is done for you.

Reach for it when:

* you need an API operation the component doesn't expose as a standard action — for example, a specialized endpoint that doesn't map cleanly to create/update/lookup/delete
* you're working with an API the component only partially covers (components typically implement the endpoints most integrators need, not the entire API surface — see the [Integration Component Overview](/getting-started/integration-component#action) for why)
* you already know the target API well and configuring the URL, method, and body directly is faster than working through a generic action

It's more configuration work — you're responsible for the URL, HTTP method, and request body — so treat it as the option you use when a more specific action doesn't cover your case, not as the default.

## Moving large volumes: Bulk actions

A handful of components — Salesforce is the clearest example, with **Bulk Create/Update/Delete/Upsert** and **Bulk Query** — offer bulk variants built for moving large numbers of records efficiently (tens of thousands at once), usually by accepting or producing a CSV file rather than one message per record. If you're processing more than a few hundred records in a single run and the component offers a bulk action, it will generally perform far better than looping the equivalent single-record action.

## Quick decision guide

1. **Writing a record and you're not sure if it exists yet?** Upsert Object.
2. **Reading exactly one known record?** Lookup Object (By ID).
3. **Reading a list of records matching some criteria?** Lookup Objects.
4. **Removing a record?** Delete Object.
5. **Moving a large batch of records at once, and a Bulk action is available?** Use it instead of the single-record action.
6. **None of the above covers what you need?** Make Raw Request — check the component's documentation page first for the exact input it expects.

## Related links

- [Understanding Actions and Triggers](actions-and-triggers-overview)
- [Choosing a Trigger](choosing-a-trigger)
- [Understanding Data Sample](/guides/data-sample-overview)
- [Mapping Data](/guides/mapping-data)
Loading