# Provision a dedicated Mind

Create a dedicated Mind and understand the current provisioning and upgrade contracts.

Source: https://docs.minds.sh/docs/api/platform/provisioning



Free and Pro are specified as dedicated Firecracker VM-based Akasha instances. Free is capped; Pro changes the resource and usage arrangement. The latest local customer provisioning code delegates creation to the Minds ensure service and fails closed when it is unconfigured. The dashboard flow rejects `mode: "shared"`.

The initial audit found a Render provisioning path. The engineering coordinator reports that the hosted application still uses that earlier path while the replacement is prepared. The local change has not yet been verified through a deployed instance-to-VM trace. [Runtime verification status](/docs/operations/compatibility).

## Before creating an instance [#before-creating-an-instance]

Sign in, select an organization, and choose a name. `GET /api/provisioning/instances/preflight` is currently a legacy diagnostic: it checks Render and Cloudflare configuration, but does not check the new ensure service. Its result is not a reliable readiness gate for the ensure-based create path.

Use the returned region choices in the UI. Do not hardcode a legacy management-region identifier into the dashboard flow: the dashboard planner and older management API have different region vocabularies.

## Create the Mind [#create-the-mind]

From the signed-in dashboard origin, send:

```typescript
const response = await fetch('/api/provisioning/instances', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    name: 'Research memory',
    mode: 'dedicated',
    plan: 'free',
  }),
});
if (!response.ok) throw new Error(`Provisioning: HTTP ${response.status}`);
const { instance } = await response.json();
```

The request's name is required after trimming. `plan` defaults to `free`; mode is dedicated. The request schema retains optional `region`, `services`, `modules`, `hotLoading`, and `customHostnames` fields. However, the current ensure request forwards only the organization as `customer_id` and an optional region. Do not assume plan capacity, service selection, or custom hostnames were applied. The accepted schema and returned `ProvisionedInstance` shape are in [the schema reference](/docs/api/platform/schemas).

The server checks organization context and entitlements, then sends `POST /v1/minds/ensure` to the configured ensure service with the signed-in bearer token. Ensure must return a Mind ID and base URL. Dashboard success is &#x2A;*201 `{instance}`**, with the returned ID, endpoint, region, and provisioning status. Keep these values rather than constructing an endpoint from the display name. A 201 response does not establish readiness or prove that every requested option was applied.

## Check readiness separately [#check-readiness-separately]

`GET /api/provisioning/instances/readiness?endpoint=...` checks `/health/ready` on a normalized HTTPS endpoint under `minds.sh`. It removes any supplied path, query, or fragment. Other domains and non-HTTPS inputs are rejected.

| HTTP result                   | Meaning                                                            |
| ----------------------------- | ------------------------------------------------------------------ |
| 200 `{status:"ready"}`        | The target readiness endpoint returned a successful response       |
| 202 `{status:"pending", ...}` | The endpoint is not ready or the request could not complete        |
| 400 `INVALID_ENDPOINT`        | The endpoint is missing or outside the allowed domain and protocol |

Use a bounded polling interval and let the user retry. A ready response verifies the health endpoint; complete a scoped memory read and the intended user journey before declaring an integration ready.

This unauthenticated probe checks only the upstream HTTP status, without inspecting its body. It does not verify ownership, authentication, memory operations, or VM isolation. An ensure endpoint outside the allowed Minds hostname policy cannot be checked through this route.

## Request an upgrade [#request-an-upgrade]

`POST /api/provisioning/instances/upgrade` takes an `instanceId` and optional provider-resolution fields. If `plan` is supplied, it must be `pro`. The server can resolve missing provider identifiers from the active organization's tenant/service records.

```json
{ "instanceId": "<existing-instance-id>", "plan": "pro" }
```

The POST wrapper returns `{instance, sameInstanceId:true}` on success. The main `/api/provisioning/instances` route also exposes a PATCH upgrade operation with `plan:"pro"` and optional `services`, returning `{instance}`. Use one flow consistently; do not issue both as a retry strategy.

The current local upgrade implementation requests the organization's Mind from ensure and returns Pro capacity metadata, but sends no explicit plan or capacity change and does not forward the signed-in bearer token. It also accepts substring matches when comparing instance IDs. Actual resizing, applied service choices, and strict preservation of the existing ID remain unverified. A successful response, including `sameInstanceId:true`, is not proof that an upgrade occurred.

## Service controls [#service-controls]

The product contract uses service toggles to control running workloads and cost, rather than separately purchased feature tiers. The current ensure integration does not forward these choices, so their effect needs verification. Existing API schemas may retain `starter` or old bundle names for compatibility; current customer packaging is Free, Pro, and Enterprise.

## Recover from a failure [#recover-from-a-failure]

401 means sign-in is required. 409 `NO_ORGANIZATION` means context is missing. The create route currently also wraps ensure failures under `INVALID_PROVISIONING_REQUEST`, so inspect the HTTP status and message instead of assuming this code always means bad input. Missing ensure configuration returns 503; an ensure response without the required ID or URL produces 502. Retain the instance state and request evidence before retrying, because a failed HTTP request can follow a partially completed provider action.

Source: `minds-ui/apps/app/lib/provisioning/service.ts`, `ensure-client.ts`, `upgrade.ts`, `types.ts`, and the dashboard provisioning route modules. This page describes the local implementation audited on September 12, 2026; hosted Firecracker lifecycle and Free-to-Pro resizing still require runtime verification.
