# Developer API

> What your plugin can do with the Oasis API, with one example from start to finish.

Source: https://oasis-protection.com/docs/api/

Oasis has a Java API for other Paper plugins. With it, your plugin can:

* **Log its own edits.** When your plugin changes blocks, moves items or spawns entities, log them. Staff can then look them up and roll them back like anything a player did.
* **Read history.** Ask for the edits a player made, the edits in an area, the whole history of one block, or the positions an operation kept, a page at a time.
* **Run rollbacks, restores and undos.** Start the same operations staff run with `/rollback`, `/rs` and `/undo`, follow their progress, and read what they did.
* **Purge history.** Delete edits for good, the same way /oasis purge does, even in a world that is not loaded.
* **Read and clear incidents.** List the problems the store recorded, and clear them, as `/oasis incidents` does.
* **Load the worlds it keeps.** Give Oasis a loader for worlds in your plugin’s own storage, such as slime worlds, so a rollback can write into them while they are not loaded.
* **React to operations and purges.** Listen for the end of every operation and every purge, and for each chunk an operation rewrites, whoever started it.

The API lives in one package, `com.oasis.api`, and its events live in `com.oasis.api.event`. Everything else in the Oasis jar is internal and can change at any time.

## A first example

This plugin asks for the API when it starts. Its `revert` method shows a staff member the newest edit a player made in the last hour, then rolls back that hour and reports the result.

```java
package com.example.quickstart;

import com.oasis.api.Edit;
import com.oasis.api.Oasis;
import com.oasis.api.OasisApi;
import com.oasis.api.Selection;
import java.time.Duration;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

public final class QuickStart extends JavaPlugin
{
    private OasisApi oasis;

    @Override
    public void onEnable()
    {
        // Oasis is in `depend` of plugin.yml, so it is enabled before this runs.
        oasis = Oasis.api(this);
    }

    public void revert(Player staff, OfflinePlayer griefer)
    {
        Selection lastHour = Selection.all().by(griefer).within(Duration.ofHours(1));

        oasis.lookups().find(lastHour, 1).thenAccept(page ->
        {
            if (page.items().isEmpty())
            {
                staff.sendMessage(griefer.getName() + " made no edits in the last hour.");
                return;
            }
            Edit newest = page.items().getFirst();
            staff.sendMessage("Newest edit: " + newest.cause().word() + " " + newest.after() + " at "
                + newest.position().x() + " " + newest.position().y() + " " + newest.position().z());

            oasis.operations().rollback(lastHour)
                .requestedBy(staff)
                .audience(staff)
                .start()
                .result().thenAccept(result ->
                    staff.sendMessage("Rolled back " + result.applied() + " edits. Kept " + result.kept() + "."));
        });
    }
}
```

Every future in the API completes on the main thread, so both callbacks can send messages and touch the world. Because the request names `staff` as its audience, the staff member also sees the start line, the progress bar and the summary, just as for a command.

## The pages

[Getting started](/docs/api/getting-started/)Add the dependency, declare Oasis in your plugin file, and get the API.

[Core concepts](/docs/api/concepts/)The person and the actor, the thread rule, pages without totals, and nullness.

[Selecting edits](/docs/api/selections/)Every Selection method: who, when, where and what.

[Reading history](/docs/api/reading-history/)Pages of edits, the history of one block, and every field of an Edit.

[Logging edits](/docs/api/logging-edits/)Log the blocks, items and entities your plugin changes.

[Running operations](/docs/api/operations/)Rollbacks, restores and undos: estimate, start, follow, cancel and read the result.

[Purging history](/docs/api/purges/)Delete edits for good: count, start, follow and read the result. Purge a world that is not loaded.

[Incidents](/docs/api/incidents/)List the problems the store recorded, and clear them.

[Loading your worlds](/docs/api/worlds/)Give Oasis a loader for the worlds your plugin keeps, so a rollback can write into them.

[Events](/docs/api/events/)Redraw a map after a rollback, and report every operation and purge that ends.

[Vocabulary](/docs/api/reference/)Every kind, cause, actor, phase, outcome and failure reason.

## For AI agents

If you build with an AI coding agent, give it the API pages as plain text, or install the `oasis-api` skill. See [For AI agents](/docs/api/ai-agents/).
