Discoveries

Discoveries automatically explore a website or Android application by spawning multiple agents across several phases. Starting from a URL (web) or an APK (Android), agents map pages/screens, forms, and interactions, then the system identifies gaps and sends agents to explore further.

Overview

A discovery is an automated exploration of a website. You provide a starting URL and the system spawns multiple agents that navigate the site, cataloging every page, form, and interaction they find. The result is a structured map of the application that can be used to generate test tests.

Discoveries run in multiple phases. The first phase explores from the entry URL. After the agents finish, the system analyzes their findings, identifies unexplored areas and gated pages (areas behind login or authentication), and spawns a second wave of agents to cover the gaps. This continues for up to three phases, with up to three agents per phase, progressively building a more complete picture of the site.

Lifecycle

A discovery moves through several statuses: running (agents are actively exploring), building (the system is processing the findings from a phase and deciding whether to spawn more agents), and completed when all phases are done. It can also be stopped manually or failed if something goes wrong.

The final output is an app map: a structured JSON representation of all discovered pages, their relationships, forms, and interactive elements. This map is stored on the project and used as context for future agent runs and test generation.

GET /api/v1/discoveries

List discoveries

Parameters

ParameterTypeInRequiredDescription
limitintegerqueryNoMaximum discoveries to return.
cursoruuidqueryNoContinue below this discovery ID.
project_iduuidqueryNoRestrict discoveries to one project.

Example Request

curl
curl "http://app.aiqaramba.com/api/v1/discoveries" \
  -H "Authorization: Bearer $AIQA_API_KEY"

Status Codes

CodeDescription
200Tenant discoveries.
400The request is malformed or failed validation.
401Authentication is missing or invalid.
500The server could not complete the request.

Response Fields (200)

FieldTypeDescription
discoveriesobject[]
discoveries[].iduuid
discoveries[].tenant_iduuid
discoveries[].project_iduuid
discoveries[].entry_urluri
discoveries[].presetstringValues: server, spa, custom.
discoveries[].settingsobjectResolved crawler settings a discovery runs with. Returned on every discovery; accepted at creation only with the custom preset.
discoveries[].settings.max_statesintegerState budget of the crawl.
discoveries[].settings.max_depthintegerMaximum exploration depth from the entry state; 0 means unlimited.
discoveries[].settings.max_duration_secondsintegerWall-clock budget of the crawl.
discoveries[].settings.settle_navigate_msintegerWait after a navigation before observing the page.
discoveries[].settings.settle_click_msintegerWait after a click before observing the page.
discoveries[].settings.near_dup_thresholdnumberNear-duplicate distance threshold; 0 disables detection.
discoveries[].statusstringPipeline stage. pending/review_pending are waiting to be picked up; preparing/crawling/reviewing are running; completed/failed/canceled are terminal. . Values: pending, preparing, crawling, review_pending, reviewing, completed, failed, canceled.
discoveries[].cancel_requestedbooleanA cancellation was requested; the run stops at its next safe point and moves to canceled.
discoveries[].failure_reasonstringWhy the discovery failed, set exactly when status is failed.
discoveries[].statsobjectSummary of what the crawl did, written when the crawl ends.
discoveries[].stats.nodesinteger
discoveries[].stats.edgesinteger
discoveries[].stats.duration_secondsnumber
discoveries[].stats.actions_firedinteger
discoveries[].stats.failed_actionsinteger
discoveries[].stats.lostinteger
discoveries[].stats.out_of_scopeinteger
discoveries[].stats.skipped_known_hrefsinteger
discoveries[].stats.suppressed_near_dupinteger
discoveries[].stats.exit_reasonstringWhy the crawl ended. Absent while the crawl is still running — progress stats are reported before there is a reason. Values: exhausted, max_states, max_duration, canceled.
discoveries[].stats.unreached_hrefsstring[]In-scope links the crawl saw on some page but never landed on (scheme, host and path). The crawl's own account of what it did not cover.
discoveries[].stats.failed_action_samplesobject[]The first few actions the browser refused or the crawler could not return to, with the element and the driver's error, so a thin crawl can be diagnosed from the API alone.
discoveries[].app_descriptionstringReviewer's best-effort description of the application.
discoveries[].created_atdate-time
discoveries[].updated_atdate-time
discoveries[].completed_atdate-time
next_cursoruuid
POST /api/v1/discoveries

Start a discovery

Creates a discovery against the given entry URL and returns it in the pending state; a background coordinator then runs the pipeline — an optional login stage using the supplied credentials, a deterministic crawl, and a review producing suggested tests and findings. Poll GET /discoveries/{id} to follow progress. Credentials are write-only and never returned; supply non-sensitive test credentials only — they are shared with an LLM during login.

