This article explains how to use Swif.ai’s new public APIs to fetch reports from custom scripts or commands run via the Swif agent/MDM. Typical use cases include:
Listing installed extensions for tools like Cursor or VS Code on a schedule
Pulling script outputs into external security/compliance platforms
Auditing command execution results across devices, users, and teams
These APIs are organization‑scoped and protected by your Swif organization public API token.
Your existing API key/token documentation is here: Your API key token.
1. Overview of the Script Report APIs
What this feature does
Swif now:
Ingests script/command execution results from MDM via an internal callback flow
Stores normalized script report records in an internal collection
Exposes two new public REST APIs so your systems can read those reports:
GET /restful/organization/api/v1/script-reports
– List and filter script reports (with pagination)GET /restful/organization/api/v1/script-reports/:reportId
– Fetch a single script report by ID
All access to these endpoints is authorized by your organization public API token (not a per‑user access token).
2. Data Model: Script Report
Each script report represents the result of one logical script/command execution on one device. At a high level, a report includes:
Organization & team
organizationIdteamIdteamName
Device & owner
deviceIdmdmDeviceIddeviceNamedeviceSerialNumberdeviceOwnerIddeviceOwnerNamedeviceOwnerEmail
Command / script
commandId– execution IDcommandTemplateId– template ID used for executioncommandName– display name (e.g., “List VS Code Extensions”)commandType– type/category (e.g.,SCRIPT)command– raw command or script textresponse– raw output from the script/commandstatus– integer status code
Timestamps
startedAt– when execution startedcompletedAt– when execution ended (may benull)collectedAt– when Swif stored/updated the recordupdatedAt– last update time of the record
Reports are retained for up to 90 days, after which they are automatically removed as part of Swif’s data cleanup.
3. Generate an Organization Public API Token
Before you can call the Script Report APIs, you need your organization public API token. This is distinct from individual user API tokens and is scoped to your entire organization.
Your existing API key/token documentation is here: Your API key token.
4. API: List Script Reports
Use this endpoint to search, filter, and paginate through script reports for your organization.
Method:
GETPath:
/restful/organization/api/v1/script-reportsAuth: Organization public API token (
Authorization: Bearer <ORG_PUBLIC_API_TOKEN>)Body: None – use query string parameters
4.1 Authentication
Authorization: Bearer <ORG_PUBLIC_API_TOKEN>
The token’s organization determines which reports are visible; you cannot use it to access data from another organization.
4.2 Query parameters
All parameters are optional. If not provided or set to null, they are ignored.
Name | Type | Matching behavior |
| string or null | Exact match (24‑char MongoID) |
| string or null | Exact match (24‑char MongoID) |
| string or null | Case‑insensitive partial match |
| string or null | Case‑insensitive partial match |
| string or null | Exact match (24‑char MongoID) |
| string or null | Case‑insensitive partial match |
| string or null | Case‑insensitive partial match |
| string or null | Case‑insensitive partial match |
| string or null | Case‑insensitive partial match |
| string or null | Case‑insensitive partial match |
| string or null | Case‑insensitive partial match |
| string or null | Case‑insensitive partial match |
| string or null | Case‑insensitive partial match |
| string or null | Case‑insensitive partial match |
| integer or null | Exact match |
| string or null | ISO‑8601, lower bound on |
| string or null | ISO‑8601, upper bound on |
| string or null | ISO‑8601, lower bound on |
| string or null | ISO‑8601, upper bound on |
| string or null | ISO‑8601, lower bound on |
| string or null | ISO‑8601, upper bound on |
| string or null | Multi‑field search (see below) |
| integer or null | Pagination offset (negative → 0) |
| integer or null | Page size; ≤0 → 20; max 200 |
Search behavior
The search parameter performs a case‑insensitive search across multiple fields, including:
teamNamemdmDeviceIddeviceNamedeviceOwnerNamedeviceOwnerEmaildeviceSerialNumbercommandIdcommandTemplateIdcommandNamecommandTypecommandresponse
This is convenient for quick keyword searches (e.g., “python” or “vscode”).
Pagination rules
If
offsetis negative, it is normalized to0.If
limit≤ 0, it default to20.If
limit> 200, it is capped at200.
4.3 Example request
{
"headers": {
"Authorization": "Bearer <ORG_PUBLIC_API_TOKEN>"
},
"pathParams": {},
"queryParams": {
"teamId": null,
"deviceId": null,
"mdmDeviceId": "dev-001",
"deviceName": null,
"ownerId": null,
"ownerName": null,
"ownerEmail": null,
"serialNumber": null,
"commandId": null,
"commandTemplateId": "tpl-vscode-extensions-001",
"commandName": "List VS Code Extensions",
"commandType": "SCRIPT",
"command": null,
"response": null,
"status": 1,
"startedAtFrom": "2026-03-01T00:00:00Z",
"startedAtTo": "2026-03-31T23:59:59Z",
"completedAtFrom": null,
"completedAtTo": null,
"collectedAtFrom": null,
"collectedAtTo": null,
"search": "python",
"offset": 0,
"limit": 20
}
}4.4 Response format
The response is paginated and includes metadata:
records[]– array of script report objectsmeta.totalCount– total results matching the filtersmeta.resultCount– number of records in this pagemeta.haveMore–trueif there are more pages
When no results match, the API returns:
records: []meta.totalCount: 0meta.resultCount: 0meta.haveMore: false
4.5 Access control
Organization access is strictly derived from the token’s orgId.
Even if you provide a
teamIdfrom another organization, the result set is always limited to your own organization.Requests without a valid token, with an invalid token, or using a token from another org will not return cross‑org data.
5. API: Get Script Report Detail
Use this endpoint to fetch the full details of a single script report.
Method:
GETPath:
/restful/organization/api/v1/script-reports/:reportIdAuth: Organization public API token
Body: None
5.1 Parameters
Headers
Name | Required | Description |
| Yes |
|
Path
Name | Required | Description |
| Yes | 24‑character MongoID of the report |
5.2 Example request
{
"headers": {
"Authorization": "Bearer <ORG_PUBLIC_API_TOKEN>"
},
"pathParams": {
"reportId": "<SCRIPT_REPORT_MONGO_ID>"
},
"queryParams": {}
}
5.3 Response format
Returns a single object with all persisted and derived fields, including:
reportIdorganizationIdteamIdteamNamedeviceIdmdmDeviceIddeviceNamedeviceOwnerNamedeviceOwnerEmaildeviceSerialNumbercommandIdcommandTemplateIdcommandNamecommandTypecommandresponsestatusstartedAtcompletedAtcollectedAtupdatedAt
5.4 Error handling and access control
If
reportIdis malformed or not a 24‑character MongoID, you receive a bad request/validation error.If
reportIdis well‑formed but does not exist, you receive a “not found” response.If a report exists but belongs to another organization, the API still returns “not found” – it never reveals cross‑org data.
6. Common Usage Patterns
6.1 Scheduled polling for new reports
You can implement “new since last run” polling using collectedAtFrom or a combination of time filters.
Example:
GET /restful/organization/api/v1/script-reports?collectedAtFrom=2026-03-24T00:00:00Z&limit=100 Authorization: Bearer <ORG_PUBLIC_API_TOKEN>
Store the last collectedAt you received and reuse it as the next collectedAtFrom to avoid gaps or duplicates.
6.2 Filtering by script or device
All VS Code extension scripts in March:
GET /restful/organization/api/v1/script-reports?commandTemplateId=tpl-vscode-extensions-001&startedAtFrom=2026-03-01T00:00:00Z&startedAtTo=2026-03-31T23:59:59Z Authorization: Bearer <ORG_PUBLIC_API_TOKEN>
All completed reports for a specific MDM device:
GET /restful/organization/api/v1/script-reports?mdmDeviceId=dev-001&status=1 Authorization: Bearer <ORG_PUBLIC_API_TOKEN>
6.3 Quick keyword search
To find any script report whose command or response references a keyword (for example python):
GET /restful/organization/api/v1/script-reports?search=python&limit=20 Authorization: Bearer <ORG_PUBLIC_API_TOKEN>
This will search across command, response, and other text fields described in Section 5.2.
7. Security and Retention
Authorization: Both Script Report APIs require an organization public API token; they do not accept user‑level tokens directly.
Multi‑tenant isolation: Organization scoping is enforced at the API layer. A valid token can only read script reports for its own organization.
Data retention: Old script reports are automatically removed after 90 days as part of Swif’s data cleanup policy.
