Ontology SDK
Overview
Generated clients for your ontology in TypeScript, Python and Java.
The Ontology SDK (OSDK) gives you a typed client for the object types and action types in your ontology. You can then read objects and run actions from your own code, with no raw HTTP calls. From TypeScript you can also subscribe to changes (see Subscriptions), and generated TypeScript clients ship test helpers (see Testing).
- The TypeScript, Python and Java typed clients are generated per ontology and per caller. They only contain the types you can see.
- Every call runs as you. Object visibility, property masking, markings and policies apply exactly as they do in the app.
- From Converge compute modules and Python functions, use the
objectsbuiltin instead of a client: it reads the declared object types as the caller, through the same enforced read path (see Functions). - These clients are versioned by content. A new version appears only when the types you can see change. The Maven artifact and the OpenAPI document are different: they are built from the API's routes, are the same for every caller, and change with server releases (see Java and other languages).
| Language | How you get it | Page |
|---|---|---|
| TypeScript | npm package @convergehq/osdk-<ontology> or a direct download | TypeScript |
| Python | pip package converge-osdk-<ontology> (Python 3.9+, standard library only) | Python |
| Java | Maven artifact dev.converge:converge-osdk-<ontology> | Java and other languages |
| Any other language | The per-ontology OpenAPI document | Java and other languages |
In package names, <ontology> is your ontology's rid in lower case, with every run of other characters turned into -. In API paths, {ontology} is the rid itself. GET /api/v2/ontologies lists the rids you can use.
Download endpoints
| Method | Path | Returns |
|---|---|---|
| GET | /api/v2/ontologies/{ontology}/osdk/typescript | TypeScript client files as JSON |
| GET | /api/v2/ontologies/{ontology}/osdk/typescript/package.tgz | The same files as an npm package |
| GET | /api/v2/ontologies/{ontology}/osdk/python | Python client files (add ?format=package for an sdist .tar.gz) |
| GET | /api/v2/ontologies/{ontology}/osdk/java | Java typed classes as JSON |
| GET | /api/v2/ontologies/{ontology}/openapi.json | OpenAPI document for this ontology |
Add ?objectTypes=A,B or ?actionTypes=x,y to limit a download to some types. With more than 50 visible object types, or more than 50 action types, a download that is not narrowed answers 422: name at most 50 in each list. Package registries always include every type you can see, and answer 422 once the client passes 1,000,000 characters; download a narrowed client instead.
Unsupported types and filters
A property type that the client cannot map becomes unknown in TypeScript and a plain value in Python. Read it, but check its shape yourself. Nothing is skipped and generation never fails on a type: an unmapped action or query parameter is typed unknown (TypeScript), untyped (Python) or Object (Java), and the server checks the value when you call it. Each object type keeps its first 500 properties and link types, and each action or query its first 500 parameters; the rest are left out of the typed client.
| Ontology type | TypeScript | Python | Java |
|---|---|---|---|
| integer, long, short, byte | number | int | Long |
| double, float, decimal | number | float | Double |
| string, date, timestamp, geohash, marking, cipher text, attachment and similar | string | str | String |
| boolean | boolean | bool | Boolean |
| array, set | Array<T> | list | List<Object> |
| vector | number[] | list | List<Object> |
| struct | Record<string, unknown> | dict | Map<String, Object> |
| object reference (action parameter) | string | number (its primary key) | str / int | Object |
| media reference | MediaReference | string (read it with client.media.get) | Media | JsonNode |
| anything else (geopoint, geoshape, time series, …) | unknown | raw value | JsonNode |
A media reference property used to be typed as a string. Generated clients from 2026-11 type it as MediaReference | string (TypeScript), Media (Python) and JsonNode (Java). The new runtime names (Media, MediaItem, MediaReference, MediaMetadata) are reserved, so an object type or property with one of those names is generated with a 2 suffix.
The clients refuse more than one $orderBy key before they send anything.
Reading one object by key (fetchOne / get) works only for keys made of letters, digits, _ and -, because that is the API's $rid rule. For any other key, such as one containing a space, filter on the key property with where. A key made of letters, a /, then letters, digits, _ or - (such as a/b or customer/c1) is the exception: an eq filter reads that value as an object reference, so it never matches a string property. Use a regex clause on the key instead; it matches the whole value, and / needs no escaping ({ type: "regex", property: "id", value: "a/b" }). The TypeScript test fakes still match such a value as text, so a test can pass where the server returns nothing.
Object set definitions over HTTP
POST /api/v2/ontologies/{ontology}/objectSets/loadObjects also takes the Converge v2 body {objectSet, pageSize, pageToken, orderBy, select, excludeRid, snapshot} and answers {data, nextPageToken, totalCount}. objectSets/count takes {objectSet} and answers {count}. objectSets/aggregate takes {objectSet, aggregation}, where aggregation uses the same grammar as objects/{type}/aggregate.
objectSet.type | Fields | Contains |
|---|---|---|
base | objectType | Every object of the type |
static | objects: up to 1,000 rids | The listed objects you can read. Other rids are dropped without an error |
reference | reference: a createTemporary rid | The temporary set's type and filter |
filter | objectSet, where | The objects that match where |
searchAround | objectSet, link: a link type | The objects linked to the set through that link type, from either side. Types in the set that the link type does not join are skipped; a link type that joins none of them answers 404, and a link to a type you cannot see answers 403 |
union, intersect, subtract | objectSets | Set algebra by rid. A union may mix types |
withProperties | objectSet, derivedProperties | The set, plus a value per object computed over its linked objects |
A derived property is {type: "selection", objectSet, operation}. Its objectSet is {type: "methodInput"}, which means the object itself, or a searchAround or filter over it. Its operation is {type: "count"} or one of sum, avg, min, max and exactDistinct with selectedPropertyApiName. You can order, group and aggregate by a derived property, but you cannot filter on one. Its name may not be type, version or the name of a property of the set's objects (400).
- Every part of the set reads as you. A linked object or a
staticrid that you cannot read is left out of the set, its count, its aggregates and its derived values. - Filtering, ordering, following a link or aggregating on a property that is masked for you answers 403.
- A definition may nest at most 8 levels and hold at most 64 sets in all. It may read at most 10,000 objects and follow at most 100,000 links per searchAround. Beyond any of these limits, or with an unknown
type, the call answers 400. orderByis{fields: [{field, direction}]}(Converge) or{property, direction}.- With
snapshot: true, the first page fixes which objects are in the set and in what order. ThenextPageTokenpages through that fixed list for 10 minutes, so edits made in the meantime do not shift pages. Each page is still read again as you, so an object that has left the set or that you can no longer read drops out of its page. Only the caller who took the snapshot can use its token. Anyone else gets 404. ?scenarioRid=or?transactionId=reads with that scenario's or transaction's uncommitted edits applied, as a query does. This works onloadObjects(either body),countandaggregate. You cannot use both in one call.
Not available yet
The following are not in the generated clients yet.
- Set operations (
union,intersect,subtract) as methods, and pivoting a whole set. On one object type, write them as filters:$oris a union,$andan intersection, and{ $and: [a, { $not: b }] }subtractsbfroma. Links work one object at a time withlinked.