DemandFlow Support Centre

comboKey: Hierarchical Relationships

ReferenceEntity Reference16/04/2026Updated 16/04/2026
How DemandFlow encodes parent-child relationships in a single string. The format, the rules, and how to query against it.

comboKey

The comboKey is a pipe-delimited string that encodes an object's full position in the data hierarchy. It is the primary mechanism for representing parent-child relationships and the basis for almost every list query in DemandFlow.

Format

SUB:{subscriptionId}|{PARENT_ENTITY}:{parentId}|...|ENT:{thisObjectId}

Three rules:

  1. Always starts with SUB:{subscriptionId}, this is the tenant scope. Every query you ever run begins with this segment.
  2. Optionally contains parent segments, one per ancestor in the hierarchy, each in the form {ENTITY_SHORT_CODE}:{parentId}. The order matches the depth of nesting, top-most parent first.
  3. Always ends with |ENT:{thisObjectId}, the trailing segment identifies this object itself.

Examples

# Top-level object (no parent)
SUB:fd6900a2-...|ENT:a8da263a-...

# Patent application (PATENTA) under a patent (PAT)
SUB:fd6900a2-...|PAT:7c2b9f60-...|ENT:38d04a10-...

# Project (PJ) under a portfolio (PORT) under a business unit (BU)
SUB:fd6900a2-...|BU:11111111-...|PORT:22222222-...|ENT:33333333-...

# User-scoped record (favourites, settings)
SUB:fd6900a2-...|USER:46e665bc-...|ENT:99999999-...

The |ENT: rule on POST

When you create an object, you supply the comboKey up to and including the trailing |ENT:, but without the new object's id. The server appends the freshly minted id directly onto that suffix. So you POST:

"comboKey": "SUB:<your-sub-id>|PAT:7c2b9f60-...|ENT:"

And the stored value becomes:

"comboKey": "SUB:<your-sub-id>|PAT:7c2b9f60-...|ENT:<new-id>"

Forgetting the trailing |ENT: produces a malformed combo key, the server appends the id directly to whatever you sent. SUB:abc|PAT:7c2b9f60 would become SUB:abc|PAT:7c2b9f60new-id, silently corrupting the relationship.

Querying with comboKey

The list endpoint uses the comboKey as a prefix. Pass everything down to the level you want to filter on, and you get back every object whose comboKey starts with that prefix.

# All people in your tenant
GET /v1/entities/PPL/SUB:<your-sub-id>

# All patent applications under one specific patent
GET /v1/entities/PATENTA/SUB:<your-sub-id>|PAT:7c2b9f60-...

# All projects across all portfolios in a business unit
GET /v1/entities/PJ/SUB:<your-sub-id>|BU:11111111-...

Why a single string

Every parent-child query becomes a single indexed prefix lookup, fast, indexed, and uniform regardless of how deep the hierarchy is. The tradeoff is that the comboKey is the source of truth for hierarchy, so it must be set correctly on create and is generally not edited afterwards.

Multiple hierarchies: comboKey2 and comboKey3

Some objects sit in more than one hierarchy at the same time. To support this, an entity can declare additional combo keys: comboKey2 and (less commonly) comboKey3. Each is indexed independently, the same single object record can be looked up under any of its parent hierarchies.

Typical uses:

  • LINK objects, every LINK has comboKey (side A) and comboKey2 (side B), so the join is queryable from either end. See LINK Objects: Bidirectional Joins.
  • Multi-parent records, an entity that genuinely belongs to two parents at once. For example, an Action that is a child of a Project (comboKey) and also assigned to a User (comboKey2).
  • Cross-cutting indexes, a third key for an alternate slice (for example, time-bucketed lookups, or an organisation-wide rollup).

Each additional combo key follows exactly the same rules as the primary one: starts with SUB:{subscriptionId}, optional parent segments, and ends with |ENT: on POST. The server appends the new id onto every combo key field present.

Example, a single Action under a Project that is also assigned to a User:

{
  "entity":     "ACTION",
  "level":      300,
  "comboKey":   "SUB:<sub>|PJ:<projectId>|ENT:",
  "comboKey2":  "SUB:<sub>|USER:<userId>|ENT:",
  "name":       "Review draft"
}

Querying additional combo keys

The standard list endpoint GET /v1/entities/{entity}/{comboKey} only queries the primary comboKey index. To query against comboKey2 or comboKey3, use the multi-query endpoint and name the key field in the query line:

POST /v1/query
[{
  "entity":   "ACTION",
  "comboKey": "comboKey2",
  "query":    "SUB:<sub>|USER:<userId>"
}]

The comboKey field in the query line names which indexed key field to match against, comboKey, comboKey2, or comboKey3. The query field is the prefix to match.

See also

combokeyhierarchyparentchildrelationshipsquerysubent

Was this article helpful?

← Back to Knowledge Base