Alert Management

This guide covers the full set of operations for working with alerts: listing and filtering, acknowledging and resolving, adding notes, bulk operations, and accessing analytics. These endpoints are the primary interface for dispatchers managing fleet operations.

List and Filter Alerts

Retrieve alerts with flexible filtering options:

curl "https://sally-api.apps.appshore.in/api/v1/alerts?status=ACTIVE&priority=HIGH&category=HOS_VIOLATION&page=1&pageSize=20" \
  -H "X-API-Key: $SALLY_API_KEY"

JavaScript (fetch):

const params = new URLSearchParams({
  status: "ACTIVE",
  priority: "HIGH",
  category: "HOS_VIOLATION",
  page: "1",
  pageSize: "20",
});
 
const response = await fetch(
  `https://sally-api.apps.appshore.in/api/v1/alerts?${params}`,
  {
    headers: { "X-API-Key": process.env.SALLY_API_KEY },
  }
);
 
const { data: alerts, total, page, pageSize } = await response.json();

Response:

{
  "data": [
    {
      "id": "alt_x1y2z3w4",
      "type": "HOS_APPROACHING_DRIVE_LIMIT",
      "category": "HOS_VIOLATION",
      "priority": "HIGH",
      "status": "ACTIVE",
      "title": "Driver approaching 11-hour drive limit",
      "message": "Mike Johnson (TRK-4821) has 45 minutes of drive time remaining.",
      "driverId": "drv_a1b2c3d4",
      "routePlanId": "rte_f8e7d6c5",
      "createdAt": "2026-02-10T16:15:00Z"
    },
    {
      "id": "alt_a5b6c7d8",
      "type": "HOS_APPROACHING_DUTY_LIMIT",
      "category": "HOS_VIOLATION",
      "priority": "HIGH",
      "status": "ACTIVE",
      "title": "Driver approaching 14-hour duty limit",
      "message": "Sarah Chen (TRK-7710) has 50 minutes of on-duty time remaining.",
      "driverId": "drv_b2c3d4e5",
      "routePlanId": "rte_g9h0i1j2",
      "createdAt": "2026-02-10T16:20:00Z"
    }
  ],
  "total": 2,
  "page": 1,
  "pageSize": 20
}

Filter Parameters

ParameterTypeDescription
statusstringACTIVE, ACKNOWLEDGED, RESOLVED, SNOOZED
prioritystringCRITICAL, HIGH, MEDIUM, LOW
categorystringHOS_VIOLATION, ROUTE_DEVIATION, WEATHER, MECHANICAL, SCHEDULING, SYSTEM
driverIdstringFilter alerts for a specific driver
routePlanIdstringFilter alerts for a specific route
startDatestring (ISO 8601)Alerts created after this date
endDatestring (ISO 8601)Alerts created before this date
pagenumberPage number (default: 1)
pageSizenumberResults per page (default: 20, max: 100)

You can combine multiple filters. For example, to find all critical HOS alerts for a specific driver:

curl "https://sally-api.apps.appshore.in/api/v1/alerts?category=HOS_VIOLATION&priority=CRITICAL&driverId=drv_a1b2c3d4" \
  -H "X-API-Key: $SALLY_API_KEY"

Get Alert Details

Retrieve full details for a single alert:

curl https://sally-api.apps.appshore.in/api/v1/alerts/alt_x1y2z3w4 \
  -H "X-API-Key: $SALLY_API_KEY"

JavaScript (fetch):

const response = await fetch(
  "https://sally-api.apps.appshore.in/api/v1/alerts/alt_x1y2z3w4",
  {
    headers: { "X-API-Key": process.env.SALLY_API_KEY },
  }
);
 
const alert = await response.json();

Response:

{
  "id": "alt_x1y2z3w4",
  "type": "HOS_APPROACHING_DRIVE_LIMIT",
  "category": "HOS_VIOLATION",
  "priority": "HIGH",
  "status": "ACTIVE",
  "title": "Driver approaching 11-hour drive limit",
  "message": "Mike Johnson (TRK-4821) has 45 minutes of drive time remaining on route rte_f8e7d6c5.",
  "driverId": "drv_a1b2c3d4",
  "driverName": "Mike Johnson",
  "vehicleId": "veh_e5f6g7h8",
  "vehicleUnit": "TRK-4821",
  "routePlanId": "rte_f8e7d6c5",
  "metadata": {
    "currentHoursDriven": 10.25,
    "driveTimeRemaining": 0.75,
    "nextSegmentDriveTime": 1.2,
    "recommendedAction": "PLAN_REST_STOP"
  },
  "notes": [],
  "history": [
    {
      "action": "CREATED",
      "timestamp": "2026-02-10T16:15:00Z",
      "details": "Alert generated by monitoring service"
    }
  ],
  "createdAt": "2026-02-10T16:15:00Z",
  "updatedAt": "2026-02-10T16:15:00Z"
}

