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

# Persistent Servers API

> Create, query, update, and delete persistent servers

A persistent server is one long-lived server configuration, such as a survival server. Unlike a group, it does not scale into multiple instances.

Use `api.persistentServer()` to create and manage persistent servers.

## Create a persistent server

This example creates `survival-1` with a new Paper blueprint. Because the persistent server is active, SimpleCloud starts its instance and replaces it after a stop.

```java theme={null}
CreatePersistentServerRequest request = CreatePersistentServerRequest.builder()
    .name("survival-1")
    .type(GroupServerType.SERVER)
    .minMemory(2048)
    .maxMemory(4096)
    .maxPlayers(80)
    .createBlueprint(CreateBlueprintRequest.builder()
        .configurator("paper")
        .serverSoftware("paper")
        .minecraftVersion("1.21.11")
        .build())
    .active(true)
    .serverhostId("serverhost-uuid")
    .tags(List.of("survival", "production"))
    .build();

api.persistentServer().createPersistentServer(request)
    .thenAccept(server -> System.out.println(
        "Created " + server.getName() + " with ID " + server.getPersistentServerId()));
```

To use an existing blueprint instead, replace `createBlueprint(...)` with a source:

```java theme={null}
.source(SourceConfig.builder()
    .type(SourceType.BLUEPRINT)
    .blueprint("blueprint-uuid")
    .build())
```

Set either `source` or `createBlueprint`, not both.

<Accordion title="CreatePersistentServerRequest fields">
  <ParamField body="name" type="string" required>
    Persistent server name. Up to 100 characters of ASCII letters, digits, underscores, and hyphens (`[A-Za-z0-9_-]`). Must be unique within the network, case-insensitive — `Survival-1` and `survival-1` are treated as the same name. A persistent server and a group may share a name. Creating or renaming to a name that only differs by case from an existing persistent server returns `409 Conflict`.
  </ParamField>

  <ParamField body="type" type="GroupServerType | null">
    `SERVER` or `PROXY`. Defaults to `SERVER`.
  </ParamField>

  <ParamField body="minMemory" type="integer | null">
    Minimum memory in MB.
  </ParamField>

  <ParamField body="maxMemory" type="integer | null">
    Maximum memory in MB.
  </ParamField>

  <ParamField body="maxPlayers" type="integer | null">
    Player limit. Defaults to `50`.
  </ParamField>

  <ParamField body="createBlueprint" type="CreateBlueprintRequest | null">
    Blueprint to create for this persistent server.
  </ParamField>

  <ParamField body="source" type="SourceConfig | null">
    Existing blueprint or container image to use. Do not set this together with `createBlueprint`.
  </ParamField>

  <ParamField body="active" type="boolean | null">
    Whether SimpleCloud should keep an instance running. Defaults to `true`.
  </ParamField>

  <ParamField body="priority" type="integer | null">
    Persistent server priority.
  </ParamField>

  <ParamField body="serverhostId" type="string | null">
    ID of the assigned serverhost.
  </ParamField>

  <ParamField body="workflows" type="WorkflowsConfig | null">
    Lifecycle and manual workflows.
  </ParamField>

  <ParamField body="properties" type="Map<String, Object> | null">
    Custom properties.
  </ParamField>

  <ParamField body="tags" type="List<String> | null">
    Tags used to organize and filter persistent servers.
  </ParamField>
</Accordion>

## Find persistent servers

Find one persistent server by name or ID:

```java theme={null}
api.persistentServer().getPersistentServerByName("survival-1")
    .thenAccept(server -> System.out.println(server.getPersistentServerId()));

api.persistentServer().getPersistentServerById("persistent-server-uuid")
    .thenAccept(server -> System.out.println(server.getName()));
```

Both methods complete exceptionally when no persistent server matches. Name lookups are case-insensitive.

Use a query to filter the list:

