Skip to content
QUICKSTART · 5 MIN

Your first verdict in 5 minutes.

One HTTPS call. The full signal set, the score, the recommended action. No agents, no migrations, no waiting on a vendor call.

3 prereqs · 5 steps · 1 production checklist. The page is linear, don't skip steps.

No credit cardFree tier with LLM layer100 IOCs/day
01 · BEFORE YOU START

Three things, two minutes.

None of these need a contract or a sales call.

01
A VerdictIQ account

Free tier monthly quota, no credit card. Sign up at portal.verdictiq.io.

02
An API key

Generated in the portal under Settings → API Keys. Dev keys are scoped, rate-limited, revocable.

03
An HTTP client

Anything that can POST JSON: curl, Postman, Python requests, Node fetch. Examples below cover four of them.

STEP 1 OF 5 · 1 MINUTE

Generate an API key.

Dev key for tests, prod key for production. Don't ship the dev key.

Step 01

Sign in at portal.verdictiq.io.

Step 02

Open Settings → API Keys.

Step 03

Click Create key and label it (local-dev, staging, prod-mssp-tenant-x). The label shows up in audit logs.

Step 04

Copy the secret once. The portal won't show it again.

Dev keys default to a free-tier quota. See pricing if you expect more than the free monthly cap. View pricing

STEP 2 OF 5 · 30 SECONDS

Make your first call.

One endpoint, one parameter. The same shape extends to bulk later.

Set $VERDICTIQ_API_KEY to the secret you just copied (format: sk_ followed by 64 hex chars). The example uses a public domain so the response is non-empty. Auth is sent via the X-API-Key header; the Authorization: ApiKey scheme is also accepted.

POST /enrich · curl
curl -X POST https://api.verdictiq.io/api/v2/ioc/enrich \
  -H "X-API-Key: $VERDICTIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"indicator":{"type":"domain","value":"example.com"}}'
200 OK · application/json (truncated)
{
  "indicator": {
    "type": "domain",
    "value": "example.com",
    "normalized": "example.com"
  },
  "risk": {
    "direction": "malicious",
    "score": 38,
    "strength": "medium",
    "category": "..."
  },
  "signals": [
    {
      "signal_id": "newly_activated_domain",
      "signal_name": "Newly-Activated Domain",
      "signal_group": "dns_history",
      "signal_subgroup": "domain_lifecycle",
      "direction": "malicious",
      "evidence": { "value": { "name": "first_seen", "type": "date", "value": "..." } }
    },
    "..."
  ],
  "signal_count": 17,
  "scores": {
    "groups":   { "...": "..." },
    "families": { "...": "..." }
  },
  "recommended_actions": [
    { "action": "monitor_domain", "order": 1 }
  ],
  "meta": {
    "engine_version": "...",
    "query_time_ms": 142,
    "request_id": "..."
  }
}

Response above is truncated for clarity (full payload includes all signals, full scores breakdown, threat_context, and meta fields). The complete schema, per-field types and all enums live in the API reference.

We don't ship official SDKs yet. Generated clients from the OpenAPI spec are the recommended path.

STEP 3 OF 5 · 1 MINUTE

Read the verdict.

Score, level, action, signals. Each field has one job.

{
  "indicator": {
    "type": "domain",
    "value": "example.com",
    "normalized": "example.com"
  },
  "risk": {
    "direction": "malicious",
    "score": 38,
    "strength": "medium",
    "category": "..."
  },
  "signals": [
    {
      "signal_id": "newly_activated_domain",
      "signal_name": "Newly-Activated Domain",
      "signal_group": "dns_history",
      "signal_subgroup": "domain_lifecycle",
      "direction": "malicious",
      "evidence": { "value": { "name": "first_seen", "type": "date", "value": "..." } }
    },
    "..."
  ],
  "signal_count": 17,
  "scores": {
    "groups":   { "...": "..." },
    "families": { "...": "..." }
  },
  "recommended_actions": [
    { "action": "monitor_domain", "order": 1 }
  ],
  "meta": {
    "engine_version": "...",
    "query_time_ms": 142,
    "request_id": "..."
  }
}
Field reference
Field · TypeWhat it means
risk.scoreint · 0-100 (50 = neutral)Numeric severity for the indicator. Higher is riskier.
risk.direction · risk.strengthenum · malicious|safe|neutral · weak|medium|strong|very_strongBucketed score for branching. Direction first, strength second.
recommended_actions[]array of action + order pairsPre-baked next steps, ordered by priority. SOAR-ready field.
signals[]array of signal_id, signal_name, direction, signal_group, signal_subgroup, evidenceEvery reason behind the score, with raw evidence.

Plain-English rule: if risk_level is medium or higher, the analyst sees the signals; if it's low, the SOAR auto-resolves.

This is the abridged response. Full catalog (all signals, group/family taxonomy, schema) lives in the API reference.

STEP 5 OF 5 · 1 MINUTE

Three endpoints. Different envelopes.

The verdict you just read is the per-IOC unit. Bulk wraps many of them in one call, item by item, same shape.

The per-IOC verdict shape (risk · signals · recommended_actions) is shared by /enrich and each item inside /enrich_bulk's results[].

WHEN THINGS BREAK

Two failures, one retry loop.

Most calls that fail are auth (401) or rate-limited (429). Both recover with the loop below; the full error catalog lives in the API reference.

Retry/backoff (Python)
for attempt in range(3):
    r = requests.post(...)
    if r.status_code < 500:
        break
    time.sleep(2 ** attempt)
BEFORE YOU SHIP

Five checks before production.

None of these are optional; all of them save a 3 a.m. page.

✓ Rotate the dev key out

Use a separate prod key. Audit logs split by key label.

✓ Implement retry/backoff

Exponential, capped at 3 retries. Honor Retry-After on 429.

✓ Cache short-TTL

Same IOC, same hour, same verdict. Free-tier saves quota; paid-tier saves cents.

✓ Alarm on 4xx spikes

Sudden 401/403 means a key issue; 422 spikes mean upstream IOC malformation.

✓ Set quota alarms in the portal

Soft cap warns at 80%, hard cap blocks. Don't find out at 100%.

You've got the verdict. Now wire it in.

Browse the full reference, or talk to the team that built it.

View pricing