Acknowledge an Alert

Acknowledging an alert signals to the team that a dispatcher is aware of the issue and working on it. This moves the alert from ACTIVE to ACKNOWLEDGED status.

curl -X POST https://sally-api.apps.appshore.in/api/v1/alerts/alt_x1y2z3w4/acknowledge \
  -H "X-API-Key: $SALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Contacting driver Mike Johnson now. Will route to nearest rest area."
  }'

JavaScript (fetch):

const response = await fetch(
  "https://sally-api.apps.appshore.in/api/v1/alerts/alt_x1y2z3w4/acknowledge",
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.SALLY_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      message:
        "Contacting driver Mike Johnson now. Will route to nearest rest area.",
    }),
  }
);
 
const acknowledged = await response.json();

Response:

{
  "id": "alt_x1y2z3w4",
  "status": "ACKNOWLEDGED",
  "acknowledgedBy": {
    "id": "usr_8a2b3c4d",
    "name": "Jane Smith",
    "role": "DISPATCHER"
  },
  "acknowledgedAt": "2026-02-10T16:18:00Z",
  "message": "Contacting driver Mike Johnson now. Will route to nearest rest area."
}

Resolve an Alert

Resolving an alert marks the issue as handled. Include a resolution message describing what was done.

curl -X POST https://sally-api.apps.appshore.in/api/v1/alerts/alt_x1y2z3w4/resolve \
  -H "X-API-Key: $SALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "resolution": "Driver Mike Johnson stopped at Pilot Travel Center in Lebanon, IN. 10-hour rest period initiated. Route will be re-planned for 02:30 UTC departure."
  }'

JavaScript (fetch):

const response = await fetch(
  "https://sally-api.apps.appshore.in/api/v1/alerts/alt_x1y2z3w4/resolve",
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.SALLY_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      resolution:
        "Driver Mike Johnson stopped at Pilot Travel Center in Lebanon, IN. 10-hour rest period initiated. Route will be re-planned for 02:30 UTC departure.",
    }),
  }
);
 
const resolved = await response.json();

Response:

{
  "id": "alt_x1y2z3w4",
  "status": "RESOLVED",
  "resolvedBy": {
    "id": "usr_8a2b3c4d",
    "name": "Jane Smith",
    "role": "DISPATCHER"
  },
  "resolvedAt": "2026-02-10T16:45:00Z",
  "resolution": "Driver Mike Johnson stopped at Pilot Travel Center in Lebanon, IN. 10-hour rest period initiated. Route will be re-planned for 02:30 UTC departure."
}

Snooze an Alert

Temporarily hide an alert. It will return to ACTIVE status after the snooze duration expires.

curl -X POST https://sally-api.apps.appshore.in/api/v1/alerts/alt_a5b6c7d8/snooze \
  -H "X-API-Key: $SALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "durationMinutes": 30,
    "reason": "Driver is 10 minutes from planned rest stop. Will re-evaluate if not stopped in 30 minutes."
  }'

JavaScript (fetch):

const response = await fetch(
  "https://sally-api.apps.appshore.in/api/v1/alerts/alt_a5b6c7d8/snooze",
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.SALLY_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      durationMinutes: 30,
      reason:
        "Driver is 10 minutes from planned rest stop. Will re-evaluate if not stopped in 30 minutes.",
    }),
  }
);
 
const snoozed = await response.json();

Response:

{
  "id": "alt_a5b6c7d8",
  "status": "SNOOZED",
  "snoozedUntil": "2026-02-10T16:50:00Z",
  "snoozedBy": {
    "id": "usr_8a2b3c4d",
    "name": "Jane Smith"
  },
  "reason": "Driver is 10 minutes from planned rest stop. Will re-evaluate if not stopped in 30 minutes."
}

Add Notes to an Alert

Attach notes to an alert for record-keeping and shift handoffs:

