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.
| Operation | Route | Where it goes now |
|---|---|---|
activateRuleset | Removed: POST /rulesets/activate and POST /console/rulesets/{id}/activate-draft | Request 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. |
retryRunDelivery | POST /runs/{runId}/delivery/retry | The 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. |
createWebhookDestination | POST /webhook-destinations | The same route, called with a tenant administrator session. The response carries the new signing secret once. |
listWebhookDestinations | GET /webhook-destinations | The same route, called with a tenant administrator session. |
getWebhookDestination | GET /webhook-destinations/{id} | The same route, called with a tenant administrator session. |
updateWebhookDestination | PATCH /webhook-destinations/{id} | The same route, called with a tenant administrator session. |
rotateWebhookDestinationSecret | POST /webhook-destinations/{id}/rotate-secret | The 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.