Skip to main content

Tags

Apps can be tagged for organization and filtering. A tag assignment is a TagEntity row linking the app to a Tag; tags themselves are managed via the general Tag API (POST /api/tags with { name, color }).

GET /api/apps/{id}/tags

Get all tags assigned to an app.

Authentication: Required

Permissions Required: None (any user who can read the app)

Path Parameters:

ParameterTypeDescription
idstringApp UUID or natural ID
List an App's tagsGET /api/apps/admin%3Aorder-desk/tags
Tag associations embed the full tag (name, color) under inf:tag.
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/apps/admin%3Aorder-desk/tags"
}
},
"start": 0,
"count": 1,
"total": 1,
"_embedded": {
"inf:tag-entity": [
{
"_links": {
"self": {
"href": "https://informer.example.com/api/apps/00000000-0000-4000-8000-000000000001/tags/00000000-0000-4000-8000-000000000002"
}
},
"id": "00000000-0000-4000-8000-000000000003",
"tagId": "00000000-0000-4000-8000-000000000002",
"datasetId": null,
"queryId": null,
"reportId": null,
"templateId": null,
"datasourceId": null,
"jobId": null,
"assistantId": null,
"libraryId": null,
"appId": "00000000-0000-4000-8000-000000000001",
"toolkitId": null,
"integrationId": null,
"source": null,
"sourceId": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"_embedded": {
"inf:tag": {
"_links": {
"self": {
"href": "https://informer.example.com/api/tags/00000000-0000-4000-8000-000000000002"
}
},
"permissions": {
"edit": true,
"delete": true,
"write": true,
"rename": true
},
"id": "00000000-0000-4000-8000-000000000002",
"tenant": "acme",
"name": "Operations",
"color": "teal",
"source": null,
"sourceId": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z"
}
}
}
]
}
}
Captured from the API examples test suite; ids and timestamps are normalized.

Key Fields:

FieldDescription
appIdApp UUID
tagIdTag UUID
_embedded.inf:tagFull tag details (name, color)

Error Responses:

  • 404 Not Found - App doesn't exist or user lacks access

GET /api/apps/{id}/tags/{tagId}

Get a specific tag assignment. The response is the same TagEntity shape as the PUT response below, plus inf:app and inf:tag links.

Error Responses:

  • 404 Not Found - App, tag, or assignment doesn't exist

PUT /api/apps/{id}/tags/{tagId}

Assign a tag to an app (create a TagEntity).

Authentication: Required

Permissions Required: app:assignTags (Designer or higher on the app's team)

Path Parameters:

ParameterTypeDescription
idstringApp UUID or natural ID
tagIdstringTag UUID

No payload is required.

Assign a tagPUT /api/apps/00000000-0000-4000-8000-000000000001/tags/00000000-0000-4000-8000-000000000002
Upsert: assigning an already-assigned tag returns the existing association.
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/apps/00000000-0000-4000-8000-000000000001/tags/00000000-0000-4000-8000-000000000002"
}
},
"id": "00000000-0000-4000-8000-000000000003",
"tenant": "acme",
"tagId": "00000000-0000-4000-8000-000000000002",
"appId": "00000000-0000-4000-8000-000000000001",
"updatedAt": "2026-01-15T16:20:00.000Z",
"createdAt": "2026-01-15T16:20:00.000Z",
"_altid": null,
"datasetId": null,
"reportId": null,
"queryId": null,
"templateId": null,
"source": null,
"sourceId": null,
"datasourceId": null,
"jobId": null,
"assistantId": null,
"libraryId": null,
"toolkitId": null,
"integrationId": null
}
Captured from the API examples test suite; ids and timestamps are normalized.

Upsert Behavior:

  • If the tag is already assigned, returns the existing TagEntity
  • If not assigned, creates a new TagEntity
  • Idempotent operation; always 200 OK

The TagEntity table is shared by every taggable entity type, so the response carries the sibling FK columns (datasetId, reportId, …) as null.

Error Responses:

  • 404 Not Found - App or tag doesn't exist, or user lacks access
  • 403 Forbidden - User lacks assignTags permission

DELETE /api/apps/{id}/tags/{tagId}

Remove a tag assignment from an app.

Authentication: Required

Permissions Required: app:assignTags (Designer or higher on the app's team)

Remove a tagDELETE /api/apps/00000000-0000-4000-8000-000000000001/tags/00000000-0000-4000-8000-000000000002
Responds 200 with an empty body.
Response · 200 · no body
Captured from the API examples test suite; ids and timestamps are normalized.

Error Responses:

  • 404 Not Found - App or tag doesn't exist
  • 403 Forbidden - User lacks assignTags permission

Common Tag Operations

Assign Multiple Tags

const tagIds = ['tag-uuid-1', 'tag-uuid-2', 'tag-uuid-3'];

for (const tagId of tagIds) {
await PUT(`/api/apps/analytics:sales-dashboard/tags/${tagId}`);
}

Get App's Tags

const response = await GET('/api/apps/analytics:sales-dashboard/tags');

const tagNames = response._embedded['inf:tag-entity']
.map(item => item._embedded['inf:tag'].name);
console.log('Tags:', tagNames.join(', '));

Replace Tags

const newTagIds = ['tag-uuid-4', 'tag-uuid-5'];

// Get current tags
const current = await GET('/api/apps/analytics:sales-dashboard/tags');
const currentIds = current._embedded['inf:tag-entity'].map(item => item.tagId);

// Remove tags not in new set
for (const tagId of currentIds) {
if (!newTagIds.includes(tagId)) {
await DELETE(`/api/apps/analytics:sales-dashboard/tags/${tagId}`);
}
}

// Add new tags
for (const tagId of newTagIds) {
await PUT(`/api/apps/analytics:sales-dashboard/tags/${tagId}`);
}

Check if App Has Tag

try {
await GET('/api/apps/analytics:sales-dashboard/tags/tag-uuid-1');
console.log('App has this tag');
} catch (e) {
if (e.statusCode === 404) {
console.log('App does not have this tag');
}
}

Tag Permissions

The assignTags permission requires Designer or higher on the app's team:

  • Members and Member+ users can view tags but not assign or remove them
  • Designers and above can modify tag assignments
  • Superusers can always modify tags

Integration with App List

Tag ids are included as a tags array in the /api/apps-list response and in the single app response (GET /api/apps/{id}), so clients can filter and organize apps without extra requests.