intentic
Download the app
Download the app
Agent setup

Extensions

Installed extensions: their settings, their readiness, their updates and their processes

On this page(22 sections)

The runtime half of the extension format documented under Developers. These routes enumerate what is installed, read and write each one's settings, switch it on or off, check for updates and apply or undo one, and start or stop the long-running processes an extension declares.

22 calls. Pick one to open it, or use the list on the right.

GET/extensionsInstalled extensions

Every extension installed here, resolved to the manifest the owner approved, which is what the app boots its extension host from. The code itself is served separately, because raw script bytes are not a JSON answer.

What you send

Nothing. Call it as it is.

What comes back

FieldType
extensionsWhat is installedobject[]
idThe extension's idstring
manifestWhat it declares about itself: what…object
$schemaThe authoring schema, for editor completion…string
publisherstring
namestring
versionYour own semver, display and identity…string
categoryWhich section of the Extensions tab…string
artThis extension's own mark, as a…string
logoA simple-icons slug, fetched from a…string
iconA name from the host's own…string
enginesA semver range over the host's…object
intenticstring
entryRepo-relative path of your prebuilt single-file…string
serverRepo-relative path of your prebuilt single-file…string
permissionsHow far this extension may reach…object
sandboxDaemon routes your UI half may…string[]
daemonDaemon routes your SERVER half may…string[]
contributesobject
viewsSidebar elements this extension may register…object[]
filesWhich workspace files back your views,…object[]
viewersFile formats this extension can renderobject[]
documentsPer-directory documents this extension can offerobject[]
sideViewsThings this extension can show in…object[]
commandsCommands this extension may register handlers…object[]
settingsTyped settings the host renders into…object[]
processesLong-lived background processes the daemon runs…object[]
agentDeclare that this checkout is also…object
environmentA Dockerfile fragment baked into the…object
capabilitiesCapability cards this pack adds to…object[]
listenerA realtime event source this extension…object
automationTemplatesStarting points this pack offers in…object[]
binA checkout-relative directory of executables the…string
toolsTools for the agent, as an…object
commitExactly which commit is installedstring
sourceWhere the code comes from: baked…"builtin" | "installed" | "workspace"
enabledThe owner's switchboolean
essentialIts switch is fixed on, because…boolean
usageHow much of the reach it…object
backendPresent only for an extension that…object
stateHow its server half is doing"running" | "error" | "absent" | "incompatible" … (6)
detailWhat went wrong, so a backend…string
problemsDeclarations in its manifest the sandbox…string[]
updateA newer version waitingobject
refThe commit being offeredstring
versionWhat it calls itselfstring
urlWhere it comes fromstring
pathWhere inside that repository it livesstring
trustWhether anybody vouched for it, or…"verified" | "listed"
securityFixThis release fixes a security problem…boolean
registryWhich registry said sostring
atWhen it was publishedstring
needsReviewWhy this one was not taken…string
reviewAn agent has already read the…object
conversationIdWhere to read what it foundstring
atWhen it lookedstring
advisoryA security warning about the installed…object
reasonWhy the registry pulled the listing,…string
registryWhich registry said sostring
atWhenstring
autoDisabledWhether the sandbox has already switched…boolean
healthHow it has behaved since the…object
stateHow it has behaved since the…"watching" | "healthy" | "unhealthy"
detailWhat is going wrong, when something…string
fromRefWhich version it was updated from,…string
atWhen the watching startedstring
autoRevertedThe update was already rolled back…boolean
previousThe version kept one step back,…object
refThe commit that was running beforestring
versionWhat it called itselfstring
updatePolicyThe owner's standing answer for this…object
updates"notify" | "agent" | "auto"
advisories"auto-disable" | "notify"
devSet while an extension installed from…object
pathThe source checkout it was pointed…string
conversationThe conversation whose isolated copy of…string
uncommittedHow many files in the checkout…integer
revisionA short fingerprint of the browser…string
heldWhy the checkout is not what…string
invalidExtensions written here that could not…object[]
dirWhich folderstring
errorWhy it could not be readstring
pendingExtensions written in this workspace that…object[]
idThe extension's idstring
dirWhich folder under .intentic/config/workspace-extensions/string
manifestWhat it declares about itselfobject
$schemaThe authoring schema, for editor completion…string
publisherstring
namestring
versionYour own semver, display and identity…string
categoryWhich section of the Extensions tab…string
artThis extension's own mark, as a…string
logoA simple-icons slug, fetched from a…string
iconA name from the host's own…string
enginesA semver range over the host's…object
intenticstring
entryRepo-relative path of your prebuilt single-file…string
serverRepo-relative path of your prebuilt single-file…string
permissionsHow far this extension may reach…object
sandboxDaemon routes your UI half may…string[]
daemonDaemon routes your SERVER half may…string[]
contributesobject
viewsSidebar elements this extension may register…object[]
filesWhich workspace files back your views,…object[]
viewersFile formats this extension can renderobject[]
documentsPer-directory documents this extension can offerobject[]
sideViewsThings this extension can show in…object[]
commandsCommands this extension may register handlers…object[]
settingsTyped settings the host renders into…object[]
processesLong-lived background processes the daemon runs…object[]
agentDeclare that this checkout is also…object
environmentA Dockerfile fragment baked into the…object
capabilitiesCapability cards this pack adds to…object[]
listenerA realtime event source this extension…object
automationTemplatesStarting points this pack offers in…object[]
binA checkout-relative directory of executables the…string
toolsTools for the agent, as an…object
powersWhat saying yes allows, as plain…object
addedWhat the new version asks for…string[]
removedWhat it no longer asks forstring[]
unchangedWhat stays the samestring[]
approvedBeforeAn earlier shape of it was…boolean
digestThe fingerprint of the powers shown,…string
updatesCheckedAtWhen updates were last looked forstring
Try itanswered in this tab
curl
curl "$SANDBOX/extensions" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.list();
POST/extensions/workspaceWrite a new extension in place

