YARA Detection API
The v2 Detection API manages the YARA rules that urlquery runs against every analysis: the same rule sets and rules you see under Detection → YARA on urlquery.net. Use it to keep rules in a repository and sync them from CI. See YARA rules for what the rules scan and how their alerts work.
All routes are on https://api.urlquery.net and require x-apikey. You see and change only your own sets and rules, and those your team shares.
| Method | Path | Quota class | Result |
|---|---|---|---|
GET | /public/v2/detection/yara/sets | yara_read | Your rule sets. |
POST | /public/v2/detection/yara/sets | yara_write | Creates a rule set. |
GET | /public/v2/detection/yara/sets/{set_id} | yara_read | One rule set. |
PUT | /public/v2/detection/yara/sets/{set_id} | yara_write | Replaces a set's name, description, and visibility. Owner only. |
DELETE | /public/v2/detection/yara/sets/{set_id} | yara_write | Deletes a set and all its rules. Owner only. |
GET | /public/v2/detection/yara/sets/{set_id}/rules | yara_read | The set's rules, with their source. |
POST | /public/v2/detection/yara/sets/{set_id}/rules | yara_write | Compiles and saves a new rule in a set you own or your team shares. |
GET | /public/v2/detection/yara/rules/{rule_id} | yara_read | One rule, with its source. |
PUT | /public/v2/detection/yara/rules/{rule_id} | yara_write | Compiles and replaces a rule. |
DELETE | /public/v2/detection/yara/rules/{rule_id} | yara_write | Deletes a rule. |
POST | /public/v2/detection/yara/validate | yara_write | Compiles a source without saving it. |
POST | /public/v2/detection/yara/test | yara_write | Runs a source against a report you can read, without saving it. |
Every call also consumes the account's overall v2 quota. yara_write is lower than the other classes because each call compiles a YARA source.
Create a rule
A detection rule is one YARA source, which can contain more than one YARA rule. The source is compiled before it is saved; includes are not allowed and the limit is 1 MiB.
curl --fail-with-body --request POST \
--header "x-apikey: ${URLQUERY_API_KEY}" \
--header 'content-type: application/json' \
--data @- \
"https://api.urlquery.net/public/v2/detection/yara/sets/${SET_ID}/rules" <<'EOF'
{
"name": "phishing-kits",
"description": "Kit fingerprints",
"content": "rule kit_a { strings: $a = \"kit-a\" condition: $a }",
"visibility": "private",
"alert_visibility": "private"
}
EOF
visibilityisprivateorteam.teamlets your teammates see and use the rule, and withcan_team_editalso change it.alert_visibilitydecides who sees the rule's alerts on matching reports:private(you) orteam.
PUT /public/v2/detection/yara/rules/{rule_id} takes the same body and replaces the rule. Only the owner's visibility, alert_visibility, and can_team_edit are applied; a teammate's update changes the name, description, and source.
To pause a rule without deleting it, replace it with "enabled": false; "enabled": true turns it back on, and leaving enabled out keeps its state. Anyone who can edit the rule can switch it. A disabled rule stops running within about five minutes. New rules are always enabled, so "enabled": false on create returns 400.
Compile errors
A source that does not compile is rejected with 422 and nothing is saved. The message lists up to 10 compiler errors with their lines:
{
"success": false,
"error": {
"http_code": 422,
"error": "UNPROCESSABLE_ENTITY",
"message": "YARA source does not compile: line 2: syntax error, unexpected end of file"
}
}
To check a source in CI before saving it, call POST /public/v2/detection/yara/validate with {"content": "..."}. It returns 200 with valid, rule_count, and every error and warning in diagnostics.
If the compiler is busy, saving a rule, validation and tests return 503 COMPILER_BUSY; retry after a few seconds. A request body over about 6 MiB returns 413 SOURCE_TOO_LARGE, like a source over 1 MiB.
Test a rule against a report
POST /public/v2/detection/yara/test with {"content": "...", "report_id": "<report UUID>"} runs a source against one report you can read, without saving anything. Use it to see what a new or changed rule matches before you save it. A report you can't read returns 404, once the source compiles. Testing YARA rules covers choosing reports to test against, how a test differs from analysis, and what to do when a result surprises you.
Each script and stored response body of the report is scanned on its own, as during analysis. A source that does not compile returns valid: false with its diagnostics, and nothing is scanned.
{
"success": true,
"data": {
"valid": true, "rule_count": 1, "diagnostics": [], "scanned": 12,
"skipped": {"unavailable": 3, "archived": 0, "limit": 0, "timeout": 0},
"matches": [{
"kind": "script", "url": "https://example.test/kit.js", "sha256": "<sha256>",
"rules": [{"name": "collect", "strings": [{"name": "$a", "count": 4,
"matches": [{"offset": 15, "length": 12, "data": "/api/collect"}]}]}]
}]
}
}
scannedcounts the resources scanned.- Each entry in
matchesis a resource that matched:kindisscriptorresponse, with itsurlandsha256;ruleslists the YARA rules that matched;- for each string,
countis how often it matched, andmatchesholds its first three matches, each with its byteoffset,length, and up to 64 bytes of matcheddata. Bytes outside printable ASCII are shown as..
skippedcounts what was not scanned:
| Field | Not scanned |
|---|---|
unavailable | Response bodies urlquery doesn't store, such as images. |
archived | Files inside archives. |
limit | Resources past 200, or past 32 MiB in total. |
timeout | Resources whose scan took over 5 s, or ran past 10 s in total. |
A test counts against yara_write, like validation.
Syncing from CI
Rule and set IDs are stable, so a sync job can keep a mapping from file to rule ID:
- Create the set once, in the UI or with
POST /public/v2/detection/yara/sets, and store its ID. - List the set's rules with
GET .../sets/{set_id}/rulesand match them to your files byname. - Optionally, test each changed file against a report it should match and one it shouldn't, with
POST .../yara/test, and stop if the results are wrong. PUTchanged files,POSTnew ones, andDELETErules whose file was removed.
Each write is checked on its own; a file that does not compile fails with 422 without affecting the others.
A create that times out or returns 502 or 504 may still have been saved. List the set before retrying, so the rule is not created twice.