Assets
Assets is Jira Service Management's configuration management database — the objects an organisation tracks, the schemas and types that describe them, and the AQL that searches them. createAssetsClient covers its sixty Cloud endpoints.
Assets is the one surface in this library that does not answer on your site's own host. Its base URL is https://api.atlassian.com/ex/jira/{cloudId}/jsm/assets/workspace/{workspaceId}/v1, so the client is built from its own configuration rather than shared with the others.
import { createServiceDeskClient, createAssetsClient } from 'jira.js';
const auth = { type: 'basic', email: 'you@example.com', apiToken: 'YOUR_API_TOKEN' } as const;
const serviceDesk = createServiceDeskClient({ host: 'https://your-domain.atlassian.net', auth });
const [workspace] = (await serviceDesk.assets.getAssetsWorkspaces()).values ?? [];
const assets = createAssetsClient({ workspaceId: workspace.workspaceId, auth });
const object = await assets.objects.loadObject({ id: '42' });workspaceId is required and explicit. A site has one, serviceDesk.assets.getAssetsWorkspaces() is what returns it, and it does not change — so fetch it once and keep it in configuration rather than paying for the lookup on every start.
Assets needs Jira Service Management Premium. On a site without it the workspace list comes back empty, and there is nothing to point a client at.
Authentication
Every strategy the rest of the library takes works here, with one difference in how the address is found.
- API token or personal access token — the client goes to
https://api.atlassian.comdirectly. Nothing else to configure. - OAuth 2.0 (3LO) — leave
hostunset. The client resolves your cloud id and routes throughhttps://api.atlassian.com/ex/jira/{cloudId}, exactly as it does for every other surface. The scopes Assets uses are thecmdbfamily:read:cmdb-object:jira,write:cmdb-object:jira,read:cmdb-schema:jiraand so on, granted per operation and named in each endpoint's documentation.
const assets = createAssetsClient({
workspaceId,
auth: { type: 'oauth2', clientId, clientSecret, accessToken, refreshToken, expiresAt },
});To send requests through the gateway address explicitly — inside a Connect or Forge app, for instance, where the cloud id is already known — pass it as host:
const assets = createAssetsClient({
workspaceId,
host: `https://api.atlassian.com/ex/jira/${cloudId}`,
auth: { type: 'bearer', token },
});Working with objects
An object belongs to an object type, which belongs to a schema. Its values are attributes, each naming the object type attribute it fills in:
const type = await assets.objectTypes.createObjectType({
name: 'Laptop',
objectSchemaId: schema.id,
iconId: icon.id,
});
const [nameAttribute] = await assets.objectTypes.findObjectTypeAttributes({ id: String(type.id) });
const object = await assets.objects.createObject({
objectTypeId: type.id,
attributes: [
{ objectTypeAttributeId: nameAttribute.id, objectAttributeValues: [{ value: 'MacBook Pro' }] },
],
});Assets rejects =, ;, :, ?, . and " in the name of a schema, an object type or an object, with a 400 naming them reserved characters. A schema key has to be unique on the instance, and every object key is built from it.
Searching with AQL
const page = await assets.objects.findObjectsByAql({
qlQuery: 'objectType = "Laptop" AND Owner = currentUser()',
});
const total = await assets.objects.countObjectsByAql({ qlQuery: 'objectType = "Laptop"' });