Request Body (application/json)

FieldTypeRequiredDescription
project_iduuidYesID of the project this discovery belongs to
entry_urluriYesAbsolute http(s) URL the crawl starts from
credentialsjsonNoWrite-only credentials for the login stage
presetstringNoCrawler settings preset. server suits server-rendered applications, spa waits longer for client-side rendering, custom requires the settings object.
settingsjsonNoResolved crawler settings a discovery runs with. Returned on every discovery; accepted at creation only with the custom preset.

Example Request

curl
curl -X POST "http://app.aiqaramba.com/api/v1/discoveries" \
  -H "Authorization: Bearer $AIQA_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "project_id": "<uuid>",
    "entry_url": "https://example.com"
  }'

Status Codes

CodeDescription
201Discovery created and queued.
400The request is malformed or failed validation.
401Authentication is missing or invalid.
500The server could not complete the request.

Response Fields (201)

FieldTypeDescription
iduuid
tenant_iduuid
project_iduuid
entry_urluri
presetstringValues: server, spa, custom.
settingsobjectResolved crawler settings a discovery runs with. Returned on every discovery; accepted at creation only with the custom preset.
settings.max_statesintegerState budget of the crawl.
settings.max_depthintegerMaximum exploration depth from the entry state; 0 means unlimited.
settings.max_duration_secondsintegerWall-clock budget of the crawl.
settings.settle_navigate_msintegerWait after a navigation before observing the page.
settings.settle_click_msintegerWait after a click before observing the page.
settings.near_dup_thresholdnumberNear-duplicate distance threshold; 0 disables detection.
statusstringPipeline stage. pending/review_pending are waiting to be picked up; preparing/crawling/reviewing are running; completed/failed/canceled are terminal. . Values: pending, preparing, crawling, review_pending, reviewing, completed, failed, canceled.
cancel_requestedbooleanA cancellation was requested; the run stops at its next safe point and moves to canceled.
failure_reasonstringWhy the discovery failed, set exactly when status is failed.
statsobjectSummary of what the crawl did, written when the crawl ends.
stats.nodesinteger
stats.edgesinteger
stats.duration_secondsnumber
stats.actions_firedinteger
stats.failed_actionsinteger
stats.lostinteger
stats.out_of_scopeinteger
stats.skipped_known_hrefsinteger
stats.suppressed_near_dupinteger
stats.exit_reasonstringWhy the crawl ended. Absent while the crawl is still running — progress stats are reported before there is a reason. Values: exhausted, max_states, max_duration, canceled.
stats.unreached_hrefsstring[]In-scope links the crawl saw on some page but never landed on (scheme, host and path). The crawl's own account of what it did not cover.
stats.failed_action_samplesobject[]The first few actions the browser refused or the crawler could not return to, with the element and the driver's error, so a thin crawl can be diagnosed from the API alone.
stats.failed_action_samples[].from_nodeinteger
stats.failed_action_samples[].urlstring
stats.failed_action_samples[].tagstring
stats.failed_action_samples[].labelstring
stats.failed_action_samples[].hrefstring
stats.failed_action_samples[].xpathstring
stats.failed_action_samples[].errorstring
stats.failed_action_samples[].kindstringValues: click, reposition, observe.
app_descriptionstringReviewer's best-effort description of the application.
created_atdate-time
updated_atdate-time
completed_atdate-time
GET /api/v1/discoveries/{id}

Get a discovery

Parameters

ParameterTypeInRequiredDescription
iduuidpathYesDiscovery ID.

Example Request

curl
curl "http://app.aiqaramba.com/api/v1/discoveries/<id>" \
  -H "Authorization: Bearer $AIQA_API_KEY"

Status Codes

CodeDescription
200Discovery found.
400The request is malformed or failed validation.
401Authentication is missing or invalid.
404The requested resource does not exist.
500The server could not complete the request.

Response Fields (200)

