# Store

URL: https://docs.hanzo.ai/docs/guides/store

> KV round-trip — create a store, read it back, delete it.

**KV round-trip — create a store, read it back, delete it.**

> The delete belongs in the language's finally/defer, so a failed read still cleans up instead of leaving the store for the next run to collide with. This is the provisioning plane — create a KV STORE, read it, drop it — at its served address, /v1/provisioning/kv. The bare /v1/kv spellings are the legacy dialect the binary itself tags compat, and the publication drops a compat operation by that declaration — so the day this file named them it would have named ids the published document does not have, which is exactly what test\_flows.py went red on. Probed at api.hanzo.ai: GET /v1/provisioning/kv answers 403 while /v1/provisioning/kv-zzq9 answers 404, which is the existence proof this file requires (auth runs before the handler; only a mounted route can refuse).

## Launches your org's OWN key-value instance and answers with its `kv://` connection string.

`POST /v1/provisioning/kv` · [reference →](https://docs.hanzo.ai/docs/openapi/provisioning)

Launches your org's OWN key-value instance and answers with its `kv://`
connection string.

The instance is yours alone — a deployment in your own tenant namespace, so its
admin credential is naturally scoped to you and no other tenant shares the
process. Off-cluster this fails closed with 503 rather than handing back a
shared one.

| Parameter  | In   | Required | Description                                                                                                              |
| ---------- | ---- | -------- | ------------------------------------------------------------------------------------------------------------------------ |
| `instance` | body | —        | Instance binds a DEDICATED add-on to the app instance whose \<instance>-addons Secret receives the \<KIND>\_URL (        |
| `name`     | body | —        | Name is the org-unique slug for the new resource, matching ^[a-z0-9](https://docs.hanzo.ai/docs/guides)?$. Every physica |

**CLI**

```bash
hanzo provisioning kv create
```

**SDK**

**.ts**

```ts
import { Configuration, ProvisioningApi } from 'hanzoai';

const api = new ProvisioningApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postProvisioningKv({ instance: "<instance>", name: "<name>" });
```

**.py**

```python
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import ProvisioningApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = ProvisioningApi(client).post_provisioning_kv(instance="<instance>", name="<name>")
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.ProvisioningAPI.PostProvisioningKv(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
use hanzo_client::apis::{configuration::Configuration, provisioning_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = provisioning_api::post_provisioning_kv(&cfg, Default::default()).await?;
```

**.java**

```java
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.ProvisioningApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new ProvisioningApi(client).postProvisioningKv();
```

**HTTP**

```bash
curl -X POST https://api.hanzo.ai/v1/provisioning/kv \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "instance": "<instance>",
       "name": "<name>"
     }'
```

**MCP**

MCP reaches **provisioning** through the `provisioning` tool, which names its 28 operations with its own verbs — this one among them, under a name only MCP declares. `describe` explains any of them:

```bash
curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "get_provisioning_datastore"
         }
       }
     }'
```

## Returns one Hanzo KV store's metadata.

`GET /v1/provisioning/kv/{name}` · [reference →](https://docs.hanzo.ai/docs/openapi/provisioning)

Returns one Hanzo KV store's metadata. It carries the store's status,
its instance address and the Valkey user it authenticates as ("default", the
only user a requirepass instance has) — never the password. A still-booting
instance reads "provisioning", reconciled from the operator's live view.

| Parameter | In   | Required | Description                                                                                                    |
| --------- | ---- | -------- | -------------------------------------------------------------------------------------------------------------- |
| `name`    | path | yes      | Name is the resource's org-unique slug, from the path. Lower-cased and trimmed before lookup, exactly as it wa |

**CLI**

```bash
hanzo provisioning kv get <name>
```

**SDK**

**.ts**

```ts
import { Configuration, ProvisioningApi } from 'hanzoai';

const api = new ProvisioningApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.getProvisioningKvByName({ name: 'name' });
```

**.py**

```python
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import ProvisioningApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = ProvisioningApi(client).get_provisioning_kv_by_name(name='name')
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.ProvisioningAPI.GetProvisioningKvByName(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
use hanzo_client::apis::{configuration::Configuration, provisioning_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = provisioning_api::get_provisioning_kv_by_name(&cfg, Default::default()).await?;
```

**.java**

```java
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.ProvisioningApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new ProvisioningApi(client).getProvisioningKvByName();
```

**HTTP**

```bash
curl https://api.hanzo.ai/v1/provisioning/kv/<name> \
  -H "Authorization: Bearer $HANZO_API_KEY"
```

**MCP**

Tool `provisioning`, op `get_provisioning_kv_by_name` — POST the JSON-RPC envelope to `https://api.hanzo.ai/v1/mcp`.

```bash
curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "provisioning",
         "arguments": {
           "op": "get_provisioning_kv_by_name",
           "input": {
             "name": "<name>"
           }
         }
       }
     }'
```

## Deprovisions one Hanzo KV store.

`DELETE /v1/provisioning/kv/{name}` · [reference →](https://docs.hanzo.ai/docs/openapi/provisioning)

Deprovisions one Hanzo KV store. It reverts any app instance bound to
it back to Base BEFORE tearing down the org's dedicated Valkey instance, then
deletes the sealed credential and removes the metadata row. Answers 204 with
no body; a second call is a 404.

| Parameter | In   | Required | Description                                                                                                    |
| --------- | ---- | -------- | -------------------------------------------------------------------------------------------------------------- |
| `name`    | path | yes      | Name is the resource's org-unique slug, from the path. Lower-cased and trimmed before lookup, exactly as it wa |

**CLI**

```bash
hanzo provisioning kv rm <name>
```

**SDK**

**.ts**

```ts
import { Configuration, ProvisioningApi } from 'hanzoai';

const api = new ProvisioningApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.deleteProvisioningKvByName({ name: 'name' });
```

**.py**

```python
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import ProvisioningApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = ProvisioningApi(client).delete_provisioning_kv_by_name(name='name')
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.ProvisioningAPI.DeleteProvisioningKvByName(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
use hanzo_client::apis::{configuration::Configuration, provisioning_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = provisioning_api::delete_provisioning_kv_by_name(&cfg, Default::default()).await?;
```

**.java**

```java
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.ProvisioningApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new ProvisioningApi(client).deleteProvisioningKvByName();
```

**HTTP**

```bash
curl -X DELETE https://api.hanzo.ai/v1/provisioning/kv/<name> \
  -H "Authorization: Bearer $HANZO_API_KEY"
```

**MCP**

MCP reaches **provisioning** through the `provisioning` tool, which names its 28 operations with its own verbs — this one among them, under a name only MCP declares. `describe` explains any of them:

```bash
curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "get_provisioning_datastore"
         }
       }
     }'
```

---

Every command, call and tool above is generated from the same OpenAPI document that generates the SDKs themselves — the four surfaces are projections of one doc comment, so they cannot disagree.
