Skip to content

Search

Search official government registries for a company. Searches are asynchronous: you submit a request, receive a searchId (and caseId), then poll until the work finishes.

A successful root search creates a new case and sets case.target to the found entity. To dig into a counterparty already on a case (ownership tree), use Expand search instead.


Request

POST https://api.revolutio.systems/search
Content-Type: application/json

Headers

Header Value
Content-Type application/json
X-API-Key or Authorization rev_… or Bearer <idToken>

Body

{
  "identifier": "HRB 246975",
  "jurisdiction": "DE",
  "include": {
    "financials": true
  }
}
Field Type Required Description
identifier string Conditional Registry registration number / search id. Required for most jurisdictions.
legal_name string Conditional Legal name. Required (instead of or in addition to identifier) for name-based jurisdictions (e.g. ID, MX, IQ, and others whose coverage schema lists legal_name without a required identifier).
jurisdiction string Yes Jurisdiction code (e.g. GB, DE, US-DE, CH-ZH).
include object No Optional add-ons
include.financials boolean No Request financial metrics when the jurisdiction supports them. Extra credits only if financials data is returned.

Info

At least one of identifier or legal_name is required, depending on the jurisdiction’s search schema. If both are missing, or only a name is sent for an identifier-only jurisdiction, the API returns 400.

Immediate response (200)

A search record with status: "PENDING":

{
  "_id": "abc123searchId",
  "caseId": "xyz789caseId",
  "createdAt": "2026-01-15T10:30:00.000Z",
  "updatedAt": "2026-01-15T10:30:00.000Z",
  "userId": "user-uid",
  "searchInputs": {
    "identifier": "HRB 246975",
    "jurisdiction": "DE",
    "include": { "financials": true }
  },
  "status": "PENDING"
}
Field Type Description
_id string Search ID. Use this to poll status.
caseId string New case grouping this search (and later expands / LEI lookups)
status string PENDING, COMPLETED, or FAILED
searchInputs object Echo of accepted search parameters
userId string Owner uid
createdAt / updatedAt string ISO 8601 timestamps

Work continues in the background. Poll Get search status.

Error responses

{ "error": "Missing identifier and/or jurisdiction input" }

Or for name-only jurisdictions:

{ "error": "Missing legal_name and/or jurisdiction input" }

Unsupported code:

{ "error": "Unsupported jurisdiction: XX" }
{ "error": "Missing Authorization or X-API-Key header" }
{
  "error": "Insufficient credits. This search requires 5 credit(s).",
  "volume_remaining": 0,
  "cost": 5
}
{
  "error": "Insufficient subscription: you are not subscribed to search in this jurisdiction",
  "jurisdiction": "DE",
  "hint": "Check your subscription coverage or contact support"
}

Or account locked:

{ "error": "Your account access has been suspended. Please contact support." }
{ "error": "Rate limit exceeded" }

Credits

  1. The jurisdiction search cost is debited up front when the search is accepted.
  2. On scrape / processing failure, that cost is refunded.
  3. include.financials: charged after success only if numeric financials came back. A charge failure is logged and does not roll back the search.

You must be subscribed to the jurisdiction and have enough volume_remaining.


Get search status / results

Request

GET https://api.revolutio.systems/search/{searchId}/status

Headers

Header Value
X-API-Key or Authorization API key or Bearer token

Path parameters

Parameter Type Description
searchId string _id from the POST response

Response

{
  "_id": "abc123searchId",
  "caseId": "xyz789caseId",
  "createdAt": "2026-01-15T10:30:00.000Z",
  "updatedAt": "2026-01-15T10:30:05.000Z",
  "userId": "user-uid",
  "searchInputs": {
    "identifier": "HRB 246975",
    "jurisdiction": "DE"
  },
  "status": "COMPLETED",
  "result": {
    "_id": "entity-uuid",
    "legalName": "EXAMPLE GMBH",
    "legalForm": "Gesellschaft mit beschränkter Haftung",
    "companyStatus": "Active",
    "countryOfRegistration": "DE",
    "jurisdiction": "DE",
    "registrationDate": "2020-03-15",
    "addresses": [],
    "identifiers": [],
    "relationships": [],
    "activities": [],
    "capital": {},
    "otherNames": [],
    "counterparties": [],
    "sourceDocuments": []
  }
}

result is a full Entity. On some jurisdictions (e.g. Singapore async document fulfilment) the search may stay PENDING with pendingDocument: true while a paid filing is still generating.

{
  "_id": "abc123searchId",
  "caseId": "xyz789caseId",
  "status": "PENDING",
  "searchInputs": {
    "identifier": "HRB 246975",
    "jurisdiction": "DE"
  },
  "createdAt": "2026-01-15T10:30:00.000Z",
  "updatedAt": "2026-01-15T10:30:00.000Z",
  "userId": "user-uid"
}
{
  "_id": "abc123searchId",
  "caseId": "xyz789caseId",
  "status": "FAILED",
  "result": {
    "error": "Timeout while fetching registry data"
  },
  "searchInputs": {
    "identifier": "HRB 246975",
    "jurisdiction": "DE"
  },
  "createdAt": "2026-01-15T10:30:00.000Z",
  "updatedAt": "2026-01-15T10:30:30.000Z",
  "userId": "user-uid"
}
{ "error": "Search not found" }