FieldTypeDescription
iduuid
tenant_iduuid
project_iduuid
entry_urluri
presetstringValues: server, spa, custom.
settingsobjectResolved crawler settings a discovery runs with. Returned on every discovery; accepted at creation only with the custom preset.
settings.max_statesintegerState budget of the crawl.
settings.max_depthintegerMaximum exploration depth from the entry state; 0 means unlimited.
settings.max_duration_secondsintegerWall-clock budget of the crawl.
settings.settle_navigate_msintegerWait after a navigation before observing the page.
settings.settle_click_msintegerWait after a click before observing the page.
settings.near_dup_thresholdnumberNear-duplicate distance threshold; 0 disables detection.
statusstringPipeline stage. pending/review_pending are waiting to be picked up; preparing/crawling/reviewing are running; completed/failed/canceled are terminal. . Values: pending, preparing, crawling, review_pending, reviewing, completed, failed, canceled.
cancel_requestedbooleanA cancellation was requested; the run stops at its next safe point and moves to canceled.
failure_reasonstringWhy the discovery failed, set exactly when status is failed.
statsobjectSummary of what the crawl did, written when the crawl ends.
stats.nodesinteger
stats.edgesinteger
stats.duration_secondsnumber
stats.actions_firedinteger
stats.failed_actionsinteger
stats.lostinteger
stats.out_of_scopeinteger
stats.skipped_known_hrefsinteger
stats.suppressed_near_dupinteger
stats.exit_reasonstringWhy the crawl ended. Absent while the crawl is still running — progress stats are reported before there is a reason. Values: exhausted, max_states, max_duration, canceled.
stats.unreached_hrefsstring[]In-scope links the crawl saw on some page but never landed on (scheme, host and path). The crawl's own account of what it did not cover.
stats.failed_action_samplesobject[]The first few actions the browser refused or the crawler could not return to, with the element and the driver's error, so a thin crawl can be diagnosed from the API alone.
stats.failed_action_samples[].from_nodeinteger
stats.failed_action_samples[].urlstring
stats.failed_action_samples[].tagstring
stats.failed_action_samples[].labelstring
stats.failed_action_samples[].hrefstring
stats.failed_action_samples[].xpathstring
stats.failed_action_samples[].errorstring
stats.failed_action_samples[].kindstringValues: click, reposition, observe.
app_descriptionstringReviewer's best-effort description of the application.
created_atdate-time
updated_atdate-time
completed_atdate-time
DELETE /api/v1/discoveries/{id}

Delete a discovery

Parameters

ParameterTypeInRequiredDescription
iduuidpathYesDiscovery ID.

Example Request

curl
curl -X DELETE "http://app.aiqaramba.com/api/v1/discoveries/<id>" \
  -H "Authorization: Bearer $AIQA_API_KEY"

Status Codes

CodeDescription
204Discovery deleted.
400The request is malformed or failed validation.
401Authentication is missing or invalid.
404The requested resource does not exist.
500The server could not complete the request.
POST /api/v1/discoveries/{id}/cancel

Cancel a discovery

Requests cancellation of a non-terminal discovery. Cancellation is asynchronous: the run stops at its next safe point and moves to the canceled state. The response echoes the discovery with cancel_requested set; poll GET /discoveries/{id} for the terminal state.

Parameters

ParameterTypeInRequiredDescription
iduuidpathYesDiscovery ID.

Example Request

curl
curl -X POST "http://app.aiqaramba.com/api/v1/discoveries/<id>/cancel" \
  -H "Authorization: Bearer $AIQA_API_KEY"

Status Codes

CodeDescription
200Discovery canceled.
400The request is malformed or failed validation.
401Authentication is missing or invalid.
404The requested resource does not exist.
409The request conflicts with the current resource state.
500The server could not complete the request.

Response Fields (200)

FieldTypeDescription
iduuid
tenant_iduuid
project_iduuid
entry_urluri
presetstringValues: server, spa, custom.
settingsobjectResolved crawler settings a discovery runs with. Returned on every discovery; accepted at creation only with the custom preset.
settings.max_statesintegerState budget of the crawl.
settings.max_depthintegerMaximum exploration depth from the entry state; 0 means unlimited.
settings.max_duration_secondsintegerWall-clock budget of the crawl.
settings.settle_navigate_msintegerWait after a navigation before observing the page.
settings.settle_click_msintegerWait after a click before observing the page.
settings.near_dup_thresholdnumberNear-duplicate distance threshold; 0 disables detection.
statusstringPipeline stage. pending/review_pending are waiting to be picked up; preparing/crawling/reviewing are running; completed/failed/canceled are terminal. . Values: pending, preparing, crawling, review_pending, reviewing, completed, failed, canceled.
cancel_requestedbooleanA cancellation was requested; the run stops at its next safe point and moves to canceled.
failure_reasonstringWhy the discovery failed, set exactly when status is failed.
statsobjectSummary of what the crawl did, written when the crawl ends.
stats.nodesinteger
stats.edgesinteger
stats.duration_secondsnumber
stats.actions_firedinteger
stats.failed_actionsinteger
stats.lostinteger
stats.out_of_scopeinteger
stats.skipped_known_hrefsinteger
stats.suppressed_near_dupinteger
stats.exit_reasonstringWhy the crawl ended. Absent while the crawl is still running — progress stats are reported before there is a reason. Values: exhausted, max_states, max_duration, canceled.
stats.unreached_hrefsstring[]In-scope links the crawl saw on some page but never landed on (scheme, host and path). The crawl's own account of what it did not cover.
stats.failed_action_samplesobject[]The first few actions the browser refused or the crawler could not return to, with the element and the driver's error, so a thin crawl can be diagnosed from the API alone.
stats.failed_action_samples[].from_nodeinteger
stats.failed_action_samples[].urlstring
stats.failed_action_samples[].tagstring
stats.failed_action_samples[].labelstring
stats.failed_action_samples[].hrefstring
stats.failed_action_samples[].xpathstring
stats.failed_action_samples[].errorstring
stats.failed_action_samples[].kindstringValues: click, reposition, observe.
app_descriptionstringReviewer's best-effort description of the application.
created_atdate-time
updated_atdate-time
completed_atdate-time
GET /api/v1/discoveries/{id}/map

