Tool Name: airdroid_business_device_batch_get_by_ids
Risk Level: 🟢 Low Risk
Execution Mode: âš¡ Synchronous
Category: Device Management
Quick Start (Copy & Use)
Summary: Retrieve all devices matching the given DeviceIds and/or GroupIds (results are union-combined, OR), with internal pagination handled automatically — no manual paging needed. Set QueryAllDevices=true for a full-tenant scan.
Prerequisites: A valid OAuth2 AccessToken in the GI node Credential, plus either DeviceIds/GroupIds from resolver tools, or the deliberate decision to scan all devices. QueryAllDevices is required (set false for normal ID queries).
Success Criteria: StatusCode == 200 and ErrorMessage == "". If both ID lists are empty and QueryAllDevices=false, the call still succeeds but no query is executed — Devices is [] and Hint explains why.
What to Do Next: Use Devices[].device_id for batch device operations (reboot, move, tag); there is no Pagination output — the array is already complete.
Minimal Request Example (recommended to copy directly):
{
"DeviceIds": ["fa6edcff65ab444e8b5e0eb08df4175d", "a286bea023eb4bfc8ef04770ee7dbb5e"],
"GroupIds": [],
"SelectedColumns": ["device_name", "device_id", "note"],
"QueryAllDevices": false
}
Minimal Response Example:
{
"Devices": [
{
"device_id": "fa6edcff65ab444e8b5e0eb08df4175d",
"device_name": "Air 1",
"note": ""
},
{
"device_id": "a286bea023eb4bfc8ef04770ee7dbb5e",
"device_name": "Air 2",
"note": ""
}
],
"Hint": "",
"Retryable": false,
"OriginalStatusCode": 200,
"StatusCode": 200,
"ErrorMessage": ""
}
> Set QueryAllDevices=true to fetch all manageable devices. On success, the tool returns StatusCode: 200 and Retryable: false.
Recipes (Common Recipes)
Recipe 1: Fetch Devices for a Known ID Set (Token Control)
When to use: You collected device_id values from List Devices or Batch Resolve Device and Group IDs by Name and need their current status.
{
"DeviceIds": ["fa6edcff65ab444e8b5e0eb08df4175d", "a286bea023eb4bfc8ef04770ee7dbb5e"],
"GroupIds": [],
"SelectedColumns": ["device_id", "device_name", "online", "battery", "group_name"],
"QueryAllDevices": false
}
Recipe 2: All Devices in One or More Groups (No Manual Paging)
When to use: You need every device in specific groups without managing PageIndex loops. GroupIds must be positive integers.
{
"DeviceIds": [],
"GroupIds": [100, 101],
"SelectedColumns": ["device_id", "device_name", "online", "group_id", "group_name"],
"QueryAllDevices": false
}
Recipe 3: Union of Device IDs and Group IDs (OR)
When to use: You need a specific device set PLUS everything in a group — the results are combined with OR, deduplicated by the underlying query.
{
"DeviceIds": ["fa6edcff65ab444e8b5e0eb08df4175d"],
"GroupIds": [100],
"SelectedColumns": ["device_id", "device_name", "online", "group_name"],
"QueryAllDevices": false
}
Recipe 4: Full-Tenant Scan
When to use: You deliberately need every device in the organization (e.g., inventory export). DeviceIds and GroupIds must both be empty when QueryAllDevices=true.
{
"DeviceIds": [],
"GroupIds": [],
"SelectedColumns": ["device_id", "device_name", "online", "group_name", "last_online_at"],
"QueryAllDevices": true
}
1. Overview
1.1 Description
Retrieve all devices matching the given DeviceIds or GroupIds. Key behaviors:
- Union semantics: DeviceIds and GroupIds conditions are combined with OR (internally built as a $or filter for Search Devices)
- Internal auto-pagination: the workflow calls Search Devices page by page (100 records per page, up to 60 pages) and merges all pages into a single Devices array — no Pagination output, no manual paging
- Full-tenant scan: QueryAllDevices=true retrieves every device in the organization
- No-query guard: when both ID lists are empty and QueryAllDevices=false, no query is executed; the call returns success with empty Devices and an explanatory Hint
1.2 When to Use
- You need device records for a known set of device IDs or group IDs
- You need all devices in one or more groups without managing pagination
- You need a full-tenant scan (set QueryAllDevices=true)
Don't use when (per tool Note):
- You only have device or group names — resolve them first with Batch Resolve Device and Group IDs by Name
- You need pagination metadata (total, last_page) or single-page access — use Search Devices
- You need complex filtering with operators (gt, lt, between) or multiple fields — use Search Devices
- You need a fuzzy keyword search — use List Devices
1.3 Execution Mode and Response
This operation is synchronous (it may take longer than single-page queries because it fetches all pages internally) and returns:
- Devices: The complete merged device array across all internal pages
- StatusCode / ErrorMessage / Hint / Retryable / OriginalStatusCode: Call status and error information
Limits: SelectedColumns accepts at most 10 fields, and the supported result ceiling is 5000 devices. Use Search Devices with manual paging for larger fleets.
1.4 Prerequisites
| Condition | Description | How to Check |
|---|---|---|
| Valid credential | A valid OAuth2 AccessToken is required | Configure AirDroid Business OAuth2 credential in the GI node |
| Valid IDs | GroupIds must be positive integers; DeviceIds must be real device_id strings | Resolve via the tools in 1.5 |
1.5 Prerequisite Tools
| Dependency Tool | Purpose | Necessity |
|---|---|---|
| Batch Resolve Device and Group IDs by Name | Resolve device/group names to IDs in one call | If you only have names |
| List Devices | Collect device_id values (and group_id via SelectedColumns) | If IDs are unknown |
| Resolve Group ID by Name / Batch Resolve Group IDs by Name | Resolve group names to group_id values | If you only have group names |
1.6 Differences from Similar Tools
| Tool | Use Case | Key Difference |
|---|---|---|
| Batch Get Devices by Device or Group IDs | Known ID sets or full scan | Auto-paginates and merges; union (OR) of DeviceIds/GroupIds; no Pagination output |
| Search Devices | Complex filters, single-page control | Operators + $or, returns Pagination metadata |
| List Devices | Simple keyword filter | Single-field Keyword, manual paging |
| Get a Device by Name | One device by exact name | Name-based, returns a single object |
2. Inputs
2.1 Parameter List
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| DeviceIds | string-array | No | [] | Device unique identifiers; union-combined (OR) with GroupIds |
| GroupIds | number-array | No | [] | Group IDs; each value must be an integer > 0 |
| SelectedColumns | string-array | No | ["device_name","device_id","note"] | Fields to return, max 10 |
| QueryAllDevices | bool | Yes | - | Safety switch for full-tenant scan; set false for normal ID queries |
2.2 Parameter Details
`DeviceIds`
- Type: string-array
- Format: Array of device_id strings; empty entries are skipped
- Source:
- List Devices — output Devices[].device_id
- Batch Resolve Device and Group IDs by Name — resolve names to IDs
- Combination: When used together with GroupIds, results are union-combined (OR) — a device is returned if it matches either list
- How to fill in GI node:
- Constant: ["fa6edcff65ab444e8b5e0eb08df4175d", "a286bea023eb4bfc8ef04770ee7dbb5e"]
- Upstream reference: Map an upstream string-array output (e.g., collected device IDs) directly
- Example:
["fa6edcff65ab444e8b5e0eb08df4175d", "a286bea023eb4bfc8ef04770ee7dbb5e"]
`GroupIds`
- Type: number-array
- Format: Each value must be an integer greater than 0 (real groups only)
- Rejected values: Negative or non-integer values (e.g. -100, -7, -30, 1.5) return StatusCode = -1. Console virtual groups (-100/-7/-30) are not supported — use QueryAllDevices=true for a full-tenant scan instead
- Source:
- Resolve Group ID by Name / Batch Resolve Group IDs by Name — resolve group names to IDs
- List Devices — output group_id (add it to SelectedColumns)
- Combination: Union-combined (OR) with DeviceIds
- Example:
[100, 101]
`SelectedColumns`
- Type: string-array
- Constraint: Maximum 10 fields; when omitted, defaults to device_name, device_id, note
- Available fields (this tool's whitelist is smaller than List Devices / Search Devices):
- Basic: device_id, device_name, account_id, note, group_id, group_name, tags
- Status: online, daemon_status, config_status, lost_mode_status, root_state, sleep_mode
- Hardware: model, manu, os_version, app_version
- Identifiers: snid, imei, mac, android_id
- Network: network_type, ip, private_ip
- Battery: battery, batterycharging
- Location: lng, lat
- Time: last_online_at, bind_date
- Enrollment: enrollment_type
- Why recommended: Since this tool merges ALL pages into one array (up to thousands of devices), keeping SelectedColumns to 3-5 fields is critical for token control.
`QueryAllDevices`
- Type: bool — Required
- Meaning: Safety switch for a full-tenant scan.
- true: retrieve every device in the organization; DeviceIds and GroupIds must both be empty when true
- false: normal mode; query only what DeviceIds/GroupIds specify. If both are empty, no query is executed — the call returns success with empty Devices and a Hint explaining this (see 3.4)
- Why it exists: prevents an accidental full-tenant scan when an upstream node produces empty ID arrays.
2.3 Parameter Combination Logic
| DeviceIds | GroupIds | QueryAllDevices | Behavior |
|---|---|---|---|
| non-empty | empty | false | Query by device IDs |
| empty | non-empty | false | Query all devices in those groups |
| non-empty | non-empty | false | Union (OR): devices matching either list |
| empty | empty | false | No query executed; success with empty Devices + explanatory Hint |
| empty | empty | true | Full-tenant scan (all devices) |
| any invalid GroupId | - | - | StatusCode = -1, no query executed |
3. Outputs
3.1 Response Example
Success response:
{
"Devices": [
{
"device_id": "fa6edcff65ab444e8b5e0eb08df4175d",
"device_name": "Air 1",
"note": ""
},
{
"device_id": "a286bea023eb4bfc8ef04770ee7dbb5e",
"device_name": "Air 2",
"note": ""
}
],
"Hint": "",
"Retryable": false,
"OriginalStatusCode": 200,
"StatusCode": 200,
"ErrorMessage": ""
}
"No query executed" response (both ID lists empty, QueryAllDevices=false):
{
"Devices": [],
"Hint": "No DeviceIds or GroupIds provided; device query was not executed and Devices is empty by design. Provide DeviceIds/GroupIds, or set QueryAllDevices=true to retrieve all devices.",
"Retryable": false,
"OriginalStatusCode": 0,
"StatusCode": 200,
"ErrorMessage": ""
}
Error response (invalid GroupIds):
{
"Devices": [],
"Hint": "Use positive integer GroupIds from 'List Groups' / 'Resolve Group ID by Name'. Console virtual groups (-100/-7/-30) are not supported; use QueryAllDevices=true for a full-tenant scan.",
"Retryable": false,
"OriginalStatusCode": 0,
"StatusCode": -1,
"ErrorMessage": "Invalid GroupIds: each value must be an integer greater than 0. Negative or non-integer values are not allowed. Invalid values: [-100]."
}
3.2 Field Descriptions
| Field Path | Type | Description |
|---|---|---|
| Devices | object-array | Complete merged device array across all internally fetched pages; each object contains the fields requested via SelectedColumns. Empty [] when nothing matched or no query was executed |
| Devices[].device_id | string | Device unique identifier |
| Devices[].device_name | string | Device display name |
| Devices[].online | string | "Online" or "Offline" |
| Devices[].battery | number | Battery percentage (0-100) |
| Devices[].group_id | string | Group identifier |
| Devices[].enrollment_type | string | "Regular Enrollment", "Device Owner Enrollment", "Android Enterprise Enrollment", "Zero Touch Enrollment", "Windows Agent Enrollment", or "Samsung KME Enrollment" |
| Devices[].last_online_at / bind_date | string | Datetime strings in YYYY-MM-DD HH:MM:SS format |
| StatusCode | number | 200 = completed (check ErrorMessage), -1 = parameter validation error, -2 = execution rejected, -3 = confirmation timed out, 500 = system/network error |
| ErrorMessage | string | Empty string = success; non-empty = failure reason |
| Hint | string | Next-action guidance. Non-empty on errors, and also when no query was executed (both ID lists empty with QueryAllDevices=false); empty otherwise |
| Retryable | boolean | true = transient error (retry may succeed); false = persistent error (do not retry same params) |
| OriginalStatusCode | number | Upstream HTTP status code (diagnostic only); 0 = no upstream response; -2 = execution rejected; -3 = confirmation timed out |
> There is no Pagination output — pagination is handled internally. If you need total/last_page metadata, use Search Devices instead.
For the full device-field catalog, see Field Reference.
3.3 Status Code / Enum Value Mapping
| Field | Value | Meaning |
|---|---|---|
| online | "Online" / "Offline" | Device online / offline |
| platform_type | "Android" / "Windows" | Product platform |
| network_type | "3G" / "4G" / "Wi-Fi" / "Ethernet" | Network type |
| batterycharging | "Not charging" / "Charging" | Charging status |
| daemon_status | "Some not granted" / "All Granted" | Biz Daemon permission status |
| lost_mode_status | "Not in lost mode" / "In lost mode" | Lost mode status |
| root_state | "Not Rooted" / "Rooted" / "Granted Non-Root permission" | Root status |
| enrollment_type | "Regular Enrollment" / "Device Owner Enrollment" / "Android Enterprise Enrollment" / "Zero Touch Enrollment" / "Windows Agent Enrollment" / "Samsung KME Enrollment" | Enrollment/management mode |
3.4 Distinguishing "Empty Result" from "No Query Executed"
Both cases return StatusCode = 200, ErrorMessage = "", and Devices = []. Check Hint:
| Condition | Meaning |
|---|---|
| Devices == [] and Hint == "" | Query ran; the given IDs matched no devices |
| Devices == [] and Hint mentions "device query was not executed" | Both ID lists were empty with QueryAllDevices=false — no query ran, by design |
Agent decision logic:
IF StatusCode == 200 AND ErrorMessage == "" THEN
IF Hint != "" THEN
// No query executed: provide DeviceIds/GroupIds, or set QueryAllDevices=true
ELSE
// Genuine result; empty Devices means no match
END IF
END IF
4. Examples
4.1 Basic Example: Fetch Devices by Device IDs
Request:
{
"DeviceIds": ["fa6edcff65ab444e8b5e0eb08df4175d", "a286bea023eb4bfc8ef04770ee7dbb5e"],
"GroupIds": [],
"SelectedColumns": ["device_name", "device_id", "note"],
"QueryAllDevices": false
}
Response:
{
"Devices": [
{
"device_id": "fa6edcff65ab444e8b5e0eb08df4175d",
"device_name": "Air 1",
"note": ""
},
{
"device_id": "a286bea023eb4bfc8ef04770ee7dbb5e",
"device_name": "Air 2",
"note": ""
}
],
"Hint": "",
"Retryable": false,
"OriginalStatusCode": 200,
"StatusCode": 200,
"ErrorMessage": ""
}
4.2 Advanced Example: Union of Device IDs and Group IDs
Scenario: Fetch one specific device plus every device in groups 100 and 101 (union, OR).
Request:
{
"DeviceIds": ["fa6edcff65ab444e8b5e0eb08df4175d"],
"GroupIds": [100, 101],
"SelectedColumns": ["device_id", "device_name", "online", "group_id", "group_name"],
"QueryAllDevices": false
}
Response:
{
"Devices": [
{
"device_id": "fa6edcff65ab444e8b5e0eb08df4175d",
"device_name": "Air 1",
"online": "Online",
"group_id": "102",
"group_name": "HQ"
},
{
"device_id": "c2e3f48add6b4bfc8ef04770ee7dbb5e",
"device_name": "Store-Tablet-01",
"online": "Offline",
"group_id": "100",
"group_name": "Stores"
}
],
"Hint": "",
"Retryable": false,
"OriginalStatusCode": 200,
"StatusCode": 200,
"ErrorMessage": ""
}
4.3 Error Example: Console Virtual Group ID
Request (error — virtual group -100 is not a real group):
{
"DeviceIds": [],
"GroupIds": [-100],
"SelectedColumns": ["device_id", "device_name"],
"QueryAllDevices": false
}
Response:
{
"Devices": [],
"Hint": "Use positive integer GroupIds from 'List Groups' / 'Resolve Group ID by Name'. Console virtual groups (-100/-7/-30) are not supported; use QueryAllDevices=true for a full-tenant scan.",
"Retryable": false,
"OriginalStatusCode": 0,
"StatusCode": -1,
"ErrorMessage": "Invalid GroupIds: each value must be an integer greater than 0. Negative or non-integer values are not allowed. Invalid values: [-100]."
}
4.4 Boundary Example: Empty IDs Without QueryAllDevices
Request:
{
"DeviceIds": [],
"GroupIds": [],
"SelectedColumns": ["device_id", "device_name"],
"QueryAllDevices": false
}
Response (success, but no query was executed):
{
"Devices": [],
"Hint": "No DeviceIds or GroupIds provided; device query was not executed and Devices is empty by design. Provide DeviceIds/GroupIds, or set QueryAllDevices=true to retrieve all devices.",
"Retryable": false,
"OriginalStatusCode": 0,
"StatusCode": 200,
"ErrorMessage": ""
}
5. Error Handling
5.1 AB Three-Layer Error Codes
Core Principle: AB uses a three-layer error code strategy. Agents should decide handling based on StatusCode.
| StatusCode | Meaning | Use Case | Agent Response |
|---|---|---|---|
| -1 | Parameter validation error | Invalid GroupIds (negative/non-integer), empty token | Do not retry; fix parameters and call again |
| 200 | Business success or business error | Query completed (or intentionally skipped); judge by ErrorMessage and Hint | Empty ErrorMessage = success; non-empty = business error |
| 500 | Network/request exception | Timeout, connection failure during any internal page fetch | May retry when Retryable=true (max 2 times, 5-second interval) |
The tool may also return -2 (execution rejected) or -3 (confirmation timed out). If any page fetch fails, Devices may contain records merged before the failure; treat any non-empty ErrorMessage as an incomplete result and do not use the partial array for batch operations.
5.2 Common Errors
| StatusCode | ErrorMessage Example | Cause | Fix |
|---|---|---|---|
| -1 | Invalid GroupIds: each value must be an integer greater than 0. ... Invalid values: [-100]. | Negative, decimal, or non-integer group IDs (incl. console virtual groups -100/-7/-30) | Use positive integer IDs from List Groups / Resolve Group ID by Name; for "all devices" use QueryAllDevices=true |
| -1 | access_token is invalid. | Credential not configured or token empty | Configure AirDroid Business OAuth2 Credential in the GI node |
| 200 | API returned HTTP 401: Unauthorized | Token expired/invalid during a page fetch | Refresh token (re-authorize if needed) and retry |
| 200 | API returned HTTP 429: Too Many Requests | Rate limited during multi-page fetching | Wait 10-30 seconds and retry (Retryable=true) |
| 500 | Request timeout after 60 seconds. | A page request timed out | Retry once; if it persists, narrow the ID set |
5.3 Agent Self-Healing Decision Table
| Condition | Handling Strategy |
|---|---|
| StatusCode == 200, ErrorMessage == "", Hint == "" | Success; Devices is the complete result |
| StatusCode == 200, ErrorMessage == "", Hint != "" | No query executed; provide IDs or set QueryAllDevices=true |
| StatusCode == 200 and ErrorMessage != "" | A page fetch failed; result is incomplete — follow Hint, retry only if Retryable == true |
| StatusCode == -1 | Fix GroupIds/credential, then call again |
| StatusCode == 500 and Retryable == true | Retry up to 2 times (5-second interval); escalate if persistent |
6. Best Practices
6.1 Performance Optimization
- Keep SelectedColumns minimal (3-5 fields): this tool returns the entire matched set in one array — on large groups or full scans, extra fields multiply token usage quickly
- Prefer targeted IDs over QueryAllDevices: a full-tenant scan fetches up to ~5000 devices across many internal requests and is the slowest, most expensive mode
- Large fleets: if the fleet may exceed the ~5000-device ceiling, use Search Devices with manual paging instead
6.2 Security Considerations
🟢 Read operation: No special security requirements.
QueryAllDevices=true is a deliberate safety switch — leave it false in workflows where upstream ID arrays could legitimately be empty, so an empty input never silently escalates into a full-tenant scan.
6.3 Idempotency
Idempotency: Naturally idempotent. This is a read operation; repeated calls have no side effects. Device status is dynamic, so identical calls may return different data over time.
7. Related Tools
7.1 Prerequisite Tools
| Tool Name | Purpose |
|---|---|
| Batch Resolve Device and Group IDs by Name | Resolve device/group names to the IDs this tool consumes |
| List Devices | Collect device_id (and group_id) values |
| Resolve Group ID by Name / Batch Resolve Group IDs by Name | Resolve group names to positive-integer group_id values |
| List Groups | Browse groups to find valid group_id values |
7.2 Follow-up Tools
| Tool Name | Purpose |
|---|---|
| Reboot Device / Lock a Device / Power off a Device | Remote commands on the returned devices (use device_id) |
| Move Devices to a Group | Regroup the returned devices |
| Set Tags | Tag the returned devices |
| Get an Activity Log | Track async commands issued afterwards (with Pid) |
7.3 Similar Tool Comparison
| Tool | Use Case | Difference |
|---|---|---|
| Batch Get Devices by Device or Group IDs | Known ID sets / full scan, no paging | Union (OR) of ID lists; internal auto-pagination; no Pagination output |
| Search Devices | Complex filters, page-level control | Operators + $or; returns Pagination metadata |
| List Devices | Simple keyword filter | Single-field Keyword; manual paging |
| Get a Device by Name | One device by exact name | Name lookup, single object |
8. Tool Chains
8.1 Names → IDs → Devices → Batch Command
Scenario: Reboot all devices in groups known only by name.
Tool Chain:
Batch Resolve Device and Group IDs by Name → Batch Get Devices by Device or Group IDs → Reboot Device → Get an Activity Log
Steps:
- Call Batch Resolve Device and Group IDs by Name with the group names to get positive-integer group IDs
- Call Batch Get Devices by Device or Group IDs with GroupIds set, QueryAllDevices=false, SelectedColumns=["device_id","device_name","online"]
- Filter for online == "Online" and call Reboot Device for each device_id
- Track each returned Pid with Get an Activity Log
8.2 Full-Tenant Inventory Snapshot
Scenario: Export a snapshot of every enrolled device.
Tool Chain:
Batch Get Devices by Device or Group IDs
Steps:
- Call with DeviceIds=[], GroupIds=[], QueryAllDevices=true, and a minimal SelectedColumns set (e.g. ["device_id","device_name","online","group_name","last_online_at"])
- The full merged array comes back in one response — no paging loop needed
- Feed Devices[] into the downstream export/report step
Appendix Reference:
- Field Reference: ./Field Reference.md
- Error Code Quick Reference: ./Error Codes.md
Leave a Reply.