Polling strategy

  1. Wait ~2 seconds after submit.
  2. GET /search/{searchId}/status.
  3. If PENDING, wait 3 seconds and poll again.
  4. Increase the interval up to ~10 seconds.
  5. Stop on COMPLETED or FAILED.

Average registry times vary widely (seconds to a few minutes). See Data Coverage.

Example (cURL)

RESPONSE=$(curl -sS -X POST https://api.revolutio.systems/search \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $REV_API_KEY" \
  -d '{"identifier": "09215191", "jurisdiction": "GB"}')

SEARCH_ID=$(echo "$RESPONSE" | jq -r '._id')
CASE_ID=$(echo "$RESPONSE" | jq -r '.caseId')

sleep 3
curl -sS "https://api.revolutio.systems/search/$SEARCH_ID/status" \
  -H "X-API-Key: $REV_API_KEY" | jq .

Follow-on registry search on a counterparty already on a case.
Unlike POST /search (new case, overwrites case.target), expand grafts the new ownership layer under the chosen company node.

The request is async: HTTP returns as soon as a PENDING search is saved.

Endpoint

POST https://api.revolutio.systems/search/expand
Content-Type: application/json

Same function as company search. Related paths:

Method Path Purpose
POST /search/expand Start expand
GET /search/{searchId}/status Full search doc (incl. result when done)
GET /casefile/{caseId} Case + search summaries (no nested result)

Request body

{
  "caseId": "abc123",
  "parentEntityId": "entity-uuid-on-case",
  "jurisdiction": "DE",
  "identifier": "HRB 12345",
  "legalName": "Example GmbH",
  "include": {
    "financials": true
  }
}
Field Required Notes
caseId Yes Existing case id
parentEntityId Yes _id of the target or a counterparty on that case
jurisdiction No Defaults from the entity (jurisdiction / countryOfRegistration)
identifier No* Registry registration number. Defaults from the entity’s identifiers
legalName No Defaults from the entity
include.financials No Same opt-in as POST /search

* A registration number is required. If neither the body nor the entity has one, the API responds 400 and tells you to resolve it first via IDFinder. Expand does not auto-pick a registry id (wrong match would corrupt the ownership graph).

Minimal example

curl -sS -X POST "https://api.revolutio.systems/search/expand" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $REV_API_KEY" \
  -d '{
    "caseId": "CASE_ID",
    "parentEntityId": "PARENT_ENTITY_ID"
  }'

Immediate response (200)

{
  "_id": "SEARCH_ID",
  "caseId": "CASE_ID",
  "createdAt": "2026-…",
  "updatedAt": "2026-…",
  "userId": "UID",
  "searchType": "expand",
  "parentEntityId": "PARENT_ENTITY_ID",
  "searchInputs": {
    "identifier": "…",
    "jurisdiction": "DE",
    "legalName": "…"
  },
  "status": "PENDING"
}

Poll GET /search/{searchId}/status until COMPLETED or FAILED. On success, new counterparties are merged onto the case under parentEntityId.

Expand credits

  1. Base jurisdiction cost debited up front (same as POST /search).
  2. On failure, base cost is refunded.
  3. Financials charged after success only if data returns.

Expand errors

Status When
400 Missing caseId / parentEntityId; unsupported jurisdiction; no registration number
401 Missing or invalid auth
402 Insufficient credits
403 Not case owner; account locked; not subscribed to jurisdiction
404 Case not found; entity not on case; user profile missing
409 Counterparty already expanded, or an expand for that entity is already PENDING
429 Rate limit
500 Internal error (credits refunded if already charged)

Example when the entity has no registry number:

{
  "error": "No registration number for this company. Resolve it first via /idfinder.",
  "legalName": "Example GmbH",
  "jurisdiction": "DE"
}

Expand behaviour notes

  • Idempotent per entity: once something in the case already points at parentEntityId as a parent, further expands return 409.
  • One in-flight expand per parentEntityId (PENDING blocks a second start).
  • Expand does not create a new case; it mutates the existing case graph under the expanded node.
  • Only the case owner may expand (collaborator access is not enough).
  • Prefer re-fetching the case for UI structure; use search status for the full expand result and failure details.

Typical end-to-end flow

1. POST /search              → caseId + root company
2. (optional) POST /idfinder → registry number for a counterparty without one
3. POST /search/expand       → caseId + parentEntityId (+ identifier if needed)
4. GET  /search/{id}/status  → wait for COMPLETED | FAILED
5. GET  /casefile/{caseId}   → updated ownership tree (summaries + target graph)