```java theme={null}
PersistentServerQuery query = PersistentServerQuery.create()
    .filterByActive(true)
    .filterByTags("survival", "production")
    .limit(20);

api.persistentServer().getAllPersistentServers(query)
    .thenAccept(servers -> servers.forEach(server ->
        System.out.println(server.getName() + ": " + server.getPlayerCount())));
```

The query can filter by tags, active state, and serverhost ID. Call `getAllPersistentServers()` without a query to return every persistent server.

## Update a persistent server

Only fields set on `UpdatePersistentServerRequest` are changed:

```java theme={null}
UpdatePersistentServerRequest update = UpdatePersistentServerRequest.builder()
    .maxMemory(6144)
    .maxPlayers(100)
    .build();

api.persistentServer()
    .updatePersistentServer("persistent-server-uuid", update)
    .thenAccept(server -> System.out.println("Updated " + server.getName()));
```

You can update the name, type, memory, player limit, active state, priority, assigned serverhost, source, workflows, properties, and tags.

## Manage properties

Use the property methods to change custom properties without updating the rest of the configuration:

```java theme={null}
api.persistentServer().updatePersistentServerProperties(
    "persistent-server-uuid",
    Map.of("gameMode", "SURVIVAL", "region", "eu-central")
).thenAccept(properties -> System.out.println("Properties: " + properties));

api.persistentServer()
    .deletePersistentServerProperty("persistent-server-uuid", "region")
    .thenAccept(properties -> System.out.println("Properties: " + properties));
```

`updatePersistentServerProperties` merges the supplied values with the existing properties. You can also update one property or delete multiple properties.

## Delete a persistent server

```java theme={null}
api.persistentServer()
    .deletePersistentServer("persistent-server-uuid")
    .thenRun(() -> System.out.println("Deleted persistent server"));
```

<Warning>
  Deactivate the persistent server first, stop its instance, and delete the configuration after the instance stops. Its files remain on the serverhost.
</Warning>

## PersistentServer fields

`PersistentServer` extends `ServerBase` and provides the following fields.

<ResponseField name="persistentServerId" type="string" required>
  Unique persistent server ID.
</ResponseField>

<ResponseField name="name" type="string" required>
  Persistent server name.
</ResponseField>

<ResponseField name="type" type="GroupServerType" required>
  `SERVER`, `PROXY`, or `UNKNOWN_SERVER`.
</ResponseField>

<ResponseField name="minMemory" type="integer | null">
  Minimum memory in MB.
</ResponseField>

<ResponseField name="maxMemory" type="integer | null">
  Maximum memory in MB.
</ResponseField>

<ResponseField name="maxPlayers" type="integer | null">
  Player limit.
</ResponseField>

<ResponseField name="active" type="boolean | null">
  Whether SimpleCloud should keep an instance running.
</ResponseField>

<ResponseField name="priority" type="integer | null">
  Persistent server priority.
</ResponseField>

<ResponseField name="serverhostId" type="string | null">
  Assigned serverhost ID.
</ResponseField>

<ResponseField name="playerCount" type="integer" required>
  Current player count, or `0` when no instance is running.
</ResponseField>

<ResponseField name="source" type="SourceConfig | null">
  Blueprint or container image source.
</ResponseField>

<ResponseField name="workflows" type="WorkflowsConfig | null">
  Lifecycle and manual workflows.
</ResponseField>

<ResponseField name="properties" type="Map<String, Object> | null">
  Custom properties.
</ResponseField>

<ResponseField name="tags" type="List<String> | null">
  Tags used for filtering and organization.
</ResponseField>

<ResponseField name="createdAt" type="string" required>
  Creation timestamp in ISO 8601 format.
</ResponseField>

<ResponseField name="updatedAt" type="string" required>
  Last update timestamp in ISO 8601 format.
</ResponseField>

Use `api.server()` to work with the running instance. Its `getPersistentServerId()` method links it back to this configuration.