Scaffolds a working extension into this workspace and installs it. The only call here that creates one, and it exists because that folder is otherwise reachable only through an agent's file tools, which is a fine way to change an extension and a poor way to meet the idea of one.

What you send

FieldTypeWhere
publisherrequiredWho it is by, which together…stringbody
namerequiredWhat it is calledstringbody

What comes back

FieldType
idThe id it was givenstring
dirWhere its files are, so you…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/workspace" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"publisher":"…","name":"nightly changelog"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.create({
  "publisher": "…",
  "name": "nightly changelog"
});
GET/extensions/{id}/removalWhat removing an extension would take away

Everything one removal destroys, before it happens: the files deleted, the connections configured from its cards, the settings and credentials forgotten, the background processes stopped, and the owner's own automations that quietly stop firing. Also answerable for an extension that cannot be removed, in which case it says why.

What you send

FieldTypeWhere
idrequiredWhich connectionstringaddress

What comes back

FieldType
idThe extension's id, as the list…string
nameIts publisher.name identity, which is the…string
versionThe version being removedstring
sourceWhere its code comes from, which…"builtin" | "installed" | "workspace"
blockedWhy this one cannot be removed,…string
filesDirectories deleted outrightobject[]
pathWorkspace-relativestring
detailWhat is in therestring
connectionsConnections configured from its cards, which…object[]
idThe name the owner gave it,…string
kindWhich core kind it is underneath:…string
entryThe catalog entry it was added…string
secretsCredential fields stored for it, by…string[]
effectWhat tearing it down actually takes…string
settingsValues the owner entered for this…object[]
keyWhich settingstring
secretWhether its value is a stored…boolean
processesBackground processes it declared, stopped before…string[]
automationsAutomations of the owner's own that…string[]
rebuildNeededIt bakes a layer into the…boolean
keepsWhat removal deliberately leaves alone, so…string[]
Try itanswered in this tab
curl
curl "$SANDBOX/extensions/a1b2c3d4/removal" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.removalPlan({
  "id": "a1b2c3d4"
});
POST/extensions/{id}/removeRemove an extension

