Bulk Actions
Applies one action to many customers at once, for multi-select workflows.
POST /api/customers/bulk
Applies a single action to a list of customer ids. Each id is processed independently: one
conflicting or missing customer does not abort the rest. The response is always 200 OK,
even when some ids failed, so check failed rather than relying on the HTTP status alone.
Authentication
BASE_URL="https://uptimeify.io"
TOKEN="<your-api-token>"Request Body
{
"ids": [101, 102, 103],
"action": "reports",
"payload": {
"enabled": true
}
}| Field | Type | Required | Description |
|---|---|---|---|
ids | number[] | yes | Customer ids (the numeric id, not publicId). Non-empty, at most 200 entries, positive integers, no duplicates. |
action | string | yes | One of reports, activate, deactivate, delete, package. |
payload | object | depends on action | Required for reports and package (see below). Ignored for activate, deactivate, delete. |
Actions
| Action | Effect | payload |
|---|---|---|
reports | Sets monthlyReportsEnabled on each customer. | { "enabled": boolean } (required) |
activate | Sets the customer's status to active (a no-op if already active) and cascades monitor statuses accordingly. | none |
deactivate | Sets the customer's status to inactive (a no-op if already inactive) and cascades monitor statuses accordingly. | none |
delete | Hard-deletes the customer. Monitors and check history are removed with it via cascade. Not reversible. | none |
package | Reassigns the customer to a different package by id. | { "packageId": number } (required) |
package only accepts a numeric packageId that belongs to the target customer's own
organization. For every caller except a global admin that is the same thing as your own
organization, because you can only address customers inside it. A global admin addressing
customers across organizations needs a packageId from each customer's own organization; one
belonging to a different organization is rejected with invalidPackageType. Unlike Update Customer, it does not resolve a legacy
packageType string or display name, since guessing which package was meant across up to 200
rows at once is not something the bulk endpoint does; look up the id from
List Package Configs first.
payload.enabled and payload.packageId are validated once, up front, before any customer
is touched. A malformed payload fails the whole request with 400 invalidRequestBody; it never
turns into 200 identical per-id failures.
Example Request
curl -X POST "$BASE_URL/api/customers/bulk" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ids": [101, 102, 103],
"action": "reports",
"payload": { "enabled": true }
}'Example Response (partial result)
{
"ok": [101, 103],
"failed": [
{ "id": 102, "reason": "customerNotFound" }
]
}ok lists the ids that were updated. failed lists the ids that were not, each with a reason
string. Render the split (for example "2 of 3 updated"), never a blanket success from the fact
that the request itself returned 200.
Common Errors
These fail the whole request before any customer is touched:
401 unauthorizedyou are not logged in403 forbiddenyour role isreadonly, or you are a global-supporter (both are read-only for this endpoint)400 invalidRequestBodyidsis missing/empty/not an array, contains more than 200 entries, contains a non-integer, a value<= 0, or a duplicate;actionis not one of the five supported actions; orpayload.enabled/payload.packageIdis missing or the wrong type for the chosen action
These appear per id, inside failed[].reason, without failing the request:
| Reason | Meaning |
|---|---|
customerNotFound | The id does not exist, or belongs to another organization (global admins may address any id; everyone else is scoped to their own organization). Deliberately indistinguishable from "does not exist", so a caller cannot use this endpoint to probe which ids exist elsewhere. |
invalidPackageType | package action only: payload.packageId does not resolve to a package config owned by this customer's organization. |
organizationIdRequired | The caller's session has neither an organization nor global-admin scope. Only possible for a malformed session/token; a normally authenticated caller never sees this. |
unknown | Any other rejection, most commonly a customer-scoped caller (a restricted role, or a customer-scoped API/agent token) addressing an id outside their assigned customers. Also the fallback for any error that carries no stable data.code. |