Provider Tutorial (Step-by-step)
Table of contents
- Goal
- Step 1: Add the API dependency
- Step 2: Add
softdependinplugin.yml - Step 3: Create a
TeamsServiceimplementation - Step 4: Adapt your team model to
Team/TeamMember - Step 5: Register provider in
onEnable - Step 6: Unregister provider in
onDisable - Step 7: Verify on a test server
- Step 8: Add optional services later
- Common mistakes
- Optional integration and shading
- Next steps
This tutorial is for team/faction plugin developers who want to expose their plugin through TeamsAPI so addon plugins can read team data.
Goal
By the end, your plugin will:
- implement
TeamsService, - register itself with TeamsAPI on enable,
- unregister cleanly on disable,
- be safely consumable by third-party addon plugins.
Step 1: Add the API dependency
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.7.0</version>
<scope>provided</scope>
</dependency>
Gradle
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
compileOnly 'com.github.ez-plugins:teams-api:1.7.0'
}
Use provided/compileOnly so you do not shade TeamsAPI into your JAR.
Step 2: Add softdepend in plugin.yml
softdepend:
- TeamsAPI
This ensures your plugin still loads even if TeamsAPI is missing.
Step 3: Create a TeamsService implementation
Create a class that maps your internal team system to the TeamsAPI interface.
public final class MyTeamsService implements TeamsService {
private final MyFactionPlugin plugin;
public MyTeamsService(final MyFactionPlugin plugin) {
this.plugin = plugin;
}
@Override
public Optional<Team> getTeamById(final UUID teamId) {
final InternalFaction faction = plugin.getFactionManager().findById(teamId);
if (faction == null) {
return Optional.empty();
}
return Optional.of(new MyTeamAdapter(faction));
}
@Override
public Optional<Team> getPlayerTeam(final UUID playerUUID) {
final InternalFaction faction = plugin.getFactionManager().findByMember(playerUUID);
if (faction == null) {
return Optional.empty();
}
return Optional.of(new MyTeamAdapter(faction));
}
}
Important:
- Return
Optional.empty()when data is not found. - Do not return
nullfrom service methods that returnOptional<T>. - Keep your own implementation classes inside your plugin, not in
teams-api.
Step 4: Adapt your team model to Team / TeamMember
Implement adapters for TeamsAPI model interfaces.
public final class MyTeamAdapter implements Team {
private final InternalFaction faction;
public MyTeamAdapter(final InternalFaction faction) {
this.faction = faction;
}
@Override
public UUID getId() {
return faction.getId();
}
@Override
public String getName() {
return faction.getName();
}
@Override
public String getDisplayName() {
return faction.getDisplayName();
}
@Override
public int getSize() {
return faction.getMembers().size();
}
@Override
public Set<TeamMember> getMembers() {
return faction.getMembers().stream()
.map(MyTeamMemberAdapter::new)
.collect(Collectors.toSet());
}
}
Step 5: Register provider in onEnable
public final class MyFactionPlugin extends JavaPlugin {
private MyTeamsService teamsService;
@Override
public void onEnable() {
teamsService = new MyTeamsService(this);
TeamsAPI.registerProvider(this, teamsService);
getLogger().info("Registered TeamsService with TeamsAPI.");
}
}
Step 6: Unregister provider in onDisable
@Override
public void onDisable() {
if (teamsService != null) {
TeamsAPI.unregisterProvider(teamsService);
}
}
Step 7: Verify on a test server
- Install
teams-api-pluginand your team/faction plugin. - Start the server.
- Check logs for your provider registration message.
- Install a consumer addon plugin and confirm it can read team data.
Step 8: Add optional services later
After core TeamsService works, you can add optional providers:
TeamsInviteServiceTeamsWarpServiceTeamsClaimServiceTeamsPowerServiceTeamsRelationServiceTeamsNotificationService
Each optional service is registered independently.
Common mistakes
- Returning
nullinstead ofOptional.empty(). - Forgetting to unregister on disable.
- Shading
teams-apiinto your plugin JAR. - Exposing provider implementation classes as public API for other plugins.
Optional integration and shading
If you want TeamsAPI support to be optional and avoid runtime conflicts caused by incorrect shading, follow:
Next steps
- Team Provider: full provider reference and patterns
- Custom Subcommands: let addons extend your command tree
- API Reference: full service and model method tables