curl -X POST https://sally-api.apps.appshore.in/api/v1/alerts/alt_x1y2z3w4/notes \
  -H "X-API-Key: $SALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Spoke with driver at 16:25. He confirmed he is pulling into the Pilot in Lebanon, IN now. ETA for rest start: 16:35 UTC."
  }'

JavaScript (fetch):

const response = await fetch(
  "https://sally-api.apps.appshore.in/api/v1/alerts/alt_x1y2z3w4/notes",
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.SALLY_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      content:
        "Spoke with driver at 16:25. He confirmed he is pulling into the Pilot in Lebanon, IN now. ETA for rest start: 16:35 UTC.",
    }),
  }
);
 
const note = await response.json();

Response:

{
  "id": "note_p1q2r3s4",
  "alertId": "alt_x1y2z3w4",
  "content": "Spoke with driver at 16:25. He confirmed he is pulling into the Pilot in Lebanon, IN now. ETA for rest start: 16:35 UTC.",
  "createdBy": {
    "id": "usr_8a2b3c4d",
    "name": "Jane Smith"
  },
  "createdAt": "2026-02-10T16:26:00Z"
}

Notes create an audit trail that is valuable for compliance reviews and shift handoffs between dispatchers.

Bulk Operations

Bulk Acknowledge

Acknowledge multiple alerts at once:

curl -X POST https://sally-api.apps.appshore.in/api/v1/alerts/bulk/acknowledge \
  -H "X-API-Key: $SALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "alertIds": ["alt_x1y2z3w4", "alt_a5b6c7d8", "alt_e9f0g1h2"],
    "message": "Shift handoff: acknowledged all active alerts. Reviewing each individually."
  }'

JavaScript (fetch):

const response = await fetch(
  "https://sally-api.apps.appshore.in/api/v1/alerts/bulk/acknowledge",
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.SALLY_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      alertIds: ["alt_x1y2z3w4", "alt_a5b6c7d8", "alt_e9f0g1h2"],
      message:
        "Shift handoff: acknowledged all active alerts. Reviewing each individually.",
    }),
  }
);
 
const result = await response.json();

Response:

{
  "acknowledged": 3,
  "failed": 0,
  "results": [
    { "id": "alt_x1y2z3w4", "status": "ACKNOWLEDGED" },
    { "id": "alt_a5b6c7d8", "status": "ACKNOWLEDGED" },
    { "id": "alt_e9f0g1h2", "status": "ACKNOWLEDGED" }
  ]
}

Bulk Resolve

Resolve multiple alerts at once:

curl -X POST https://sally-api.apps.appshore.in/api/v1/alerts/bulk/resolve \
  -H "X-API-Key: $SALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "alertIds": ["alt_x1y2z3w4", "alt_a5b6c7d8"],
    "resolution": "End of shift cleanup. All issues verified resolved with drivers."
  }'

Response:

{
  "resolved": 2,
  "failed": 0,
  "results": [
    { "id": "alt_x1y2z3w4", "status": "RESOLVED" },
    { "id": "alt_a5b6c7d8", "status": "RESOLVED" }
  ]
}

Alert History

Retrieve paginated alert history for audit and compliance purposes:

curl "https://sally-api.apps.appshore.in/api/v1/alerts/history?startDate=2026-02-01T00:00:00Z&endDate=2026-02-10T23:59:59Z&page=1&pageSize=50" \
  -H "X-API-Key: $SALLY_API_KEY"

JavaScript (fetch):

const params = new URLSearchParams({
  startDate: "2026-02-01T00:00:00Z",
  endDate: "2026-02-10T23:59:59Z",
  page: "1",
  pageSize: "50",
});
 
const response = await fetch(
  `https://sally-api.apps.appshore.in/api/v1/alerts/history?${params}`,
  {
    headers: { "X-API-Key": process.env.SALLY_API_KEY },
  }
);
 
const { data: history, total } = await response.json();

Response:

{
  "data": [
    {
      "id": "alt_x1y2z3w4",
      "type": "HOS_APPROACHING_DRIVE_LIMIT",
      "category": "HOS_VIOLATION",
      "priority": "HIGH",
      "status": "RESOLVED",
      "title": "Driver approaching 11-hour drive limit",
      "driverId": "drv_a1b2c3d4",
      "driverName": "Mike Johnson",
      "createdAt": "2026-02-10T16:15:00Z",
      "acknowledgedAt": "2026-02-10T16:18:00Z",
      "resolvedAt": "2026-02-10T16:45:00Z",
      "responseTimeMinutes": 3,
      "resolutionTimeMinutes": 30
    }
  ],
  "total": 156,
  "page": 1,
  "pageSize": 50
}

