AI-assisted business research API
Submit structured business details to the business research worker pool. Each business becomes a task. The API returns task IDs immediately; poll until the task is complete, then download its JSON result.
The customer-facing product name is AI-assisted business research. Existing
API paths and permission scopes keep ai-mode in their names.
The service uses the supplied business identity and location to research the matching legal entity and individual business locations. Results are returned as structured JSON, including the submitted details, registry status, company-number verification, location records, and an evidence-based data-quality assessment. A completed task's result is JSON data; it is not a claim that every field was found or independently verified.
Accuracy notice: AI-assisted business research results may be inaccurate, outdated, or incomplete. Independently verify important details against authoritative sources before relying on them, particularly for legal, financial, or compliance decisions. This service does not provide an official registry confirmation.
Before you start
- Sign in to the customer portal and create an API key.
- Ask your account administrator to grant the key both
ai-mode:createandai-mode:read. - Set the key as the
API_KEYenvironment variable. Keep it private; do not commit it to source control.
Examples use https://bankworks.info as the API base URL.
Python requires requests (pip install requests).
The Node.js example uses built-in fetch, needs Node 18 or newer,
and should be saved as an ES module such as ai_mode.mjs.
The cURL example also uses jq to read JSON fields.
export API="https://bankworks.info"
export API_KEY="your-api-key"
Load API_KEY from your secret manager in production.
Each POST creates new tasks; poll an existing task while it is still running.
Resubmitting creates a new task and may incur another charge.
Request fields
Send between 1 and 100 entities in one request. The first three fields
are required. address is a free-text location field: include
any available street, city, region, or postal code in one string.
companyNumber is optional and represents the provided corporate
registration or tax number.
Set the top-level mode to control how much of the result the
result endpoint returns. regular includes the submitted entity,
requested-location status, company-number verification, and data quality.
advance also includes the parent company and business locations.
premium returns the complete JSON result. If omitted,
mode defaults to regular. The same mode applies to
every entity in the request and is shown as task.resultMode when
polling task status. This controls response detail only; it does not change
task routing or billing, which remains one REGULAR API task per
entity when billing is enabled.
The sample business details below are entirely fictional.
| JSON field | Required | Meaning | Maximum |
|---|---|---|---|
mode | No | regular, advance, or premium; controls result detail | One value per request |
businessName | Yes | Business or group name | 500 characters |
address | Yes | Address, city, region, and/or postal code as supplied | 1,000 characters |
country | Yes | Country where the business is located | 200 characters |
companyNumber | No | Provided corporate ID or tax number; use null or omit it when unknown | 200 characters |
Complete example
Pick a language tab. Each complete example submits two fictional businesses
in one request, polls each task, and saves each returned JSON to a local file.
One request accepts 1–100 businesses; each entry creates a separate task.
The cURL example requires jq.
import os
import time
from pathlib import Path
import requests
API = os.environ.get("API", "https://bankworks.info")
API_KEY = os.environ["API_KEY"]
headers = {"Authorization": f"Bearer {API_KEY}"}
created = requests.post(
f"{API}/v1/ai-mode/tasks",
headers=headers,
json={"mode": "regular", "entities": [
{
"businessName": "BLUE COMET PAPERWORK LAB (FICTIONAL)",
"address": "42 Imaginary Lane, Sample City, ZZ 00000",
"country": "Fictionland",
"companyNumber": "FICTIONAL-0001",
},
{
"businessName": "MOON LANTERN DESIGN HOUSE (FICTIONAL)",
"address": "8 Paper Street, Example Bay, YY 11111",
"country": "Fictionland",
},
]},
timeout=30,
)
created.raise_for_status()
job = created.json()
task_ids = job["taskIds"]
print(f"Created {len(task_ids)} tasks")
for index, task_id in enumerate(task_ids, start=1):
while True:
status_response = requests.get(
f"{API}/v1/ai-mode/tasks/{task_id}", headers=headers, timeout=30,
)
status_response.raise_for_status()
task = status_response.json()["task"]
if task["status"] == "DONE" and task["resultAvailable"]:
break
if task["status"] in {"FAILED", "CANCELLED"}:
print(f"Task {task_id} {task['status']}: {task.get('error', 'no details')}")
break
time.sleep(5)
if task["status"] != "DONE" or not task["resultAvailable"]:
continue
result = requests.get(
f"{API}/v1/ai-mode/tasks/{task_id}/result", headers=headers, timeout=60,
)
result.raise_for_status()
output = Path(f"ai-searching-{index}-{task_id}.json")
output.write_bytes(result.content)
print("Saved JSON to", output)
import { writeFile } from "node:fs/promises";
import { setTimeout as delay } from "node:timers/promises";
const API = process.env.API || "https://bankworks.info";
const API_KEY = process.env.API_KEY;
if (!API_KEY) throw new Error("Set API_KEY first");
const headers = { Authorization: "Bearer " + API_KEY };
const created = await fetch(API + "/v1/ai-mode/tasks", {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ mode: "regular", entities: [
{
businessName: "BLUE COMET PAPERWORK LAB (FICTIONAL)",
address: "42 Imaginary Lane, Sample City, ZZ 00000",
country: "Fictionland",
companyNumber: "FICTIONAL-0001",
},
{
businessName: "MOON LANTERN DESIGN HOUSE (FICTIONAL)",
address: "8 Paper Street, Example Bay, YY 11111",
country: "Fictionland",
},
] }),
});
if (!created.ok) throw new Error(created.status + ": " + await created.text());
const job = await created.json();
console.log("Created tasks:", job.taskIds.length);
for (const [index, taskId] of job.taskIds.entries()) {
let task;
while (true) {
const response = await fetch(API + "/v1/ai-mode/tasks/" + taskId, { headers });
if (!response.ok) throw new Error(response.status + ": " + await response.text());
task = (await response.json()).task;
if (task.status === "DONE" && task.resultAvailable) break;
if (["FAILED", "CANCELLED"].includes(task.status)) {
console.error("Task", taskId, task.status + ":", task.error || "no details");
break;
}
await delay(5000);
}
if (task.status !== "DONE" || !task.resultAvailable) continue;
const result = await fetch(API + "/v1/ai-mode/tasks/" + taskId + "/result", { headers });
if (!result.ok) throw new Error(result.status + ": " + await result.text());
const output = "ai-searching-" + (index + 1) + "-" + taskId + ".json";
await writeFile(output, Buffer.from(await result.arrayBuffer()));
console.log("Saved JSON to", output);
}
: "${API_KEY:?Set API_KEY first}"
API="${API:-https://bankworks.info}"
CREATED="$(curl --fail --silent --show-error \
-X POST "$API/v1/ai-mode/tasks" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"mode":"regular","entities":[{"businessName":"BLUE COMET PAPERWORK LAB (FICTIONAL)","address":"42 Imaginary Lane, Sample City, ZZ 00000","country":"Fictionland","companyNumber":"FICTIONAL-0001"},{"businessName":"MOON LANTERN DESIGN HOUSE (FICTIONAL)","address":"8 Paper Street, Example Bay, YY 11111","country":"Fictionland"}]}')"
TASK_IDS="$(printf '%s' "$CREATED" | jq -r '.taskIds[]')"
printf 'Created %s tasks\n' "$(printf '%s\n' "$TASK_IDS" | wc -l | tr -d ' ')"
INDEX=0
for TASK_ID in $TASK_IDS; do
INDEX=$((INDEX + 1))
while true; do
STATUS_JSON="$(curl --fail --silent --show-error \
-H "Authorization: Bearer $API_KEY" \
"$API/v1/ai-mode/tasks/$TASK_ID")"
STATUS="$(printf '%s' "$STATUS_JSON" | jq -r '.task.status')"
RESULT_AVAILABLE="$(printf '%s' "$STATUS_JSON" | jq -r '.task.resultAvailable')"
if [ "$STATUS" = "DONE" ] && [ "$RESULT_AVAILABLE" = "true" ]; then break; fi
case "$STATUS" in
FAILED|CANCELLED) printf 'Task %s failed: %s\n' "$TASK_ID" "$(printf '%s' "$STATUS_JSON" | jq -r '.task.error // "no details"')"; break ;;
esac
sleep 5
done
if [ "$STATUS" != "DONE" ] || [ "$RESULT_AVAILABLE" != "true" ]; then continue; fi
OUTPUT="ai-searching-$INDEX-$TASK_ID.json"
curl --fail --silent --show-error \
-H "Authorization: Bearer $API_KEY" \
"$API/v1/ai-mode/tasks/$TASK_ID/result" \
-o "$OUTPUT"
printf 'Saved JSON to %s\n' "$OUTPUT"
done
Track a task
The submit response includes jobId, a taskIds
array, taskCount, dispatched, and
duplicate. Save a task ID and poll
GET /v1/ai-mode/tasks/{taskId}. The status response wraps
details in a task object; when task.status is
DONE and task.resultAvailable is true, fetch the
result. While the task is queued or running, wait a few seconds before
polling again. A worker can claim it only after completing all four
current setup prompts.
{
"ok": true,
"task": {
"taskId": "TASK_ID",
"status": "DONE",
"resultAvailable": true
}
}
Download the JSON
The result endpoint returns the stored JSON as an attachment. Save the response body to a file on the machine running your client.
Understand the JSON result
The response uses the schema below. Every company, identifier, address,
source, and contact detail is invented for this example; it does not
describe a real business or research result. Most fields are populated so
you can see the shape of a complete response. The actual result can have
multiple entries in businessLocations when separate businesses
are supported by the research.
Use the tabs to compare the exact response shape for each mode. The
regular result contains submittedEntity,
companyNumberVerification, and dataQuality.
advance adds parentCompany and
businessLocations, without coordinates, map identifiers, or
marketplace profiles. premium includes the complete response.
{
"submittedEntity": {
"providedDetails": {
"businessName": "AURORA CRAFT SYSTEMS (FICTIONAL)",
"street": "17 Example Row",
"postalCode": "EX 2048",
"city": "Sampleville",
"country": "Example Republic",
"companyNumber": "EXAMPLE-REG-2048"
},
"requestedLocationStatus": {
"status": "MOVED",
"registryAction": "Fictional record of relocation to a new workshop",
"statusEffectiveDate": "2024-06-15",
"relocation": {
"movedWithinSameCountry": true,
"newAddress": {
"streetNumber": "88",
"streetName": "Fictional Harbor Road",
"city": "Sampleville",
"postalCode": "EX 2088",
"region": "North Example District",
"country": "Example Republic"
}
}
}
},
"companyNumberVerification": {
"providedCompanyNumber": "EXAMPLE-REG-2048",
"verificationStatus": "VALID",
"resolvedCompanyNumber": "EXAMPLE-REG-2048",
"resolutionNotes": "Illustrative match only; this fictional identifier was not checked against a registry."
},
"dataQuality": {
"confidenceLevel": "LOW",
"confidenceScore": 0,
"assessmentReason": "All values are fictional examples; no registries, maps, marketplaces, or other sources were checked."
}
}
{
"submittedEntity": {
"providedDetails": {
"businessName": "AURORA CRAFT SYSTEMS (FICTIONAL)",
"street": "17 Example Row",
"postalCode": "EX 2048",
"city": "Sampleville",
"country": "Example Republic",
"companyNumber": "EXAMPLE-REG-2048"
},
"requestedLocationStatus": {
"status": "MOVED",
"registryAction": "Fictional record of relocation to a new workshop",
"statusEffectiveDate": "2024-06-15",
"relocation": {
"movedWithinSameCountry": true,
"newAddress": {
"streetNumber": "88",
"streetName": "Fictional Harbor Road",
"city": "Sampleville",
"postalCode": "EX 2088",
"region": "North Example District",
"country": "Example Republic"
}
}
}
},
"parentCompany": {
"legalName": "AURORA IMAGINARY HOLDINGS LTD (FICTIONAL)",
"companyRegistrationNumber": "EXAMPLE-HOLDCO-2048",
"currentSiteStatus": "ACTIVE"
},
"companyNumberVerification": {
"providedCompanyNumber": "EXAMPLE-REG-2048",
"verificationStatus": "VALID",
"resolvedCompanyNumber": "EXAMPLE-REG-2048",
"resolutionNotes": "Illustrative match only; this fictional identifier was not checked against a registry."
},
"businessLocations": [
{
"brandOrDepartmentName": "Harbor Studio (FICTIONAL)",
"publicName": "AURORA CRAFT SYSTEMS (FICTIONAL)",
"companyRegistrationNumber": "EXAMPLE-REG-2048",
"locationRegistrationNumber": "EXAMPLE-BRANCH-01",
"vatNumber": "EXAMPLE-VAT-2048",
"franchiseType": "INDEPENDENT",
"organizationType": "PRIVATE_LIMITED_COMPANY",
"parentCompanyName": "AURORA IMAGINARY HOLDINGS LTD (FICTIONAL)",
"networkName": "Aurora Craft Collective (FICTIONAL)",
"businessStartDate": "2020-03-12",
"businessEndDate": null,
"operatingStatus": "ACTIVE",
"industry": "Custom stationery and paper goods",
"address": {
"streetNumber": "88",
"streetName": "Fictional Harbor Road",
"city": "Sampleville",
"postalCode": "EX 2088",
"region": "North Example District",
"country": "Example Republic"
},
"contact": {
"internationalPhone": "+1-202-555-0147",
"localPhone": "(202) 555-0147",
"website": "https://aurora-craft.example"
}
}
],
"dataQuality": {
"confidenceLevel": "LOW",
"confidenceScore": 0,
"assessmentReason": "All values are fictional examples; no registries, maps, marketplaces, or other sources were checked."
}
}
{
"submittedEntity": {
"providedDetails": {
"businessName": "AURORA CRAFT SYSTEMS (FICTIONAL)",
"street": "17 Example Row",
"postalCode": "EX 2048",
"city": "Sampleville",
"country": "Example Republic",
"companyNumber": "EXAMPLE-REG-2048"
},
"requestedLocationStatus": {
"status": "MOVED",
"registryAction": "Fictional record of relocation to a new workshop",
"statusEffectiveDate": "2024-06-15",
"relocation": {
"movedWithinSameCountry": true,
"newAddress": {
"streetNumber": "88",
"streetName": "Fictional Harbor Road",
"city": "Sampleville",
"postalCode": "EX 2088",
"region": "North Example District",
"country": "Example Republic"
}
}
}
},
"parentCompany": {
"legalName": "AURORA IMAGINARY HOLDINGS LTD (FICTIONAL)",
"companyRegistrationNumber": "EXAMPLE-HOLDCO-2048",
"currentSiteStatus": "ACTIVE"
},
"companyNumberVerification": {
"providedCompanyNumber": "EXAMPLE-REG-2048",
"verificationStatus": "VALID",
"resolvedCompanyNumber": "EXAMPLE-REG-2048",
"resolutionNotes": "Illustrative match only; this fictional identifier was not checked against a registry."
},
"businessLocations": [
{
"brandOrDepartmentName": "Harbor Studio (FICTIONAL)",
"publicName": "AURORA CRAFT SYSTEMS (FICTIONAL)",
"companyRegistrationNumber": "EXAMPLE-REG-2048",
"locationRegistrationNumber": "EXAMPLE-BRANCH-01",
"vatNumber": "EXAMPLE-VAT-2048",
"franchiseType": "INDEPENDENT",
"organizationType": "PRIVATE_LIMITED_COMPANY",
"parentCompanyName": "AURORA IMAGINARY HOLDINGS LTD (FICTIONAL)",
"networkName": "Aurora Craft Collective (FICTIONAL)",
"businessStartDate": "2020-03-12",
"businessEndDate": null,
"operatingStatus": "ACTIVE",
"industry": "Custom stationery and paper goods",
"address": {
"streetNumber": "88",
"streetName": "Fictional Harbor Road",
"city": "Sampleville",
"postalCode": "EX 2088",
"region": "North Example District",
"country": "Example Republic"
},
"coordinates": {
"latitude": 12.345678,
"longitude": -98.765432
},
"contact": {
"internationalPhone": "+1-202-555-0147",
"localPhone": "(202) 555-0147",
"website": "https://aurora-craft.example"
},
"googleMaps": {
"placeId": "FICTIONAL_PLACE_ID_2048",
"cid": "FICTIONAL_CID_2048"
},
"marketplaceProfiles": [
{
"platformName": "Example Handmade Market (FICTIONAL)",
"profileUrl": "https://market.example/aurora-craft",
"profileType": "SELLER_PROFILE"
}
]
}
],
"dataQuality": {
"confidenceLevel": "LOW",
"confidenceScore": 0,
"assessmentReason": "All values are fictional examples; no registries, maps, marketplaces, or other sources were checked."
}
}
Field meanings
Each tab shows only the fields added by that mode compared with the previous one.
| Field | Meaning |
|---|---|
| REGULAR · Core fields | |
submittedEntity | The business and location submitted for research, with the result for that requested location. |
submittedEntity.providedDetails | The original input values, preserved so the result can be matched to the submitted entity. |
submittedEntity.providedDetails.businessName | Business or group name as supplied by the caller. |
submittedEntity.providedDetails.street | Street portion of the supplied address, when it can be separated. |
submittedEntity.providedDetails.postalCode | Postal or ZIP code from the supplied address, when available. |
submittedEntity.providedDetails.city | City from the supplied address, when available. |
submittedEntity.providedDetails.country | Country supplied for the business. |
submittedEntity.providedDetails.companyNumber | Corporate or tax number supplied by the caller; null when none was provided. |
submittedEntity.requestedLocationStatus | Registry status and any relocation information for the exact submitted location. |
submittedEntity.requestedLocationStatus.status | ACTIVE, CLOSED, MOVED, or UNKNOWN for the requested location. |
submittedEntity.requestedLocationStatus.registryAction | Relevant registry action or event behind the status, when supported by evidence. |
submittedEntity.requestedLocationStatus.statusEffectiveDate | Date the status or registry action took effect, formatted as YYYY-MM-DD. |
submittedEntity.requestedLocationStatus.relocation | Relocation details when the requested location is marked MOVED; otherwise null. |
submittedEntity.requestedLocationStatus.relocation.movedWithinSameCountry | Whether evidence indicates the business moved within the same country. |
submittedEntity.requestedLocationStatus.relocation.newAddress | Structured destination address after a move. |
submittedEntity.requestedLocationStatus.relocation.newAddress.streetNumber | House or building number at the new address. |
submittedEntity.requestedLocationStatus.relocation.newAddress.streetName | Street name at the new address. |
submittedEntity.requestedLocationStatus.relocation.newAddress.city | City at the new address. |
submittedEntity.requestedLocationStatus.relocation.newAddress.postalCode | Postal or ZIP code at the new address. |
submittedEntity.requestedLocationStatus.relocation.newAddress.region | State, province, or region at the new address. |
submittedEntity.requestedLocationStatus.relocation.newAddress.country | Country at the new address. |
companyNumberVerification | Comparison of the submitted company number with the resolved entity and registry evidence. |
companyNumberVerification.providedCompanyNumber | Company number supplied by the caller. |
companyNumberVerification.verificationStatus | VALID, INVALID_OR_NOT_FOUND, or NOT_PROVIDED. |
companyNumberVerification.resolvedCompanyNumber | Official number resolved for the matching company, if available. |
companyNumberVerification.resolutionNotes | Short explanation of the number match, mismatch, or resolution. |
dataQuality | Summary of how complete and consistent the evidence is for this result. |
dataQuality.confidenceLevel | Text label describing the overall evidence strength. |
dataQuality.confidenceScore | Evidence-based integer from 0 to 100; it is not a statistically measured probability. |
dataQuality.assessmentReason | Explanation of the evidence and any uncertainty behind the quality assessment. |
| ADVANCE · Additional fields beyond Regular | |
parentCompany | The resolved parent organization, when a relationship is supported by evidence. |
parentCompany.legalName | Parent company's legal name. |
parentCompany.companyRegistrationNumber | Parent company's official registration number. |
parentCompany.currentSiteStatus | Current status of the parent company's site: ACTIVE, CLOSED, MOVED, or UNKNOWN. |
businessLocations | Array of separately identified businesses or locations at the submitted address; may be empty or contain multiple entries. |
businessLocations[].brandOrDepartmentName | Brand or department name associated with this location. |
businessLocations[].publicName | Name used publicly by this business location. |
businessLocations[].companyRegistrationNumber | Registration number of the company operating this location. |
businessLocations[].locationRegistrationNumber | Registration identifier specific to the branch or location. |
businessLocations[].vatNumber | VAT registration number for this business, when available. |
businessLocations[].franchiseType | FRANCHISE or INDEPENDENT when evidence supports a classification. |
businessLocations[].organizationType | Business or legal organization type, when known. |
businessLocations[].parentCompanyName | Name of the parent company associated with this location. |
businessLocations[].networkName | Dealer group, franchise network, or other business network name. |
businessLocations[].businessStartDate | Start date of this business or location, if known. |
businessLocations[].businessEndDate | Closure or end date, if known. |
businessLocations[].operatingStatus | ACTIVE, INACTIVE, or UNKNOWN for this individual location. |
businessLocations[].industry | Industry or business activity associated with the location. |
businessLocations[].address | Structured address for this individual location: street number/name, city, postal code, region, and country. |
businessLocations[].address.streetNumber | House or building number for the location. |
businessLocations[].address.streetName | Street name for the location. |
businessLocations[].address.city | City where the location operates. |
businessLocations[].address.postalCode | Postal or ZIP code for the location. |
businessLocations[].address.region | State, province, or region for the location. |
businessLocations[].address.country | Country where the location operates. |
businessLocations[].contact | Contact details associated with the location: international/local phone and website. |
businessLocations[].contact.internationalPhone | Phone number in international dialing format. |
businessLocations[].contact.localPhone | Phone number in the local format used by the source. |
businessLocations[].contact.website | Official website URL for this location or business. |
| PREMIUM · Additional fields beyond Advance | |
businessLocations[].coordinates | Latitude and longitude as JSON numbers, or null when unavailable. |
businessLocations[].coordinates.latitude | North/south coordinate as a JSON number. |
businessLocations[].coordinates.longitude | East/west coordinate as a JSON number. |
businessLocations[].googleMaps | Google Maps identifiers for the matching location, when found. |
businessLocations[].googleMaps.placeId | Google Maps Place ID for the matching place. |
businessLocations[].googleMaps.cid | Google Maps customer identifier (CID) for the matching place. |
businessLocations[].marketplaceProfiles | Array of supported vehicle-marketplace profiles; each item identifies a platform, direct profile URL, and profile type. |
businessLocations[].marketplaceProfiles[].platformName | Name of the vehicle marketplace hosting the profile. |
businessLocations[].marketplaceProfiles[].profileUrl | Direct URL to the dealer profile, inventory, or relevant listing page. |
businessLocations[].marketplaceProfiles[].profileType | Type of marketplace page represented by the URL. |
Responses and errors
- 201: new task batch accepted. 200: idempotent repeat returned the existing job.
- 202 from the result endpoint: task is still running;
retry after the response's
Retry-Afterdelay. - 409: task failed/cancelled, or the same idempotency key was reused with different input.
- 402: account balance is insufficient when billing is enabled.
- 403: the API key lacks a required business research API scope. 404: task does not exist or belongs to another account.
- 410: the completed result is no longer retained.
When billing is enabled, each entity is charged as one
REGULAR API task. The full JSON result is stored with the task
in MySQL and follows its one-year result retention period. Keep the
downloaded copy if you need it longer.
This API submits a business research request and returns its response; it does not guarantee that every business detail is present or independently verified. Review the returned JSON before using it for consequential decisions.