> For the complete documentation index, see [llms.txt](https://docs.myarc.icu/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.myarc.icu/en/feature-configuration/application-api.md).

# Developer application API

Through the ArcMenu developer API, add-on plugins can attach business callbacks to existing YAML menus, bind dynamic data to individual sessions, or register fully code-hosted interactive applications. Chat panels, music players, card games, guild dashboards, and custom login screens can all share ArcMenu's screen surface, pointer input, tooltips, and navigation history.

## Dependency setup and service access

Declare `arcmenu-api` as a `provided` dependency in your build configuration, and add `ArcMenu` to `depend` or `softdepend` in your plugin's `plugin.yml` or `paper-plugin.yml`. In Maven, you can manage the version through an `arcmenu.version` property set to the `arcmenu-api` artifact version running on your server:

```xml
<properties>
    <!-- Replace with the arcmenu-api version used on your server -->
    <arcmenu.version>...</arcmenu.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.fentai</groupId>
        <artifactId>arcmenu-api</artifactId>
        <version>${arcmenu.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
```

When ArcMenu starts, it registers `ArcMenuApi` and its specialized sub-service interfaces with Bukkit's `ServicesManager`. Both Java and Kotlin plugins can load them directly:

```java
import com.fentai.arcmenu.api.ArcMenuApi;
import com.fentai.arcmenu.api.ArcMenuCursorApi;
import org.bukkit.Bukkit;

ArcMenuApi api = Bukkit.getServicesManager().load(ArcMenuApi.class);
if (api == null) {
    throw new IllegalStateException("ArcMenu API service is unavailable");
}

// Sub-services can be retrieved from the main interface or loaded directly from ServicesManager
ArcMenuCursorApi cursor = api.cursor();
```

Only import public interfaces and data types from the `com.fentai.arcmenu.api` package; do not reference internal implementation classes under the `paper` or `core` modules. Service registrations are automatically unregistered when ArcMenu unloads.

### Core services overview

In addition to basic menu opening, closing, animation control, and application registration, `ArcMenuApi` provides nine specialized service accessors:

| Accessor         | Interface             | Purpose                                                                                                                                        |
| ---------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `sessions()`     | `ArcMenuSessions`     | Query a player's active runtime session snapshot and safely dispatch asynchronous callbacks bound to an exact session token.                   |
| `menus()`        | `ArcMenuMenus`        | Start menu navigation with completion callbacks, read/validate/reload menu catalog snapshots, and register backend region handlers.            |
| `state()`        | `ArcMenuState`        | Bind isolated session-scoped key-value data, read and write `META`/`DATA`/`GLOBAL` state, manage menu arguments, and resolve placeholder text. |
| `textInput()`    | `ArcMenuTextInput`    | Read committed Arcitx input values or open a native anvil text input prompt bound to the active session.                                       |
| `effects()`      | `ArcMenuEffects`      | Play, pause, resume, or stop Effect cutscenes and listen for playback completion reasons.                                                      |
| `availability()` | `ArcMenuAvailability` | Query server-supported features alongside a player's active pointer mode, Vision handshake status, and resource pack state.                    |
| `preferences()`  | `ArcMenuPreferences`  | Read, update, or clear a player's pointer sensitivity and cursor scale levels.                                                                 |
| `cursor()`       | `ArcMenuCursorApi`    | Check whether the player's current connection has completed a compatible ArcMenu Editor Vision handshake.                                      |
| `resources()`    | `ArcMenuResources`    | Query pixel and glyph metadata for resolved images and calculate hotbar scroll steps.                                                          |

## Threading model and region scheduling

All methods and callbacks targeting a specific player must run on **that player's owning thread**: the main server thread on Paper or Leaf, and the player's current entity region thread on Folia. Callbacks for different players may execute concurrently, so do not directly manipulate another player's entities inside a player callback.

When asynchronous work (such as a database query or HTTP request) finishes and needs to update the interface, use `api.sessions().execute(...)` or `context.execute(...)` inside a hosted application to hop back to the player's thread. Never call open, refresh, or entity modification methods directly from an asynchronous thread.

Global menu catalog operations—`menus().validate()`, `menus().reload()`, and `reloadMenuFiles()`—must be called during startup or on the global tick thread. Registration methods for applications, routes, and region handlers are thread-safe and can be called during plugin initialization. When an add-on plugin disables, ArcMenu automatically cleans up all registrations, session bindings, and open requests owned by that plugin.

## Hosted applications

If you want your code to take full control over rendering and interaction, you can register a hosted application.

### Registering an application and options

Application IDs use the `namespace:path` format (lowercase letters, digits, underscores, dots, hyphens, or slashes), such as `myplugin:shop`. When you register a factory with `registerApplication`, ArcMenu creates an isolated `ArcMenuApplicationSession` instance each time a player opens the application:

```java
import com.fentai.arcmenu.api.ArcMenuApplicationHandle;
import com.fentai.arcmenu.api.ArcMenuApplicationOptions;
import com.fentai.arcmenu.api.ArcMenuCanvas;

ArcMenuApplicationHandle handle = api.registerApplication(
    this,
    "myplugin:shop",
    ArcMenuApplicationOptions.builder()
        .permission("myplugin.shop")
        .captureMouseScroll(true)
        .inheritCanvas(true)
        .canvas(new ArcMenuCanvas(320.0, 180.0, 100.0, 3.0))
        .tickInterval(1)
        .build(),
    ShopSession::new
);
```

`ArcMenuApplicationOptions` supports the following configuration settings:

* `permission`: String specifying the permission node required to open the application. Defaults to an empty string, which adds no application-specific permission requirement beyond basic menu access.
* `captureMouseScroll`: Boolean, defaults to `false`. When set to `true`, hotbar mouse-wheel scrolling is captured in mouse-based modes and delivered to the `onScroll` callback.
* `inheritCanvas`: Boolean, defaults to `true`. Controls whether switching to this application from an existing menu reuses the previous page's canvas size and scale.
* `canvas`: An `ArcMenuCanvas` instance defining the logical `width` and `height`, `pixelsPerBlock`, and `designDistance`. All four values must be finite floating-point numbers greater than `0`.
* `tickInterval`: Integer from `1` to `1200` defining how many ticks elapse between `onTick` calls. Defaults to `1`.

Once registered, the application can be opened from code with `api.openApplication(player, "myplugin:shop", List.of("featured"))`, or launched directly from a YAML menu action with arguments:

```yaml
actions:
  right:
    - 'open-app: myplugin:shop featured'
```

If you only need to forward a namespaced target to an existing menu or custom branching logic without hosting a custom screen, register a lightweight virtual route with `api.registerRoute(this, "myplugin:Entry", (player, args) -> ...)`.

### Screen surface and world coordinate conversion

An application session interacts with the screen through `ArcMenuApplicationContext`. Calling `context.surface()` returns an immutable `ArcMenuSurface` snapshot containing the world, screen `origin()`, `right()` vector, `up()` vector, `normal()` vector, and canvas metrics.

To place text, item displays, or custom visual effects on the screen, call `surface().toWorld(x, y, depth)` to convert logical canvas coordinates into a Minecraft world `Location`:

* `x` and `y` are logical canvas coordinates (`0, 0` is the center, `+x` points right, and `+y` points up).
* `depth` is the depth offset (`0.0` by default; positive values move closer to the player's camera).

When a player switches between a menu and an application, or navigates via `context.openMenu(...)`, `context.openApplication(...)`, or `context.back()`, ArcMenu reuses the same screen plane so the interface stays anchored in place without shifting.

### Private entities, resource tracking, and scheduling

Display entities created by a hosted application should remain visible only to the viewing player and be cleaned up automatically when the session closes:

* `context.spawnPrivate(location, TextDisplay.class, display -> { ... })`: Spawns a private entity visible only to the session's player at the given location and registers it for automatic cleanup when the session ends.
* `context.track(entity)` / `context.track(task)` / `context.track(closeable)`: Registers an existing entity, `BukkitTask`, or `AutoCloseable` resource with the session. Tracked objects are destroyed or closed automatically when the session ends—whether the player closes the menu, navigates back, disconnects, or the owning plugin disables.
* `context.execute(runnable)`: Safe to call from any thread. Dispatches the runnable to the player's owning region thread only if this application session is still active.
* `context.runLater(delayTicks, runnable)` and `context.runTimer(delayTicks, periodTicks, runnable)`: Schedules delayed or repeating tasks on the player's owning region thread. On Folia, tasks automatically follow the player across region boundaries. Use the returned `BukkitTask` handle if you need to cancel a task early.

### Session lifecycle and input callbacks

Subclass `ArcMenuApplicationSession` and override the callbacks your application needs:

* `onSurfaceChanged(ArcMenuSurfaceEvent)`: Fired when the session is first created (`initial == true`) or when the screen surface is re-anchored.
* `onPointerModeChanged(ArcMenuPointerModeEvent)`: Fired when the player's active input mode switches between `TOUCH`, `MOUSE`, and `VISION`.
* `onPointerMove(ArcMenuPointerMoveEvent)`: Fired as the pointer moves across the canvas, providing the current coordinates (`point`) and previous coordinates (`previous`).
* `onActivate(ArcMenuActivateEvent)`: Fired when the player clicks, providing the click coordinates (`point`), `button` (`LEFT`, `RIGHT`, or `MIDDLE`), active `pointerMode`, and `sneaking` state.
* `onScroll(ArcMenuScrollEvent)`: Fired when `captureMouseScroll` is enabled and the player scrolls the mouse wheel. Positive `steps` indicate scrolling toward the next hotbar slot; negative values indicate scrolling toward the previous slot.
* `onTick(ArcMenuTickEvent)`: Fired periodically according to the configured `tickInterval`.
* `onClose(ArcMenuApplicationCloseEvent)`: Fired when the session closes, with `reason` indicating why it ended (`REQUESTED`, `BACK`, `REPLACED`, `PLAYER_QUIT`, `PLUGIN_DISABLE`, `OWNER_DISABLED`, or `ERROR`).

During interaction, call `context.setCursorInteractive(true)` to switch the cursor to its interactive state, or use `context.showTooltip(point, lines)` and `context.hideTooltip()` to show and hide native tooltips.

## Runtime sessions and asynchronous data updates

Whether a player is viewing a standard YAML menu or a hosted application, `api.sessions().current(player)` returns the active `ArcMenuSessionSnapshot` (or `null` if no runtime menu or application is open). The snapshot exposes:

* `getToken()`: The unique `UUID` token for this exact physical session. Every new open or page switch generates a fresh token.
* `getKind()`: `MENU` or `APPLICATION`.
* `getId()`: The active menu ID or application ID.
* `getArguments()`: An immutable list of arguments passed to the session.
* `getPointerMode()`: The currently effective pointer mode.
* `getCatalogRevision()`: The menu catalog revision number that was active when the session opened.

When querying a database asynchronously and writing results back into an open menu, combining the **session token** with **session bindings** prevents stale async callbacks from polluting a different page after the player has already navigated away or closed the menu:

```java
import com.fentai.arcmenu.api.ArcMenuSessionBindings;
import com.fentai.arcmenu.api.ArcMenuSessionSnapshot;
import java.util.concurrent.CompletableFuture;

ArcMenuSessionSnapshot session = api.sessions().current(player);
if (session != null) {
    ArcMenuSessionBindings bindings = api.state().bind(this, player, session.getToken());
    if (bindings != null) {
        CompletableFuture.supplyAsync(() -> "1280").thenAccept(coins ->
            api.sessions().execute(this, player, session.getToken(), () -> {
                bindings.set("coins", coins);
                api.refresh(player, "coins-label");
            })
        );
    }
}
```

In YAML menu text, read bound values with `{session:<namespace>:<key>}`. Use the exact string returned by `bindings.getNamespace()` for `<namespace>` (a lowercase identifier derived from your plugin name), such as `{session:myplugin:coins}`. Bound data lives only for that specific session and add-on plugin; it is cleared automatically when the session ends or `bindings.close()` is called, leaving no leftover global or persistent state.

To listen for session lifecycle transitions across the server, register listeners for the Bukkit events `ArcMenuSessionOpenedEvent` and `ArcMenuSessionClosedEvent`.

## Menu navigation, history policies, and locks

Alongside the boolean-returning `api.open(...)` and `api.close(player)` methods, `api.menus()` provides navigation request methods with history stack policies and completion callbacks:

```java
import com.fentai.arcmenu.api.ArcMenuHistoryPolicy;
import com.fentai.arcmenu.api.ArcMenuOpenOutcomeKind;
import com.fentai.arcmenu.api.ArcMenuOpenRequest;
import java.util.List;

ArcMenuOpenRequest request = api.menus().open(
    this, player, "shop", List.of("featured"),
    ArcMenuHistoryPolicy.PUSH,
    outcome -> {
        if (outcome.getKind() == ArcMenuOpenOutcomeKind.OPENED) {
            player.sendMessage("Opened menu: " + outcome.getSession().getId());
        }
    }
);
```

* **History policies (`ArcMenuHistoryPolicy`)**:
  * `PUSH`: Default policy. Pushes the current page onto the back stack so the player can return to it via `back`.
  * `RESET_ON_SUCCESS`: Clears the back stack once the target page opens (also available via the `api.menus().openRoot(...)` shortcut).
  * `PRESERVE`: Leaves the existing back stack untouched.
* **Open outcomes (`ArcMenuOpenOutcomeKind`)**:
  * `OPENED`: The menu opened. Check `outcome.getSession().getId()` if you need the final menu ID, as a fallback menu (`permission-denied-menu`) or hook may have redirected the open request.
  * `ROUTE_HANDLED`: The request was handled by a registered custom route.
  * Other terminal outcomes: `REJECTED`, `SUPERSEDED` (overridden by a newer navigation request), `CANCELLED` (via `request.cancel()`), `TIMED_OUT`, `PLAYER_LEFT`, `OWNER_DISABLED`, and `ERROR`.
* **Navigating back**: Call `api.menus().back(this, player, outcome -> { ... })`. If navigating back fails, the existing history stack is preserved.

Right before a standard YAML menu opens, ArcMenu fires `ArcMenuBeforeOpenEvent`, which provides `isSwitching()` and `isFirstOpen()` to distinguish page transitions from initial opens.

For mandatory flows such as authentication or onboarding tutorials, call `api.lockMenu(this, player, "login", List.of())` to acquire an `ArcMenuLock`. While the lock is active, the player cannot close the menu or switch to unrelated menus. You can transition between locked pages with `lock.open("register", List.of())`, and call `lock.close()` once verification finishes to release the lock.

## Backend region handlers

When you build a menu layout in the visual editor or YAML but want Java or Kotlin code to handle a specific button click (such as purchase validation or asynchronous currency deduction), register a region handler for that menu ID and region ID:

```java
import com.fentai.arcmenu.api.ArcMenuRegionResult;
import com.fentai.arcmenu.api.ArcMenuRegistration;

ArcMenuRegistration reg = api.menus().registerRegionHandler(this, "shop", "buy-button", context -> {
    Player buyer = context.getPlayer();
    String inputAmount = context.getInputValue(); // Reads the committed value if this region is linked to an Arcitx input
    // Run synchronous logic or start an async task here
    return ArcMenuRegionResult.SKIP_YAML;
});
```

Each `menuId + regionId` pair supports one active region handler at a time. The handler runs after the region's `condition` passes and any linked Arcitx input is committed, right before the region's YAML `actions` execute:

* Return `ArcMenuRegionResult.CONTINUE_YAML` to proceed with the YAML actions configured on that region.
* Return `ArcMenuRegionResult.SKIP_YAML` to bypass the YAML actions and let your code handle the response. If your handler starts an asynchronous task, return `SKIP_YAML` immediately and use `sessions().execute(...)` to refresh or navigate when the async work completes.

For read-only analytics or logging after a region click completes, listen for `ArcMenuRegionActivatedEvent` and check `getYamlActionsSkipped()` to see whether the YAML actions were bypassed.

## State management and in-place refresh

### Reading and writing state and resolving placeholders

`api.state()` provides direct access to ArcMenu's three data scopes (`ArcMenuStateScope`):

* `META`: Temporary per-player in-memory data kept for the current server runtime (persists across player reconnects until explicitly removed or the plugin shuts down).
* `DATA`: Persistent per-player data saved across restarts.
* `GLOBAL`: Server-wide persistent data shared by all players.

```java
import com.fentai.arcmenu.api.ArcMenuStateScope;

api.state().set(player, ArcMenuStateScope.META, "selected-tab", "weapons");
String tab = api.state().get(player, ArcMenuStateScope.META, "selected-tab");
api.state().remove(player, ArcMenuStateScope.META, "selected-tab");

// Read or update positional arguments for the active menu ({0}, {1}, etc.)
List<String> args = api.state().arguments(player);
api.state().setArguments(player, List.of("page-2"));

// Resolve a string containing placeholders and math expressions using runtime rules
String text = api.state().resolveText(player, "Current balance: %vault_eco_balance%");
```

### Refreshing a running menu in place

When a player's balance, points, or quest progress changes, you can update placeholders in place without reopening the menu:

```java
api.refresh(player);            // Refreshes all text, images, and the currently hovered tooltip in the active menu
api.refresh(player, "balance"); // Refreshes only the specified text/image node or tooltip region (including static nodes with update: -1)
```

Call `refresh` on the player's owning thread. It preserves existing menu entities, pointer position, and animation progress, and only sends update packets when the resolved display content actually changes. It returns `true` when an active runtime menu (and matching target node, if specified) was found, or `false` otherwise.

Administrators and the console can also trigger an in-place refresh by running `/arcmenu refresh <online-player> [element-id]`.

## Explicit text input service

`api.textInput()` provides two capabilities:

1. **Reading committed Arcitx input**: Call `api.textInput().committed(player, "search-box")` to read the last committed string from an Arcitx editing region in the active runtime menu (uncommitted draft text is not returned). You can also listen for `ArcMenuInputSubmittedEvent`.
2. **Requesting native anvil text input**: While a runtime menu or hosted application is open, your plugin can open a native anvil input UI bound to the active session:

```java
import com.fentai.arcmenu.api.ArcMenuTextInputEndReason;
import com.fentai.arcmenu.api.ArcMenuTextInputHandle;
import com.fentai.arcmenu.api.ArcMenuTextInputOptions;

ArcMenuTextInputHandle handle = api.textInput().request(
    this, player,
    ArcMenuTextInputOptions.builder()
        .title("Enter search keyword")
        .initialValue("")
        .maxLength(30)
        .mask("")
        .build(),
    result -> {
        if (result.getReason() == ArcMenuTextInputEndReason.SUBMITTED) {
            player.sendMessage("You submitted: " + result.getValue());
        }
    }
);
```

`ArcMenuTextInputOptions` parameters:

* `maxLength`: Integer from `1` to `50` (measured in UTF-16 code units). Defaults to `50`.
* `initialValue`: Initial string pre-filled in the input box; its length must not exceed `maxLength`.
* `mask`: An empty string or a single Unicode character (such as `"*"`) used to mask the preview text.

The returned `ArcMenuTextInputHandle` lets you read the live draft via `value()`, programmatically submit the current text via `submit()`, or abort via `cancel()`. The completion reason is `SUBMITTED` only when the player clicks the completion slot or your code calls `submit()`; pressing Esc to close the UI produces `CANCELLED` so draft text is never submitted accidentally.

## Controlling Effect cutscenes

Use `api.effects()` to play and control standalone Effect cutscene projects from code:

```java
import com.fentai.arcmenu.api.ArcMenuEffectHandle;

ArcMenuEffectHandle playback = api.effects().play(this, player, "rtp-overworld", end -> {
    player.sendMessage("Cutscene finished: " + end.getReason());
});

if (playback != null) {
    playback.pause();
    playback.resume();
    // Call playback.stop() to end playback early
}
```

* `api.effects().ids()`: Returns the set of all currently loaded Effect project IDs.
* `api.effects().current(player)`: Returns an `ArcMenuEffectStatus` snapshot for the cutscene currently playing for the player, including its playback `token`, `effectId`, current `frame`, total `durationFrames`, `fps`, and `isPaused` state.
* Each `ArcMenuEffectHandle` controls only the specific playback instance it created and will not accidentally stop a newer cutscene that replaced it. The completion callback always runs once on the player's owning thread with a reason of `COMPLETED`, `REQUESTED`, `REPLACED`, `PLAYER_LEFT`, `OWNER_DISABLED`, `PLUGIN_DISABLE`, or `ERROR`.

## Availability checks, Vision handshake, and player preferences

### Feature availability and player readiness

* `api.availability().serverFeatures()`: Returns the set of `ArcMenuFeature` values supported by the server (`TOUCH`, `MOUSE`, `VISION`, `RESOURCE_PACKS`, `TOOLTIPS`, `ANIMATIONS`, `CRAFT_ENGINE`, `EDITOR`, `EFFECTS`, `NATIVE_TEXT_INPUT`).
* `api.availability().player(player)`: Queries the player's live readiness snapshot (`ArcMenuPlayerAvailability`) on the player's thread:
  * `getRequestedPointerMode()` and `getEffectivePointerMode()`: The player's requested pointer mode and the mode currently in effect.
  * `isVisionHandshakeReady()`: Whether the player's current connection has completed a compatible ArcMenu Editor Vision handshake.
  * `getResourcePackState()`: The resource pack status (`UNSUPPORTED`, `UNKNOWN`, `NOT_READY`, or `READY`), alongside `isResourcePackAssumed()` (whether the server is configured to treat resource packs as loaded by default).
* `api.cursor().hasCursorMod(player)`: Directly checks whether the player's current connection has an active Vision handshake. When a player joins and completes the Vision handshake, ArcMenu fires `ArcMenuCursorReadyEvent`.

### Player pointer preferences

`api.preferences()` reads and updates a player's personal mouse sensitivity and cursor scale levels:

* `get(player)`: Returns `ArcMenuPointerPreferences`, which includes `sensitivityLevel` and `cursorScaleLevel` (integers from `1` to `9`, defaulting to `5`) and their computed multipliers `sensitivityMultiplier` and `cursorScaleMultiplier` (calculated as `2^((level - 5) / 4)`, where level `1` is `0.5x`, level `5` is `1.0x`, and level `9` is `2.0x`).
* `setSensitivity(player, level)` / `setCursorScale(player, level)`: Sets an integer level from `1` to `9` and immediately applies it to any open mouse menu. Returns `false` if the level is outside `1..9`.
* `clearSensitivity(player)` / `clearCursorScale(player)` / `clear(player)`: Clears saved personal preferences and restores the default level `5`.
* Whenever preferences change via commands or the API, ArcMenu fires `ArcMenuPreferencesChangedEvent`.

## Image metadata, hotbar scroll steps, and catalog snapshots

* **Image asset metadata**: `api.resources().image("/ui/logo.png")` returns the resolved `ArcMenuImageAsset` (or `null` if the image does not exist). You can inspect its pixel dimensions (`getPixelWidth()`, `getPixelHeight()`), assigned font (`getFont()`), Unicode codepoint (`getCodepoint()`), and glyph metrics (`getGlyphWidth()`, `getGlyphHeight()`, `getGlyphAdvance()`, `getFullGlyphAdvance()`). When building text components, use `asset.getCharacter()` to get the full character string (including surrogate pairs).
* **Hotbar scroll step calculation**: `api.resources().hotbarScrollSteps(previousSlot, newSlot)` (or the static helper `ArcMenuHotbarScroll.steps(prev, next)`) converts adjacent hotbar slot changes—including wrap-around steps between `8 -> 0` and `0 -> 8`—into `+1` or `-1`, returning `0` for non-adjacent or invalid slots.
* **Menu catalog snapshots and validation**:
  * `api.menus().catalog()` returns the current `ArcMenuCatalogSnapshot`, containing the catalog `revision` and `ArcMenuMenuDescriptor` entries for every loaded menu (including menu ID, permission, frontend node IDs, backend region IDs, bound animation track IDs, and Arcitx input region IDs).
  * `api.menus().validate()` validates the menu configuration files on disk without altering runtime state, returning an `ArcMenuReloadReport` (check `getErrors().isEmpty()` to verify that all files are valid).
  * `api.menus().reload()` validates the disk configuration and atomically publishes the new catalog if no errors are found, firing `ArcMenuCatalogChangedEvent` on the global thread.
  * When an external resource pack plugin (CraftEngine, Nexo, or ItemsAdder) finishes reloading and merging resources, ArcMenu fires `ArcMenuResourcesReadyEvent` on the global thread.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.myarc.icu/en/feature-configuration/application-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
