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>, where BasicContext = { 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 user
  • preventClose: 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 characters
  • content — max. 500 characters
  • actions — 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 }.

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

  1. Relative links and links to the plugin domain => open in the plugin

  2. 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, optionally queryParams.
  • v3.post[path](payload) / put / patchpayload includes bodyParams (and if necessary pathParams, queryParams).
  • v3.delete[path](payload) — DELETE; payload: pathParams, optionally queryParams.

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 through hostApi.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.

Previous