Skip to content
Plane

Plane Query Language (PQL) Pro

Plane Query Language (PQL) lets you filter work items using text-based queries. Write structured expressions to quickly find exactly what you need, combine conditions with logic, call built-in functions, and sort and limit the results.

PQL editor

Use the PQL editor

Plane includes an interactive editor that helps you build queries.

To switch to PQL mode, click PQL in the filter bar.

When you start typing in the PQL field:

  1. A dropdown shows available fields and functions
  2. After selecting a field, you see operators
  3. Then you choose or type values
  4. Continue building your query using AND or OR

This guided experience lets you construct queries without memorizing syntax.

Generate a filter with AI

Instead of writing PQL by hand, you can describe the filter you want in plain language and let Plane AI translate it into a PQL query for you.

In the advanced (PQL) filter view, look for the AI filter input with the prompt "Describe your filter in plain language..."

  1. Type what you want in natural language, for example "high priority bugs assigned to me that are overdue."
  2. Press Enter, or click the submit button.
  3. Plane AI generates the matching PQL query, fills it into the PQL editor, and applies it.

The generated query appears in the PQL editor as normal PQL, so you can review it, tweak it by hand, and save it as a view like any other query.

Examples

You typePlane AI produces a query like
"urgent items with no assignee"priority = Urgent AND hasNoAssignee()
"everything due this week in the current cycle"dueDate BETWEEN startOfWeek() AND endOfWeek() AND cycle IN (activeCycle())
"bugs Priya is working on that aren't done"type = Bug AND assignee = Priya AND stateGroup IN (openStates())

When your description names people, cycles, labels, or other entities, Plane AI resolves them to the actual items in your workspace so the query filters correctly and reads with their real names. If you are filtering inside a project, the AI scopes the query to that project. Otherwise it generates a workspace-level query.

If your description is too ambiguous or can't be turned into a valid filter, you'll see "Could not generate a PQL query from the given input." Try rephrasing with more specific terms, or build the filter manually.

Generating filters with AI requires Plane AI to be enabled for your workspace.

Query structure

PQL queries follow a simple pattern:

Field Operator Value

Example:

priority = High

This returns all work items where priority is High.

You can also combine multiple conditions using the logical operators AND, OR, and NOT.

Using AND

type = Bug AND priority = High

This returns work items that match both conditions.

Using OR

state = Todo OR state = In Progress

This returns work items that match either condition.

Using NOT

NOT hasNoAssignee()

This returns work items that do have an assignee.

Combined:

(priority = High AND state in (Backlog, In Progress, Todo)) OR (type in (Bug, Task, Improvements) AND assignee in (Ethan, Parker, Amanda))

Sort and limit results

You can sort results and cap how many are returned by adding ORDER BY and LIMIT clauses to the end of a query.

priority = High ORDER BY dueDate ASC LIMIT 20
  • ORDER BY sorts the results by a field. Add ASC (ascending, the default) or DESC (descending).
  • LIMIT caps the number of results returned. The maximum is 1000.

Fields you can sort by: priority, state, title, assignee, label, module, startDate, dueDate, createdAt, updatedAt, sortOrder, rank.

Save as view

Once you've built your query, click Save view to preserve it for quick access later. See Views for details.

Where PQL works

PQL is available wherever work items are listed:

  • Work items
  • Cycles
  • Modules
  • Views
  • Teamspace work items
  • Workspace views

The exact fields available in the editor depend on what is enabled for the project or workspace you are filtering. For example, cycle and module appear where those features are on, and custom properties appear when your work item types define them.

Fields reference

FieldWhat it searches
titleThe work item title (name) only
textThe work item title and description together, in a single condition

Use text when you want to match a term whether it appears in the title or the body of a work item. For example, text ~ "login" returns work items with "login" in the title or the description.

Common fields

FieldFilters on
typeWork item type
stateWorkflow state
stateGroupState group (Backlog, Unstarted, Started, Completed, Cancelled)
priorityPriority (Urgent, High, Medium, Low, None)
assigneeAssigned members
labelLabels applied
cycleCycle membership
moduleModule membership
milestoneMilestone
mentionMembers mentioned in the work item
createdByWho created the work item
projectProject the work item belongs to
startDateStart date
dueDateDue date
createdAtCreation date
updatedAtLast updated date

Operators reference

Each field supports different operators. The available operators depend on the field type.

All operators available in PQL:

OperatorMeaning
=Matches exactly
!=Does not match
~Contains the text
INMatches any value in a set
NOT INMatches none of the values in a set
<Less than / before
<=Less than or equal to / on or before
>Greater than / after
>=Greater than or equal to / on or after
BETWEENWithin a range
IS NULLThe field has no value
IS NOT NULLThe field has a value

The tables below show which operators apply to each field.

id

The id field matches a work item by its identifier (like WEB-11) or by its sequence number, and it supports comparisons as well as exact matches.

OperatorDescription
=ID matches exactly
!=ID does not match
~Identifier contains text (partial match)
< <= > >=Sequence comparison
BETWEENSequence within a range
INAny of the listed identifiers or sequence numbers

The value can take several forms:

FormMeaningExample
Identifier equalityExact work item keyid = "WEB-11"
Identifier comparisonProject-scoped sequence comparisonid >= "WEB-11" matches project WEB with sequence 11 or higher
Bare integerSequence number only, in any project in scopeid >= 10, id IN (1, 2, 3)
ContainsPartial identifier matchid ~ "WEB"

title

OperatorDescription
=Title matches exactly
!=Title does not match
~Title contains text

text

OperatorDescription
=Title or description matches the text
!=Title or description does not match the text
~Title or description contains the text

type

OperatorDescription
INType is any of the specified values
NOT INType is not any of the specified values
=Type matches exactly
!=Type does not match

state

OperatorDescription
INState is any of the specified values
NOT INState is not any of the specified values
=State matches exactly
!=State does not match

stateGroup

OperatorDescription
INState group is any of the specified values
NOT INState group is not any of the specified values
=State group matches exactly
!=State group does not match

assignee

OperatorDescription
INAssigned to any of the specified members
NOT INNot assigned to any of the specified members
=Assigned to this member
!=Not assigned to this member
IS NULLNo assignee
IS NOT NULLHas an assignee

priority

OperatorDescription
INPriority is any of the specified values
NOT INPriority is not any of the specified values
=Priority matches exactly
!=Priority does not match

mention

OperatorDescription
INMentions any of the specified members
NOT INDoes not mention any of the specified members
=Mentions this member
!=Does not mention this member
IS NULLNo mentions
IS NOT NULLHas mentions

label

OperatorDescription
INHas any of the specified labels
NOT INDoes not have any of the specified labels
=Has this label
!=Does not have this label
IS NULLNo labels
IS NOT NULLHas at least one label

cycle

OperatorDescription
INIn any of the specified cycles
NOT INNot in any of the specified cycles
=In this cycle
!=Not in this cycle
IS NULLNot in any cycle
IS NOT NULLIn a cycle

module

OperatorDescription
INIn any of the specified modules
NOT INNot in any of the specified modules
=In this module
!=Not in this module
IS NULLNot in any module
IS NOT NULLIn a module

milestone

OperatorDescription
INIn any of the specified milestones
NOT INNot in any of the specified milestones
=In this milestone
!=Not in this milestone
IS NULLNo milestone
IS NOT NULLHas a milestone

startDate, dueDate, createdAt, updatedAt

Date fields all support the same operators.

OperatorDescription
=Is this date
!=Is not this date
<Before this date
<=On or before this date
>After this date
>=On or after this date
BETWEENWithin the specified range
IS NULLNo date set
IS NOT NULLA date is set

Date values can be literal dates or date functions, for example dueDate < today() or createdAt >= daysAgo(7).

createdBy

OperatorDescription
INCreated by any of the specified members
NOT INNot created by any of the specified members
=Created by this member
!=Not created by this member

Custom properties

The available operators depend on the property type.

Text

OperatorDescription
=Text matches exactly
!=Text does not match
~Text contains value

Number

OperatorDescription
=Number equals this value
!=Number does not equal this value
<Number is less than this value
<=Number is less than or equal to this value
>Number is greater than this value
>=Number is greater than or equal to this value
BETWEENNumber is within the specified range
IS NULLNo number set
OperatorDescription
INOption is any of the specified values
NOT INOption is not any of the specified values
=Option matches exactly
!=Option does not match
IS NULLNo option selected

Boolean

OperatorDescription
=Value is true or false
!=Value is not true or false

Date

OperatorDescription
=Date is this date
!=Date is not this date
<Date is before this date
<=Date is on or before this date
>Date is after this date
>=Date is on or after this date
BETWEENDate is within the specified range
IS NULLNo date set

Member picker

OperatorDescription
INMember is any of the specified values
NOT INMember is not any of the specified values
=Member matches exactly
!=Member does not match
IS NULLNo member selected

