Skip to content
← Back to blogLatch Journal

How to Add External Actions Without Creating Integration Debt

Use extensible plugin architecture to preserve discovery, authorization, and result capture without long-term integration debt.

See how it worksPlugin SDK →

How to Add Plugin Actions Without Creating Integration Debt

Teams want plugin actions to do real work from the product. They do not want every downstream system to become a one-off integration project. The goal is reasonable. The failure mode is familiar.

The first plugin is simple. The second becomes special. Soon the UI knows too much. Authorisation is duplicated. Nobody can explain why a button exists or what evidence it produces.

Integration debt starts when plugin actions are treated like shortcuts instead of bounded system capabilities.

Integration Debt Comes from Unbounded Integration

External actions close the gap between insight and execution. An operator sees a ticket or email thread and wants to trigger a downstream workflow without leaving the product.

The debt appears when the integration has no clear shape. The UI knows too much about the plugin. The plugin knows too much about the UI state. Authorisation is copied into each path. The result is a distributed special case, not a capability.

The right pattern is narrower:

  1. Discover what actions exist.
  2. Decide whether the current user and context may run them.
  3. Execute one action with a bounded payload.
  4. Capture the result in a structured way.

If a plugin action does not fit that model, it does not belong in the operator workflow yet.

Discovery Comes Before Buttons

Good integration design starts with discovery. The platform should ask the plugin what actions are available for the current record. It should not infer them from a static list.

Discovery answers concrete questions:

  • What action IDs exist for this record type?
  • Which actions are available in the current context?
  • What display label and description should the operator see?
  • What inputs, if any, are required before execution?

That matters because actions are usually conditional. A reprocess action may be valid only for certain ticket states. A partner sync action may appear only when a linked record exists.

Discovery should be read-only. If it mutates state, every refresh is risky. If it stays pure, the UI can cache it. It can rerun discovery after state changes. It can render the action list without side effects.

Authorisation Belongs at the Edge of Execution

The worst pattern is to show every action and let the plugin reject the ones that should be hidden.

That wastes operator time and leaks implementation detail. It also encourages the false belief that plugin checks are enough.

Authorisation should be evaluated twice:

  • At discovery time, it decides what is visible.
  • At execution time, it decides what is allowed.

Those checks can use the same policy inputs. They serve different purposes. Discovery keeps the interface accurate. Execution prevents privilege bypass.

The decision should consider user role, record status, account scope, sensitivity, and any required approval path. This matters for actions that affect external systems. Once a workflow leaves your boundary, it may be expensive or impossible to undo. Visibility is not permission.

The Payload Must Stay Bounded and Intentional

Every plugin action should accept a narrow request shape. The request should contain only what the plugin needs to do the job.

That usually means a stable action identifier, the record or ticket identifier, the operator identity, a small set of validated inputs, and an idempotency token or request reference.

It should not contain arbitrary UI state, entire object graphs, or undocumented fields 'for flexibility'.

Loose payloads feel fast at first. They cost more later. They create hidden coupling between the UI, the platform, and the plugin implementation.

Bounded payloads make testing practical. You can simulate a plugin with a handful of well-defined inputs instead of reproducing the entire application state.

Execution Should Be an Observable Event

A plugin action is not finished when the request leaves the platform. It is finished when the result is written back into the ticket timeline.

Every execution should produce a structured record. At minimum, the record must name the operator. It must name the action. It must give the start time. It must state success or failure. It must store the external reference returned. It must record what changed in the local record.

This is where integration debt often hides. Teams build the action but not the result capture. Then they rely on vendor dashboards, shared inboxes, or ad-hoc log searches to reconstruct what happened.

If the result is not in the ticket history, it is not operationally complete.

Operators need the full sequence:

  • The action was discovered.
  • The operator selected it.
  • The platform authorised it.
  • The plugin executed it.
  • The platform persisted the result.

That sequence creates a durable audit trail. It reduces support burden when someone asks why a downstream system changed.

Failure Handling Should Be First-Class

External actions fail in predictable ways. The plugin is unavailable. It rejects the request. It times out. It returns success while the local record cannot be updated.

The platform should distinguish those failures. A generic "failed" state is not enough. Useful categories are denied, rejected, unavailable, timed out, and partial.

This makes retry behaviour safer. It makes support triage easier. It helps product teams decide whether an action needs idempotency, backoff, or human follow-up.

Extensibility Requires a Plugin Contract

The cheapest way to create integration debt is to build the first plugin as if it will be the last.

Define a small contract. Enforce it consistently. A healthy action system usually has these properties:

  • Each plugin is discovered through a standard interface.
  • Actions are described with stable IDs and human-readable metadata.
  • Execution requests are validated before dispatch.
  • Authorisation is platform-controlled.
  • Results are stored in the ticket record, not scattered across systems.

That gives teams room to add new external capabilities without rewriting the operator experience each time. The contract should be opinionated enough to avoid drift, but flexible enough to support multiple plugins and use cases.

A Practical Rule of Thumb Separates Prototypes from Integrations

If you cannot answer these questions, the integration is too loose:

  • Can the platform discover the action without hard-coding it?
  • Can the platform hide it when the user is not allowed to run it?
  • Can the action run with a narrow, validated payload?
  • Can the result be written back as ticket evidence?
  • Can support teams reconstruct the full history later?

If the answer is no to any of those, the integration is still a prototype.

Reducing Work without Reducing Control Is the Operating Principle

External actions are valuable when they reduce swivel-chair work without reducing control.

That only happens when the platform owns discovery, authorisation, and result capture. Plugins own the bounded external work. When those responsibilities blur, integration debt begins to accumulate.

Keep the contract small. Keep the permissions explicit. Keep the result in the record.

That is how plugin actions stay extensible instead of becoming an operational liability.

Continue exploring
Next product pathPlugin SDKAdd plugin actions without hard-coding every downstream workflow into the core product.Related pathProduct OverviewSee how unified triage, approvals, audit trails, and plugins connect.
Related reads
Extend the Platform with Providers Instead of Hard-Coded Custom WorkflowsExtensible plugin architecture lets teams extend workflows safely without brittle custom code or fragmented control logic.Building a Latch Plugin That Reads Handwritten ChequesA Latch plugin that reads handwritten fields from a cheque — payee, amount, cheque number — validates them, and gates credit or reject actions on the result.The First Three Workflows to Govern with Action ProvidersPlugins should start with workflows that need governed approvals, immutable audit logs, and safe external execution in production.
Ready to move beyond reading?

See the same workflow running end to end.

The walkthrough follows one ticket from intake through triage, an approval gate, plugin execution, and the audit record it leaves behind. It runs on the model you choose, inside your own boundary.

Talk to usSee the platform →