HTTP API
Appaloosa Scout API
Query the mobile iOS/Android CVE database programmatically. JSON. Part of it is public (read-only, no auth), part requires an API key. Sources: NVD (NIST) + CISA KEV, updated continuously.
Public endpoints
No API key required. Rate-limited at the reverse-proxy (Cloudflare / fail2ban). CDN-friendly cache.
GET
/api/check
Evaluates whether an installed version of an app is still affected by known CVEs. Single source of truth shared with the HTML page /check.
Parameters (query string)
| Name | Type | Required | Description |
|---|---|---|---|
bundle_id | string | yes | App identifier (e.g. com.microsoft.Office.Outlook). Format: ^[A-Za-z0-9][A-Za-z0-9._-]{1,154}$. |
version | string | no | Installed version to evaluate (e.g. 16.78.1). Without it, all CVEs are marked undetermined. |
Example
curl 'https://scout.appaloosa.io/api/check?bundle_id=com.microsoft.Office.Outlook&version=4.2244.0'
Response (200)
{
"app": {
"bundle_id": "com.microsoft.Office.Outlook",
"name": "Microsoft Outlook",
"platform": "ios",
"current_version": "4.2433.0"
},
"version_checked": "4.2244.0",
"summary": {
"affected_count": 1,
"fixed_count": 7,
"unknown_count": 2,
"kev_affected": 0
},
"affected": [
{
"cve_id": "CVE-2024-XXXXX",
"severity": "HIGH",
"cvss_v3_score": 7.5,
"is_kev": false,
"kev_due_date": null,
"fixed_in_version": "4.2300.0",
"affected_versions": { "start": null, "start_inclusive": false,
"end": "4.2300.0", "end_inclusive": false },
"published": "2024-08-12",
"description": "Microsoft Outlook for iOS …"
}
],
"fixed": [ /* … */ ],
"unknown": [ /* … */ ]
}
Response codes
200— verdict returned (even ifsummary.affected_count = 0)400—{"error": "missing bundle_id"}or{"error": "invalid_bundle_id"}404—{"error": "not_tracked"}: app is not indexed by Scout
Authentication
Authenticated endpoints require a header X-API-Key: scout_….
Keys are generated from the admin by OB2J SAS — contact scout@appaloosa.io to request one.
- Format:
scout_+ 64 hex chars (256 bits of entropy). - Storage: SHA-256 in DB, never in cleartext. The token appears only once at creation.
- Revocation: takes effect immediately (soft delete
revoked_at). - Sliding rate-limit:
rate_per_hour(default 30) andrate_per_day(default 200). On overflow:429 Too Many Requests+ headerRetry-After.
Authenticated endpoints
POST
/api/check/bulk
— verdicts for N apps in one call
For MDM connectors: extract your inventory {bundle_id, installed_version}, POST to Scout, ingest verdicts. The glue layer between bare MDM and paid MTD. Max 500 apps per call.
Body (JSON)
{
"apps": [
{ "bundle_id": "com.microsoft.Office.Outlook", "version": "4.2244.0" },
{ "bundle_id": "com.whatsapp", "version": "2.21.5" },
{ "bundle_id": "us.zoom.videomeetings", "version": "5.13.4" }
]
}
Response (200)
{
"summary": {
"total": 3, "affected_apps": 1, "kev_apps": 0,
"clean_apps": 1, "not_tracked": 1, "invalid_input": 0
},
"results": [
{
"bundle_id": "com.microsoft.Office.Outlook",
"name": "Microsoft Outlook",
"platform": "ios",
"current_version": "4.2433.0",
"version_checked": "4.2244.0",
"summary": { "affected_count": 2, "fixed_count": 9, "unknown_count": 0, "kev_affected": 0 },
"affected": [ { "cve_id": "CVE-…", "severity": "HIGH", "cvss_v3_score": 7.5, … } ],
"url": "/apps/com.microsoft.Office.Outlook"
},
{
"bundle_id": "com.whatsapp",
"summary": { "affected_count": 0, … },
"affected": []
},
{
"bundle_id": "us.zoom.videomeetings",
"error": "not_tracked",
"submit_url": "/submit?bundle_id=us.zoom.videomeetings"
}
]
}
Example
curl -X POST https://scout.appaloosa.io/api/check/bulk \
-H 'X-API-Key: scout_…' \
-H 'Content-Type: application/json' \
-d '{"apps":[{"bundle_id":"com.whatsapp","version":"2.21.5"}]}'
Codes
200— batch results (even if some apps are not tracked, markederror: not_tracked)400— invalid JSON, empty list, or > 500 apps401— API key missing / revoked429— rate-limit
POST
/api/apps
Adds an app to tracking. Asynchronous: an ingestion job is created and drained by the dispatcher (≤ 1 min).
Body (JSON)
{
"bundle_id": "com.example.app",
"platform": "ios",
"vendor": "example",
"product": "app"
}
Response (202)
{ "job_id": 42, "status_url": "/api/jobs/42" }
Example
curl -X POST https://scout.appaloosa.io/api/apps \
-H 'X-API-Key: scout_…' \
-H 'Content-Type: application/json' \
-d '{"bundle_id":"com.example.app","platform":"ios"}'
GET
/api/apps/{bundle_id}
— enriched record
App metadata + per-version CVE classification (if ?version= provided).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bundle_id | string (path) | yes | URL-encoded identifier. |
version | string (query) | no | Enables affected/fixed/unknown classification per CVE. |
Example
curl 'https://scout.appaloosa.io/api/apps/com.microsoft.Office.Outlook?version=4.2244.0' \
-H 'X-API-Key: scout_…'
GET
/api/apps/{bundle_id}/diff
— CVE diff between 2 versions
Lists CVEs fixed (and possibly introduced) between two observed versions. Helps justify a version push to the CISO.
Parameters
bundle_id(path)from(query, required) — e.g.17.2to(query, required) — e.g.17.5
Example
curl 'https://scout.appaloosa.io/api/apps/com.microsoft.Office.Outlook/diff?from=4.2244.0&to=4.2433.0' \
-H 'X-API-Key: scout_…'
Response (200)
{
"bundle_id": "com.microsoft.Office.Outlook",
"from": "4.2244.0", "to": "4.2433.0",
"summary": { "fixed_between_count": 4, "introduced_between_count": 0, "common_count": 12, "kev_fixed_between": 1 },
"fixed_between": [ { "cve_id": "CVE-…", "severity": "HIGH", … } ],
"introduced_between": [],
"common": [ /* … */ ]
}
GET
/api/jobs/{id}
— ingestion job status
Polling: pending → running → done|error. When done, result contains the full enriched record.
Example
curl https://scout.appaloosa.io/api/jobs/42 -H 'X-API-Key: scout_…'
Exponential backoff recommended (1s, 2s, 4s…). A typical job finishes in 5-15 s (network store enrich).
Error codes
| Code | Body | When |
|---|---|---|
400 | {"error":"missing bundle_id"} | Required parameter missing. |
400 | {"error":"invalid_bundle_id"} | Invalid bundle_id format. |
401 | {"error":"unauthorized"} | API key missing / revoked / expired. |
404 | {"error":"not_tracked"} | App is not in the Scout catalog. Submit it via /submit. |
429 | {"error":"rate_limited"} | Rate-limit exceeded. Retry-After in header. |
503 | Service Unavailable | Data update in progress (post-deploy). Retry-After: 30. |
API key
Need a key?
Email scout@appaloosa.io with your use case (MDM admin, SOC, research…). Reply within 48 business hours. A free evaluation key is available for fleets < 500 devices.
For anonymous public use without a key, the /api/check endpoint already covers the version-vs-CVE lookup.