# Batched API Calls Batching lets multiple plugins enqueue control-plane calls that are sent as one HTTP request to `/api/v1/batch`. Use batching when: - many plugins read data at the same time - looped tasks report state periodically - call latency can be handled asynchronously Do not use batching when: - the caller needs a blocking result immediately - the endpoint should bypass queueing for operational safety ## One-Off Calls ```java CompletableFuture future = NetworkPlugin.client() .batch() .get(ProfileEndpoint.VALUE, ProfileEndpoint.VALUE.uri(), ServerProfile.class); ``` ```java CompletableFuture future = NetworkPlugin.client() .batch() .enqueueJson("GET", "/api/v1/server/profile", null); ``` Queued calls complete when the batch loop flushes, or when code calls: ```java NetworkPlugin.client().batch().flush(); ``` ## Looped Calls ```java LoopHandle handle = NetworkPlugin.client().batch().registerLoopedCall( LoopedApiCall.builder(ServerProfile.class) .id("server-profile-loop") .interval(Duration.ofSeconds(5)) .method("GET") .uri("/api/v1/server/profile") .onSuccess(profile -> { // update local state }) .onFailure(error -> { // log or mark degraded }) .build() ); ``` Cancel when no longer needed: ```java handle.cancel(); ``` ## Batch Endpoint Contract Request: ```json { "requests": [ { "id": "generated-call-id", "method": "GET", "uri": "/api/v1/server/profile", "body": null } ] } ``` Response: ```json { "responses": [ { "id": "generated-call-id", "status": 200, "body": { "data": {} }, "error": null } ] } ``` Each item completes independently. A failed item does not fail unrelated futures. ## Defaults - endpoint: `/api/v1/batch` - flush interval: `250ms` - max batch size: `100` - batching enabled: `true` Configure with `ControlPlaneClient.builder()`.