Compatibility
Minecraft: Java Edition
Platforms
Tags
Creators
Details
The universal bridge between team plugins and everything else.
TeamsAPI is a passive, server-side bridge plugin for Paper, Spigot, Purpur, and Folia servers, inspired by Vault. It provides a single, stable interface for team operations, so any plugin that needs team data can work with any compatible team plugin, without either plugin knowing about the other.
Implemented in our refactored Factions fork: https://modrinth.com/plugin/pvpindex-factions
How it works

- Providers -- faction, clan, guild, or custom team plugins
implement TeamsServiceand register with TeamsAPI duringonEnable(). - Consumers -- scoreboard plugins, chat formatters, quest plugins, or any plugin that
needs team data call
TeamsAPI.getService()and use the returned interface. - Server owners -- install
TeamsAPI.jarand one compatible team plugin. Done.
No two plugins need to know about each other. When the team plugin changes, every consumer plugin keeps working without a recompile.
Features
- Provider-agnostic: works with any team plugin that ships a
TeamsServiceimplementation. - Graceful fallback: if no provider is present,
TeamsAPI.isAvailable()returnsfalse; consumers can disable their team features cleanly instead of crashing. - Read-only snapshots:
TeamandTeamMemberare immutable interfaces; providers own the backing data. - Role hierarchy: built-in
OWNER > ADMIN > MEMBERwithoutranks()andcanManage()helpers. - Optional invite service: providers can expose
TeamsInviteServicefor invitation workflows. - Optional warp service: providers can expose
TeamsWarpServicefor named team warps. - Optional claim service: providers can expose
TeamsClaimServicefor chunk-claim management. - Optional power service: providers can expose
TeamsPowerServicefor player and team power values. - Optional relation service: providers can expose
TeamsRelationServicefor inter-team diplomacy (ally/truce/neutral/enemy). - Custom subcommands: any plugin registers a
TeamsSubcommandviaTeamsAPI.registerSubcommand(); team plugins callTeamsAPI.getSubcommands()in their own command handler to dispatch them, extending the command tree without coupling. - Cancellable events: fifteen Bukkit events that providers can fire so other plugins can react to or cancel team operations.
- Lightweight: a single shaded JAR with no required runtime dependencies beyond the Bukkit API (optional: Vault for the built-in power shop).
- JitPack-ready: depend on just the API module at compile time; no transitive dependencies leak into your plugin.
- Velocity bridge (experimental): optional
teams-api-velocityplugin for querying team data from the Velocity proxy. Supports multi-proxy networks via Redis. - BungeeCord bridge (experimental): optional
teams-api-bungeecordplugin for querying team data from BungeeCord / Waterfall proxies. Supports multi-proxy networks via Redis.
Requirements
| Requirement | Value |
|---|---|
| Server software | Paper / Spigot / Purpur / Folia 1.16+ |
| Java | 17+ (25 recommended) |
| Plugin dependencies | None (optional: Vault for power shop) |
Installation (server owners)
- Download
teams-api-plugin-VERSION.jarfrom the Files tab of this listing or from GitHub Releases. - Drop it into your server's
plugins/directory. - Install a compatible team plugin that provides a
TeamsServiceimplementation. - Restart the server.
TeamsAPI has no configuration files.
For developers
Add the API artifact to your project via JitPack:
Maven
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.ez-plugins</groupId>
<artifactId>teams-api</artifactId>
<version>1.6.1</version>
<scope>provided</scope>
</dependency>
Gradle
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
compileOnly 'com.github.ez-plugins:teams-api:1.6.1'
}
Consumer quick-start
Declare the dependency in plugin.yml (use softdepend if team support is optional):
depend:
- TeamsAPI
Then use the API at runtime:
@Override
public void onEnable() {
if (!TeamsAPI.isAvailable()) {
getLogger().warning("No team plugin found. Team features disabled.");
return;
}
getLogger().info("TeamsAPI found. Team features enabled.");
}
// In a command or listener:
TeamsService teams = TeamsAPI.getService();
Optional<Team> team = teams.getPlayerTeam(player.getUniqueId());
team.ifPresent(t -> player.sendMessage("Your team: " + t.getDisplayName()));
Provider quick-start
Declare a soft-dependency in plugin.yml:
softdepend:
- TeamsAPI
Register your implementation when the plugin loads:
@Override
public void onEnable() {
TeamsAPI.registerProvider(this, new MyTeamsService(this));
}
@Override
public void onDisable() {
TeamsAPI.unregisterProvider(teamsService);
}
API surface
Team lifecycle & lookup
| Method | Returns | Description |
|---|---|---|
createTeam(name, ownerUUID) |
Optional<Team> |
Creates a new team |
deleteTeam(teamId) |
boolean |
Deletes a team by UUID |
getTeam(teamId) |
Optional<Team> |
Looks up a team by UUID |
getTeamByName(name) |
Optional<Team> |
Looks up a team by name |
getPlayerTeam(playerUUID) |
Optional<Team> |
Returns the player's current team |
getAllTeams() |
Collection<Team> |
Returns every registered team |
getTeamCount() |
int |
Total number of teams |
Membership management
| Method | Returns | Description |
|---|---|---|
addMember(teamId, playerUUID, role) |
boolean |
Adds a player with a given role |
removeMember(teamId, playerUUID) |
boolean |
Removes a player from the team |
setMemberRole(teamId, playerUUID, role) |
boolean |
Changes a member's role |
getMemberRole(teamId, playerUUID) |
Optional<TeamRole> |
Returns the member's current role |
Invite service (optional)
Register alongside TeamsService if your plugin supports invitations:
TeamsAPI.registerInviteProvider(this, inviteService);
| Method | Returns | Description |
|---|---|---|
invitePlayer(teamId, inviterUUID, inviteeUUID) |
boolean |
Sends an invitation |
acceptInvite(teamId, playerUUID) |
Optional<Team> |
Accepts the invitation and joins the team |
declineInvite(teamId, playerUUID) |
boolean |
Declines an invitation |
Consumers check availability with TeamsAPI.isInviteAvailable() before calling TeamsAPI.getInviteService().
Warp service (optional)
Register alongside TeamsService if your plugin supports team warps:
TeamsAPI.registerWarpProvider(this, warpService);
| Method | Returns | Description |
|---|---|---|
setWarp(teamId, name, location, creatorUUID) |
boolean |
Creates or updates a named warp |
removeWarp(teamId, name) |
boolean |
Deletes a warp by name |
getWarp(teamId, name) |
Optional<TeamWarp> |
Looks up a warp by name |
getWarps(teamId) |
Collection<TeamWarp> |
Returns all warps for a team |
Consumers check availability with TeamsAPI.isWarpAvailable() before calling TeamsAPI.getWarpService().
Claim service (optional)
Register alongside TeamsService if your plugin supports chunk claims:
TeamsAPI.registerClaimProvider(this, claimService);
| Method | Returns | Description |
|---|---|---|
claimChunk(teamId, playerUUID, world, x, z) |
boolean |
Claims a chunk for the team |
unclaimChunk(teamId, playerUUID, world, x, z) |
boolean |
Removes the claim |
unclaimAll(teamId) |
boolean |
Removes all claims for the team |
getClaimAt(world, x, z) |
Optional<TeamClaim> |
Returns the claim at a chunk, if any |
getTeamClaims(teamId) |
Collection<TeamClaim> |
All claims for the team |
getClaimCount(teamId) |
int |
Number of claimed chunks |
isClaimed(world, x, z) |
boolean |
Whether the chunk is claimed by anyone |
isClaimedBy(teamId, world, x, z) |
boolean |
Whether the chunk is claimed by this team |
getTeamMaxClaims(teamId) |
int |
Claim limit (-1 means unlimited) |
Consumers check availability with TeamsAPI.isClaimAvailable() before calling TeamsAPI.getClaimService().
Power service (optional)
Register alongside TeamsService if your plugin exposes power values:
TeamsAPI.registerPowerProvider(this, powerService);
| Method | Returns | Description |
|---|---|---|
getPlayerPower(playerUUID) |
double |
Current power of the player |
getPlayerMaxPower(playerUUID) |
double |
Maximum power the player can hold |
setPlayerPower(playerUUID, power) |
boolean |
Sets the player's power |
getTeamPower(teamId) |
double |
Combined power of all team members |
getTeamMaxPower(teamId) |
double |
Maximum combined power the team can hold |
Consumers check availability with TeamsAPI.isPowerAvailable() before calling TeamsAPI.getPowerService().
Relation service (optional)
Register alongside TeamsService if your plugin supports inter-team diplomacy:
TeamsAPI.registerRelationProvider(this, relationService);
| Method | Returns | Description |
|---|---|---|
setRelation(fromTeamId, toTeamId, relation, initiatorUUID) |
boolean |
Declares a relation from one team toward another. Fires TeamRelationChangeEvent; returns false if cancelled. Setting NEUTRAL removes the relation. |
getRelation(fromTeamId, toTeamId) |
TeamRelation |
Returns the declared relation (defaults to NEUTRAL if none is set). |
getRelations(teamId) |
Map<UUID, TeamRelation> |
All non-neutral relations declared by the team. |
clearRelations(teamId) |
boolean |
Removes all relations declared by or toward the team (use on disband). |
areAllies(teamAId, teamBId) |
boolean |
Returns true when both teams have declared ALLY toward each other. |
areEnemies(teamAId, teamBId) |
boolean |
Returns true when either team has declared ENEMY toward the other. |
getTeamsInRelation(teamId, relation) |
Collection<UUID> |
Returns all team UUIDs toward which teamId has declared the given relation. Filters getRelations(teamId) by value; providers may override for efficiency. |
getRelationColor(relation) |
String |
#RRGGBB hex color for the relation. Default returns relation.getDefaultHexColor(); providers may override to supply server-configured colors. |
TeamRelation values with display name, legacy color code, and hex color:
| Constant | Display name | Legacy color | Hex color |
|---|---|---|---|
ALLY |
"Ally" | §a (green) |
#55FF55 |
TRUCE |
"Truce" | §6 (gold) |
#FFAA00 |
NEUTRAL |
"Neutral" | §7 (gray) |
#AAAAAA |
ENEMY |
"Enemy" | §c (red) |
#FF5555 |
Consumers check availability with TeamsAPI.isRelationAvailable() before calling TeamsAPI.getRelationService().
Custom subcommands
Any plugin can register a TeamsSubcommand via TeamsAPI.registerSubcommand(). Team
plugins call TeamsAPI.getSubcommands() in their own command executor to dispatch them,
extending the command tree without any direct coupling between plugins.
Register in onEnable:
TeamsAPI.registerSubcommand(this, new MySubcommand());
Unregister in onDisable (Bukkit's ServicesManager also handles this automatically
on plugin unload):
TeamsAPI.unregisterSubcommand(mySubcommand);
| Method | Returns | Description |
|---|---|---|
getName() |
String |
Matched case-insensitively against args[0] |
getDescription() |
String |
Optional description for help output |
getPermission() |
String |
Permission required, or null for no check |
execute(sender, args) |
boolean |
Called when the subcommand is dispatched; return false to show usage |
getUsage() |
String |
Usage hint sent when execute returns false |
tabComplete(sender, args) |
List<String> |
Tab-completion suggestions; default: empty list |
Commands & permissions
| Subcommand | Permission | Default | Description |
|---|---|---|---|
/teamsapi / /teamsapi help |
teamsapi.use |
everyone | Lists commands the sender can use |
/teamsapi version |
teamsapi.use |
everyone | Prints plugin and API version |
/teamsapi status |
teamsapi.status |
everyone | Active provider, team count, registered services |
/teamsapi info |
teamsapi.admin |
op | Full internal diagnostic |
/teamsapi power status |
teamsapi.power |
op | Sender's current and max power |
/teamsapi power buy <n> |
teamsapi.power.buy |
disabled | Disabled by default; enable with power-shop.enabled: true in config.yml. Requires Vault. |
Events
All events live in com.skyblockexp.teamsapi.event. Providers are encouraged but not required to fire them.
| Event | Cancellable | Fired when |
|---|---|---|
TeamCreateEvent |
Yes | Before a team is created |
TeamDeleteEvent |
Yes | Before a team is deleted |
TeamJoinEvent |
Yes | Before a player joins a team |
TeamLeaveEvent |
Yes | Before a player leaves a team |
TeamRoleChangeEvent |
Yes | Before a member's role changes |
TeamInviteEvent |
Yes | Before an invitation is sent |
TeamInviteAcceptEvent |
No | After a player accepts an invitation |
TeamInviteDeclineEvent |
No | After a player declines an invitation |
TeamWarpSetEvent |
Yes | Before a warp is created or updated |
TeamWarpDeleteEvent |
Yes | Before a warp is deleted |
TeamClaimEvent |
Yes | Before a chunk is claimed |
TeamUnclaimEvent |
Yes | Before a chunk is unclaimed |
Roles
| Role | Priority | Description |
|---|---|---|
OWNER |
100 | Full control; cannot be removed by others |
ADMIN |
50 | Can manage members with a lower priority |
MEMBER |
10 | Regular team member |
Links
- GitHub -- source code & issue tracker
- Developer Guide -- full integration walkthrough
- API Reference -- complete method tables
- JitPack -- Maven / Gradle dependency
MIT License - free to use in any project, open- or closed-source.


