Ownership
Every Query has an ownerId that points at a Principal: either a user (whose
Principal id is its username) or a team (whose Principal id is the team id). The
owner is part of the Query's natural id (ownerId:slug), so transferring
ownership changes the natural id.
These two routes read the current owner and transfer ownership to a different Principal.
GET /api/queries/{id}/owner
Resolve a Query's ownerId to a Principal and return it as HAL.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Query UUID or natural id (ownerId:slug) |
Response:
A HAL Principal body: a flat { id, userId, teamId, tenant } envelope whose
matching subtype is embedded under _embedded. A user-owned Query embeds
inf:user (and teamId is null); a team-owned Query embeds inf:team (and
userId is null). Whichever subtype matches is embedded; the other rel is
absent. This is not the flat { username, displayName, email, avatar } (user)
or { name, slug, memberCount } (team) object.
{
"_links": {
"self": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/owner"
}
},
"id": "admin",
"userId": "admin",
"teamId": null,
"tenant": "acme",
"_embedded": {
"inf:user": {
"_links": {
"self": {
"href": "https://informer.example.com/api/users/admin"
},
"inf:memberships": {
"href": "https://informer.example.com/api/users/admin/memberships"
},
"inf:avatar-upload": {
"href": "https://informer.example.com/api/users/admin/_upload/{uploadId}/avatar-upload",
"templated": true
},
"inf:password": {
"href": "https://informer.example.com/api/users/admin/password"
},
"inf:feed": {
"href": "https://informer.example.com/api/users/admin/feed"
},
"inf:viewed-feed": {
"href": "https://informer.example.com/api/users/admin/_markFeedViewed"
},
"inf:superuser": {
"href": "https://informer.example.com/api/users/admin/superuser"
}
},
"permissions": {
"changeDomain": false,
"changeProfile": true,
"changePassword": true,
"delete": false,
"edit": true,
"reassign": true,
"superuser": true,
"enable": true,
"changeTheme": true,
"lock": true,
"setGlobalPermissions": true,
"manageLogin": true
},
"domain": "local",
"username": "admin",
"displayName": "acme Administrator",
"familyName": "Administrator",
"givenName": "acme",
"middleName": null,
"email": null,
"data": null,
"superuser": true,
"timezone": "America/New_York",
"settings": {
"log": {
"log": false,
"info": false,
"warn": false,
"debug": false,
"error": true,
"remote": false
}
},
"enabled": true,
"source": null,
"sourceId": null,
"lastViewedFeed": null,
"tenant": "acme",
"globalPermissions": {
"ai": false,
"jobCreation": true,
"viewAllTeams": true,
"viewAllUsers": true,
"painlessScriptCreation": true
},
"userFields": {},
"locked": false,
"lockedAt": null,
"loginAttempts": 0,
"passwordSetAt": "2026-01-15T16:20:00.000Z",
"passwordExpiresAt": "2026-01-15T16:20:00.000Z",
"forgotPasswordRequestTime": null,
"mfa": null,
"mfaConfig": {},
"aiMessage": null,
"aiConsent": false,
"hasSharedDatasources": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"initials": "EA",
"colorIndex": 4,
"avatarColor": {
"background": "#81C784",
"text": "#1B5E20"
},
"managesPassword": true
}
}
}
For a team-owned Query the matching inf:team Principal is embedded instead.
{
"_links": {
"self": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/owner"
}
},
"id": "analytics",
"userId": null,
"teamId": "analytics",
"tenant": "acme",
"_embedded": {
"inf:team": {
"_links": {
"self": {
"href": "https://informer.example.com/api/teams/analytics"
}
},
"permissions": {
"addComment": true,
"addMember": true,
"delete": true,
"removeMember": true,
"editMemberRole": true,
"write": true,
"reassign": true,
"assignOwnership": true
},
"id": "analytics",
"name": "Analytics Team",
"description": "Data analytics and reporting team",
"domain": "local",
"data": null,
"icon": null,
"materialIcon": null,
"color": null,
"defaultRole": null,
"source": null,
"sourceId": null,
"lastViewedFeed": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"_changes": null,
"tenant": "acme"
}
}
}
PUT /api/queries/{id}/owner
Transfer ownership of a Query to a different user or team.
Authentication: Required
Permission: query:write on the Query (Designer for ad-hoc, Data Wizard
for embedded; superusers pass).
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Query UUID or natural id (ownerId:slug) |
Request Body:
The route has no Joi payload validation. The entire payload is passed straight
to the Principal lookup as its where clause, so the only reliable key is id,
set to the target Principal's id.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Target Principal id. A user's id is its username; a team's id is the team id. |
id, not usernameA user's Principal id is its username, so the transfer target always goes in
id. There is no username column on Principal, so a { "username": "..." }
payload is unreliable. A payload that resolves to no Principal answers 400.
Example Request (transfer to a user):
{
"id": "annie.larson"
}
Example Request (transfer to a team):
{
"id": "analytics"
}
Response:
Responds 200 (not 201) with the updated Query and a Location header
pointing at the Query's new natural-id lookup. The response body is the full
updated Query: its ownerId, naturalId, and _links now reflect the new
owner. The natural id changes from oldOwner:slug to newOwner:slug.
{
"id": "annie.larson"
}
{
"_links": {
"self": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001"
},
"inf:run": {
"href": "https://informer.example.com/api/queries/annie.larson%3Asales-analysis-query/_run{?progress}",
"templated": true
},
"inf:benchmark": {
"href": "https://informer.example.com/api/queries/annie.larson%3Asales-analysis-query/_benchmark{?progress}",
"templated": true
},
"inf:execute": {
"href": "https://informer.example.com/api/queries/annie.larson%3Asales-analysis-query/_execute{?output,limit,pretty,timezone,applyFormatting}",
"templated": true
},
"inf:comments": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/comments"
},
"inf:dataset": {
"href": "https://informer.example.com/api/queries/annie.larson%3Asales-analysis-query/dataset"
},
"inf:query-shares": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/shares"
},
"inf:query-share": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/shares/{principalId}",
"templated": true
},
"inf:draft": {
"href": "https://informer.example.com/api/queries/annie.larson%3Asales-analysis-query/draft"
},
"inf:query-tags": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/tags"
},
"inf:favorite": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/favorite"
},
"inf:query-tag": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/tags/{tagId}",
"templated": true
},
"inf:export-bundle": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/_export"
},
"edit": {
"href": "https://informer.example.com/api/queries/annie.larson%3Asales-analysis-query/_edit"
},
"inf:owner": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/owner"
},
"inf:user-settings": {
"href": "https://informer.example.com/api/queries/annie.larson%3Asales-analysis-query/settings"
},
"inf:input-templates": {
"href": "https://informer.example.com/api/queries/annie.larson%3Asales-analysis-query/input-templates{?dataType,wildcard}",
"templated": true
}
},
"naturalId": "annie.larson:sales-analysis-query",
"fields": null,
"permissions": {
"assignTags": true,
"changeOwner": true,
"copy": true,
"delete": true,
"edit": true,
"rename": true,
"run": false,
"share": true,
"write": true
},
"id": "00000000-0000-4000-8000-000000000001",
"tenant": "acme",
"ownerId": "annie.larson",
"slug": "sales-analysis-query",
"name": "Sales Analysis Query",
"description": null,
"shared": false,
"embedded": false,
"source": null,
"sourceId": null,
"settings": {},
"inputs": null,
"language": "informer",
"flow": null,
"payload": {
"fields": [],
"groupBy": [],
"distinct": false
},
"defnUpdatedAt": null,
"limit": -1,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"datasourceId": null,
"editingId": null,
"folderId": null,
"datasource": null,
"_embedded": {
"inf:query-language": {
"_links": {
"self": {
"href": "https://informer.example.com/api/query-languages/informer"
}
},
"id": "informer",
"name": "common:ad_hoc_query",
"description": "query-languages:ad_hoc.description",
"image": "/assets/query-languages/images/query-designer.svg",
"color": "blue",
"preProcessors": [
"iqlTclPredicateValidationProcessor",
"resolveLinkRefProcessor",
"iqlPayloadFieldPermissionEvaluator",
"… 8 more items (11 total) — omitted from docs"
]
}
}
}
Transferring to a team uses the team's Principal id; the natural id becomes
teamId:slug.
{
"id": "analytics"
}
{
"_links": {
"self": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001"
},
"inf:run": {
"href": "https://informer.example.com/api/queries/analytics%3Arevenue-query/_run{?progress}",
"templated": true
},
"inf:benchmark": {
"href": "https://informer.example.com/api/queries/analytics%3Arevenue-query/_benchmark{?progress}",
"templated": true
},
"inf:execute": {
"href": "https://informer.example.com/api/queries/analytics%3Arevenue-query/_execute{?output,limit,pretty,timezone,applyFormatting}",
"templated": true
},
"inf:comments": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/comments"
},
"inf:dataset": {
"href": "https://informer.example.com/api/queries/analytics%3Arevenue-query/dataset"
},
"inf:query-shares": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/shares"
},
"inf:query-share": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/shares/{principalId}",
"templated": true
},
"inf:draft": {
"href": "https://informer.example.com/api/queries/analytics%3Arevenue-query/draft"
},
"inf:query-tags": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/tags"
},
"inf:favorite": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/favorite"
},
"inf:query-tag": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/tags/{tagId}",
"templated": true
},
"inf:export-bundle": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/_export"
},
"edit": {
"href": "https://informer.example.com/api/queries/analytics%3Arevenue-query/_edit"
},
"inf:owner": {
"href": "https://informer.example.com/api/queries/00000000-0000-4000-8000-000000000001/owner"
},
"inf:user-settings": {
"href": "https://informer.example.com/api/queries/analytics%3Arevenue-query/settings"
},
"inf:input-templates": {
"href": "https://informer.example.com/api/queries/analytics%3Arevenue-query/input-templates{?dataType,wildcard}",
"templated": true
}
},
"naturalId": "analytics:revenue-query",
"fields": null,
"permissions": {
"assignTags": true,
"changeOwner": true,
"copy": true,
"delete": true,
"edit": true,
"rename": true,
"run": false,
"share": true,
"write": true
},
"id": "00000000-0000-4000-8000-000000000001",
"tenant": "acme",
"ownerId": "analytics",
"slug": "revenue-query",
"name": "Revenue Query",
"description": null,
"shared": false,
"embedded": false,
"source": null,
"sourceId": null,
"settings": {},
"inputs": null,
"language": "informer",
"flow": null,
"payload": {
"fields": [],
"groupBy": [],
"distinct": false
},
"defnUpdatedAt": null,
"limit": -1,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"datasourceId": null,
"editingId": null,
"folderId": null,
"datasource": null,
"_embedded": {
"inf:query-language": {
"_links": {
"self": {
"href": "https://informer.example.com/api/query-languages/informer"
}
},
"id": "informer",
"name": "common:ad_hoc_query",
"description": "query-languages:ad_hoc.description",
"image": "/assets/query-languages/images/query-designer.svg",
"color": "blue",
"preProcessors": [
"iqlTclPredicateValidationProcessor",
"resolveLinkRefProcessor",
"iqlPayloadFieldPermissionEvaluator",
"… 8 more items (11 total) — omitted from docs"
]
}
}
}
Transferring ownership records a queryAssigned Activity entry.
Because the owner is part of the natural id, a transfer changes it from
oldOwner:slug to newOwner:slug. References that use the natural id need to
be updated; references that use the Query UUID are stable across transfers.