Skip to content
Console
Browse documentation
Guide

Pin the contract your app is built on

Find the REST contract your Anectico deployment serves, verify its digest, and fetch the operations your program calls.

On this page

A program you build on Anectico's REST API must be written against the contract of the deployment it calls, not against whatever the documentation site describes today. The documentation can be newer than the deployment, and a URL that contains /api/v1 says nothing about which operations, fields and limits that deployment actually serves. Every deployment therefore publishes the exact contract it serves, with a digest, and your agent can fetch and verify it before it writes a line of code.

Until Anectico's first supported release the contract is experimental: routes and response shapes can change without notice, so record the revision and the digest you built against and re-test when either changes (see Compatibility).

Find the contract a deployment serves

GET /api/v1/api-contract answers with the deployment's contract manifest. It needs no credential, so your agent can read it before any key exists, and it holds no organization, project, person or credential data: every caller of one deployment receives the same document. It accepts no query parameters; one is refused with 400 rather than ignored. It never fetches the documentation site's manifest, so it can only describe the build that answers.

curl --fail-with-body https://app.anectico.com/api/v1/api-contract
{
  "schema_version": 1,
  "serving_build": "2026.10.15",
  "contract_revision": "experimental-03f7a62d28df",
  "digest": "sha256:ab7b71b7…",
  "audience_counts": { "app_data": 432, "customer_control": 164, "operator": 25, "protocol": 35, "sdk_data_plane": 18 },
  "app_qualification_counts": { "supported": 3, "restricted": 277, "experimental": 152, "excluded": 0 },
  "active_operation_ids": ["get_analytics_insights_by_id", "…"],
  "active_audience_counts": { "app_data": 432, "…": 0 },
  "protocol_availability": [{ "operation_id": "mcp", "route": "/mcp", "active": true }],
  "artifacts": [{ "partition": "customer", "revision": "experimental-03f7a62d28df", "digest": "sha256:4f9c426f…", "url": "https://anectico.com/docs/api-contract/artifacts/…", "media_type": "application/json", "byte_count": 10635930, "operation_count": 614, "protocol_entry_count": 0, "qualification_boundary": "…" }],
  "proof_links": { "viewing": ["…"], "none": ["…"] },
  "stability": { "status": "experimental", "pin": "…", "policy_reference": "https://anectico.com/docs/apps/contract/" }
}
Field Meaning
serving_build The release or build identity of the deployment that answered.
contract_revision The exact revision of the contract this deployment serves. One revision is one set of bytes: it is derived from the manifest's own content.
digest The SHA-256 of the master contract, written sha256: and 64 lowercase hex characters. The master contract is the complete census, which includes operations that are not part of any customer contract, so it is not downloadable. It is a different hash from the digest of any artifact below.
audience_counts, app_qualification_counts How many operations the revision declares, by audience and by app qualification. These are what the revision contains, not what this deployment mounted.
active_operation_ids, active_audience_counts, protocol_availability What this deployment mounted when it started. An operation that the revision declares but the deployment did not mount is not served here, and is not listed. A configuration change can change these without changing any digest.
artifacts The contracts you can download: customer (every app-data, customer-control and SDK operation, each labeled with its audience and qualification), apps (the app-data operations that are supported, or restricted with the reason stated) and protocol (sign-in, discovery, MCP and receiver flows). Each has its own digest, size, immutable address and a statement of what it does and does not promise.
proof_links Which console proof pages exist and which query parameters each needs, and the resource types that have no proof page. It carries no link and no origin; a link comes only from a result that has a page.
stability experimental until the first supported release.

An operation's stable ID is its operationId; active_operation_ids lists the ones you can select.

Write the contract to a file

anectico api spec fetches the manifest of the configured deployment, downloads the exact artifact it names, verifies the artifact, and writes it where you say. It sends no API key, token or cookie to either host: the contract is public, and the documentation host is not the API.

# The whole customer contract
anectico api spec --out ./anectico-api.json

# Only the operations your program calls, with the schemas they reference
anectico api spec \
  --operation get_oncall_schedules_by_id_on_call \
  --operation get_analytics_results_by_result_id \
  --revision experimental-03f7a62d28df \
  --out ./anectico-api.json
Flag Meaning
--out The file to write. Required. An existing file is replaced only with --force. It is not the global --output, which chooses how the result is printed.
--operation A stable operation ID; repeat it to select several. Without it the whole contract is written.
--revision Refuse unless the deployment serves exactly this revision. A different revision is an error, never a fallback to the newest published one.
--digest Refuse unless the digest of the source artifact is this. Accepts sha256: followed by 64 hex characters, or the 64 hex characters sha256sum prints. The master digest is refused.
--partition The source contract: customer (default), apps or protocol.
--force Replace an existing --out file.

