curl --request DELETE \
--url https://app.chainpatrol.io/api/v2/organization/asset-groups/{groupId} \
--header 'X-API-KEY: <api-key>'{
"success": true,
"id": 123,
"unassignedAssetCount": 123
}Delete an asset group. Assets in this group will become ungrouped.
curl --request DELETE \
--url https://app.chainpatrol.io/api/v2/organization/asset-groups/{groupId} \
--header 'X-API-KEY: <api-key>'{
"success": true,
"id": 123,
"unassignedAssetCount": 123
}X-API-KEY header:
X-API-KEY: your_api_key_here
const response = await fetch(
"https://app.chainpatrol.io/api/v2/organization/asset-groups/4",
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY_HERE",
},
body: JSON.stringify({
groupId: 4,
}),
}
);
const data = await response.json();
console.log(data);
| Parameter | Type | Required | Description |
|---|---|---|---|
| groupId | number | Yes | ID of the group to delete |
| Field | Type | Required | Description |
|---|---|---|---|
| groupId | number | Yes | ID of the group to delete (must match path parameter) |
{
"success": true,
"id": 4,
"unassignedAssetCount": 5
}
| Field | Type | Description |
|---|---|---|
| success | boolean | Always true for successful deletions |
| id | number | ID of the deleted group |
| unassignedAssetCount | number | Number of assets that were in the group (now ungrouped) |
{
"error": {
"code": "BAD_REQUEST",
"message": "Group ID is required"
}
}
{
"error": {
"code": "UNAUTHORIZED",
"message": "API key with organization access required"
}
}
{
"error": {
"code": "FORBIDDEN",
"message": "Group does not belong to your organization"
}
}
{
"error": {
"code": "NOT_FOUND",
"message": "Group with ID 4 not found"
}
}
async function safeDeleteGroup(groupId: number) {
// First, get group details
const listResponse = await fetch(
"https://app.chainpatrol.io/api/v2/organization/asset-groups",
{
headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
}
);
const { groups } = await listResponse.json();
const group = groups.find((g) => g.id === groupId);
if (!group) {
console.error("Group not found");
return;
}
console.log(`About to delete group: "${group.name}"`);
console.log(`This will unassign ${group.assetCount} asset(s)`);
// In production, add user confirmation here
// const confirmed = await getUserConfirmation();
// if (!confirmed) return;
const deleteResponse = await fetch(
`https://app.chainpatrol.io/api/v2/organization/asset-groups/${groupId}`,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY_HERE",
},
body: JSON.stringify({ groupId }),
}
);
const result = await deleteResponse.json();
console.log(
`✓ Deleted group "${group.name}", unassigned ${result.unassignedAssetCount} assets`
);
}
async function deleteGroupWithReassignment(
groupId: number,
targetGroupId: number | null
) {
// Get all assets in the group
const assetsResponse = await fetch(
`https://app.chainpatrol.io/api/v2/organization/assets?groupId=${groupId}`,
{
headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
}
);
const { assets } = await assetsResponse.json();
console.log(`Found ${assets.length} assets to reassign`);
// Reassign each asset
for (const asset of assets) {
await fetch(
`https://app.chainpatrol.io/api/v2/organization/assets/${asset.id}`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY_HERE",
},
body: JSON.stringify({
assetId: asset.id,
groupId: targetGroupId,
}),
}
);
}
console.log(`Reassigned ${assets.length} assets`);
// Now delete the group
const deleteResponse = await fetch(
`https://app.chainpatrol.io/api/v2/organization/asset-groups/${groupId}`,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY_HERE",
},
body: JSON.stringify({ groupId }),
}
);
const result = await deleteResponse.json();
console.log(`✓ Deleted group ${groupId}`);
return result;
}
// Usage: Move assets to group 2 before deleting group 4
await deleteGroupWithReassignment(4, 2);
// Usage: Ungroup all assets before deleting
await deleteGroupWithReassignment(4, null);
async function deleteEmptyGroups() {
// Get all groups
const listResponse = await fetch(
"https://app.chainpatrol.io/api/v2/organization/asset-groups",
{
headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
}
);
const { groups } = await listResponse.json();
// Filter for empty groups
const emptyGroups = groups.filter((g) => g.assetCount === 0);
console.log(`Found ${emptyGroups.length} empty groups to delete`);
const results = [];
for (const group of emptyGroups) {
try {
const deleteResponse = await fetch(
`https://app.chainpatrol.io/api/v2/organization/asset-groups/${group.id}`,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY_HERE",
},
body: JSON.stringify({ groupId: group.id }),
}
);
if (deleteResponse.ok) {
const result = await deleteResponse.json();
results.push({ id: group.id, name: group.name, success: true });
console.log(`✓ Deleted empty group: "${group.name}"`);
} else {
const error = await deleteResponse.json();
results.push({
id: group.id,
name: group.name,
success: false,
error: error.error.message,
});
}
} catch (error) {
results.push({
id: group.id,
name: group.name,
success: false,
error: String(error),
});
}
}
return results;
}
// Usage
deleteEmptyGroups().then((results) => {
const successful = results.filter((r) => r.success).length;
console.log(`\nDeleted ${successful} of ${results.length} empty groups`);
});
async function deleteGroupWithAudit(
groupId: number,
deletedBy: string,
reason: string
) {
// Get group details before deletion
const listResponse = await fetch(
"https://app.chainpatrol.io/api/v2/organization/asset-groups",
{
headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
}
);
const { groups } = await listResponse.json();
const group = groups.find((g) => g.id === groupId);
if (!group) {
throw new Error("Group not found");
}
// Perform deletion
const deleteResponse = await fetch(
`https://app.chainpatrol.io/api/v2/organization/asset-groups/${groupId}`,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY_HERE",
},
body: JSON.stringify({ groupId }),
}
);
const result = await deleteResponse.json();
// Create audit log
const auditLog = {
timestamp: new Date().toISOString(),
action: "GROUP_DELETED",
groupId: group.id,
groupName: group.name,
assetCount: group.assetCount,
unassignedAssetCount: result.unassignedAssetCount,
deletedBy: deletedBy,
reason: reason,
success: result.success,
};
console.log("Audit log:", JSON.stringify(auditLog));
// await sendToAuditSystem(auditLog);
return result;
}
// Usage
await deleteGroupWithAudit(4, "admin@example.com", "Consolidating group structure");
async function cleanupUnusedGroups() {
const listResponse = await fetch(
"https://app.chainpatrol.io/api/v2/organization/asset-groups",
{
headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
}
);
const { groups } = await listResponse.json();
// Delete groups with 0 or very few assets
const threshold = 3;
const groupsToDelete = groups.filter((g) => g.assetCount <= threshold);
console.log(`Found ${groupsToDelete.length} groups with ≤${threshold} assets`);
for (const group of groupsToDelete) {
console.log(`Deleting "${group.name}" (${group.assetCount} assets)...`);
await fetch(
`https://app.chainpatrol.io/api/v2/organization/asset-groups/${group.id}`,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY_HERE",
},
body: JSON.stringify({ groupId: group.id }),
}
);
}
console.log("Cleanup complete");
}
async function consolidateGroups(
oldGroupIds: number[],
newGroupName: string
) {
// Create new group
const createResponse = await fetch(
"https://app.chainpatrol.io/api/v2/organization/asset-groups",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY_HERE",
},
body: JSON.stringify({ name: newGroupName }),
}
);
const newGroup = await createResponse.json();
console.log(`Created new group "${newGroup.name}" (ID: ${newGroup.id})`);
// Move all assets from old groups to new group
for (const oldGroupId of oldGroupIds) {
const assetsResponse = await fetch(
`https://app.chainpatrol.io/api/v2/organization/assets?groupId=${oldGroupId}`,
{
headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
}
);
const { assets } = await assetsResponse.json();
console.log(`Moving ${assets.length} assets from group ${oldGroupId}...`);
for (const asset of assets) {
await fetch(
`https://app.chainpatrol.io/api/v2/organization/assets/${asset.id}`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY_HERE",
},
body: JSON.stringify({
assetId: asset.id,
groupId: newGroup.id,
}),
}
);
}
// Delete old group
await fetch(
`https://app.chainpatrol.io/api/v2/organization/asset-groups/${oldGroupId}`,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY_HERE",
},
body: JSON.stringify({ groupId: oldGroupId }),
}
);
console.log(`Deleted old group ${oldGroupId}`);
}
console.log("Consolidation complete");
}
// Usage: Merge groups 2, 3, and 4 into "Consolidated Assets"
await consolidateGroups([2, 3, 4], "Consolidated Assets");
import * as readline from "readline";
async function interactiveDeleteGroup(groupId: number) {
// Get group details
const listResponse = await fetch(
"https://app.chainpatrol.io/api/v2/organization/asset-groups",
{
headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
}
);
const { groups } = await listResponse.json();
const group = groups.find((g) => g.id === groupId);
if (!group) {
console.error("Group not found");
return;
}
console.log("\nGroup to be deleted:");
console.log(` ID: ${group.id}`);
console.log(` Name: ${group.name}`);
console.log(` Asset count: ${group.assetCount}\n`);
if (group.assetCount > 0) {
console.log(
`⚠️ Warning: This group contains ${group.assetCount} asset(s) that will become ungrouped.\n`
);
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question(
'Type the group name to confirm deletion (or press Enter to cancel): ',
async (confirmation) => {
if (confirmation !== group.name) {
console.log("Deletion cancelled");
rl.close();
return;
}
const deleteResponse = await fetch(
`https://app.chainpatrol.io/api/v2/organization/asset-groups/${groupId}`,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY_HERE",
},
body: JSON.stringify({ groupId }),
}
);
if (deleteResponse.ok) {
const result = await deleteResponse.json();
console.log(
`\n✓ Group deleted successfully. Unassigned ${result.unassignedAssetCount} assets.`
);
} else {
const error = await deleteResponse.json();
console.error(`\n✗ Failed to delete: ${error.error.message}`);
}
rl.close();
}
);
}
| Error Message | Cause | Resolution |
|---|---|---|
| Group with ID not found | Invalid group ID or already deleted | Verify the group ID exists |
| Group does not belong to your organization | Group belongs to a different organization | Use a group ID from your organization |
| Group ID is required | Missing groupId field in request | Provide a groupId field |
| Path parameter groupId does not match body | Mismatch between URL and body group IDs | Ensure both group IDs match |
unassignedAssetCount in the response shows how many assets were affectedYour API key. This is required by most endpoints to access our API programatically. Reach out to us at support@chainpatrol.io to get an API key for your use.
ID of the group to delete
x > 0Was this page helpful?