API Reference
Analyze any Windows installer and get silent install switches, Intune detection rules, publisher metadata, and more — in a single API call.
Base URL: https://app.silentinstallhq.com
·
Get a free API key →
Authentication
Pass your API key in the X-API-Key request header on every request.
Requests without a key are accepted but consume the anonymous shared quota.
Keys are shown once at signup. If lost, rotate from your dashboard — the old key is immediately invalidated.
curl -X POST https://app.silentinstallhq.com/identify \ -H "X-API-Key: sihq_your_key_here" \ -F "file=@setup.exe"
Rate limits
Each plan has a daily request quota that resets at midnight UTC. Per-endpoint hourly limits also apply.
| Plan | Daily quota | Price |
|---|---|---|
| free | 100 / day | — |
| pro | 1,000 / day | $49 / month |
| Endpoint | Hourly limit |
|---|---|
POST /identify | 20 / hour |
POST /identify/url | 10 / hour |
POST /identify/upload-url | 20 / hour |
{
"detail": {
"error": "Daily limit of 100 requests exceeded (free tier).",
"upgrade_url": "/billing/upgrade",
"resets_at": "midnight UTC"
}
}
Errors
All errors return JSON with a detail field.
On rate-limit errors detail is an object (not a string) so you can
surface the upgrade URL directly in your application.
| Status | Meaning |
|---|---|
400 | Bad request — invalid input or download failed |
401 | Missing or invalid API key |
413 | File exceeds size limit |
422 | Validation error — check content type or body shape |
429 | Daily quota exceeded |
503 | File too large for sync endpoint — use the large file flow |
{
"detail": "Invalid or inactive API key."
}
{
"detail": "File exceeds 50 MB sync limit. Use POST /identify/upload-url to upload large files via pre-signed URL."
}
Upload a file directly. Analyzes it synchronously and returns a full profile object.
| Parameter | Type | Description | |
|---|---|---|---|
| file | file | required | The installer binary (.exe, .msi, .msix, .appx, …) |
curl -X POST https://app.silentinstallhq.com/identify \ -H "X-API-Key: sihq_your_key_here" \ -F "file=@7zip-24.09-x64.exe"
import requests with open("7zip-24.09-x64.exe", "rb") as f: resp = requests.post( "https://app.silentinstallhq.com/identify", headers={"X-API-Key": "sihq_your_key_here"}, files={"file": f}, ) profile = resp.json()
Submit a public download URL. The server downloads the file and analyzes it, then returns the profile object synchronously.
| Parameter | Type | Description | |
|---|---|---|---|
| url | string | required | Public HTTPS URL to the installer file |
curl -X POST https://app.silentinstallhq.com/identify/url \ -H "X-API-Key: sihq_your_key_here" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com/setup.exe"}'
import requests
resp = requests.post(
"https://app.silentinstallhq.com/identify/url",
headers={"X-API-Key": "sihq_your_key_here"},
json={"url": "https://example.com/setup.exe"},
)
profile = resp.json()
Large files > 50 MB
Files over 50 MB use a three-step async flow. You get a pre-signed URL, upload directly to cloud storage (bypassing the app entirely), then queue the job. Poll GET /jobs/{job_id} for the result.
POST /identify/upload-url — reserve a slot,
receive upload_url + job_id
PUT {upload_url} — upload binary directly to cloud storage
POST /identify/submit — queue the job, then poll
GET /jobs/{job_id}
| Parameter | Type | Description | |
|---|---|---|---|
| filename | string | required | Original filename — used for analysis and extension detection |
curl -X POST https://app.silentinstallhq.com/identify/upload-url \ -H "X-API-Key: sihq_your_key_here" \ -H "Content-Type: application/json" \ -d '{"filename": "office-setup.exe"}' # Response { "job_id": "3f8a1c2d-...", "upload_url": "https://storage.example.com/...", "expires_in": 3600 }
curl -X PUT "$UPLOAD_URL" \ -H "Content-Type: application/octet-stream" \ --data-binary @office-setup.exe
curl -X POST https://app.silentinstallhq.com/identify/submit \ -H "X-API-Key: sihq_your_key_here" \ -H "Content-Type: application/json" \ -d '{"job_id": "3f8a1c2d-..."}' # Response — 202 Accepted { "job_id": "3f8a1c2d-...", "status": "queued" }
Poll for async job status. The profile field is populated when
status is complete.
Recommended polling interval: 5–10 seconds.
| Status | Meaning |
|---|---|
pending_upload |
Waiting for step 2 — PUT the file |
queued |
File uploaded, waiting for worker |
processing |
Analysis in progress |
complete |
profile is populated |
failed |
Check the error field |
curl https://app.silentinstallhq.com/jobs/3f8a1c2d-... \ -H "X-API-Key: sihq_your_key_here"
{
"job_id": "3f8a1c2d-...",
"status": "complete",
"profile": { /* profile object */ },
"error": null,
"created_at": "2026-06-19T10:00:00Z",
"completed_at": "2026-06-19T10:02:14Z"
}
Profile object
Every endpoint returns the same profile shape. Fields are null
when not detected. The shape is identical whether the analysis ran synchronously or via a job.
| Field | Type | Description |
|---|---|---|
| SHA256 | string | SHA-256 of the file |
| FileName | string | Original filename |
| ProductName | string? | Product name from file metadata |
| Publisher | string? | Publisher name |
| ProductVersion | string? | Version string |
| InstallerType | string? | msi · nsis · inno · burn · wix · exe |
| Architecture | string? | x64 · x86 · arm64 |
| SilentInstall | string? | Silent install switch string |
| SilentUninstall | string? | Silent uninstall command |
| IntuneRule | object? | Intune Win32 detection rule — see Intune Rule shapes |
| IntuneRuleSource | string? | How the rule was derived — msi_product_code · winget_apps_features · manual |
| ProductCode | string? | MSI ProductCode GUID |
| UpgradeCode | string? | MSI UpgradeCode GUID |
| DigitallySigned | bool | File carries a valid digital signature |
| Signer | string? | Code-signing certificate subject |
| ReadinessScore | float | 0–1 confidence score for the silent install data |
| WingetPackageId | string? | Matched WinGet package ID |
| Description | string? | Product description (from WinGet) |
| HomepageUrl | string? | Product homepage |
| warnings | string[] | Non-fatal analysis warnings |
{
"SHA256": "a3f9c1...",
"FileName": "7zip-24.09-x64.exe",
"ProductName": "7-Zip 24.09 (x64)",
"Publisher": "Igor Pavlov",
"ProductVersion": "24.09",
"InstallerType": "nsis",
"Architecture": "x64",
"SilentInstall": "/S",
"SilentUninstall": "\"C:\\Program Files\\7-Zip\\Uninstall.exe\" /S",
"IntuneRule": {
"ruleType": "registry",
"keyPath": "HKLM:\\SOFTWARE\\7-Zip",
"valueName": "DisplayVersion",
"operator": "greaterThanOrEqual",
"detectionValue": "24.09"
},
"IntuneRuleSource": "winget_apps_features",
"ProductCode": null,
"DigitallySigned": true,
"Signer": "Igor Pavlov",
"ReadinessScore": 0.95,
"WingetPackageId": "7zip.7zip",
"warnings": []
}
Intune Rule shapes
The IntuneRule object varies by detection method.
Use ruleType to branch your Intune deployment logic.
| ruleType | When used |
|---|---|
msi | MSI installers with a known ProductCode GUID |
registry | EXE installers detected via Apps & Features registry key |
unknown | No reliable detection method found |
{
"ruleType": "msi",
"productCode": "{23170F69-40C1-2702-2409-000001000000}"
}
{
"ruleType": "registry",
"keyPath": "HKLM:\\SOFTWARE\\Microsoft\\Teams",
"detection": "keyExists"
}
{
"ruleType": "registry",
"keyPath": "HKLM:\\SOFTWARE\\7-Zip",
"valueName": "DisplayVersion",
"operator": "greaterThanOrEqual",
"detectionValue": "24.09"
}