Before anything is written the command checks the manifest format, the revision pin, the artifact's size and its SHA-256 against what the manifest advertises, that the artifact is the contract it claims to be, and that every reference inside it resolves. If any check fails, nothing is written: there is never a half-written spec that looks plausible. An operation your deployment did not mount is refused.

Three digests that are not interchangeable

Digest What it hashes Where you meet it
Master The complete census The manifest's digest
Source artifact The exact bytes of one downloadable contract artifacts[].digest, --digest, and source_digest inside a selected file
Selected output The exact bytes of the file --operation writes The selected_output_digest the command prints

--digest compares the source artifact's digest, so it still holds for every selection cut from that artifact. Supplying the master digest is refused with a message that says so.

A selected file says it is a selection

The file --operation writes is a valid OpenAPI 3.1 document containing only the operations you named and the schemas, responses and security schemes they reference. It carries an x-anectico-selection extension so it cannot be mistaken for the complete contract:

"x-anectico-selection": {
  "selected_count": 2,
  "source_digest": "sha256:4f9c426f…",
  "source_revision": "experimental-03f7a62d28df"
}

source_digest is the digest of the verified source artifact, not of the selected file. The document never embeds its own digest: selected_output_digest is the SHA-256 of exactly the bytes written, and it is the same whether you selected through the CLI or through MCP.

Read the contract over MCP

With mcp:read and docs:read, the get_rest_contract read action returns the same manifest, or the declarations of the operations you name. It spends no tool slot of its own: call it through execute_read_action.

{
  "name": "execute_read_action",
  "arguments": {
    "action": "get_rest_contract",
    "arguments": {
      "operation_ids": ["get_oncall_schedules_by_id_on_call"],
      "expected_revision": "experimental-03f7a62d28df"
    }
  }
}
  • With no operation_ids it returns the manifest and nothing larger.
  • With 1 to 100 unique operation_ids it returns selected_count, complete: true, the source revision and digest, the selected_output_digest and the document, the exact canonical bytes the CLI would write. Write the document verbatim to keep it verifiable.
  • expected_revision refuses an answer from any other revision.
  • A selection whose document would exceed one MiB is refused with selection_too_large; nothing is cut to fit, complete is false and selected_count is 0. Select fewer operations, or use the CLI for the whole file.
Refusal Meaning
invalid_selection Zero or more than 100 operation IDs, a repeated or oversized ID, or an unknown partition.
unknown_operation The contract of this revision has no such operation.
operation_not_active The revision declares the operation but this deployment did not mount it.
revision_mismatch The deployment serves another revision than expected_revision.
selection_too_large The selected document would exceed one MiB.

An ordinary runtime key that only calls the API needs none of this: docs:read is a discovery grant for the agent that builds your program, not a permission your program holds.

The published copies

The same revision is published, immutably, on the documentation site:

Address What it is
https://anectico.com/docs/api-contract/latest.json The manifest of the newest published revision. It selects a revision; it never replaces one.
https://anectico.com/docs/api-contract/revisions/<revision>.json The manifest of one revision. It never changes.
https://anectico.com/docs/api-contract/artifacts/anectico-<partition>-<sha256>.openapi.json One contract. The file name contains the SHA-256 of its bytes, so a name can never refer to two different files.

Treat latest.json as news about what exists, not as the contract of your deployment: the deployment's own GET /api/v1/api-contract is. To check a downloaded file yourself:

sha256sum anectico-customer-4f9c426f….openapi.json

The result must equal the 64 characters in the file name and the digest the manifest lists for it.

Compatibility

Until the first supported release there is no compatibility promise:

  • routes and response shapes may change without a deprecation period;
  • every contract is experimental, including the operations marked supported;
  • clients pin the serving build and the digest they tested, and re-test before moving.

At the first supported release, the release notes name the exact set of supported app operations and their compatibility and deprecation policy, and the manifest's stability records the release the promise starts in. The promise starts there and is never backdated; an operation that is merely listed in a contract, or in the REST reference, is not stable because it is listed.

Browser aggregate sharing

Read the customer contract partition for owner grant controls and dedicated mint and view protocols. These operations are excluded from the ordinary app-data subset. Pin and inspect their actual credential, confirmation, paging and refusal declarations; a protocol exclusion does not mean unavailable.

See Share a saved aggregate with a browser page for the full credential, theft, lifetime, privacy and external-copy contract.