API Reference - @yandex-data-ui/tracker-plugin-sdk-core
hostApi (HostApi)
API for interacting with the host (Tracker): plugin initialization, theme, language, slot context, window size, and readiness notification.
Exports the hostApi singleton. Usually used inside TrackerPluginProvider (react package); you can call it directly if needed.
init()
Initializes the plugin (reads parameters from the URL, initializes the bridge, and performs auto-resize if necessary). Call once before using other methods.
Parameters: options?: HostInitOptions — options (for example autoResize, defaults to true).
Throws: Error — if the URL lacks required parameters (slot, parentOrigin, id, elementId).
import { hostApi } from "@yandex-data-ui/tracker-plugin-sdk-core";
hostApi.init({ autoResize: true });
getTheme()
Returns the host's current theme.
Returns: Promise<Theme>
const theme = await hostApi.getTheme(); // 'light' | 'light-hc' | 'dark' | 'dark-hc' | 'system'
getLanguage()
Returns the host's current language.
Returns: Promise<string> (for example 'ru', 'en').
const language = await hostApi.getLanguage();
getContext()
Returns the context of the slot where the plugin is running. The level of returned data is determined by the contextLevel parameter specified for the slot in manifest.json (see Slot context levels).
Parameters: level: 'basic' | 'full' (required)
Returns:
- For
level: 'basic'—Promise<BasicContext>, whereBasicContext = { entityId: string; entityMeta?: Record<string, string> } - For
level: 'full'—Promise<SlotContextMap[TSlot]>
// Basic context (only entity identifier)
// Requires contextLevel: 'basic' in manifest.json for this slot
const basicContext = await hostApi.getContext("basic");
// basicContext.entityId — identifier of the current entity
// basicContext.entityMeta — additional metadata (optional)
// Full context (all entity data)
// Requires contextLevel: 'full' in manifest.json for this slot
const fullContext = await hostApi.getContext("full");
updateContentSize()
Sends a request to the host to change the plugin window size.
Parameters: payload: ContentSizeUpdateRequest (fields height and width — at least one must be present).
Returns: Promise<…>
await hostApi.updateContentSize({ height: 500 }); // sets the plugin window height
await hostApi.updateContentSize({ width: 800 }); // sets the plugin window width
await hostApi.updateContentSize({ height: 500, width: 800 }); // sets the plugin window height and width
The plugin window width is applied considering the embedding space constraints.
notifyReady()
Notifies the host that the plugin is ready.
Returns: Promise<…>
await hostApi.notifyReady();
getSlot()
Returns the current slot. Call only after init().
Returns: TSlot (key from SlotContextMap).
const slot = hostApi.getSlot(); // for example 'issue.action'
disableAutoResize()
Disables automatic container resizing based on content.
hostApi.disableAutoResize();
close()
Closes the plugin if it's displayed in a popup window.
hostApi.close();
Data transfer
Some slots support processing data that will be passed as an argument to the close method.
See the documentation for specific integration points for exact types and functionality.
preventClose() {
Protects the plugin from accidental closure by the user, for example, by pressing Esc or clicking the close button. If the preventClose: true flag is set, the host will block closure until the flag is cleared. Only works with plugins displayed in a modal window.
Use this method to prevent the loss of unsaved changes.
import { hostApi } from "@yandex-data-ui/tracker-plugin-sdk-core";
// Block closure if there are unsaved changes
hostApi.preventClose({ preventClose: true });
Parameters: { preventClose: boolean }
preventClose: true— blocks the plugin from being closed by the userpreventClose: false— removes the block
Example usage with React:
import { hostApi } from "@yandex-data-ui/tracker-plugin-sdk-react";
import { useEffect, useState } from "react";
function MyEditor() {
const [content, setContent] = useState("");
const [saved, setSaved] = useState(true);
const hasChanges = !saved;
// Automatically set/remove the block when the state changes
useEffect(() => {
hostApi.preventClose({ preventClose: hasChanges });
}, [hasChanges]);
const handleSave = async () => {
await saveContent(content);
setSaved(true);
};
return (
<div>
<textarea
value={content}
onChange={(e) => {
setContent(e.target.value);
setSaved(false);
}}
/>
<button onClick={handleSave}>Save</button>
</div>
);
}
Important
- Remember to remove the block (
preventClose: false) after saving data, otherwise the user won't be able to close the plugin. - During forced closure (for example, navigating to another screen) the host may ignore the block.
uiApi
API for interacting with the host application's user interface: showing notifications, opening pop-ups, etc.
Toasts
Plugins can show toast notifications in the host application via uiApi.toaster. The API closely resembles useToaster from @gravity-ui/uikit.
Permission
The tracker:ui:toaster permission must be requested in manifest.json:
{
"permissions": {
"ui": ["toaster"]
}
}
import { uiApi } from "@yandex-data-ui/tracker-plugin-sdk-core";
// Simple toast
uiApi.toaster.add({
title: "Saved",
theme: "success",
});
// Toast with text content and custom display time
uiApi.toaster.add({
title: "Error",
theme: "danger",
content: "Failed to load data",
autoHiding: 10000,
});
// Toast with an action button
uiApi.toaster.add({
title: "Item deleted",
theme: "info",
content: "QUEUE-123",
actions: [
{
label: "Undo",
onClick: () => {
// handle click
},
},
],
});
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
title |
string |
— | Toast title (required) |
name |
string |
auto | Unique key for deduplication. Generated automatically if not provided |
theme |
'success' | 'danger' | 'warning' | 'info' |
'info' |
Theme (color and icon) |
content |
string |
— | Text content below the title |
autoHiding |
number |
5000 |
Display time in ms (from 1000 to 30000) |
isClosable |
boolean |
true |
Show close button |
actions |
ToastAction[] |
— | Action buttons (max. 2) |
ToastAction:
| Parameter | Type | Description |
|---|---|---|
label |
string |
Button text (max. 50 characters) |
onClick |
() => void |
Callback on click |
Returns: Promise<{ name: string }> — toast name (for identification).
Limitations:
title— max. 200 characterscontent— max. 500 charactersactions— max. 2 buttons- Rate limit — 5 toasts per 10 seconds per plugin
Error handling
import {
trackerApi,
PluginActionError,
} from "@yandex-data-ui/tracker-plugin-sdk-core";
try {
await trackerApi.v3.get["/issues/{id}"]({ pathParams: { id: "BAD" } });
} catch (e) {
if (e instanceof PluginActionError) {
console.log(e.code, e.message, e.errorData);
}
}
Confirm Dialog
A plugin can show a modal confirmation dialog. The dialog is rendered on the Tracker side (not inside the iframe), so it overlays the entire application and focuses the user on making a decision.
Permission
The tracker:ui:confirm permission must be requested in manifest.json:
{
"permissions": {
"ui": ["confirm"]
}
}
import { uiApi } from "@yandex-data-ui/tracker-plugin-sdk-core";
const { confirmed } = await uiApi.confirm.show({ message: "Are you sure?" });
Parameters
| Parameter | Type | Limit | Default | Description |
|---|---|---|---|---|
title |
string |
≤ 200 | — | Dialog title |
message |
string |
≤ 500 | — (required) | Confirmation text |
textButtonApply |
string |
≤ 50 | "OK" |
Confirm button text |
textButtonCancel |
string |
≤ 50 | "Cancel" |
Cancel button text |
theme |
'normal' | 'danger' |
— | 'normal' |
Theme for the apply button |
Limits and errors
- 1 active confirm per plugin. Attempting to open a second dialog while the first is active rejects the promise with
CONFIRM_ALREADY_OPEN. - Maximum 5 simultaneous dialogs in the shared queue (from all plugins). If the queue overflows —
QUEUE_OVERFLOW. - 5-minute timeout. If the user doesn't respond, the promise is rejected with
Request timeout. - Closing the plugin iframe (removing it from the screen) automatically resolves all pending confirm dialogs for that plugin as
{ confirmed: false }. - Esc / clicking the close button —
{ confirmed: false }.
Navigation
Programmatically open links
uiApi.navigate({
path: `/path`,
params: { a: "testParam" },
options: { newTab: true },
});
type NavigateRequest = {
path: string;
params?: QueryParams;
options?: {
newTab?: boolean;
};
};
Handling link clicks
-
Relative links and links to the plugin domain => open in the plugin
-
External links => are passed to Tracker via uiApi.navigate =>
links to Tracker => open in the current tab or a new tab depending on target="_blank"
external links => always open in a new tab
trackerApi (TrackerApi)
A class for calling the Tracker Public API via the host (contract api.tracker.call). Access to endpoints is through the typed v3 API.
For method descriptions and response formats, see: Common format.
Exports the trackerApi singleton.
v3
An object with HTTP methods: get, post, put, patch, delete. Keys are endpoint paths from OpenAPI (@yandex-data-ui/tracker-pub-api-types); when accessing a path, the IDE shows hints and JSDoc.
Examples:
import { trackerApi } from "@yandex-data-ui/tracker-plugin-sdk-core";
// GET
const data = await trackerApi.v3.get["/issues/{id}"]({
pathParams: { id: "QUEUE-123" },
queryParams: { expand: ["COMMENTS"] },
});
// POST
await trackerApi.v3.post["/v2/issues"]({
bodyParams: { queue: { key: "TASK" }, summary: "New issue" },
});
//POST with file
await trackerApi.v3.post["/attachments"]({
bodyParams: { filename },
file,
});
v3.get[path](payload)— GET;payload:pathParams, optionallyqueryParams.v3.post[path](payload)/ put / patch —payloadincludesbodyParams(and if necessarypathParams,queryParams).v3.delete[path](payload)— DELETE;payload:pathParams, optionallyqueryParams.
All requests via trackerApi.v3 send version: 'v3' in the contract.
storageApi
A JSON storage at the organization level, mediated by the host — storageApi.orgShared.get / storageApi.orgShared.patch. A full description of the methods, patch merge semantics, versioning, and error codes is in the Data storage section.
import { storageApi } from "@yandex-data-ui/tracker-plugin-sdk-core";
const record = await storageApi.orgShared.get("settings");
await storageApi.orgShared.patch({
bucket: "settings",
data: { theme: "dark" },
});
hostApi.externalApi*
Methods for calling external (non-Tracker) HTTP APIs through the host's proxy with OAuth authorization support.
⚠️ Security policy: direct HTTP requests from the plugin (
fetch,XMLHttpRequest, etc.) are forbidden — the browser will block them due to CSP and iframe policy. All calls to external APIs must go throughhostApi.externalApiCall().
Manifest permission
Add the permissions.external section to manifest.json with a list of allowed domains:
{
"permissions": {
"external": [
{
"domain": "api.example.com",
"authorization": {
"type": "oauth",
"scopes": ["read", "write"],
"contextTypes": ["user"]
}
},
{
"domain": "cdn.example.com"
}
]
}
}
The authorization field is optional — you can omit it for domains that don't require authorization (for example, public CDNs). The "token" type is used for API keys and other non-OAuth tokens.
Network access (Puncher)
Proxy requests are executed from the platform servers. To ensure requests reach your service, request network access in Puncher from the macro _STARTREK_PLUGINS_PLATFORM_PRODUCTION_NETS_ to your services.
externalApiCall()
Executes an HTTP request to an external API through the platform proxy. The URL must belong to a domain allowed in permissions.external; the host adds authorization headers.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
url |
string |
— | Full request URL (required) |
method |
'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' |
— | HTTP method (required) |
headers |
Record<string, string> |
— | Additional headers |
body |
Record<string, unknown> |
— | Request body |
timeoutMs |
number |
— | Request timeout in milliseconds |
contextType |
'user' | 'organization' |
— | Credential context for the proxy |
Returns: Promise<{ status: number; headers?: Record<string, string>; body?: Record<string, unknown> }>
If the proxy request fails, throws PluginActionError with code EXTERNAL_API_CALL_ERROR (1013); details are in e.errorData.
import {
hostApi,
PluginActionError,
EXTERNAL_API_CALL_ERROR,
} from "@yandex-data-ui/tracker-plugin-sdk-core";
// GET
const { status, body } = await hostApi.externalApiCall({
url: "https://api.example.com/v1/items",
method: "GET",
contextType: "user",
});
// POST with body and timeout
const result = await hostApi.externalApiCall({
url: "https://api.example.com/v1/items",
method: "POST",
headers: { "Content-Type": "application/json" },
body: { name: "New item", value: 42 },
contextType: "organization",
timeoutMs: 10000,
});
// Error handling
try {
await hostApi.externalApiCall({
url: "https://api.example.com/data",
method: "GET",
});
} catch (e) {
if (e instanceof PluginActionError && e.code === EXTERNAL_API_CALL_ERROR) {
console.error("Proxy error:", e.errorData);
}
}
externalApiAuthCheckAndRequest()
Combines checking the authorization status and requesting credentials only for unauthenticated domains. If all domains are already authenticated — immediately returns { success: true } without a dialog.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
domains |
string[] |
all plugin domains | Domains to check |
contextType |
'user' | 'organization' |
— | Credential context type |
Returns: Promise<{ success: boolean }> — false if the user closed the dialog or the timeout expired (~5 minutes).
const { success } = await hostApi.externalApiAuthCheckAndRequest({
domains: ["api.example.com"],
contextType: "user",
});
if (!success) return;
externalApiAuthGetStatus()
Returns the authorization status for domains.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
domains |
string[] |
all plugin domains | Domains to check |
contextType |
'user' | 'organization' |
— | Credential context type |
Returns: Promise<{ domains: Array<{ domain: string; contextType: AuthContextType; authenticated: boolean }> }>
const { domains } = await hostApi.externalApiAuthGetStatus({
domains: ["api.example.com"],
contextType: "user",
});
const isAuthed = domains.every((d) => d.authenticated);
externalApiAuthRequest()
Shows the user a dialog for entering credentials for the specified domains. If confirmed successfully, the host saves the credentials.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
domains |
ExternalApiDomainInfo[] |
— | Domains (required, at least one) |
ExternalApiDomainInfo:
| Field | Type | Description |
|---|---|---|
domain |
string |
Domain from the manifest |
instructions |
string | { en?: string; ru?: string } |
Hint in the dialog (optional) |
Returns: Promise<{ success: boolean }> — false if the user closed the dialog.
await hostApi.externalApiAuthRequest({
domains: [
{
domain: "api.example.com",
instructions: { ru: "Войдите в Example", en: "Sign in to Example" },
},
],
});
externalApiAuthRevoke()
Revokes the saved authorization for the specified domains.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
domains |
string[] |
— | Domains to revoke (required, at least one) |
contextType |
'user' | 'organization' |
— | Credential context type |
Returns: Promise<{ success: boolean }>
await hostApi.externalApiAuthRevoke({
domains: ["api.example.com"],
contextType: "user",
});
Types
TrackerApiInitOptions
Options for creating a TrackerApi instance (if not using the singleton). Currently, only trackerApi is exported from core, and no options are passed.
interface TrackerApiInitOptions {
apiVersion?: string;
}
TrackerApiCallOptions
Parameters for calling a v3 endpoint: pathParams, queryParams, bodyParams.
interface TrackerApiCallOptions {
pathParams?: Record<string, string>;
queryParams?: Record<string, unknown>;
bodyParams?: Record<string, unknown>;
}
TrackerApiV3
Type of the trackerApi.v3 object: get/post/put/patch/delete methods with typed paths (from @yandex-data-ui/tracker-pub-api-types).
Theme
Host theme type.
type Theme = "light" | "light-hc" | "dark" | "dark-hc" | "system";
SlotContextMap
Mapping of slot names to full context types (level: 'full'). For example, the issue.action slot provides a context of type Issue. Context types (Issue, etc.) are defined by the @yandex-data-ui/tracker-pub-api-types package.
When level: 'basic', instead of the full entity object, BasicContext is returned:
type BasicContext = {
/** Identifier of the current entity */
entityId: string;
/** Additional basic information.
* For example, for a comment, it contains the parent ticket identifier. */
entityMeta?: Record<string, string>;
};
// Basic context: only entityId and entityMeta
const basicContext = await hostApi.getContext("basic");
// basicContext.entityId — entity identifier
// Full context: for the 'issue.action' slot, returns Issue
// Requires contextLevel: 'full' in manifest.json
const fullContext = await hostApi.getContext("full");
ContentSizeUpdateRequest
Request to change the plugin content size.
type ContentSizeUpdateRequest = { height?: number };
HostInitOptions
Host initialization options (passed to hostApi.init()).
interface HostInitOptions {
/** Auto-resize based on content, defaults to true */
autoResize?: boolean;
}
API error codes
When calling methods, the host may return an error with a code. Constants are exported from the package:
import {
EXTERNAL_API_CALL_ERROR,
METHOD_NOT_SUPPORTED,
MISSING_REQUIRED_SCOPE,
PLUGIN_ID_IS_NOT_CORRECT,
PLUGIN_ID_OR_SLOT_NOT_PROVIDED,
UNKNOWN_ERROR,
VALIDATION_ERROR,
} from "@yandex-data-ui/tracker-plugin-sdk-core";
| Constant | Code | Description |
|---|---|---|
PLUGIN_ID_OR_SLOT_NOT_PROVIDED |
1000 | Required plugin initialization parameters are missing. |
PLUGIN_ID_IS_NOT_CORRECT |
1001 | Incorrect or mismatched pluginId. |
VALIDATION_ERROR |
1002 | Request validation error. |
METHOD_NOT_SUPPORTED |
1003 | Method is not supported. |
MISSING_REQUIRED_SCOPE |
1004 | Insufficient permissions (scope). |
EXTERNAL_API_CALL_ERROR |
1013 | Error occurred while executing an HTTP request via hostApi.externalApiCall(). |
UNKNOWN_ERROR |
6666 | Unknown error. |
Utils
getLocalizedString()
Returns a localized string based on the language code. The LocalizedString type is exported from @yandex-data-ui/tracker-pub-api-types and re-exported from core.
function getLocalizedString(
value: LocalizedString,
language: string,
fallbackLanguage?: string,
): string;
getField()
Extracts a value from an object using a dot notation path.
function getField<T = unknown>(
obj: Record<string, unknown>,
path: string,
defaultValue?: T,
): T | undefined;
Handlers
getHandler, setHandler, types HandlerFunction, Handlers, HttpMethod are exported — for registering request handlers from the host side (see the contract and slots).
Complete Example
import {
hostApi,
trackerApi,
getField,
type Theme,
} from "@yandex-data-ui/tracker-plugin-sdk-core";
// Initialization is typically done in TrackerPluginProvider (react)
hostApi.init({ autoResize: true });
const theme: Theme = await hostApi.getTheme();
const language = await hostApi.getLanguage();
const context = await hostApi.getContext();
// Calling Tracker API v3 (version: 'v3' is sent in the payload)
const issue = await trackerApi.v3.get["/issues/{id}"]({
pathParams: { id: "KEY-1" },
queryParams: { expand: ["COMMENTS"] },
});
const summary = getField<string>(issue, "summary", "No summary");
await hostApi.notifyReady();
Request/response types for endpoints (Issue, types for creating issues, queues, etc.) are defined by the @yandex-data-ui/tracker-pub-api-types package.