---
question: How do I set a TTL on a key-value entry?
kind: task
via_web: available
via_cli: na
via_python: available
via_api: available
via_config: na
ref_web: System › Data › Key-value
ref_python: kv.set
ref_api: PUT /api/admin/system/resources/keyvalue/entry
prereq: For the Python steps, an in-engine module that lists `KeyValueService` in its dependencies. [Create a module](/user-guide/build/modules/creating-a-module) first.
next:
  - /capabilities/build/platform/compare-and-set
  - /capabilities/build/platform/key-value-overview
---

# Store a value

A value is bytes under a key, with an optional expiry in seconds. Writing a key that exists replaces its value. Keys are shared by every module, so prefix yours.

## Web UI

Super admins only. Use it to inspect or fix a value by hand.

### Open the store

In Nexus, open **System** in the sidebar, then the **Data** tab, then **Key-value**. The search box finds keys that contain the text.

![System app, Data tab, on Key-value, filtered](/abi/Screenshot_System_KeyValue.png)

*System › Data › Key-value, filtered to one key: its value, size and expiry.*

### Add a key

Choose **New key**. Enter the key (for example `my_module:greeting`) and the value, or upload a file as the value. Set **Expires after** with a number and a unit (seconds, minutes, hours or days), or leave it empty for no expiry. Choose **Create**.

### Edit or delete it

Select the key. The panel shows its value, size and expiry. Edit replaces the value; Nexus asks you to type the key back first. Delete asks the same.

## CLI

Not applicable. There is no `abi` command for the key-value store. Use another tab on this page. The command list is the [CLI reference](/user-guide/reference/cli).

## Python

### Declare the service

```python title="src/my_module/__init__.py"
from naas_abi_core.module.Module import BaseModule, ModuleDependencies
from naas_abi_core.services.keyvalue.KeyValueService import KeyValueService


class ABIModule(BaseModule):
    dependencies: ModuleDependencies = ModuleDependencies(
        modules=[],
        services=[KeyValueService],
    )
```

### Set and read a value

```python
from naas_abi_core.services.keyvalue.KeyValuePorts import KVNotFoundError

kv = self.engine.services.kv
kv.set("my_module:session:1", b"ready", ttl=3600)

try:
    value = kv.get("my_module:session:1")   # b"ready"
except KVNotFoundError:
    value = None
```

`ttl` is in seconds; leave it out for no expiry. `exists(key)` returns a bool. `get_ttl(key)` returns the seconds left, or `None` when the key does not expire. `get`, `get_ttl` and `delete` raise `KVNotFoundError` for a missing key.

### List and delete keys

```python
page = kv.list_keys(prefix="my_module:", limit=100)
while True:
    for key in page.keys:
        ...
    if page.next_after is None:
        break
    page = kv.list_keys(prefix="my_module:", limit=100, after=page.next_after)

kv.delete("my_module:session:1")
```

`list_keys` returns a `KVKeyPage` of unexpired keys in ascending order. `limit` is 1 to 1000.

## REST API

The System routes of the Nexus API. Auth: a Nexus session of a super admin (`POST /api/auth/login` returns the access token). Every change is audited.

### Write the value

The body is the raw value. `ttl_seconds` sets the expiry:

```bash
curl -X PUT "http://localhost:9879/api/admin/system/resources/keyvalue/entry?id=my_module:greeting&ttl_seconds=3600" \
  -H "Authorization: Bearer $NEXUS_TOKEN" \
  --data-binary 'hello'
```

With `abi dev up`, use the `api` port that `abi dev ports` prints. When the key exists, the call answers 409: add `&confirm=my_module:greeting` to replace it. Replacing without `ttl_seconds` keeps the key's remaining expiry.

### Read or list

```http
GET /api/admin/system/resources/keyvalue/entry?id=my_module:greeting
GET /api/admin/system/resources/keyvalue/entries?query=my_module
```

`query` keeps keys that contain the text, case-insensitive.

## Config

Not applicable. `services.kv` in `config.yaml` picks the store, not its keys. See [Key-value store](/user-guide/get-started/configuration#key-value-store).
