LibraryOperation IDs Namespacev4 · Updated Report

Operation IDs Namespace

Integration Identityids · core
Category
core
Namespace
ids

Mint fresh UUIDv7 values for the caller-owned keys some writes take, for hosts that cannot generate one locally, in a run of its own whose whole purpose is to hand those literals to a later script.

Integration CapabilitymintOperationIds · read
Access
read
Method
mintOperationIds
Side Effect
No

Returns { operationIds }, an array of fresh UUIDv7 strings. It must be the first and only provider call in its run: the runtime rejects any other provider call in a run that mints, and rejects a mint that follows any other provider call. Each call returns new values, so it is not idempotent and must never be used to produce a retry id.

Limitations

One method, and a hard structural rule around it. A run that successfully mints may make no other provider call, and a run that has already made a provider call may not mint; both violations fail with the same preparation-run error. That also means one mint call per run: a second mintOperationIds in the same run is rejected like any other second call, so ask for every id you need in the one call. count defaults to 1 and is bounded to at most 32; values outside that range are refused by schema validation. Minting reserves nothing, registers nothing, and creates no record anywhere: a minted id is a random value until some later call uses it, and an unused id simply evaporates. It also never replaces a platform-returned operation id. Where an operation id comes back from the platform, as planDocumentCopy returns a snapshot-copy operationId, that value is the identity of the existing operation and substituting a minted one is wrong. Inside run, crypto.randomUUID deliberately throws rather than being absent, because it produces v4 and these fields want v7; crypto.getRandomValues remains available for ordinary randomness.

Usage

Generate the key on your own host when you can; this regime is for hosts that cannot. The regime is: mint in one run, paste literals in the next. Minted values must be preserved outside the sandbox, written into a later script as string literals, and reused only for an exact retry of the same intended operation. Reuse the identical literal when a call's outcome is genuinely ambiguous, so the retry replays instead of writing twice. Use a fresh id, from a new preparation run, for a deliberate new attempt. Never mint an id as a retry: a retry under a new id is a second operation, which is exactly the duplicate the receipt was there to prevent. Some caller-owned fields accept any UUID version for compatibility with existing receipts, and some accept only v7; minting v7 satisfies both, so mint every new value here rather than hand-rolling one. Reads take none: a document read, search, or type call mints its own operationId and echoes it, and you pass that value back only to replay an exact retry. Fields that take minted values include the optional creationId when creating a document or comment thread, the optional operationId on createType, resolveComment, and reopenComment, and the required keys on connector writes, session.focus, resolveEmbed, the document copy plan (copyId), and lens creation; applyDocumentCopy takes the operationId that planDocumentCopy returned, never a minted one.

Authorization

mintOperationIds resolves no organization and checks no organization permission: it is pure local computation over a random source, and any authenticated connection can call it. It reads no data and writes no data, so it needs neither a document permission nor knowledge of which organization you will act in. That is also why it costs nothing to mint slightly more ids than you end up using.

Composition

This namespace exists to serve every other one. documents reads, searches, and type calls take no id, and some documents writes take an optional key; files ingestion takes a creationId; session.focus takes an operationId on every call and a creationId when creating a lens; connector mutations across the integration namespaces take a receipted operationId. A host that can generate a UUIDv7 locally, outside the sandbox, can generate the value itself and skip this namespace entirely, which saves a whole round trip. Minting is only necessary when the host has no local UUIDv7 source.

Operation IDs

What it does

The ids namespace has one method, mintOperationIds, which returns fresh UUIDv7 values for the caller-owned idempotency fields that appear all over the Oddlynew API. Those fields exist so that when a call's outcome is unknown, resubmitting the same identity replays the original operation instead of performing a second one. That guarantee is worth exactly as much as the discipline around the identity, which is why minting is structured the way it is.

If your host can generate a UUIDv7 locally, do that and skip this namespace. The whole ritual below is a workaround for hosts that cannot.

Why minting gets its own run

mintOperationIds must be the first and only provider call in its run. This is enforced, not advised: the runtime wraps every provider function for the duration of the run and tracks a single piece of state. If a mint is attempted after any other provider call has run, it is rejected. If any other provider call is attempted after a mint has started or succeeded, it is rejected. Both failures carry the same message telling you to return the values from a preparation run and paste them into a new script.

The reason is the failure mode the fence eliminates. If minting and consuming lived in one program, then when that program had an ambiguous outcome and you resubmitted it, the resubmission would mint a different id and perform a second operation. The identity would change exactly when it most needed to stay the same. Separating the runs makes the id an inert literal in your source, which is the only form that survives a retry unchanged.

A consequence worth noting: because the fence rejects a second mint the same way it rejects any other second call, you get one mintOperationIds call per run. Ask for everything you need at once.

The two-run pattern

First run, nothing else in it:

return await ids.mintOperationIds({ count: 1 })
// => { operationIds: ["0192f3c1-...-7..."] }

Second run, with the returned values written in as literals:

const creationId = "0192f3c1-2222-7aaa-8bbb-cccccccccccc"

// Reads take no id; the answer echoes the operationId the server minted for it.
const document = await documents.getDocument({
  documentId,
  scope: { type: "read" },
})

// The minted literal goes to a write that takes a key, here a createDocument.
return { title: document.title, creationId }

Preserve that literal outside the sandbox for as long as the operation might need retrying. If the second run's outcome is ambiguous, resubmit it with the same literal unchanged.

The example shows the flow; live server validation inside run is authoritative for exact parameters.

Reuse, and the one rule that matters

Reuse a minted id only for an exact retry of the same intent, where "same intent" means the same operation against the same target with the same content. That is the case the identity was minted for, and reusing it is what makes the retry safe.

Use a fresh id, from a new preparation run, when you have decided to make a genuinely new attempt: a different document, corrected content, or a second deliberate copy. That is a different operation and deserves a different identity. Paging a read needs no id at all: a deliberate new call or next page takes none, and an echoed operationId is passed back only to replay an exact retry.

Never mint an id in order to retry. This is the failure the whole design is built against, and it is the one that produces duplicate writes: a duplicate voucher, a duplicate file ingestion, a second lens. If a call was ambiguous and you no longer have its id, you have lost the ability to retry it safely; verify the external state first, then decide whether a new operation under a new id is actually correct.

Note also that a minted id reserves nothing. Nothing is recorded when you mint, so an id you never use costs nothing and an id you use twice for two different calls is a genuine mistake the platform may reject as an idempotency conflict rather than a harmless coincidence.

Sizing the mint

count defaults to 1 and accepts 1 through 32. Because minting is free, cheap, and confined to its own run, mint the number of ids the following script will consume rather than making the script pause to acquire more. If you are about to write a script that creates three documents and ingests two files, mint five in one call and label them in your own notes as you paste them in.

Do not use these values for anything other than the field that asked for one. In particular, never overwrite an operation id the platform gave you. When a call returns an operationId as part of its result, that value identifies an operation that already exists, and passing a minted id in its place addresses a different operation or none at all.

For discovery, ask guide a direct question such as How do operation IDs work in Oddlynew?. For exact parameters, live server validation inside run is authoritative.

Oddlynew PublicSign in