Kaminari Ad · Schema
ScanResponse
Full scan detail returned by GET /scans/:id.
AdvertisingSecurityArtificial IntelligenceFraud PreventionReal Devices
Properties
| Name | Type | Description |
|---|---|---|
| id | string | |
| url | string | |
| country_code | string | |
| emulator_id | string | |
| status | object | |
| parent_scan_id | object | |
| ad_discovery | boolean | |
| max_discovered_ads | object | |
| ad_formats | object | |
| slot_index | object | |
| ad_kind | object | |
| network | string | |
| network_host | string | |
| offer_url | string | |
| redirect_chain | array | |
| screenshot_url | string | |
| report_url | string | |
| public_report_url | string | |
| ad_tag | object | |
| vast_tag | object | |
| referrer | object | |
| ignore_first_n_domains | integer | |
| creative_kind | string | |
| creative_screenshot_url | string | |
| creative_video_url | string | |
| vast_xml_url | string | |
| creative_html_url | string | |
| creative_width | integer | |
| creative_height | integer | |
| creative_redirect_chain | array | |
| video | object | |
| proxy | object | |
| page_title | string | |
| elapsed_ms | integer | |
| error | string | |
| labels | object | |
| classification | object | |
| campaign_id | object | |
| campaign_name | object | |
| campaign_group_id | object | |
| campaign_group_name | object | |
| created_at | string | |
| completed_at | object | |
| landings | array | |
| repeat_index | integer | |
| repeat_total | integer | |
| repeat_session_id | object | |
| repeat_scan_ids | array | The sibling scans this request also created, excluding this one. Populated only by the create endpoints — list and detail responses leave it empty. |
| retry_attempt | integer | |
| retry_max_attempts | integer |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/kaminari-ad/json-schema/kaminari-ad-scan-response-schema.json",
"title": "ScanResponse",
"description": "Full scan detail returned by GET /scans/:id.",
"x-generated": "2026-11-13",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/kaminari-ad-openapi.json#/components/schemas/ScanResponse",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"title": "Id"
},
"url": {
"type": "string",
"title": "Url"
},
"country_code": {
"type": "string",
"title": "Country Code"
},
"emulator_id": {
"type": "string",
"title": "Emulator Id"
},
"status": {
"$ref": "#/$defs/ScanStatus"
},
"parent_scan_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Parent Scan Id"
},
"ad_discovery": {
"type": "boolean",
"title": "Ad Discovery",
"default": false
},
"max_discovered_ads": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Max Discovered Ads"
},
"ad_formats": {
"anyOf": [
{
"items": {
"$ref": "#/$defs/AdKind"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Ad Formats"
},
"slot_index": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Slot Index"
},
"ad_kind": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Ad Kind"
},
"network": {
"type": "string",
"title": "Network",
"default": ""
},
"network_host": {
"type": "string",
"title": "Network Host",
"default": ""
},
"offer_url": {
"type": "string",
"title": "Offer Url"
},
"redirect_chain": {
"items": {
"$ref": "#/$defs/RedirectHopResponse"
},
"type": "array",
"title": "Redirect Chain"
},
"screenshot_url": {
"type": "string",
"title": "Screenshot Url",
"default": ""
},
"report_url": {
"type": "string",
"title": "Report Url",
"default": ""
},
"public_report_url": {
"type": "string",
"title": "Public Report Url",
"default": ""
},
"ad_tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Ad Tag"
},
"vast_tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Vast Tag"
},
"referrer": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Referrer"
},
"ignore_first_n_domains": {
"type": "integer",
"title": "Ignore First N Domains",
"default": 0
},
"creative_kind": {
"type": "string",
"enum": [
"banner",
"video"
],
"title": "Creative Kind",
"default": "banner"
},
"creative_screenshot_url": {
"type": "string",
"title": "Creative Screenshot Url",
"default": ""
},
"creative_video_url": {
"type": "string",
"title": "Creative Video Url",
"default": ""
},
"vast_xml_url": {
"type": "string",
"title": "Vast Xml Url",
"default": ""
},
"creative_html_url": {
"type": "string",
"title": "Creative Html Url",
"default": ""
},
"creative_width": {
"type": "integer",
"title": "Creative Width",
"default": 0
},
"creative_height": {
"type": "integer",
"title": "Creative Height",
"default": 0
},
"creative_redirect_chain": {
"items": {
"$ref": "#/$defs/RedirectHopResponse"
},
"type": "array",
"title": "Creative Redirect Chain"
},
"video": {
"anyOf": [
{
"$ref": "#/$defs/VideoMetaResponse"
},
{
"type": "null"
}
]
},
"proxy": {
"anyOf": [
{
"$ref": "#/$defs/ProxyTargetResponse"
},
{
"type": "null"
}
]
},
"page_title": {
"type": "string",
"title": "Page Title"
},
"elapsed_ms": {
"type": "integer",
"title": "Elapsed Ms"
},
"error": {
"type": "string",
"title": "Error"
},
"labels": {
"additionalProperties": {
"type": "string"
},
"type": "object",
"title": "Labels"
},
"classification": {
"anyOf": [
{
"$ref": "#/$defs/ScanClassificationResponse"
},
{
"type": "null"
}
]
},
"campaign_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Campaign Id"
},
"campaign_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Campaign Name"
},
"campaign_group_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Campaign Group Id"
},
"campaign_group_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Campaign Group Name"
},
"created_at": {
"type": "string",
"format": "date-time",
"title": "Created At"
},
"completed_at": {
"anyOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "null"
}
],
"title": "Completed At"
},
"landings": {
"items": {
"$ref": "#/$defs/LandingResponse"
},
"type": "array",
"title": "Landings"
},
"repeat_index": {
"type": "integer",
"title": "Repeat Index",
"default": 0
},
"repeat_total": {
"type": "integer",
"title": "Repeat Total",
"default": 1
},
"repeat_session_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Repeat Session Id"
},
"repeat_scan_ids": {
"items": {
"type": "string",
"format": "uuid"
},
"type": "array",
"title": "Repeat Scan Ids",
"description": "The sibling scans this request also created, excluding this one. Populated only by the create endpoints — list and detail responses leave it empty."
},
"retry_attempt": {
"type": "integer",
"title": "Retry Attempt",
"default": 0
},
"retry_max_attempts": {
"type": "integer",
"title": "Retry Max Attempts",
"default": 0
}
},
"type": "object",
"required": [
"id",
"url",
"country_code",
"emulator_id",
"status",
"offer_url",
"redirect_chain",
"page_title",
"elapsed_ms",
"error",
"created_at",
"completed_at"
],
"$defs": {
"AdKind": {
"type": "string",
"enum": [
"banner",
"pop",
"video"
],
"title": "AdKind",
"description": "Closed vocabulary for a discovered ad block.\n\n``banner`` and ``video`` carry a creative (screenshot/HTML) plus an\noptional click-through landing — ``video`` is a VAST creative playing\nin a video element (in-player or outstream); ``pop`` is a behaviour\n(pop-under or tab-under) with a landing but no creative."
},
"AiCategoryResponse": {
"properties": {
"tier1": {
"type": "string",
"title": "Tier1"
},
"tier2": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tier2"
},
"tier3": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tier3"
},
"tier4": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tier4"
}
},
"type": "object",
"required": [
"tier1"
],
"title": "AiCategoryResponse",
"description": "Freeform AI category tiers (legacy ``iab_v3`` semantics)."
},
"IabV3CategoryResponse": {
"properties": {
"tier1": {
"type": "string",
"title": "Tier1"
},
"tier2": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tier2"
},
"tier3": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tier3"
},
"tier4": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tier4"
}
},
"type": "object",
"required": [
"tier1"
],
"title": "IabV3CategoryResponse",
"description": "Canonical IAB Content Taxonomy V3 category tiers (validated)."
},
"LandingResponse": {
"properties": {
"ord": {
"type": "integer",
"title": "Ord"
},
"opener_url": {
"type": "string",
"title": "Opener Url",
"default": ""
},
"final_url": {
"type": "string",
"title": "Final Url",
"default": ""
},
"offer_url": {
"type": "string",
"title": "Offer Url",
"default": ""
},
"page_title": {
"type": "string",
"title": "Page Title",
"default": ""
},
"screenshot_url": {
"type": "string",
"title": "Screenshot Url",
"default": ""
},
"redirect_chain": {
"items": {
"$ref": "#/$defs/RedirectHopResponse"
},
"type": "array",
"title": "Redirect Chain"
},
"elapsed_ms": {
"type": "integer",
"title": "Elapsed Ms",
"default": 0
},
"created_at": {
"type": "string",
"format": "date-time",
"title": "Created At"
}
},
"type": "object",
"required": [
"ord",
"created_at"
],
"title": "LandingResponse",
"description": "One landing tab of an ad-tag scan, exposed via ``ScanResponse.landings``.\n\nMulti-tab landing capture: a single ad creative click can open\nmultiple browser tabs (offer + tracking pixels + secondary popups);\neach becomes its own ``LandingResponse``. ``ord=0`` is the primary\nlanding whose URL/screenshot are also mirrored into the legacy\nscalar fields on ``ScanResponse`` for backward compatibility."
},
"ProxyTargetResponse": {
"properties": {
"proxy_type": {
"type": "string",
"title": "Proxy Type"
},
"region": {
"type": "string",
"title": "Region",
"default": ""
},
"city": {
"type": "string",
"title": "City",
"default": ""
},
"isp": {
"type": "string",
"title": "Isp",
"default": ""
}
},
"type": "object",
"required": [
"proxy_type"
],
"title": "ProxyTargetResponse",
"description": "Proxy targeting info in a scan response."
},
"RedirectHopResponse": {
"properties": {
"url": {
"type": "string",
"title": "Url"
},
"status_code": {
"type": "integer",
"title": "Status Code"
},
"content_type": {
"type": "string",
"title": "Content Type"
},
"body_size": {
"type": "integer",
"title": "Body Size"
},
"timestamp_ms": {
"type": "integer",
"title": "Timestamp Ms"
},
"redirected_from": {
"type": "string",
"title": "Redirected From"
},
"sub_requests": {
"items": {
"$ref": "#/$defs/SubRequestResponse"
},
"type": "array",
"title": "Sub Requests"
}
},
"type": "object",
"required": [
"url",
"status_code",
"content_type",
"body_size",
"timestamp_ms",
"redirected_from",
"sub_requests"
],
"title": "RedirectHopResponse",
"description": "One main-frame redirect step with nested sub-request tree."
},
"ScanClassificationResponse": {
"properties": {
"brand": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Brand"
},
"ai_category": {
"anyOf": [
{
"$ref": "#/$defs/AiCategoryResponse"
},
{
"type": "null"
}
]
},
"iab_v3": {
"anyOf": [
{
"$ref": "#/$defs/IabV3CategoryResponse"
},
{
"type": "null"
}
]
},
"custom_taxonomies": {
"items": {
"$ref": "#/$defs/ScanTaxonomyClassificationResponse"
},
"type": "array",
"title": "Custom Taxonomies",
"default": []
}
},
"type": "object",
"title": "ScanClassificationResponse",
"description": "Classification result for a scan — AI category + IAB V3 + brand + custom taxonomies."
},
"ScanStatus": {
"type": "string",
"enum": [
"pending",
"running",
"crawled",
"checking",
"checking_async",
"rechecking",
"completed",
"partial",
"failed",
"cancelled"
],
"title": "ScanStatus",
"description": "Status of a scan through its lifecycle.\n\nOrdered: pending(0) → running(1) → crawled(2) → checking(3) →\nchecking_async(4) → terminal(5). Forward-only transitions enforced by\nadvance_status() in the DB (see status_order() Postgres function).\n\n``CHECKING_ASYNC`` means all inline parts (regexp + domain checks) have\nbeen applied and we are waiting only on async parts (LLM batch today,\nSafeBrowsing / VirusTotal tomorrow). UI can show partial tags + alerts\nat this stage; only classification is still pending.\n\n``RECHECKING`` is a **transient** state used **only** by the recheck\nflow. The recheck use case atomically moves a scan from a terminal\nstate into ``RECHECKING``, wipes prior tags (CH tombstones), wipes\nscan_part_state, then atomically transitions to ``CHECKING`` with\nfresh ``expected_parts``. Both transitions bypass the forward-only\n``advance_status()`` guard via dedicated repository methods.\n\nWhy RECHECKING exists: stale ``check.parts.*`` messages for a now-\nrechecking scan must NOT write tags (those would survive the wipe\nwithout tombstones, corrupting the post-recheck tag set). Consumers\ncheck ``WRITE_BLOCKED_STATUSES`` and skip the message when the scan\nis in ``RECHECKING``. Defence in depth — the TagWriterAdapter's UoW\nalso re-reads the scan status before save."
},
"ScanTaxonomyClassificationResponse": {
"properties": {
"taxonomy_id": {
"type": "string",
"format": "uuid",
"title": "Taxonomy Id"
},
"taxonomy_name": {
"type": "string",
"title": "Taxonomy Name"
},
"taxonomy_slug": {
"type": "string",
"title": "Taxonomy Slug"
},
"taxonomy_version": {
"type": "integer",
"title": "Taxonomy Version"
},
"leaf_node_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Leaf Node Id"
},
"tier1": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tier1"
},
"tier2": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tier2"
},
"tier3": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tier3"
},
"tier4": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tier4"
},
"used_default": {
"type": "boolean",
"title": "Used Default",
"default": false
}
},
"type": "object",
"required": [
"taxonomy_id",
"taxonomy_name",
"taxonomy_slug",
"taxonomy_version",
"leaf_node_id",
"tier1"
],
"title": "ScanTaxonomyClassificationResponse",
"description": "One per-(scan, custom-taxonomy) classification.\n\nMirrors the ``scan_taxonomy_classifications`` row + adds the\ntaxonomy ``name`` and ``slug`` so the UI can render the block\nwithout a second round-trip. ``leaf_node_id`` is included for\nclick-to-filter integrations on the scan list page; ``used_default``\nis a UI hint that the AI fell back to the default leaf rather\nthan picking a specific category."
},
"SubRequestResponse": {
"properties": {
"url": {
"type": "string",
"title": "Url"
},
"resource_type": {
"type": "string",
"title": "Resource Type"
},
"status_code": {
"type": "integer",
"title": "Status Code"
},
"content_type": {
"type": "string",
"title": "Content Type"
},
"body_size": {
"type": "integer",
"title": "Body Size"
},
"timestamp_ms": {
"type": "integer",
"title": "Timestamp Ms"
},
"children": {
"items": {
"$ref": "#/$defs/SubRequestResponse"
},
"type": "array",
"title": "Children"
}
},
"type": "object",
"required": [
"url",
"resource_type",
"status_code",
"content_type",
"body_size",
"timestamp_ms"
],
"title": "SubRequestResponse",
"description": "One sub-request node with recursive children (initiator tree)."
},
"VideoMetaResponse": {
"properties": {
"duration_ms": {
"type": "integer",
"title": "Duration Ms",
"default": 0
},
"mediafile_url": {
"type": "string",
"title": "Mediafile Url",
"default": ""
},
"vast_version": {
"type": "string",
"title": "Vast Version",
"default": ""
},
"ad_system": {
"type": "string",
"title": "Ad System",
"default": ""
},
"is_vpaid": {
"type": "boolean",
"title": "Is Vpaid",
"default": false
},
"wrapper_depth": {
"type": "integer",
"title": "Wrapper Depth",
"default": 0
},
"click_through": {
"type": "string",
"title": "Click Through",
"default": ""
}
},
"type": "object",
"title": "VideoMetaResponse",
"description": "Slim VAST video metadata surfaced on the scan report.\n\nPresent only for VAST scans. The rendered video frame is served via\nthe existing creative-screenshot URL; this block carries the\nvideo-specific facts the report shows alongside it."
}
}
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/kaminari-ad-scan-response"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.