@comms-id/company
Typed client for the Comms.ID Company API (https://api.comms.id/asic-company-lookup/v1): Australian companies from ASIC's public registers: search by name, look up one by ACN or ARBN. Each record names its number asicNumber and its kind asicNumberType (ACN, or ARBN for a registered foreign company or registered Australian body). Company v1 and its acn field are retired (ADR-0050, #714); earlier versions of this package call v1 and get VERSION_RETIRED.
src/ is generated from the Company contract (packages/asic-public-registers/openapi/asic-company-lookup.v1.json) by @comms-id/forge-transformers. Do not edit it: change the contract and run pnpm --filter @comms-id/forge-transformers generate.
import { createAsicCompanyLookupClient } from "@comms-id/asic-company-lookup/server";
const client = createAsicCompanyLookupClient({
clientId: process.env.COMMS_ID_CLIENT_ID!,
privateJwk: JSON.parse(process.env.COMMS_ID_PRIVATE_JWK!),
});
const reply = await client.lookup({"asicNumber": "001234564"});
Operations
lookup: Look up one nine-digit ASIC number (ACN or ARBN) with a valid ASIC check digit in the company snapshot. ABN lookup is not offered. At most ten rows; no uniqueness or complete history claim.search: Search the company snapshot by case-insensitive name prefix and optional exact status. Default eight rows, maximum ten, no paging. A snapshot miss does not prove absence from the live register.
Every operation is a read, safe to repeat, and is retried after a retryable failure. A reply that is not a match is one of the outcomes of the reply convention: an error with outcomeOf(error) of no-match, source-unavailable or failed; an outage is never a "no match".
Test it first
createAsicCompanyLookupFixtureClient() from @comms-id/asic-company-lookup/fixtures answers from the contract's own examples with no network and says so (fixture: true). To call the TEST service (synthetic replies, your development app's key), pass environment: "test"; going live changes only the environment and the key.
COMMS_ID_PRIVATE_JWK is an ML-DSA-87 private JWK (kty AKP, with priv and pub). The server entry needs Node.js 24.7 or later, or a Cloudflare Worker with the compatibility flag webcrypto_modern_algorithms.
Entries: . (types and errors, safe in a browser), ./server (signs each call), ./browser (your relay route; never signs), ./fixtures (LOCAL FIXTURES, no network), ./descriptor (what @comms-id/relay may forward).
LICENSE is the consumer client licence.
The field
@comms-id/asic-company-lookup/controller is the headless controller of a company name, ACN or ARBN field: input, debounce, suggestions, identifier checks, choice and errors, with the WAI-ARIA combobox attributes and key handler. It has no framework and no DOM. @comms-id/asic-company-lookup-react (a hook and a component) and <comms-id-asic-company-lookup> (a web element) run on it, and so can your own UI.
import { createAsicCompanyLookupController } from "@comms-id/asic-company-lookup/controller";
const controller = createAsicCompanyLookupController({ client, onSelect: (record, timing) => console.log(record, timing.ms) });
controller.subscribe(() => render(controller.getState()));
controller.setQuery("…");
src/local/profile.ts is the only product-specific part: it reads the typed text, calls the client and reduces every reply to the text the UIs show and the record onSelect receives. Everything else is generated.