> ## Documentation Index
> Fetch the complete documentation index at: https://www.kitemc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API Getting Started

<span id="api-getting-started" />

This guide covers how to integrate ArcPass API into your plugin.

<h2 id="add-dependency">
  Add Dependency
</h2>

<h3 id="maven">
  Maven
</h3>

```xml theme={null}
<repositories>
    <repository>
        <id>github</id>
        <url>https://maven.pkg.github.com/KiteMC/ArcPass</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.kitemc</groupId>
        <artifactId>arcpass-api</artifactId>
        <version>1.9.4</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
```

<h3 id="gradle-kotlin-dsl">
  Gradle (Kotlin DSL)
</h3>

```kotlin theme={null}
repositories {
    maven("https://maven.pkg.github.com/KiteMC/ArcPass")
}

dependencies {
    compileOnly("com.kitemc:arcpass-api:1.9.4")
}
```

<h3 id="gradle-groovy">
  Gradle (Groovy)
</h3>

```groovy theme={null}
repositories {
    maven { url = "https://maven.pkg.github.com/KiteMC/ArcPass" }
}

dependencies {
    compileOnly 'com.kitemc:arcpass-api:1.9.4'
}
```

<h2 id="configure-plugin-yml">
  Configure plugin.yml
</h2>

Add ArcPass as soft dependency:

```yaml theme={null}
name: MyPlugin
version: 1.0.0
main: com.example.myplugin.MyPlugin
softdepend:
  - ArcPass
```

<h2 id="get-api-instance">
  Get API Instance
</h2>

<h3 id="check-availability">
  Check Availability
</h3>

```java theme={null}
import com.kitemc.arcpass.api.ArcPassAPI;
import com.kitemc.arcpass.api.ArcPassProvider;
import org.bukkit.plugin.java.JavaPlugin;

public class MyPlugin extends JavaPlugin {

    private ArcPassAPI arcPassAPI;

    @Override
    public void onEnable() {
        if (getServer().getPluginManager().getPlugin("ArcPass") != null) {
            arcPassAPI = ArcPassProvider.get();
            getLogger().info("ArcPass API loaded!");
        } else {
            getLogger().warning("ArcPass not installed");
        }
    }

    public boolean isArcPassAvailable() {
        return arcPassAPI != null;
    }

    public ArcPassAPI getArcPassAPI() {
        return arcPassAPI;
    }
}
```

<h3 id="delayed-access-recommended">
  Delayed Access (Recommended)
</h3>

```java theme={null}
@Override
public void onEnable() {
    getServer().getScheduler().runTaskLater(this, () -> {
        if (getServer().getPluginManager().getPlugin("ArcPass") != null) {
            arcPassAPI = ArcPassProvider.get();
            initializeArcPassFeatures();
        }
    }, 1L);
}

private void initializeArcPassFeatures() {
    getLogger().info("ArcPass version: " + arcPassAPI.getVersion());
}
```

<h2 id="basic-operations">
  Basic Operations
</h2>

<h3 id="get-player-data">
  Get Player Data
</h3>

```java theme={null}
public void showPlayerInfo(Player player) {
    if (!isArcPassAvailable()) return;

    arcPassAPI.getPlayerData(player.getUniqueId())
        .thenAccept(optionalData -> {
            if (optionalData.isEmpty()) {
                player.sendMessage("§cCouldn't get pass data");
                return;
            }

            PlayerData data = optionalData.get();

            Bukkit.getScheduler().runTask(plugin, () -> {
                player.sendMessage("§6=== Pass Info ===");
                player.sendMessage("§7Level: §e" + data.getLevel());
                player.sendMessage("§7XP: §e" + data.getTotalExperience());
                player.sendMessage("§7Tiers: §e" + String.join(", ", data.getUnlockedTiers()));
            });
        })
        .exceptionally(ex -> {
            getLogger().warning("Failed to get data: " + ex.getMessage());
            return null;
        });
}
```

<h3 id="use-cached-data">
  Use Cached Data
</h3>

```java theme={null}
public int getPlayerLevel(Player player) {
    if (!isArcPassAvailable()) return 0;

    PlayerData data = arcPassAPI.getPlayerDataIfCached(player.getUniqueId());
    return data != null ? data.getLevel() : 0;
}
```