Uninstalls it and everything that only existed because it was here: the connections added from its cards, with their stored credentials, its settings, its switch and its update record. What the owner made with it — automations, files in the workspace — is left alone. Owner only, for the same reason installing is. Built-in extensions cannot be removed; switch them off instead.

What you send

FieldTypeWhere
idrequiredWhich connectionstringaddress

What comes back

FieldType
okIt is gonetrue
connectionsWhich configured connections went with it,…string[]
rebuildNeededIts image layer is still in…boolean
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/remove" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.remove({
  "id": "a1b2c3d4"
});
GET/extensions/{id}/settingsAn extension's settings

The current values for the settings this extension declared it has.

What you send

FieldTypeWhere
idrequiredWhich connectionstringaddress

What comes back

FieldType
settingsThe values, minus anything marked secretobject
secretsSetWhich of its secret settings actually…string[]
Try itanswered in this tab
curl
curl "$SANDBOX/extensions/a1b2c3d4/settings" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.settings({
  "id": "a1b2c3d4"
});
POST/extensions/{id}/settingsChange an extension's settings

Writes new values. A key the extension never declared is refused rather than quietly stored, the same honesty rule that governs everything else an extension claims.

What you send

FieldTypeWhere
idrequiredWhich extensionstringaddress
settingsrequiredThe values to writeobjectbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/settings" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"settings":{"src/app.ts":"…","README.md":"…"}}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.setSettings({
  "id": "a1b2c3d4",
  "settings": {
    "src/app.ts": "…",
    "README.md": "…"
  }
});
POST/extensions/{id}/approveLet a workspace extension run

Approves an extension written in this workspace with the powers it declares now: its background processes start, its backend loads, and what it contributes is wired from the next turn. Editing its code keeps the approval; declaring a power it did not have puts it back in the pending list. Owner and maintainers only.

What you send

FieldTypeWhere
idrequiredWhich extensionstringaddress
digestrequiredThe fingerprint of the powers you…stringbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/approve" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"digest":"…"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.approve({
  "id": "a1b2c3d4",
  "digest": "…"
});
POST/extensions/{id}/enabledTurn an extension on or off

The owner's switch. Turning one off stops its background processes at once. What it contributes to an agent's tools is rebuilt at the start of the next turn, and anything it adds to the sandbox image only at the next rebuild.

What you send

FieldTypeWhere
idrequiredWhich extensionstringaddress
enabledrequiredOn or offbooleanbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/enabled" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"enabled":true}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.setEnabled({
  "id": "a1b2c3d4",
  "enabled": true
});
POST/extensions/usageRecord what extensions just used

One batch written by the app rather than measured by the daemon, because the permission gate runs in the browser: from the sandbox's side extension traffic is indistinguishable from anyone else's. This is how the record of which powers each extension actually exercises gets kept without one reporting request per extension.

What you send

FieldTypeWhere
reportsrequiredEach extension that called something, and…objectbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/usage" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"reports":{"src/app.ts":{"src/app.ts":1,"README.md":1},"README.md":{"src/app.ts":1,"README.md":1}}}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.recordUsage({
  "reports": {
    "src/app.ts": {
      "src/app.ts": 1,
      "README.md": 1
    },
    "README.md": {
      "src/app.ts": 1,
      "README.md": 1
    }
  }
});
GET/extensions/{id}/readinessWhether an extension is fit to share

The checks that can be answered from an extension's own files, for an author about to publish. Read on demand rather than carried on the list, because it reads the code off disk each time.

What you send

FieldTypeWhere
idrequiredWhich connectionstringaddress

What comes back

