Uninstall a droplet
Uninstalls one of your company’s installations. Its API credentials are revoked and Fluid sends the droplet’s uninstall webhook so it can clean up; the installation reads pending_uninstall until that finishes. Uninstalling again changes nothing, except for an installation the legacy PUT /api/droplet_installations/{uuid} left pending_uninstall without telling the droplet: its credentials are revoked and the uninstall webhook is sent then. If that webhook cannot be queued, its credentials stay revoked, the answer is 422, and calling again sends it.
Needs the droplets.update permission. Replaces DELETE /api/droplet_installations/{uuid}, and returns the whole installation rather than only its identifiers.
curl --request DELETE \
--url https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}"
headers = {"Authorization": "Bearer <token>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.delete("https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"droplet_installation": {
"uuid": "dri_7Hc2kWq9mNz4pLx8",
"droplet_uuid": "drp_4tq8nxw2kfl9mrv3bpz6cyh1jds7age5",
"droplet": {
"uuid": "drp_4tq8nxw2kfl9mrv3bpz6cyh1jds7age5",
"title": "Order Sync",
"logo_url": "https://ik.imagekit.io/fluid/droplets/order-sync/logo.png"
},
"status": "pending_uninstall",
"role": {
"id": 4182,
"name": "Order Sync"
},
"scopes": [
"orders"
],
"effective_scopes": [
"orders"
],
"created_at": "2026-10-18T15:32:08Z",
"updated_at": "2026-10-20T15:32:08Z"
},
"status": 200,
"meta": {
"request_id": "7e2c9b41-3f8a-4d15-b6e0-9a4c21d7f583",
"timestamp": "2026-10-20T15:32:08Z"
}
}{
"message": "Invalid credentials."
}{
"message": "Not authorized."
}{
"error": {
"message": "Droplet installation not found",
"details": {}
},
"status": 404,
"meta": {
"request_id": "7e2c9b41-3f8a-4d15-b6e0-9a4c21d7f583",
"timestamp": "2026-10-20T15:32:08Z"
}
}{
"error": {
"message": "The droplet could not be told it was uninstalled; try again",
"details": {
"installation": [
"notification_failed"
]
}
},
"status": 422,
"meta": {
"request_id": "7e2c9b41-3f8a-4d15-b6e0-9a4c21d7f583",
"timestamp": "2026-10-20T15:32:08Z"
}
}Authorizations
A company admin credential for your company. Droplet installation tokens are refused.
Path Parameters
The installation's uuid, from uuid on an installation.
curl --request DELETE \
--url https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}"
headers = {"Authorization": "Bearer <token>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.delete("https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/company/v2026-10/droplet-installations/{uuid}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"droplet_installation": {
"uuid": "dri_7Hc2kWq9mNz4pLx8",
"droplet_uuid": "drp_4tq8nxw2kfl9mrv3bpz6cyh1jds7age5",
"droplet": {
"uuid": "drp_4tq8nxw2kfl9mrv3bpz6cyh1jds7age5",
"title": "Order Sync",
"logo_url": "https://ik.imagekit.io/fluid/droplets/order-sync/logo.png"
},
"status": "pending_uninstall",
"role": {
"id": 4182,
"name": "Order Sync"
},
"scopes": [
"orders"
],
"effective_scopes": [
"orders"
],
"created_at": "2026-10-18T15:32:08Z",
"updated_at": "2026-10-20T15:32:08Z"
},
"status": 200,
"meta": {
"request_id": "7e2c9b41-3f8a-4d15-b6e0-9a4c21d7f583",
"timestamp": "2026-10-20T15:32:08Z"
}
}{
"message": "Invalid credentials."
}{
"message": "Not authorized."
}{
"error": {
"message": "Droplet installation not found",
"details": {}
},
"status": 404,
"meta": {
"request_id": "7e2c9b41-3f8a-4d15-b6e0-9a4c21d7f583",
"timestamp": "2026-10-20T15:32:08Z"
}
}{
"error": {
"message": "The droplet could not be told it was uninstalled; try again",
"details": {
"installation": [
"notification_failed"
]
}
},
"status": 422,
"meta": {
"request_id": "7e2c9b41-3f8a-4d15-b6e0-9a4c21d7f583",
"timestamp": "2026-10-20T15:32:08Z"
}
}