Skip to content

Reliable API automation

This page defines the safe operating contract for a developer or AI agent that changes a Moltaro workspace through its APIs. It starts after the workspace owner has prepared access in the Moltaro Portal or administrative Web Application interface.

The workspace owner gives the developer or agent:

  1. the downloaded workspace-specific AGENTS.md or CLAUDE.md;
  2. the exact WORKSPACE_API_BASE_URL;
  3. an API key through an appropriate secret channel;
  4. a task and an account with the narrowest roles needed for that task.

The guide must not contain the key. A missing URL, guide, key, or permission is an administrative prerequisite, not an API-discovery problem.

This prerequisite boundary does not remove the configured Application’s administrative APIs from the agent workflow. Once authenticated with the provided roles, the agent uses documented /api/workspace/admin/... Configuration API routes for entity definitions, Net Operation Project, Boards and Entitlement configuration, Agent integration, and Workspace UI. Those are workspace Application endpoints. Portal administration endpoints are a different surface and are not part of the developer contract.

Keep the public and workspace origins visibly separate in scripts and prompts:

PUBLIC_DOCS_BASE=https://moltaro.com
WORKSPACE_API_BASE_URL=https://customer-workspace-api.example.com

PUBLIC_DOCS_BASE is for documentation only. Every /api/workspace/... and installation-local /openapi/... path resolves against WORKSPACE_API_BASE_URL. The Web Application used by people may have another origin; never derive the API hostname from it.

Before changing anything:

GET ${WORKSPACE_API_BASE_URL}/api/workspace/context
GET ${WORKSPACE_API_BASE_URL}/api/workspace/auth/me
GET ${WORKSPACE_API_BASE_URL}/openapi/moltaro-public-v1.json
GET ${WORKSPACE_API_BASE_URL}/openapi/moltaro-config-v1.json
GET ${WORKSPACE_API_BASE_URL}/api/workspace/admin/net-operation-project/developer-surface

After this handoff, the authenticated Application endpoints below may also be used to refresh the installation manifest or generated guide:

GET ${WORKSPACE_API_BASE_URL}/api/workspace/admin/agent-integration
GET ${WORKSPACE_API_BASE_URL}/api/workspace/admin/agent-integration/agents-md

They do not discover an unknown workspace; they require the API base URL and authorized key that the user already supplied.

Read the workspace locale and time zone, the caller’s roles and module states, the installed API contract, and the supported C# surface. Treat the installation-local OpenAPI documents and developer-surface response as authoritative for that workspace. Do not infer an endpoint, enum value, injectable service, or module availability from a different release or from a public CLR type.

Use the same sequence for schema, records, C# logic, Boards, Entitlement Operations, and custom pages:

  1. Discover the installed contract, entity schema, module state, current revision, and permissions.
  2. Read before writing. Capture ids, stable keys, row versions, source checksums, and file hashes from current responses.
  3. Preview where supported. Use schema-change plans, source-template preview, page-generator preview, validation, and language diagnostics before creating a revision or changing data.
  4. Make one bounded change. Keep a stable external correlation or idempotency key when the operation supports one.
  5. Verify the saved state. Read the entity, revision, source index, board item, entitlement history, or generated artifact back from the API.
  6. Check before publishing. Net Operation Project Build activates on success; Workspace UI Build does not. Use their exact lifecycles below.
  7. Verify the runtime result and history. Check the Function Catalog or active artifact, invoke only when requested, and read the relevant audit or ledger surface.

Do not delete schema, purge artifacts, deactivate pages, rotate credentials, or activate code merely because an endpoint exists. Those actions require an explicit task. For a destructive schema change, inspect the server-provided change plan and surface its data-loss warnings before proceeding.

Moltaro rejects stale writes instead of silently overwriting newer work:

  • record updates use the last observed RowVersion;
  • Net Operation Project manual edits use BaseRevisionId, BaseSourceChecksum, and ExpectedContentHash for every changed existing file;
  • Workspace UI source edits use the same base revision/checksum pattern and file hashes where the request schema requires them;
  • artifact activation, deactivation, rollback, and purge use expected project and artifact row versions.