FieldType
checksEverything that can be checked from…object[]
idWhich checkstring
labelWhat it is calledstring
statusHow it went"pass" | "warn" | "fail"
detailWhat it foundstring
Try itanswered in this tab
curl
curl "$SANDBOX/extensions/a1b2c3d4/readiness" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.readiness({
  "id": "a1b2c3d4"
});
POST/extensions/updates/checkLook for extension updates now

Compares every installed extension against its source and reports what is newer, what carries an advisory and what looks unhealthy. This also happens on a schedule; call it to check on demand.

What you send

Nothing. Call it as it is.

What comes back

FieldType
okThe check rantrue
checkedAtWhen, so a screen can date…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/updates/check" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.checkUpdates();
POST/extensions/{id}/update/previewWhat an update would change

The read before the click: which versions are involved and exactly which powers the new code asks for that the running one does not. Costs one throwaway copy of the source, the same as browsing a registry entry.

What you send

FieldTypeWhere
idrequiredWhich extensionstringaddress
refWhich commit, in fullstringbody

What comes back

FieldType
refThe commit this would installstring
versionWhat that version calls itselfstring
installedVersionWhat is running nowstring
enginesWhich sandbox versions the new one…string
compatibleWhether this sandbox is one of…boolean
powersExactly what the new code asks…object
addedWhat the new version asks for…string[]
removedWhat it no longer asks forstring[]
unchangedWhat stays the samestring[]
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/update/preview" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"ref":"refs/heads/main"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.updatePreview({
  "id": "a1b2c3d4",
  "ref": "refs/heads/main"
});
POST/extensions/{id}/updateUpdate an extension

The whole swap as one transaction: fetch, check, quiet the running one, replace it while keeping the outgoing copy one step back, restart and watch it come up. The existing configuration is kept, so a token for a private source survives what removing and re-adding would lose. Owner only, because it changes what code runs.

What you send

FieldTypeWhere
idrequiredWhich extensionstringaddress
refWhich commit, in fullstringbody

What comes back

FieldType
okIt went throughtrue
refWhich commit is now runningstring
rebuildNeededThe new version changes what the…boolean
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/update" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"ref":"refs/heads/main"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.applyUpdate({
  "id": "a1b2c3d4",
  "ref": "refs/heads/main"
});
POST/extensions/{id}/revertGo back to the previous version

Swaps the copy kept from before the last update back into place. Owner only, for the same reason updating is.

What you send

FieldTypeWhere
idrequiredWhich connectionstringaddress

What comes back

FieldType
okIt went throughtrue
refWhich commit is now runningstring
rebuildNeededThe new version changes what the…boolean
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/revert" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.revert({
  "id": "a1b2c3d4"
});
POST/extensions/{id}/update-policyHow an extension should handle its own updates

The owner's standing answer for one extension: tell me, have an agent look at it, or just do it. Security advisories can be opted out of separately.

What you send

FieldTypeWhere
idrequiredWhich extensionstringaddress
updatesWhat to do about a newer…"notify" | "agent" | "auto"body
advisoriesWhat to do about a security…"auto-disable" | "notify"body

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/update-policy" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"updates":"notify","advisories":"auto-disable"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.setUpdatePolicy({
  "id": "a1b2c3d4",
  "updates": "notify",
  "advisories": "auto-disable"
});
GET/extensions/{id}/processes/{name}Whether an extension's background process is up

The state of one process an extension declared, with the port it was given and its preview address if it has one.

What you send

FieldTypeWhere
idrequiredWhich extensionstringaddress
namerequiredWhich of its declared processesstringaddress

What comes back

FieldType
nameWhich processstring
runningWhether it is upboolean
portThe port it was givennumber
restartsHow many times it died and…number
lastExitCodeHow it last exited, when it…number
previewUrlWhere to open it, when it…string
Try itanswered in this tab
curl
curl "$SANDBOX/extensions/a1b2c3d4/processes/nightly%20changelog" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.processStatus({
  "id": "a1b2c3d4",
  "name": "nightly changelog"
});
POST/extensions/{id}/processes/{name}/startStart an extension's background process

