Skip to main content

Contract changes

This page lists the changes to the published integration contract, the OpenAPI document and the @one-unity/rule-line-sdk package generated from it. Read it before you upgrade the SDK, and whenever a call that worked stops working. The endpoint reference always describes the contract as it is now; this page describes how it got there.

There are two kinds of change below. A removal narrows the contract: something you could have called is no longer part of it. An addition widens it: a new optional member, a new response, or a more precise type.

Removed operations​

Seven operations used to appear in the published contract and in the generated SDK even though no integration API key could call them. Every one of them needs a signed-in tenant session, and an rl_key_... key is refused before the operation runs. They are removed from the OpenAPI document and from @one-unity/rule-line-sdk, so a generated function with one of these names no longer exists.

Six of these routes still answer a tenant session. The direct activation routes have since been removed as described below. None has an API-key replacement. Each entry names where the work goes now.

OperationRouteWhere it goes now
activateRulesetRemoved: POST /rulesets/activate and POST /console/rulesets/{id}/activate-draftRequest activation in the console. An approver reviews the pinned revision and its evidence, then approves or refuses the request. Direct activation is no longer available.
retryRunDeliveryPOST /runs/{runId}/delivery/retryThe same route, called with a tenant session of an editor or approver, never an API key. Recover a delivery documents the request and the response.
createWebhookDestinationPOST /webhook-destinationsThe same route, called with a tenant administrator session. The response carries the new signing secret once.
listWebhookDestinationsGET /webhook-destinationsThe same route, called with a tenant administrator session.
getWebhookDestinationGET /webhook-destinations/{id}The same route, called with a tenant administrator session.
updateWebhookDestinationPATCH /webhook-destinations/{id}The same route, called with a tenant administrator session.
rotateWebhookDestinationSecretPOST /webhook-destinations/{id}/rotate-secretThe same route, called with a tenant administrator session.

Read the tenant session access token from wherever your application keeps the current session, for example supabase.auth.getSession(). Send it as Authorization: Bearer <tenant-session-access-token>, exactly as the retry example in Recover a delivery does. There is no generated SDK function for any of these calls, because a typed client function could not work with the credential the SDK is built around.

Naming a webhook destination for a job is not affected. A job body still carries an existing destination's id as webhookDestinationId, and a key that sends it needs the webhook_destination_override scope. See Submit a job.

Language and active version changes​

POST /jobs now accepts optional locale: de for German check messages or en for English. Omission uses the tenant's configured default at submission, and the run freezes that language. The same rule applies to jobs with documents.

GET /jobs/{id} adds three required members: locale, rulesetVersionId for the version actually executed, and requestedRulesetVersionId for the activated version handle the caller named. The requested id is null on historical runs without this attribution. Clients that validate responses strictly must accept these new members.

A rulesetId naming any activated version now runs that ruleset's active version at submission. An approval or rollback can therefore change what executes for the same requested handle; polling reports both ids.

GET /jobs/{id}/result adds Rule-Line-Result-Locale, carrying the frozen de or en language. Its body stays the exact declared canonical output, and Rule-Line-Result-Sha256 continues to describe those unchanged bytes. Terminal webhook events add locale and requestedRulesetId; their existing rulesetId and rulesetVersion describe the version that executed. See Submit a job and Poll a run.

Phase 9 additions​

Document extraction ships with six additive changes to the contract. One of them is a new response your client must handle. The page also records two changes that add no member and no response: one to how the error code catalog reads, and one to the occurrenceKey that the trace of a sample try carries.

bypassAiCache on POST /jobs​

POST /jobs accepts an optional boolean bypassAiCache. When it is true, every extract step of the run skips the AI result cache read and writes its fresh result as the newest cache entry for its key. Omitting it means false, and any value that is not a boolean is refused with VALIDATION_FAILED rather than converted. A call made because of the flag is metered like any other call. See Submit a job.

An erased run's trace answers 410​

GET /runs/{runId}/trace now answers 410 Gone for a run that its tenant erased under the retention policy. Before this change it answered 404, the same answer as a run that never existed. The 410 body is the erased acknowledgement that GET /jobs/{id} already returns:

{
"id": "22222222-2222-4222-8222-222222222222",
"status": "erased",
"erasedAt": "2026-10-01T08:00:00.000Z"
}

The body carries no events and no decision metadata, because the trace is gone with the run. An id that never existed, and an id that belongs to another tenant, still answer 404. If your client treats every non-2xx answer from the trace route as a missing run, add a branch for 410. See Poll a run for the same acknowledgement on the job routes.

GET /runs publishes test as a boolean​

The test query parameter of GET /runs is now typed as a boolean in the OpenAPI document and in the generated SDK. It used to be published without a type. On the wire nothing changes: the values are still true and false, and any other value is still refused. In TypeScript, pass test: true or test: false, not a string. See Page through runs.

workingOrActiveVersionId on dataset items​

Each item of GET /datasets, and the response of GET /datasets/{datasetId}, carries a new member, workingOrActiveVersionId. It is the id of one version of the ruleset the dataset belongs to: the working version's id when the ruleset has one, otherwise its newest activated version's id. It is null only when this key can see no version of that ruleset. The value changes whenever a version of the ruleset is created or activated, so it is not a stable key; use rulesetName for that. A client that validates responses strictly must accept the new member.

The member was first drafted as rulesetId. For job submission, rulesetId now names an activated version handle that resolves through the active version; it is still a different concept from a dataset's working or newest activated version. It was renamed before release, and no published contract carried rulesetId on dataset items. See Browse reference data.

GET /runs/{runId}/trace publishes test​

The response of GET /runs/{runId}/trace carries a new required boolean, test. It is true when the run was a test run and false for a production run. A test run's calls can be answered from the production cache, so a trace that shows only cache hits is no sign that the run was a production run. A client that validates responses strictly must accept the new member.

occurrenceKey in the trace of a sample try​

The console can test one extract step on a sample document. That test run executes a derived, one step ruleset, but the run still pins the real revision of your ruleset. The trace events of such a run used to carry the key the derived ruleset gives the step, which is the bare step id, for example read. For an extract step nested in a branch or a loop that key names no step of the pinned revision.

GET /runs/{runId}/trace now publishes the key of the sampled step in the pinned revision as occurrenceKey, for example compare/cases[0]/read. The change applies to the events of past sample runs too, because the key is resolved when the trace is read. stepPath is unchanged: it still holds the path the run executed, for example read. The members, their types and the events of every other run are unchanged. A client that looks an event up by occurrenceKey in the revision the run pinned now finds the step.

DATASET_QUERY_TIMEOUT​

GET /datasets/{datasetId}/versions/{version}/rows answers 504 with the code DATASET_QUERY_TIMEOUT when the row query runs past its time limit. Before this change that case answered a generic 500. Narrow the filter parameters and retry. See Browse reference data.

Console only codes in the error code catalog​

The error code catalog now marks a code as Console only when no operation of the Integration API lists it in its error responses. Five codes carry the mark: EXTRACT_SAMPLE_STEP_NOT_FOUND, which this phase added for the console's sample-document try, and four codes that were already in the catalog: CONFLICT, DELIVERY_NOT_EXHAUSTED, DELIVERY_RETRY_FORBIDDEN and WEBHOOK_DESTINATION_URL_REJECTED. They used to read Active. No response changed: the catalog now says that the endpoint reference does not promise them to a client that uses an API key. They stay in the generated SDK's error code type, because the platform renders their titles, so a client that switches on that type may still meet them.