Promises

How asynchronous results are returned

Every function on the client is asynchronous. p.card(), p.fields(), p.query(), p.get() and the rest all return a promise. Your app runs in an iframe, so every call crosses the frame boundary — even reads of context Pipefy already has, like p.timezone(), come back asynchronously.

There is nothing Pipefy-specific to learn here — use .then()/.catch()/.finally(), or async/await:

// then / catch
p.card()
  .then(function (card) {
    console.log(card.title);
  })
  .catch(function (error) {
    console.error('Could not load the card', error);
  });

// async / await
async function showCardTitle() {
  try {
    const card = await p.card();
    console.log(card.title);
  } catch (error) {
    console.error('Could not load the card', error);
  }
}

Always handle rejection

Your app runs in an iframe inside Pipefy, so an unhandled rejection is invisible to the user — nothing appears, and nothing explains why. Attach a .catch() (or use try/catch) and tell the user what happened with p.showNotification():

p.get('pipe', 'private', 'token')
  .then(function (token) {
    if (!token) {
      return showConnectPrompt();
    }
    return loadData(token);
  })
  .catch(function (error) {
    console.error(error);
    p.showNotification('Could not reach the server. Please try again.', 'error');
  });

Running calls in parallel

Independent reads should not wait on each other:

Promise.all([p.card(), p.fields(), p.pipe()]).then(function (results) {
  const [card, fields, pipe] = results;
  render(card, fields, pipe);
});

The synchronous exceptions

Only the client's plain properties are synchronous, because they are data rather than functions: p.locale, p.appId, p.pipeId, p.cardId and the rest of the context properties.

Anything you call is asynchronous. If it has parentheses, it returns a promise.

Not a native Promise

The returned object is promise-like, not a native Promise. It implements .then(), .catch() and .finally(), and works with await and Promise.all(), so in practice you can treat it as one. The single difference worth knowing:

p.card() instanceof Promise; // false — use await or .then(), don't type-check it

To get a real native promise, wrap it: Promise.resolve(p.card()).

PipefyApp.Promise

⚠️

Deprecated

PipefyApp.Promise is an alias for the browser's native Promise. It exists only so that older apps referencing it keep working, and will be removed in a future major version. Use Promise directly.

Older versions of this page said the SDK shipped Bluebird. It no longer does — native promises are supported everywhere Pipefy runs, so the polyfill was dropped:

// Don't do this
var Promise = PipefyApp.Promise;

// Just use the global
new Promise(function (resolve) { /* ... */ });