# Namespaces Replication

Every registered namespaces replication instance operation, with source-derived inputs, outputs, access policy, and errors.

Source: https://docs.minds.sh/docs/api/instance/namespaces-replication



This reference covers **5 HTTP operations** registered by the Akasha daemon. Call these paths on your instance base URL. See [authentication](/docs/api/instance/authentication), [errors](/docs/api/instance/errors), and [coverage](/docs/api/instance/coverage) before integrating.

| Method | Path                     | Operation                                         |
| ------ | ------------------------ | ------------------------------------------------- |
| `GET`  | `/v1/dataspaces`         | [Dataspaces list](#get-v1-dataspaces)             |
| `POST` | `/v1/namespace/switch`   | [Namespace switch](#post-v1-namespace-switch)     |
| `POST` | `/v1/replication/links`  | [Replication create](#post-v1-replication-links)  |
| `POST` | `/v1/replication/stop`   | [Replication stop](#post-v1-replication-stop)     |
| `POST` | `/v1/replication/status` | [Replication status](#post-v1-replication-status) |

<a id="get-v1-dataspaces" />

## GET `/v1/dataspaces` [#get-v1dataspaces]

Dataspaces list

| Availability         | Source contract                                                  |
| -------------------- | ---------------------------------------------------------------- |
| Registration         | `config.enable_kv`                                               |
| Runtime service      | No prefix-level service check; handler dependencies still apply. |
| Handler dependencies | See handler source and return expressions.                       |

**Access:** Daemon authentication and capability namespace authority; memory-domain permissions apply where mapped.

### Request [#request]

No typed JSON, query, or path extractor is declared in the handler signature. Headers or request objects may still be consumed; the signature below is authoritative.

### Response [#response]

**Declared return:** `Result<impl IntoResponse, DaemonError>`

The following are the exact JSON construction expressions in the handler. Values such as `rows`, `result`, and delegated types are runtime values, not literal example payloads.

```rust
serde_json::to_value(list).unwrap_or(serde_json::json!([])),
```

### Errors and validation [#errors-and-validation]

Directly referenced error variants: `Internal`. Middleware and delegated services can return additional errors described in the shared error reference.

<Accordions>
  <Accordion title="Inspect implementation">
    This exact source excerpt includes validation, defaults, delegated calls, and response assembly.

    ```rust
    async fn dataspaces_list(
        State(state): State<AppState>,
        Extension(db): Extension<Arc<AkashaDB>>,
    ) -> Result<impl IntoResponse, DaemonError> {
        state.record_http_request();
        let list = db
            .dataspaces()
            .list_dataspaces()
            .map_err(|e| DaemonError::Internal(e.to_string()))?;
        Ok(Json(
            serde_json::to_value(list).unwrap_or(serde_json::json!([])),
        ))
    }
    ```
  </Accordion>
</Accordions>

Source: `akasha-daemon/src/main.rs:3461`. Registration: `akasha-daemon/src/main.rs:4584`.

<a id="post-v1-namespace-switch" />

## POST `/v1/namespace/switch` [#post-v1namespaceswitch]

Namespace switch

| Availability         | Source contract                                                  |
| -------------------- | ---------------------------------------------------------------- |
| Registration         | `config.enable_kv`                                               |
| Runtime service      | No prefix-level service check; handler dependencies still apply. |
| Handler dependencies | `KV`                                                             |

**Access:** Daemon authentication and capability namespace authority; memory-domain permissions apply where mapped.

### Request [#request-1]

**Json** — `NamespaceSwitchReq`

| Field          | Rust type | Required on input | Notes |
| -------------- | --------- | ----------------- | ----- |
| `tenant_id`    | `String`  | Yes               |       |
| `reservoir_id` | `String`  | Yes               |       |
| `agent_id`     | `String`  | Yes               |       |
| `dataspace_id` | `String`  | Yes               |       |

```rust
struct NamespaceSwitchReq {
    tenant_id: String,
    reservoir_id: String,
    agent_id: String,
    dataspace_id: String,
}
```

### Response [#response-1]

**Declared return:** `Result<impl IntoResponse, DaemonError>`

The following are the exact JSON construction expressions in the handler. Values such as `rows`, `result`, and delegated types are runtime values, not literal example payloads.

```rust
serde_json::json!({
        "ok": true,
        "namespace": {
            "tenant_id": namespace.tenant_id.to_string(),
            "reservoir_id": namespace.reservoir_id.to_string(),
            "agent_id": namespace.agent_id.to_string(),
            "dataspace_id": namespace.dataspace_id.to_string(),
        }
    })
```

### Errors and validation [#errors-and-validation-1]

Directly referenced error variants: `Internal`, `InvalidRequest`, `Unauthorized`. Middleware and delegated services can return additional errors described in the shared error reference.

<Accordions>
  <Accordion title="Inspect implementation">
    This exact source excerpt includes validation, defaults, delegated calls, and response assembly.

    ```rust
    async fn namespace_switch(
        State(state): State<AppState>,
        capability: Option<Extension<CapabilityTokenPayload>>,
        Json(req): Json<NamespaceSwitchReq>,
    ) -> Result<impl IntoResponse, DaemonError> {
        if let Some(Extension(capability)) = capability.as_ref() {
            AppState::validate_capability_payload(capability)?;
            let matches_verified_scope = capability.tenant_id.as_deref()
                == Some(req.tenant_id.as_str())
                && capability.reservoir_id.as_deref() == Some(req.reservoir_id.as_str())
                && capability.agent_id.as_deref() == Some(req.agent_id.as_str())
                && capability.dataspace_id.as_deref() == Some(req.dataspace_id.as_str());
            if !matches_verified_scope {
                return Err(DaemonError::Unauthorized(
                    "namespace switch scope does not match verified capability".into(),
                ));
            }
        }

        let namespace = CoreNamespace {
            tenant_id: Uuid::parse_str(&req.tenant_id)
                .map_err(|_| DaemonError::InvalidRequest("invalid tenant_id".into()))?,
            reservoir_id: Uuid::parse_str(&req.reservoir_id)
                .map_err(|_| DaemonError::InvalidRequest("invalid reservoir_id".into()))?,
            agent_id: Uuid::parse_str(&req.agent_id)
                .map_err(|_| DaemonError::InvalidRequest("invalid agent_id".into()))?,
            dataspace_id: Uuid::parse_str(&req.dataspace_id)
                .map_err(|_| DaemonError::InvalidRequest("invalid dataspace_id".into()))?,
        };

        let ns_id = namespace.id();
        let db = require_service!(state.db, "KV");
        let scoped = db
            .with_namespace(namespace.clone(), Some(state.core_authorizer.clone()))
            .await
            .map_err(|e| DaemonError::InvalidRequest(e.to_string()))?;
        let scoped = Arc::new(scoped);
        let cell = Arc::new(OnceCell::new());
        if cell.set(scoped).is_err() {
            return Err(DaemonError::Internal(
                "failed to cache namespace-scoped database".into(),
            ));
        }
        state.scoped_dbs.write().await.insert(ns_id, cell);

        Ok(Json(serde_json::json!({
            "ok": true,
            "namespace": {
                "tenant_id": namespace.tenant_id.to_string(),
                "reservoir_id": namespace.reservoir_id.to_string(),
                "agent_id": namespace.agent_id.to_string(),
                "dataspace_id": namespace.dataspace_id.to_string(),
            }
        })))
    }
    ```
  </Accordion>
</Accordions>

Source: `akasha-daemon/src/main.rs:3484`. Registration: `akasha-daemon/src/main.rs:4585`.

<a id="post-v1-replication-links" />

## POST `/v1/replication/links` [#post-v1replicationlinks]

Replication create

| Availability         | Source contract                                                  |
| -------------------- | ---------------------------------------------------------------- |
| Registration         | `config.enable_kv`                                               |
| Runtime service      | No prefix-level service check; handler dependencies still apply. |
| Handler dependencies | See handler source and return expressions.                       |

**Access:** Daemon authentication and capability namespace authority; memory-domain permissions apply where mapped.

### Request [#request-2]

**Json** — `ReplicationCreateReq`

| Field           | Rust type        | Required on input         | Notes |
| --------------- | ---------------- | ------------------------- | ----- |
| `dest_data_dir` | `String`         | Yes                       |       |
| `link_id`       | `Option<String>` | No; optional or defaulted |       |

```rust
struct ReplicationCreateReq {
    dest_data_dir: String,
    link_id: Option<String>,
}
```

### Response [#response-2]

**Declared return:** `Result<impl IntoResponse, DaemonError>`

The following are the exact JSON construction expressions in the handler. Values such as `rows`, `result`, and delegated types are runtime values, not literal example payloads.

```rust
serde_json::json!({"link_id": link_id.to_string()})
```

### Errors and validation [#errors-and-validation-2]

Directly referenced error variants: `InvalidRequest`. Middleware and delegated services can return additional errors described in the shared error reference.

<Accordions>
  <Accordion title="Inspect implementation">
    This exact source excerpt includes validation, defaults, delegated calls, and response assembly.

    ```rust
    async fn replication_create(
        State(state): State<AppState>,
        Extension(db): Extension<Arc<AkashaDB>>,
        Json(req): Json<ReplicationCreateReq>,
    ) -> Result<impl IntoResponse, DaemonError> {
        state.record_http_request();
        let cfg = CoreReplicationLinkConfig::new(
            req.link_id
                .as_deref()
                .and_then(|s| uuid::Uuid::parse_str(s).ok())
                .unwrap_or_else(uuid::Uuid::new_v4),
        );
        let dest_cfg = AkashaConfig {
            data_dir: std::path::PathBuf::from(&req.dest_data_dir),
            ..Default::default()
        };
        let dest = AkashaDB::new(dest_cfg)
            .await
            .map_err(|e| DaemonError::InvalidRequest(e.to_string()))?;
        let link_id = cfg.link_id;
        let handle = db
            .replication_create_link(&dest, cfg.clone())
            .await
            .map_err(|e| DaemonError::InvalidRequest(e.to_string()))?;
        {
            let mut tasks = state.repl_tasks.write().await;
            tasks.insert(link_id, handle);
        }
        Ok(Json(serde_json::json!({"link_id": link_id.to_string()})))
    }
    ```
  </Accordion>
</Accordions>

Source: `akasha-daemon/src/main.rs:3547`. Registration: `akasha-daemon/src/main.rs:4586`.

<a id="post-v1-replication-stop" />

## POST `/v1/replication/stop` [#post-v1replicationstop]

Replication stop

| Availability         | Source contract                                                  |
| -------------------- | ---------------------------------------------------------------- |
| Registration         | `config.enable_kv`                                               |
| Runtime service      | No prefix-level service check; handler dependencies still apply. |
| Handler dependencies | See handler source and return expressions.                       |

**Access:** Daemon authentication and capability namespace authority; memory-domain permissions apply where mapped.

### Request [#request-3]

**Json** — `ReplicationIdReq`

| Field | Rust type | Required on input | Notes |
| ----- | --------- | ----------------- | ----- |
| `id`  | `String`  | Yes               |       |

```rust
struct ReplicationIdReq {
    id: String,
}
```

### Response [#response-3]

**Declared return:** `Result<impl IntoResponse, DaemonError>`

The following are the exact JSON construction expressions in the handler. Values such as `rows`, `result`, and delegated types are runtime values, not literal example payloads.

```rust
serde_json::json!({"stopped": true})
```

### Errors and validation [#errors-and-validation-3]

Directly referenced error variants: `InvalidRequest`. Middleware and delegated services can return additional errors described in the shared error reference.

<Accordions>
  <Accordion title="Inspect implementation">
    This exact source excerpt includes validation, defaults, delegated calls, and response assembly.

    ```rust
    async fn replication_stop(
        State(state): State<AppState>,
        Json(req): Json<ReplicationIdReq>,
    ) -> Result<impl IntoResponse, DaemonError> {
        let id = uuid::Uuid::parse_str(&req.id)
            .map_err(|_| DaemonError::InvalidRequest("invalid id".into()))?;
        let h = {
            let mut tasks = state.repl_tasks.write().await;
            tasks
                .remove(&id)
                .ok_or_else(|| DaemonError::InvalidRequest("unknown replication id".into()))?
        };
        h.abort();
        Ok(Json(serde_json::json!({"stopped": true})))
    }
    ```
  </Accordion>
</Accordions>

Source: `akasha-daemon/src/main.rs:3583`. Registration: `akasha-daemon/src/main.rs:4587`.

<a id="post-v1-replication-status" />

## POST `/v1/replication/status` [#post-v1replicationstatus]

Replication status

| Availability         | Source contract                                                  |
| -------------------- | ---------------------------------------------------------------- |
| Registration         | `config.enable_kv`                                               |
| Runtime service      | No prefix-level service check; handler dependencies still apply. |
| Handler dependencies | See handler source and return expressions.                       |

**Access:** Daemon authentication and capability namespace authority; memory-domain permissions apply where mapped.

### Request [#request-4]

**Json** — `ReplicationIdReq`

| Field | Rust type | Required on input | Notes |
| ----- | --------- | ----------------- | ----- |
| `id`  | `String`  | Yes               |       |

```rust
struct ReplicationIdReq {
    id: String,
}
```

### Response [#response-4]

**Declared return:** `Result<impl IntoResponse, DaemonError>`

The following are the exact JSON construction expressions in the handler. Values such as `rows`, `result`, and delegated types are runtime values, not literal example payloads.

```rust
serde_json::json!({"running": running})
```

### Errors and validation [#errors-and-validation-4]

Directly referenced error variants: `InvalidRequest`. Middleware and delegated services can return additional errors described in the shared error reference.

<Accordions>
  <Accordion title="Inspect implementation">
    This exact source excerpt includes validation, defaults, delegated calls, and response assembly.

    ```rust
    async fn replication_status(
        State(state): State<AppState>,
        Json(req): Json<ReplicationIdReq>,
    ) -> Result<impl IntoResponse, DaemonError> {
        let id = uuid::Uuid::parse_str(&req.id)
            .map_err(|_| DaemonError::InvalidRequest("invalid id".into()))?;
        let running = {
            let tasks = state.repl_tasks.read().await;
            tasks.get(&id).map(|h| !h.is_finished()).unwrap_or(false)
        };
        Ok(Json(serde_json::json!({"running": running})))
    }
    ```
  </Accordion>
</Accordions>

Source: `akasha-daemon/src/main.rs:3599`. Registration: `akasha-daemon/src/main.rs:4588`.
