- Brand
- Unknown
- Category
- Pending
- Primary Subcategory
- Pending
Integration details
Description
Orgvue is the organizational design and workforce planning platform used by enterprises to model, cost and reshape their organizations. Connect OpenAI to Orgvue to explore workforce data, organizational structures, and planning scenarios. In plain, natural language, ask questions about your workforce data: spans and layers, headcount by function, cost of a proposed structure, the gap between your current and future-state organization, or anything else you might want to know. Ask workforce modelling questions and see the changes happening directly in Orgvue. You’ll get trusted answers grounded in your Orgvue data. See the impact of a scenario before you commit, draft the narrative for a restructure paper, or quickly pull the numbers you need for a board meeting. Access follows your existing Orgvue permissions. OpenAI sees only the workspaces and datasets you're already entitled to, and only when you ask. Orgvue remains the trusted source of workforce data and organizational scenarios, while OpenAI provides a conversational way to interact with them. What you can do: - Query datasets and properties across your Orgvue workspaces - Summarize org structures - reporting lines, spans, layers, vacancies - Ask the agent workforce modelling questions and instantly visualise the impact of changes in Orgvue - Pull metrics and aggregations for reports, papers and presentations - Explain what a dataset contains before you dig into it
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Category
- Pending
- Primary Subcategory
- Pending
- Secondary Subcategories
- None listed
- Brand
- Unknown
- Access
- Account required
- First tracked
- 2026-10-17
- Tool count
- 16
- Geography
- US
The broad Category that contains the Primary Subcategory.
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for Orgvue EU
Get updates when Orgvue EU’s Discoverability Score or category rank changes.
Competitive lineup
16 tools agents can invoke
Execute a sentinel-prefixed PQL script against the current data graph and return its result. PQL is Orgvue's query language for reading/deriving data from the graph (e.g. filtering, selecting, aggregating properties); a script must start with a sentinel such as @NODES or @ALL_NODES, which selects the query's starting scope. @BASELINE starts from the dataset as it was before the user's unsaved changes (including deleted nodes), and BASESTATE <property> reads a row's pre-change value. To find out what changed, call list_changes first and use these only on the properties it reports. Read-only — this never writes to the data graph.
execute_pql_expression
Execute a PQL script against the current data graph and apply its result as a mutation to the working copy of the data — not a preview or read-only check. The script must evaluate to a raw frame whose _mutate field is an array of item-operation objects (e.g. produced by an @UPDATE-style PQL script); anything else is rejected with an error before any change is applied. Operations are grouped and applied by their _viewId (falling back to the current dataset's view when unset), so a single call can touch more than one dataset if the script's payload spans them. The change only affects the current working copy, not the saved/published data — it isn't persisted until the user (or a separate save action) saves. There's no dedicated undo for this: to reverse a mutation before it's saved, call this again with a script that applies the opposite change.
execute_pql_mutation
Get the id and title of the slide the user currently has open in the pack. Cheap, single-purpose check — call this before answering anything scoped to "this slide"/"the current slide" rather than trusting a slide id or title from earlier in the conversation, since the user may have navigated since then. activeSlideId is an internal identifier — never show it to the user; describe the slide to the user by title only from this tool. This tool does NOT return slide type or content detail — for what kind of slide it is (chart/multiViz/dashboard/etc) or how it's built (e.g. "a box grid of location against department"), use get_pack_structure and match this slide's id against its slides list. For the full list of slides, their sections, and content summaries, use get_pack_structure instead.
get_active_slide
Get the datasets that make up the currently open data graph: their human-readable name, dataset type (e.g. POSITIONS, PEOPLE, ROLES — a stable per-tenant dataset-type identifier), and dataset (their structural role relative to the open page: 'nodes' is the current dataset, 'target' is the dataset it's linked to, 'links' is the join dataset itself — the exact same 'nodes'/'target'/'links' values accepted by get_property_metadata's and summarize_properties' dataset parameter). The result is COLUMNAR: each field is a top-level array, parallel-indexed (e.g. name[i]/type[i]/dataset[i] describe the same dataset). Always includes 'nodes'; 'target'/'links' rows are only present if the current dataset has a Links-type join. Call this when you need to orient yourself on what data is available, or when the user asks what data/datasets are open. dataset ('nodes'/'target'/'links') is an internal role label for reasoning about structure and for other tools' dataset parameters — NEVER say 'nodes'/'target'/'links' to the user. When talking to the user (describing what's available, listing candidate properties, or asking them to choose a dataset), always identify each dataset by its name field (e.g. 'Positions file', 'People file') — that's the exact label the user recognizes from the product UI. Do NOT substitute the type field (e.g. 'POSITIONS', 'PEOPLE') as a stand-in for the name, even as a short parenthetical tag like '(People)' — type is a dataset category, not the dataset's identity, and two datasets can share the same type (e.g. two POSITIONS datasets) while having different names, so using type alone can be ambiguous or simply wrong. If you want to also mention the type for extra context, say both, e.g. 'People file (a PEOPLE dataset)', but the name must always be present. This output is for internal reasoning only, not for reciting to the user: describe the datasets in plain language (e.g. 'you have a Positions file dataset linked to a People file dataset').
get_data_graph
Get the structure of the currently open pack: its slides, in order, with id, title, slide type ('singleViz'/'multiViz'/'dashboard'), which section they sit in, and a one-line summary of their content (type + title only, e.g. '1 bar chart: Headcount by Department' — NOT full config). Also returns the currently active slide's id. Call this first to orient yourself on what's already in the pack before placing or editing a chart — don't guess. Every slide's id here is an internal identifier — never show it to the user; a person never knows or supplies a slide id, only its title. sectionPath is the section names from root to the slide's section, root-to-leaf order, empty if the slide is at the top level (not inside any section).
get_pack_structure
List properties with metadata for ONE dataset: key, name, description, type, tags, aliases, and flags (isRequired, isGenerated, isEvaluated, isOnDemand, isMultiline, isPack), plus lookup config where applicable. key/name/type are dense arrays, parallel-indexed across properties (e.g. name[i] and type[i] describe the same property as key[i]). isRequired/isGenerated/isEvaluated/isOnDemand/isMultiline/isPack are SPARSE: each is an array of the indices where that flag is true (e.g. isPack: [3, 17] means only properties at index 3 and 17 are pack properties; every other index is false). description/tags/aliases/lookup are also SPARSE: each is an object mapping index -> value, containing an entry ONLY for properties with a non-empty value at that index (e.g. lookup: {"5": {...}} means only the property at index 5 has lookup config; absence from the map means empty/null, not an error). A lookup config of type "dataset" or "expr" (a script-defined lookup) also includes allowedValues — the configured/permitted set for that property. For a "dataset" lookup these are always strings; for an "expr" lookup they keep their original JSON type, so the number 5 and the string "5" are reported as two distinct entries, never merged. Check allowedValues before writing a mutation that sets one of these properties to a new value — never guess a permitted value. allowedValues is capped at 100 entries; when truncated, allowedValuesTruncated: true is also present, meaning more values exist than are listed — call summarize_properties for that property if you need its full value distribution rather than assuming this list is complete. allowedValues is best-effort and may be absent even for a "dataset"/"expr" lookup if resolution fails (e.g. a broken dataset reference) — treat a missing field as "couldn't be resolved," not "nothing is allowed." A lookup config of type "join_lookup", or a property with no lookup config at all despite having lookupType "auto" in its underlying setup, never gets this field — there is no values-enumeration mechanism for those today. type uses PQL's vocabulary: 'boolean', 'text', 'number', 'date', or 'unknown' (not the dataset's dimension/measure/temporal terms). isGenerated means the property is Orgvue-generated (Depth, Span, Layers, etc.), not user data. isPack means it exists solely in the pack, not the underlying dataset. isEvaluated means the property's value is computed rather than static, though this is an approximate signal and may include properties that aren't specifically script-driven. isOnDemand means that computation is a calculation the user runs on demand rather than automatically. Use dataset to choose which single dataset to list properties for: 'nodes' is the current dataset, 'target' is the dataset it's linked to (e.g. People linked to Activities), 'links' is the join dataset itself. Each call covers exactly one dataset — if you need to check more than one (e.g. surveying where a property named 'fte' actually lives, across nodes/target/links), call this tool again for each dataset and compare the returned key/name lists yourself. If the current data graph has more than one dataset and you call this without datasetsConfirmed: true, this tool returns a message asking you to clarify with the user instead of property data — follow that message's instructions, then call again with dataset set accordingly and datasetsConfirmed: true. The underlying links dataset also has from_id:<key>/to_id:<key> properties that are pass-through copies of every nodes/target property — these are ALWAYS excluded from the returned links properties, since they're never links' own data; call this again with dataset: 'nodes' or 'target' to see the real property instead. 'target'/'links' only work if the current dataset has a Links-type join; requesting them otherwise returns an error. This output is for internal reasoning only, not for reciting to the user: describe properties in plain language grouped by type or purpose when summarizing, and when referring to which dataset a property came from, use its name field from get_data_graph (e.g. 'Positions file') — not 'nodes'/'target'/'links' (internal labels) and not the dataset's type field (e.g. 'POSITIONS') either, since type is a category, not the dataset's identity. If you're using results from multiple calls to ask the user which of several matching properties they mean (e.g. before calling summarize_properties), see summarize_properties' error message for the required presentation format (one enumerated line per candidate, dataset name repeated on every line).
get_property_metadata
Get the _id and _label of every node currently selected by the user in the canvas/sidebar. Returns { _id: [], _label: [] } (empty arrays, not an error) when nothing is selected. The selection is live: the user can change it at any time by clicking, without saying so in the chat. Call this again EVERY time the user refers to their selection ("selected", "these", "this node"), even if you called it moments ago — never reuse a selection from earlier in the conversation. The result is COLUMNAR: _id[i] and _label[i] describe the same node. This only ever covers the nodes dataset — node selection is not a concept on target/links datasets. _id is an internal identifier for cross-referencing with other tools (e.g. execute_pql_mutation) — never recite raw _id values to the user. When describing the selection to the user, use _label (and count, e.g. "3 nodes selected: ..."); if multiple selected nodes share the same _label, distinguish them descriptively (e.g. by position or other context) rather than by showing their _id.
selected_nodes
Get the current browser tab title
get_tab_title
List the unsaved changes in ONE dataset. Use this FIRST for any question about changes — how many, what kind, which nodes, what values — never discover changes by comparing every property with BASESTATE in PQL. Changes are live: the user can edit, add, delete or save at any time between messages, so call this again for EVERY question about changes, including follow-ups. Never answer from an earlier result or the conversation history. The default summary is cheap, so re-calling costs little. By default the result is a SUMMARY: totals (nodes new/updated/deleted across the whole dataset), sortOrderChanged (true when nodes were reordered — a dataset-level change that is saved with the others but isn't attributed to nodes, so mention it even when totals are all zero) and byProperty (parallel arrays key/name/cells: how many updated cells each property has). Ask for detail: true — narrowed with propertyKeys, changeTypes or autoIds — only when you need node names or before/after values. A DETAIL result is COLUMNAR and SPARSE. nodes.id and nodes.label are parallel arrays; nodes.new and nodes.deleted list positions in nodes, and a node listed in neither is updated. changes maps each property key to { name, node, before, after }: name is the property's display name, and node/before/after are parallel arrays where node[i] is a position in nodes (before is null for new nodes). A node with several changed properties appears once in nodes and once in each property's block. totals ignores filters; matching is the node count after filters; when truncated is true only the first limit nodes are listed (in no meaningful order), so narrow the filters or tell the user the list is partial. nodes.id values belong to the property named by idProperty, not _id — in PQL, filter with FILTER <idProperty> EQ "<id>". Detail limits: new nodes' values are left out unless newNodeValues is true or propertyKeys names them, and properties set to 0, false or blank are never listed for new nodes. Deleted nodes have only an id and label; for their original values use execute_pql_expression with @BASELINE | FILTER _change EQ "deleted". Dates are yyyy-mm-dd without a time, text that looks like a number may appear as a number, and list or multi-value properties appear as null — when an exact value matters, read that property with BASESTATE in execute_pql_expression. If before and after look identical, the change is in something the export can't show (surrounding whitespace, time of day, list contents): say so, and read that property with BASESTATE rather than reporting "no change". Only the net state is kept: there is no edit history, and a value edited back to its original is not a change. Use 'dataset' to choose the dataset. If the current data graph has more than one dataset and you call this without datasetsConfirmed: true, this tool returns a message asking you to clarify with the user instead of changes — follow it, then call again. This output is for internal reasoning only: describe changes in plain language using node labels and property names, never raw ids or the internal 'nodes'/'target'/'links' labels.
list_changes
List the datasets available to the user in the current tenant, by name. Returns { datasets: [...] }, each with id, name, dataset type (e.g. POSITIONS, PEOPLE, ROLES — a stable per-tenant dataset-type identifier), and when it was last modified. At most 100 datasets come back at a time. If there are more, a truncated field gives the number shown and the total — say so rather than implying the list is complete, and narrow with nameContains or typeIs instead of asking for more. Call this to find a dataset before opening one with load_dataset_and_pack, and whenever the user asks what data they have. Don't guess a dataset id — it only ever comes from here. A dataset always opens together with a pack, so opening one also needs a pack id from list_packs. Every id here is an internal identifier — never show it to the user; a person never knows or supplies a dataset id, only its name. Always identify a dataset to the user by its name, never by its type: type is a category, not the dataset's identity, and two datasets can share a type (e.g. two POSITIONS datasets) while having different names. To give extra context, say both, e.g. 'People file (a PEOPLE dataset)', but the name must always be present. Dataset names are NOT unique — two datasets can have the same name and the same type, differing only by id. If more than one dataset matches what the user asked for, don't just pick one: tell them there are several of that name and ask which they mean, distinguishing them by when they were last modified (never by id). Archived datasets, and dataset types this user can't open, are not listed. Two filters, for two different questions, and they combine. Use nameContains when the user names a dataset ('open the headcount file'). Use typeIs when they ask about a category of data ('what people data do we have?'), or when you are exploring a tenant you know nothing about and have no name to search for. Filter here rather than listing everything and narrowing yourself — with the cap in play, what you'd be filtering may not be the whole set. typeIs matches the type exactly (case-insensitive), so pass a type string exactly as it appears in a previous result's type field. It narrows to a category, not to one dataset: a tenant can hold many datasets of the same type, so expect several results and still identify each by name. This lists the datasets the user could open; to see the datasets making up the data graph that is already open, use get_data_graph instead. An empty list means this tenant has no datasets matching the request, not that the tool failed.
list_datasets
List the packs available to the user in the current tenant, most recently modified first. Returns { packs: [...] }, each with id, name, description, and when it was last modified. At most 100 packs come back at a time. If there are more, a truncated field gives the number shown and the total — say so rather than implying the list is complete, and narrow with nameContains instead of asking for more. Call this to find a pack before opening one with load_dataset_and_pack, and whenever the user asks what packs they have. Don't guess a pack id — it only ever comes from here. A pack always opens together with a dataset, so opening one also needs a dataset id from list_datasets. Every id here is an internal identifier — never show it to the user; a person never knows or supplies a pack id, only its name. Always identify a pack to the user by its name. Only live packs are listed — archived ones are held separately and are not reachable from here, so a pack the user remembers but can't find here may have been archived or deleted. nameContains narrows the list to packs whose name contains that text — use it when the user names a pack, rather than listing everything and filtering yourself. An empty list means this tenant has no packs matching the request, not that the tool failed.
list_packs
List skills available from the selected source. Each result includes a key — pass that key to load_skill to load the full skill body.
list_skills
Open a pack against a dataset, navigating the user away from whatever page they're on. A pack and a dataset always open together — the workspace can't show one without the other — so this tool takes both, and there is no way to open just a pack or just a dataset. Both ids must come from list_packs and list_datasets: call those first to find what the user means. Never guess an id, and never ask the user for one — a person knows a pack or dataset by its name, not its id. The user usually names only one of the two (e.g. 'open the headcount pack'). Don't invent the other: if they didn't say which dataset, ask, offering the datasets from list_datasets by name. Remember that dataset names are not unique, so where several share a name, tell them apart by when they were last modified. This moves the user's screen, so only call it when the user has asked to open, load, go to, or switch to a pack or dataset. Only works when the user doesn't already have a pack and dataset open. If they do, this returns a message saying so instead of opening anything: switching would navigate away and lose any unsaved changes there, so that's the user's own call — tell them what's already open and let them switch themselves rather than retrying. Report what happened by the pack's and dataset's names, never their ids. After this returns, the workspace is loading: the tools that read the open pack or data (get_pack_structure, get_active_slide, get_data_graph) may briefly still describe the previous page, so re-check rather than assuming the new one is ready.
load_dataset_and_pack
Load a skill by key, from list_skills' results. Pass the same source used for list_skills, if any was given.
load_skill
Get value statistics for one or more properties in ONE dataset: count, null count, distinct count, numeric count, data types present, and (for numeric properties) sum/average/standard deviation/min/max/quartiles. The result is COLUMNAR: each field is a top-level array, parallel-indexed across the requested properties. Every response includes key and name (the human-readable property name) alongside the stats, so results are self-describing. Complements get_property_metadata, which describes property definitions (type, tags, flags, lookup config) but not their values — use get_property_metadata first to find a property's key (and which dataset it's in), then call this to understand what its values actually look like. Every call must include propertiesConfirmed: true, and ONLY when the user's own message named an exact property key or exact display name — never when they used a generic or partial term (e.g. 'my fte property', 'my cost property'). If you haven't confirmed, this tool returns a message instead of statistics, with instructions for how to ask the user — follow those, then retry with propertiesConfirmed: true. Use dataset to choose which single dataset the given propertyKeys belong to: 'nodes' is the current dataset, 'target' is the dataset it's linked to (e.g. People linked to Activities), 'links' is the join dataset itself. Each call covers exactly one dataset — if the same property name exists in more than one dataset and the user wants to compare them, call this tool again per dataset (with the resolved key for that dataset) and present the results together yourself. 'target'/'links' only work if the current dataset has a Links-type join; requesting them otherwise returns an error. If the current data graph has more than one dataset and you call this without datasetsConfirmed: true, this tool returns a message asking you to clarify with the user instead of statistics — follow that message's instructions, then call again with dataset set accordingly and datasetsConfirmed: true. This applies regardless of what you already know or learned earlier in the conversation (including from a prior get_property_metadata call) — prior knowledge that a property exists in multiple datasets is a reason to ask, never a reason to skip asking. For non-numeric properties, only count/count_null/count_distinct/types are meaningful; the numeric fields will be null. This output is for internal reasoning only, not for reciting to the user: describe the distribution in plain language, and if you called this for the same property across more than one dataset, be explicit about which dataset each result is from — using its name field from get_data_graph (e.g. 'Positions file'), not the internal 'nodes'/'target'/'links' labels and not the dataset's type field (e.g. 'POSITIONS') either, since type is a category, not the dataset's identity.
summarize_properties
Run ("trigger") ONE on-demand property's stored calculation and write the freshly-computed values back into the data graph, for every item in the dataset — not just filtered/selected ones. This tool runs exactly one on-demand property per call, deliberately — on-demand properties are often chained (one's formula reads another's on-demand output), so the user usually cares about the order they run in, not just the set. If the user wants several run, call this once per property, in the order the user gives (or ask them for the order if it isn't obvious), rather than assuming they're independent. On-demand properties have isOnDemand: true (evaluationMode 'ondemand') in get_property_metadata: unlike auto-calculated properties, their value only updates when this is explicitly called, so their current stored value may be stale. Use get_property_metadata first to find candidates and their exact keys — this tool does not search or guess property names, and errors if the requested key doesn't exist or isn't an on-demand property. Every call must include propertiesConfirmed: true, and ONLY when the user's own message named an exact property key or exact display name, or explicitly confirmed a specific candidate you offered. If you haven't confirmed, this tool returns a message instead of running anything — call get_property_metadata, present the real candidates, and wait for the user to pick before retrying. Use dataset to choose which single dataset propertyKey belongs to: 'nodes' is the current dataset, 'target' is the dataset it's linked to, 'links' is the join dataset itself. 'target'/'links' only work if the current dataset has a Links-type join; requesting them otherwise returns an error. If the current data graph has more than one dataset and you call this without datasetsConfirmed: true, this tool returns a clarification message instead of running anything — ask the user which dataset they mean, identifying it by its name field from get_data_graph, never the internal 'nodes'/'target'/'links' labels or the dataset's type field, then retry with dataset set accordingly and datasetsConfirmed: true. Returns counts of items updated, partially updated, and failed. Report these to the user rather than assuming full success — any partial or failed count means some items didn't receive the new value (e.g. due to permissions) and is worth surfacing.
trigger_on_demand_calculation
Orgvue EU ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Orgvue EU's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.