Alert Analytics

Statistics

Get a summary of alert statistics:

curl "https://sally-api.apps.appshore.in/api/v1/alerts/stats" \
  -H "X-API-Key: $SALLY_API_KEY"

Response:

{
  "total": 156,
  "byStatus": {
    "ACTIVE": 3,
    "ACKNOWLEDGED": 7,
    "RESOLVED": 142,
    "SNOOZED": 4
  },
  "byCategory": {
    "HOS_VIOLATION": 42,
    "ROUTE_DEVIATION": 28,
    "WEATHER": 15,
    "MECHANICAL": 8,
    "SCHEDULING": 63
  },
  "byPriority": {
    "CRITICAL": 5,
    "HIGH": 31,
    "MEDIUM": 72,
    "LOW": 48
  },
  "averageResponseTimeMinutes": 8.3,
  "averageResolutionTimeMinutes": 34.7
}
curl "https://sally-api.apps.appshore.in/api/v1/alerts/analytics/volume?period=daily&startDate=2026-02-01&endDate=2026-02-10" \
  -H "X-API-Key: $SALLY_API_KEY"

Response:

{
  "period": "daily",
  "data": [
    { "date": "2026-02-01", "count": 12 },
    { "date": "2026-02-02", "count": 8 },
    { "date": "2026-02-03", "count": 15 },
    { "date": "2026-02-04", "count": 11 },
    { "date": "2026-02-05", "count": 19 },
    { "date": "2026-02-06", "count": 14 },
    { "date": "2026-02-07", "count": 22 },
    { "date": "2026-02-08", "count": 17 },
    { "date": "2026-02-09", "count": 20 },
    { "date": "2026-02-10", "count": 18 }
  ]
}
curl "https://sally-api.apps.appshore.in/api/v1/alerts/analytics/response-time?period=daily&startDate=2026-02-01&endDate=2026-02-10" \
  -H "X-API-Key: $SALLY_API_KEY"

Resolution Analytics

curl "https://sally-api.apps.appshore.in/api/v1/alerts/analytics/resolution?startDate=2026-02-01&endDate=2026-02-10" \
  -H "X-API-Key: $SALLY_API_KEY"

Response:

{
  "totalResolved": 142,
  "averageResolutionTimeMinutes": 34.7,
  "resolutionRate": 0.91,
  "byCategory": {
    "HOS_VIOLATION": { "count": 38, "avgMinutes": 22.4 },
    "ROUTE_DEVIATION": { "count": 25, "avgMinutes": 18.6 },
    "WEATHER": { "count": 13, "avgMinutes": 45.2 },
    "MECHANICAL": { "count": 7, "avgMinutes": 120.5 },
    "SCHEDULING": { "count": 59, "avgMinutes": 31.8 }
  }
}

Top Alert Types

curl "https://sally-api.apps.appshore.in/api/v1/alerts/analytics/top-types?limit=5" \
  -H "X-API-Key: $SALLY_API_KEY"

Response:

{
  "data": [
    { "type": "LATE_TO_APPOINTMENT", "count": 38, "percentage": 24.4 },
    { "type": "HOS_APPROACHING_DRIVE_LIMIT", "count": 27, "percentage": 17.3 },
    { "type": "DOCK_DELAY", "count": 25, "percentage": 16.0 },
    { "type": "ROUTE_DEVIATION_DETECTED", "count": 22, "percentage": 14.1 },
    { "type": "HOS_BREAK_REQUIRED", "count": 15, "percentage": 9.6 }
  ]
}

These analytics help you identify operational patterns — for example, if LATE_TO_APPOINTMENT alerts are frequent, it may indicate that scheduled delivery windows are too tight or that route plans need to account for more buffer time.

Error Responses

404 Not Found

{
  "statusCode": 404,
  "message": "Alert with ID alt_invalid not found",
  "error": "Not Found"
}

400 Bad Request — Invalid State Transition

{
  "statusCode": 400,
  "message": "Cannot acknowledge alert: alert is already RESOLVED",
  "error": "Bad Request"
}

400 Bad Request — Snooze Duration Out of Range

{
  "statusCode": 400,
  "message": "Snooze duration must be between 5 and 480 minutes",
  "error": "Bad Request"
}

Next Steps