On HTTP 409, do not resend the old body. Re-read the object or source tree, compare the intervening change with the intended change, merge when safe, and submit a new request using the fresh concurrency values. If the correct merge is ambiguous, stop and ask the user.

  • Retry reads after a transient transport failure.
  • Do not blindly retry a mutation after an unknown outcome. First read the target state or use the operation’s documented idempotency key.
  • Boards automation commands mirror Runtime API semantics and do not have a separate durable receipt. After an unknown add outcome, query the open item; after an unknown mutation outcome, read the item and compare its current state and RowVersion before deciding whether another command is needed.
  • Reuse the same durable idempotency key when retrying the same logical Entitlement grant, renewal, lifecycle, consume, reverse, adjustment, or renewal-operation command. Do not generate a new key for each attempt. The Entitlement facade reports a native durable replay as Replayed = true.
  • A source template’s StableKey identifies the published function or data source across revisions. Read the template catalog to learn whether it is required; do not derive it from a display name.
  • A command CorrelationId connects one external operation with its run and downstream history. It is observability context, not a substitute for an operation-specific idempotency key.
  • Validation, permission, not-found, and concurrency responses require a corrected request or fresh state, not automatic retry.

Queue a build once, retain its returned id, and poll that exact resource with a bounded delay and overall client deadline. Do not queue duplicate builds because a build remains Queued or Running longer than expected.

First establish that the operation is actually queued. A C# Task, an Async method name, or HTTP 200 is not an execution-mode signal: Moltaro enqueue endpoints return a normal success envelope containing a queued resource. Use Function Catalog contract, binding source, API publication kind, schedule metadata, and the response schema. The complete discovery table, CRON flow, job/run distinction, and polling algorithm are in Asynchronous operations and polling.

Both project build status enums use Queued = 0, Running = 1, Succeeded = 2, Failed = 3, and Cancelled = 4. 2, 3, and 4 are terminal. On failure, read the stored diagnostics rather than immediately submitting an identical build.

The build kinds and activation behavior are different:

ProjectCheckBuildActivation
Net Operation Project10A successful Build automatically replaces the active C# artifact. A failed Build leaves the previous artifact active.
Workspace UI Project01Build creates an inactive artifact. Activation is a separate, row-version-protected operation; rollback can restore a compatible prior artifact.

Function jobs use Queued = 0, Leased = 1, Completed = 2, Failed = 3, and Cancelled = 4. Poll the job id returned by enqueue; do not enqueue the same business operation again simply because it is still queued or leased.

For recurring work, create one Function Schedule through the Configuration API instead of running a client-side timer that repeatedly calls a manual enqueue endpoint. The schedule processor leases each due occurrence and the function queue suppresses a new scheduled job while the target function has queued or running work. That due occurrence remains visible as a diagnostic Skipped run. Do not add another singleton or deduplication layer and do not submit a compensating manual job for Skipped; observe the active job and let the next CRON occurrence proceed normally.

Generated entity contract after schema changes

Section titled “Generated entity contract after schema changes”

Moltaro regenerates GeneratedWorkspaceContract on the server. Each C# language request and Check/Build receives the current generated entity source; there is no contract download or refresh endpoint in the API-first workflow.

After creating, changing, or deleting an entity field:

  1. read the entity definition again and use its current keys and ids;
  2. call completions, hover, signature help, or diagnostics again for the current source buffer;
  3. fix any renamed or removed generated members;
  4. if the source changed, create a new immutable source revision; run Check against the exact revision before Build.

Do not continue from completion results captured before the schema change.

The current source contract accepts at most 500 files, 512 KiB of UTF-8 text per file, 5 MiB of UTF-8 source in total, and 500 changes in one manual-edit request. Paths are relative, use /, and are at most 512 characters. Supported stored paths are:

  • C# files below src/;
  • Markdown at the project root or below docs/;
  • root package-references.json, with at most 50 package references.

Generated, build, dependency, and repository directories such as GeneratedWorkspaceContract, bin, obj, lib, node_modules, .git, and .moltaro cannot be edited through the source API. Language requests use the same 512 KiB active-buffer and 5 MiB snapshot limits.