<Warning>
  Cached data may be null. Always check before use.
</Warning>

<h3 id="give-experience">
  Give Experience
</h3>

```java theme={null}
public void giveExperience(Player player, long amount) {
    if (!isArcPassAvailable()) return;

    arcPassAPI.addExperience(player.getUniqueId(), amount)
        .thenAccept(newTotal -> {
            Bukkit.getScheduler().runTask(plugin, () -> {
                player.sendMessage("§aGained " + amount + " pass XP!");
                player.sendMessage("§7Total XP: §e" + newTotal);
            });
        });
}
```

<h3 id="trigger-custom-quest-event">
  Trigger Custom Quest Event
</h3>

```java theme={null}
public void onCustomAction(Player player, String actionType) {
    if (!isArcPassAvailable()) return;

    arcPassAPI.triggerCustomEvent(
        player.getUniqueId(),
        "my_action",
        actionType
    );
}
```

Corresponding quest config:

```yaml theme={null}
custom_task:
  type: daily
  display-name: "&eCustom Task"
  objectives:
    - type: custom
      event: my_action
      amount: 10
```

<h3 id="query-pass-info">
  Query Pass Info
</h3>

```java theme={null}
public void showPassInfo(Player player) {
    if (!isArcPassAvailable()) return;

    Pass defaultPass = arcPassAPI.getDefaultPass();
    player.sendMessage("§6Current Pass: §e" + defaultPass.getDisplayName());
    player.sendMessage("§7Max Level: §e" + defaultPass.getMaxLevel());

    player.sendMessage("§7Available Tiers:");
    for (PassTier tier : defaultPass.getTiers()) {
        String status = tier.isFree() ? "§aFree" : "§e$" + tier.getPrice();
        player.sendMessage("  §7- " + tier.getDisplayName() + " " + status);
    }
}
```

<h3 id="query-season-info">
  Query Season Info
</h3>

```java theme={null}
public void showSeasonInfo(Player player) {
    if (!isArcPassAvailable()) return;

    Optional<Season> seasonOpt = arcPassAPI.getCurrentSeason();

    if (seasonOpt.isEmpty()) {
        player.sendMessage("§cNo active season");
        return;
    }

    Season season = seasonOpt.get();
    player.sendMessage("§6Current Season: §e" + season.getDisplayName());
    player.sendMessage("§7Status: §e" + season.getStatus());

    long remaining = season.getTimeRemainingSeconds();
    if (remaining > 0) {
        long days = remaining / 86400;
        long hours = (remaining % 86400) / 3600;
        player.sendMessage("§7Remaining: §e" + days + "d " + hours + "h");
    }
}
```

<h2 id="error-handling">
  Error Handling
</h2>

<h3 id="handle-completablefuture-exceptions">
  Handle CompletableFuture Exceptions
</h3>

```java theme={null}
arcPassAPI.getPlayerData(playerId)
    .thenAccept(data -> {
        // Normal processing
    })
    .exceptionally(ex -> {
        getLogger().severe("API call failed: " + ex.getMessage());
        ex.printStackTrace();

        Player player = Bukkit.getPlayer(playerId);
        if (player != null) {
            player.sendMessage("§cOperation failed, please retry");
        }

        return null;
    });
```

<h3 id="timeout-handling">
  Timeout Handling
</h3>

```java theme={null}
import java.util.concurrent.TimeUnit;

arcPassAPI.getPlayerData(playerId)
    .orTimeout(5, TimeUnit.SECONDS)
    .thenAccept(data -> {
        // Process data
    })
    .exceptionally(ex -> {
        if (ex.getCause() instanceof java.util.concurrent.TimeoutException) {
            getLogger().warning("Data fetch timeout");
        }
        return null;
    });
```

<h2 id="next-steps">
  Next Steps
</h2>

<Columns cols={2}>
  <Card title="Event System" icon="zap" href="/en/arcpass/developer/events">
    Listen to ArcPass events
  </Card>

  <Card title="Code Examples" icon="code" href="/en/arcpass/developer/examples">
    More practical examples
  </Card>
</Columns>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.