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, notp.pipeIdBoth properties exist, and they are not interchangeable.
p.app.pipeIdis the ID the GraphQL API expects, and is what you should pass as a variable.p.pipeIdcarries 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 top.cardId— prefer the ID returned byp.card().
p.organizationIdis 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()andp.mutation()catch everything internally — including network failures and expired sessions — and hand it back aserrorson a resolved result. A.catch()will never fire, so error handling that relies on it silently does nothing. Always inspectresult.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
- Creating calls with GraphQL — query and mutation structure
- Limits and best practices — rate limits and complexity budgets
- What is GraphQL — start here if GraphQL is new to you
- Status and error handling — error shapes and status codes
- Get Pipefy data — cheaper, context-aware reads that need no query