Successful diagnostics and manual-edit responses include Limits, which is the machine-readable contract for source size, manual-edit count, diagnostics timeout, manual-edit timeout, and diagnostics concurrency. A size rejection includes safe MaxBytes and ActualBytes metadata without source text. File-count and manual-edit-count rejections likewise include exact maximum and actual counts. Diagnostics that exceed the server deadline return HTTP 503 with netOperationProject.language.analysis.timeout. A manual edit that exceeds its deadline or cannot acquire the project write lock in time returns HTTP 503 with netOperationProject.source.manualEdit.timeout; it creates no revision. After either response, read current status and retry with current concurrency values. Client cancellation may leave analysis completing safely in the background, but it does not retain the project write lock or block status reads. An ExpectedContentHash mismatch is a distinct HTTP 409 response.

  • JSON properties are PascalCase and public enums are numeric. Read x-enum-varnames from the installed OpenAPI document instead of guessing a number.
  • Check the response envelope’s Success before using Data. Branch on the stable error Code and optional Field, never on localized Message.
  • Read locale and time zone from /api/workspace/context. Send dates, times, decimals, and currency values in the exact JSON shape declared by OpenAPI; never apply locale-specific display formatting to an API value.
  • A 403 can mean the account lacks a role or resource-context permission. The agent asks the user or workspace administrator to review access; it does not attempt to grant itself permissions.
SymptomSafe response
401Confirm the request used WORKSPACE_API_BASE_URL and the provided bearer key. If the key is missing, expired, or revoked, ask the user to update it in the Portal or administrative interface.
403Read the operation’s permission requirements and ask the administrator for the narrowest missing permission. Do not switch to a personal login or change roles yourself.
404First verify the API origin. Then re-discover the entity, function, board, module resource, or artifact; ids and visibility are workspace-specific.
409Re-read, compare, merge, and retry with fresh row versions, revision ids, checksums, and hashes. Never overwrite blindly.
Net Operation Project source processing returns 503For netOperationProject.language.analysis.timeout or netOperationProject.source.manualEdit.timeout, read current status, respect the returned retry metadata and Limits, then retry from fresh revision, checksum, and file-hash values. A timed-out manual edit creates no revision.
Diagnostics pass but Check failsDiagnostics replace one unsaved buffer inside a revision snapshot. Save every intended file, then inspect Check diagnostics for the exact immutable revision and installed dependencies.
Check passes but Build failsRead the stored Build stage and nullable structured Failure. Branch on ReasonCode, not the localized summary. The previous Net Operation Project artifact remains active. For storage_capacity_exhausted, ask the operator to free or expand storage before queueing a new Build. For publication_commit_unconfirmed, re-read the Build and active artifact before retrying; do not repair catalog rows manually. Workspace UI never activates a failed build.
Workspace UI Build succeeds but users see no changeFind the artifact by BuildId and RevisionId, activate it with current row versions, then perform the required full WebApp refresh.
Module is disabled or an injectable service is absentRead workspace module state and developer-surface. Ask the administrator to enable/configure the supported module, or remove the dependency. Do not inject an unlisted internal service.
moltaro.automation.executionPhase.unsupportedMove the module operation out of Validation/BeforeSaveMutation and into an Action, TriggerHandler, Command, Job, or HttpEndpoint. Prefer an after-commit trigger when it depends on a saved record.
Polling reaches the client deadlineKeep the build or job id, report its latest state, and let the user decide whether to continue polling or request cancellation. Do not enqueue a duplicate.
Change pathHistory behavior
Runtime record create/update/archive through Moltaro APIs and product surfacesThe platform writes field, table, assignment, and system-field history when audit is enabled for the entity definition.
Net Operation Project direct-DB saveAutomatic field-level audit is not added. Emit a display-safe AddBusinessEventAsync event for each meaningful custom state change.
Boards application-automation operationStored actor is moltaro-system-automation; join Function operations to board history/resource events by correlation and origin metadata.
Entitlement application-automation operationStored actor is moltaro-system-automation; treat the append-only ledger and entitlement history as truth and join them to the function run by correlation/origin metadata.
Net Operation Project or Workspace UI publicationProject build and publication governance is separate from one record’s change feed. Verify the active artifact through the project APIs.

See Record history and audit for the record change feed and business-event recipe, and Errors and responses for the common response shape.