Get the crawled map

Returns the state-flow graph discovered so far: one node per distinct UI state, one edge per observed transition. Available while the crawl is still running — nodes and edges appear as they are discovered.

Parameters

ParameterTypeInRequiredDescription
iduuidpathYesDiscovery ID.

Example Request

curl
curl "http://app.aiqaramba.com/api/v1/discoveries/<id>/map" \
  -H "Authorization: Bearer $AIQA_API_KEY"

Status Codes

CodeDescription
200Crawled state-flow graph.
400The request is malformed or failed validation.
401Authentication is missing or invalid.
404The requested resource does not exist.
500The server could not complete the request.

Response Fields (200)

FieldTypeDescription
nodesobject[]
nodes[].node_idinteger
nodes[].urlstring
nodes[].depthinteger
nodes[].candidates_countintegerNumber of clickable elements extracted from the state.
nodes[].near_duplicate_ofinteger
nodes[].near_dup_distancenumber
nodes[].console_error_countintegerSEVERE console entries captured when the state was first observed.
nodes[].discovered_atdate-time
edgesobject[]
edges[].from_nodeinteger
edges[].to_nodeinteger
edges[].tagstring
edges[].labelstring
GET /api/v1/discoveries/{id}/suggestions

List a discovery's suggestions

Returns the reviewer's drafted tests and findings for a discovery. Populated once the review stage completes; empty before then. These are drafts — accepting one into a real test or finding is a separate action.

Parameters

ParameterTypeInRequiredDescription
iduuidpathYesDiscovery ID.

Example Request

curl
curl "http://app.aiqaramba.com/api/v1/discoveries/<id>/suggestions" \
  -H "Authorization: Bearer $AIQA_API_KEY"

Status Codes

CodeDescription
200Discovery suggestions.
400The request is malformed or failed validation.
401Authentication is missing or invalid.
404The requested resource does not exist.
500The server could not complete the request.

Response Fields (200)

FieldTypeDescription
suggestionsobject[]
suggestions[].iduuid
suggestions[].kindstringValues: test, finding.
suggestions[].statusstringValues: suggested, dismissed, accepted.
suggestions[].created_atdate-time
suggestions[].testobjectA machine-drafted test in the structured-prompt shape: instructions (what the agent should do) plus validations (what must check out).
suggestions[].test.namestring
suggestions[].test.descriptionstring
suggestions[].test.importancestringValues: critical, high, medium, low.
suggestions[].test.entry_urlstring
suggestions[].test.instructionsstringThe goal and what the agent cannot invent; the path is left to the agent.
suggestions[].test.validationsstring[]The outcomes that must check out for the test to pass.
suggestions[].test.hintsstringThe path the reviewer observed, phrased as a dated observation the agent may find outdated.
suggestions[].test.side_effectsstring[]What a run does beyond reading pages.
suggestions[].test.surfacestringWhether end users or operators touch this flow. Values: customer, operator.
suggestions[].test.evidence_state_idsinteger[]Crawl states that show the flow exists.
suggestions[].findingobjectA machine-drafted finding observed during the crawl.
suggestions[].finding.typestringValues: bug, ux_issue, cosmetic, observation, accessibility.
suggestions[].finding.severitystringValues: critical, high, medium, low.
suggestions[].finding.titlestring
suggestions[].finding.descriptionstring
suggestions[].finding.urlstring
suggestions[].finding.elementstring
suggestions[].finding.impactstring
suggestions[].finding.remediationstring
suggestions[].finding.state_idintegerThe crawl state (node_id) that evidences this finding.