Make API calls

With this functionality, you can use our GraphQL to make API calls

p.query() and p.mutation() give your app the whole Pipefy GraphQL API from inside its iframe — no tokens to manage, no CORS to configure. Use them for anything the context functions don't cover.

⚠️

Calls run as the logged-in user

Both functions execute with the full permissions and access rights of whoever is using your app. Your app is not sandboxed to a narrower scope: if the user can do something in Pipefy, a query from your app can do it too. Only request what your app actually needs, and be deliberate about anything destructive.

p.query(query, variables)

Makes a GraphQL query using the permissions and access rights of the currently authenticated user. To learn more about our queries, visit our documentation.

Parameters

query: a GraphQL query. It accepts queries with operation names, but only ones whose operation type is query. You can learn more about operation names in the GraphQL official documentation. Mutations are not accepted — use p.mutation() for those.

variables (optional): queries with operation names can receive variables. You can learn more about them here.

If you want to test a query, use our interactive GraphQL playground.

Returns

A Promise containing the result of your API call. You can learn more about promises in the MDN documentation page.

Once the promise resolves, the result object may contain data and errors. A response can contain both — a partial success — because the query runs with errorPolicy: 'all'. Check for errors even when data is present; see Call with error and data below. There's more on error shapes in Status and error handling.

The promise resolves even when the call fails outright — see Checking for errors.

Query example calls

Simple call

// Returns the ID of the logged user
p.query('{ me { id } }').then(function(result) {
  console.log(result) // { data: { me: { id: "123", __typename: "User" } } }
});

Call with operation name

// Returns the title of a card
const cardTitleQuery = `
query CardTitle {
  card(id: 1234) {
    title
  }
}`;

p.query(cardTitleQuery).then(function(result) {
  console.log(result) // { data: { card: { title: "My Card", __typename: "Card" } } }
});

Call with variables

// Returns the name of the current pipe
const pipeNameQuery = `
query PipeName($pipeId: ID!) {
  pipe(id: $pipeId) {
    name
  }
}`;

const variables = { pipeId: p.app.pipeId };

p.query(pipeNameQuery, variables).then(function(result) {
  console.log(result) // { data: { pipe: { name: "My Pipe", __typename: "Pipe" } } }
});

⚠️

Use p.app.pipeId, not p.pipeId

Both properties exist, and they are not interchangeable. p.app.pipeId is the ID the GraphQL API expects, and is what you should pass as a variable. p.pipeId carries a short ID on some surfaces, so queries built from it fail with a "not found" error that looks like a permissions problem. The same applies to p.cardId — prefer the ID returned by p.card().

p.organizationId is the organization ID and is safe to pass directly, as in the next example.

Call with error

// Returns an error
// It can be helpful to check those errors when making your implementation

const userIdQuery = 'me { id } }' // Query missing a curly bracket

p.query(userIdQuery).then(function(result) {
  console.log(result) // { errors: "Error: GraphQLError: Syntax Error: Unexpected Name "me"" }
});

Call with error and data

// Returns the org name, but not its members, because the user doesn't have permission to see it
const orgNameAndMembersQuery = `
query OrgNameAndMembers($orgId: ID!) {
  organization(id: $orgId) {
    name
    orgMembers {
      nodes {
        name
      }
    }
  }
}`;

const variables = { orgId: p.organizationId };

p.query(orgNameAndMembersQuery, variables).then(function (result) {
  console.log(result);
  /*
  { data: { organization: { name: "My Org", orgMembers: null, __typename: "Organization" } },
  errors: [ { message: "Permission denied" ... } ] }
  */
});

Checking for errors

⚠️

These promises never reject

p.query() and p.mutation() catch everything internally — including network failures and expired sessions — and hand it back as errors on a resolved result. A .catch() will never fire, so error handling that relies on it silently does nothing. Always inspect result.errors.

p.query('{ me { id } }').then(function (result) {
  if (result.errors) {
    // Covers GraphQL errors, permission denials, and transport failures alike
    console.error('Query failed', result.errors);
    p.showNotification('Could not load your user', 'error');
    return;
  }

  console.log(result.data.me.id);
});

Note that errors is not one consistent shape: a GraphQL response gives you an array of error objects, while a thrown transport error gives you a single Error. Treat it as truthy-or-not rather than always indexing into it.

p.mutation(mutation, variables)

Makes a GraphQL mutation using the permissions and access rights of the currently authenticated user.

Parameters

mutation: a GraphQL mutation. It accepts mutations with operation names, but only ones whose operation type is mutation. You can learn more about operation names in the GraphQL official documentation. Queries are not accepted — use p.query() for those.

variables (optional): mutations with operation names can receive variables. You can learn more about them here.

If you want to test a mutation, use our interactive GraphQL playground.

Returns

A Promise containing the result of your API call, with the same data/errors shape as p.query().

Mutation example calls

Simple call

// Creates a card and returns its id
const createCardMutation = `
mutation {
  createCard(input: {pipe_id: ${p.app.pipeId}, title: "Novo card"}) {
    card {
      id
    }
  }
}`;
p.mutation(createCardMutation).then(function (result) {
  console.log(result);
  /* { data: { createCard: { card: { id: "12", __typename: "Card" } },
  "__typename": "CreateCardPayload" } */
});

Call with operation name

// Deletes a card and returns if the mutation was successful or not
const deleteCardMutation = `
mutation deleteCard {
  deleteCard(input: { id: 1234 }) {
    success
  }
}`;
p.mutation(deleteCardMutation).then(function (result) {
  console.log(result);
  // { data: { deleteCard: { success: true, __typename: "DeleteCardPayload" } } }
});

Call with variables

Prefer variables over string interpolation for anything that comes from user input — interpolating unescaped values into a mutation string breaks on quotes and newlines:

const createCardMutation = `
mutation CreateCard($pipeId: ID!, $title: String!) {
  createCard(input: { pipe_id: $pipeId, title: $title }) {
    card { id }
  }
}`;

const variables = { pipeId: p.app.pipeId, title: userProvidedTitle };

p.mutation(createCardMutation, variables).then(function (result) {
  if (result.errors) {
    p.showNotification('Could not create the card', 'error');
    return;
  }
  p.showNotification('Card created', 'success');
});

Other calls

To learn how to use variables and the error object, see the query examples above — the shapes are identical.

See also