URL

OperatorDescription
=URL matches exactly
!=URL does not match
~URL contains text

Built-in functions

PQL includes functions that cover common scenarios. Type ( after a field, or start typing a function name, and the editor suggests the ones that fit.

Functions come in two kinds:

  • Value functions return a value or a list. You use them inside a condition, on the right side of a comparison or with IN.
  • Condition functions are standalone true/false checks. You use them on their own and combine them with AND, OR, and NOT.

Value functions

Date functions

Return a date. Use them on the right side of a date-field condition.

FunctionReturns
now() / today()Today's date
startOfDay() / endOfDay()Start / end of today
startOfWeek() / endOfWeek()Start / end of this week
startOfMonth() / endOfMonth()Start / end of this month
startOfYear() / endOfYear()Start / end of this year
daysAgo(n) / daysFromNow(n)n days before / after today
weeksAgo(n) / weeksFromNow(n)n weeks before / after today
monthsAgo(n) / monthsFromNow(n)n months before / after today

Examples:

dueDate BETWEEN startOfWeek() AND endOfWeek()
createdAt >= daysAgo(7)

User functions

FunctionReturns
currentUser()The person running the query
inactiveUsers()Deactivated workspace members

Examples:

assignee = currentUser()
assignee IN (inactiveUsers())

Cycle functions

Return a list of cycles. Use them with IN.

FunctionReturns
activeCycle()The cycle active today
completedCycles()Cycles whose end date has passed
upcomingCycles()Cycles whose start date is in the future

Example:

cycle IN (activeCycle())

State group functions

Return a list of state groups. Use them with IN on stateGroup.

FunctionReturns
openStates()Backlog, unstarted, and started groups
closedStates()Completed and cancelled groups
activeStates()Unstarted and started groups

Example:

stateGroup IN (openStates())

Condition functions

Standalone checks that return true or false. Combine them with AND, OR, and NOT. Arguments shown as "user", "date", "text", or n are values you supply; you pick users and dates from the editor's suggestions.

Structure and relationships

Relation functions each take one or more work item identifiers, for example blockedBy("WEB-11", "WEB-20").

FunctionMatches work items thatExample
isTopLevel()Are not a sub-work item (no parent)isTopLevel()
isSubWorkItem()Are a sub-work item (have a parent)isSubWorkItem()
hasChildren()Have at least one sub-work itemhasChildren()
hasRelations()Have at least one relation to another work itemhasRelations()
blockedBy("id", …)Are blocked by the given itemsblockedBy("WEB-11")
blocks("id", …)Block the given itemsblocks("WEB-11")
linkedTo("id", …)Are related to the given itemslinkedTo("WEB-11")
duplicateOf("id", …)Are marked duplicate of the given itemsduplicateOf("WEB-11")
childOf("id", …)Are a child of the given itemschildOf("WEB-11")
parentOf("id", …)Are a parent of the given itemsparentOf("WEB-11")

Assignees and labels

FunctionMatches work items thatExample
hasNoAssignee()Have no assigneehasNoAssignee()
hasNoLabel()Have no labelshasNoLabel()

Dates and status

FunctionMatches work items thatExample
isOverdue()Are past their due date and still openisOverdue()
hasStartAndDueDates()Have both a start date and a due datehasStartAndDueDates()

Count arguments accept a number or a comparison such as ">= 2".

FunctionMatches work items thatExample
hasComments([n])Have comments, optionally a counthasComments(">= 3")
commentedAfter("date")Have a comment on or after the datecommentedAfter("2026-01-01")
commentedBefore("date")Have a comment on or before the datecommentedBefore("2026-06-30")
commentContains("text")Have a comment containing the textcommentContains("blocker")
lastCommentBy("user")Whose most recent comment is by the userlastCommentBy("Priya")
hasLinks([n])Have URL links, optionally a counthasLinks(">= 1")
linkContains("text")Have a link whose URL or title contains the textlinkContains("figma")
hasAttachments([n])Have attachments, optionally a counthasAttachments(">= 2")
attachedBy("user")Have an attachment uploaded by the userattachedBy("Priya")

Worklogs and activity

FunctionMatches work items thatExample
hasWorklogs()Have at least one worklog (logged time)hasWorklogs()
workLoggedBy("user")Have time logged by the userworkLoggedBy("Priya")
workLoggedBetween("from", "to")Have time logged between two datesworkLoggedBetween("2026-01-01", "2026-01-31")
recentlyViewed()You viewed in the last 30 daysrecentlyViewed()