Custom App Data

Store your app's own data, and attach links to cards

Your app can store its own data inside Pipefy, so it does not need a database of its own for small amounts of state — an API token, a user preference, an ID mapping to an external system.

It can also attach links to cards, which Pipefy renders in the card's attachment list and hands back to your app later.

Apps can only read and write their own data. One app cannot see another app's keys, and cannot detach another app's attachments.

Storing data

p.set()

p.set(scope, visibility, key, value);

Stores a value against a card, pipe or organization. Returns a Promise.

⚠️

Don't depend on what p.set() resolves to

The write itself is reliable, but the resolved value is not: on some surfaces p.set() resolves to the stored result and on others it resolves to undefined. Use it as a completion signal — p.set(...).then(function () { ... }) — and read the value back with p.get() if you need to confirm it.

Scope

Scope decides what the data is attached to, and therefore who can reach it.

ScopeDescription
organizationAvailable to every pipe across the organization
pipeAttached to the current pipe. Other pipes cannot read it.
cardAttached to the current card. Other cards and pipes cannot read it.

Visibility

Visibility decides which users can reach it, within that scope.

VisibilityDescription
privateOnly the current user. Use this for anything personal — API tokens, per-user credentials.
publicEvery user who can reach that scope

⚠️

Never store secrets as public

public means every user with access to the card, pipe or organization can read the value through your app. Access tokens, refresh tokens, API keys and personal data belong in private, always. Note also that public and private describe visibility inside Pipefy — neither is a substitute for encrypting data you consider sensitive.

Examples

// A personal token — only visible to me, only on this pipe
p.set('pipe', 'private', 'token', 'VERY_IMPORTANT_TOKEN');

// A card annotation everyone on the card can see
p.set('card', 'public', 'emoji', '😈');

// A setting shared by every pipe in the organization
p.set('organization', 'public', 'default_region', 'us-east-1');

value is stored as a string. To keep structured data, serialise it yourself:

p.set('pipe', 'public', 'settings', JSON.stringify({ region: 'us-east-1', retries: 3 }));

Keep stored values small — this is a place for configuration and identifiers, not a general-purpose datastore. If you are storing more than a few kilobytes per key, or need to query across records, use your own backend and store only the reference here.

p.get()

p.get(scope, visibility, key);

Reads back a value your app stored. The scope, visibility and key must match what you passed to p.set()p.get('pipe', 'public', 'token') will not find something written as private.

Resolves to the stored value, or a falsy value if the key was never set.

p.get('pipe', 'private', 'token')
  .then(function (token) {
    if (!token) {
      // First run — nothing stored yet
      return showConnectPrompt();
    }
    console.log(token);
  })
  .catch(function (error) {
    console.error(error);
    p.showNotification('Could not load your settings', 'error');
  });

Reading JSON back:

p.get('pipe', 'public', 'settings').then(function (raw) {
  var settings = raw ? JSON.parse(raw) : { region: 'us-east-1', retries: 3 };
  apply(settings);
});

Card attachments

Attachments are links your app puts on a card. Pipefy shows them in the card's attachment list, and your app can read them back to render its own view of them — which is how the card-tab and card-badges features usually decide what to display.

p.attach()

p.attach({ url, name });

Attaches a link to the current card. Returns a Promise.

p.attach({
  url: 'https://github.com/piedpiper/hotdog-app/pull/1000',
  name: 'Hotdog App PR #1000',
}).then(function (result) {
  console.log(result);
  p.showNotification('Pull request attached', 'success');
}).catch(function (error) {
  console.error(error);
  p.showNotification('Could not attach the pull request', 'error');
});

p.detach()

p.detach(id);

Removes an attachment from the current card. Resolves to true on success. Apps can only detach attachments they attached themselves.

p.detach('231jasd').then(function (result) {
  console.log(result); // true
});

The id comes from p.cardAttachments().

📘

p.dettach()

A misspelled alias, p.dettach(), exists for backward compatibility. Use p.detach().

The attachment round trip

The three functions form one workflow:

// 1. Attach something
p.attach({ url: prUrl, name: 'PR #' + prNumber })
  // 2. Read back everything this app has attached
  .then(function () { return p.cardAttachments(); })
  .then(function (attachments) {
    console.log(attachments);
    // [{ id: "LPpssdkK", url: "https://github.com/...", name: "PR #1000" }]

    // 3. Remove one by id
    return p.detach(attachments[0].id);
  });

p.cardAttachments() is documented on the Get Pipefy data page.

See also