Brings one of an extension's declared processes up in an attachable terminal.

What you send

FieldTypeWhere
idrequiredWhich extensionstringaddress
namerequiredWhich of its declared processesstringaddress

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/processes/nightly%20changelog/start" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.processStart({
  "id": "a1b2c3d4",
  "name": "nightly changelog"
});
POST/extensions/{id}/processes/{name}/stopStop an extension's background process

Shuts one of an extension's declared processes down and frees its port.

What you send

FieldTypeWhere
idrequiredWhich extensionstringaddress
namerequiredWhich of its declared processesstringaddress

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/processes/nightly%20changelog/stop" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.processStop({
  "id": "a1b2c3d4",
  "name": "nightly changelog"
});
GET/extensions/devInstalled extensions and their source checkouts

Every extension installed from a repository, with its pinned commit, whether it runs from a source checkout, and the checkout of its repository this workspace holds, if any. The calling conversation's own copy is named first.

What you send

Nothing. Call it as it is.

What comes back

FieldType
extensionsEvery extension installed from a repositoryobject[]
idIts connection idstring
nameIts manifest id, publisher.namestring
commitThe pinned commit, in fullstring
devPresent while it is pointed at…object
pathThe source checkout it was pointed…string
conversationThe conversation whose isolated copy of…string
uncommittedHow many files in the checkout…integer
revisionA short fingerprint of the browser…string
heldWhy the checkout is not what…string
checkoutA checkout of its source repository…object
pathRelative to the workspace, or to…string
conversationSet when the calling conversation's own…string
Try itanswered in this tab
curl
curl "$SANDBOX/extensions/dev" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.devList();
POST/extensions/{id}/devRun an installed extension from its source checkout

Serves the extension's browser bundle, backend, processes, skills and contributions from a checkout of its source instead of its pinned copy, so a change to it shows on reload without being landed first. The checkout must hold the same extension and declare the same powers; one asking for more, or not built yet, is held and the pinned version keeps running, with the reason. Nothing is installed or updated: the pinned copy stays where it is.

What you send

FieldTypeWhere
idrequiredWhich installed extension: its connection id…stringaddress
pathThe checkout to run it fromstringbody

What comes back

FieldType
idIts connection idstring
nameIts manifest id, publisher.namestring
devWhere it runs from now, or…object
pathThe source checkout it was pointed…string
conversationThe conversation whose isolated copy of…string
uncommittedHow many files in the checkout…integer
revisionA short fingerprint of the browser…string
heldWhy the checkout is not what…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/dev" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"path":"src/app.ts"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.devSet({
  "id": "a1b2c3d4",
  "path": "src/app.ts"
});
POST/extensions/{id}/dev/clearGo back to the pinned version

Stops serving the extension from its source checkout. The checkout itself is left exactly as it is.

What you send

FieldTypeWhere
idrequiredWhich installed extension: its connection id…stringaddress

What comes back

FieldType
idIts connection idstring
nameIts manifest id, publisher.namestring
clearedWhether it was pointed at a…boolean
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/dev/clear" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.devClear({
  "id": "a1b2c3d4"
});
POST/extensions/{id}/dev/reloadPick up a rebuilt checkout

Call after rebuilding an extension that runs from its source checkout: its backend restarts on the new code, and an open app is told the list changed, so it offers to reload the new browser bundle.

What you send

FieldTypeWhere
idrequiredWhich installed extension: its connection id…stringaddress

What comes back

FieldType
idIts connection idstring
nameIts manifest id, publisher.namestring
devWhere it runs from now, or…object
pathThe source checkout it was pointed…string
conversationThe conversation whose isolated copy of…string
uncommittedHow many files in the checkout…integer
revisionA short fingerprint of the browser…string
heldWhy the checkout is not what…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/extensions/a1b2c3d4/dev/reload" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.extensions.devReload({
  "id": "a1b2c3d4"
});

Type to search every page, in the docs and the API reference.