Client SDK overview

Loading the SDK, and the difference between initCall() and init()

Use the Client SDK to interact with our Apps framework directly from your iframe. The SDK provides a PipefyApp global that handles cross-frame communication between your app and the host Pipefy product.

Getting the SDK

Load it from https://platform.staticpipefy.com/pipefy-app.js:

<script src="https://platform.staticpipefy.com/pipefy-app.js"></script>

The SDK is distributed as a plain script that defines a window.PipefyApp global. It is not published to npm, so bundlers cannot import it — load it with a script tag and read it off window. In a framework app, that means guarding on its presence rather than importing it:

if (window.PipefyApp) {
  const p = window.PipefyApp.init();
}

Every page of your app that needs a client — the entry point, plus each sidebar, modal, dropdown and tab page — needs this script tag.

⚠️

Apps only run inside Pipefy

Pipefy appends an appID query parameter when it builds your iframe, and the SDK needs it. Opening your app's URL directly in a browser tab throws:

PipefyApp: no "appID" query parameter found on this page. This app must be opened from within Pipefy, not by navigating to the app URL directly.

This is the most common surprise when testing locally. To exercise your app, register it against your local URL and open it from within Pipefy — see Introduction.

Two ways to start

There are two entry points, and which one you call depends on which page of your app is running.

PipefyApp.initCall(features) — your entry point

The page at your manifest's init_url is loaded once, hidden, and its only job is to declare what your app adds to Pipefy. Call initCall() with one handler per feature:

PipefyApp.initCall({
  'pipe-buttons': function (p, pipe) {
    return [
      {
        text: 'Sprint',
        callback: function (p) {
          p.sidebar({ title: 'Sprint', url: './sprints/new' });
        },
      },
    ];
  },
});

Each handler receives a client and returns a description of what to render — see the individual feature pages for the exact shape each one expects. initCall() also initialises the client internally, so you do not call init() first.

This works only on the init_url page. Calling it from a sidebar or tab page does nothing.

PipefyApp.init() — every other page

The pages you render inside a dropdown, modal, tab, sidebar or pipe view are separate documents in separate iframes. Each one gets its own client:

var p = PipefyApp.init();

p.card().then(function (card) {
  document.getElementById('title').textContent = card.title;
});

init() returns the client object — the p you see throughout these docs. It is safe to call more than once on the same page; the second call returns the existing client rather than building a new one. If you need the client from a module that did not call init(), use PipefyApp.client().

Which to use

Your page is…CallThen
The init_url entry pointPipefyApp.initCall({...})Nothing else. It renders no UI.
A card tab or pipe viewPipefyApp.init()Must also call PipefyApp.render()
A modal, dropdown or sidebarPipefyApp.init()Optionally PipefyApp.resizeTo('#root')

The client is the same object in all cases. What differs is the set of PipefyApp.* helpers available to that surface — see Where each function works.

A note on p

p is just the conventional name for the client, used consistently across these docs and the sample apps. Feature callbacks receive it as their first argument, so you will often see it shadowed:

PipefyApp.initCall({
  'card-buttons': function (p, pipe) {   // p for the root frame
    return [{
      text: 'Open',
      callback: function (p) {           // p for the click context
        p.modal({ url: './modal.html', width: '70%', height: '70%' });
      },
    }];
  },
});

Use the p your callback was handed rather than one captured from an outer scope.

Next