---
title: "Your first Semurg calls from Python or Elixir: remember a fact, recall it"
slug: hello-semurg-first-calls-from-a-client
date: 2026-10-12
author: Semurg
section: how-to
tags: [sdk, python, elixir, getting-started, how-to]
summary: Download the signed client archive, check it, and make your first three calls from Python or Elixir: is the node up, remember a fact, recall it. Plus where each of the other languages starts.
status: published
covers: [hello:Python, hello:Elixir, sdk:health, sdk:remember, sdk:recall]
constants: [1.18, 2024]
---
Three calls and you are talking to a node from your own code: is it up, remember a fact, recall it. This guide does it from Python or
Elixir, in about five minutes if a node is already running. A client takes the node's address and its API token, and that is all:
there is no hosted service in the middle and no account.

> Diagram three-calls: Your program, given the node's address and token, asks whether the node is up, remembers two entities and the relationship between them in the hello scope, and recalls Ada, reading the state before the items.

No node yet? Start with [the five-minute guide](/blog/agent-memory-mcp-five-minutes), which installs one.

## Get the client

All the client libraries ship in one signed archive beside the installer. Download it with the published checksums and check it before
you unpack anything:

> Diagram client-archive: Download the client archive and its published checksums, check it, unpack it, and pick your language's folder, which carries its own README and the connecting guide.

```bash runnable kind=shell needs=none
curl -fsSLO https://one.semurg.io/dl/clients.tar.gz
curl -fsSLO https://one.semurg.io/dl/SHA256SUMS
sha256sum -c --ignore-missing SHA256SUMS
```

```expect
expect: the checksum line for the archive, ending in OK
assert: out~clients\.tar\.gz: OK
```

Then unpack it with `tar xzf clients.tar.gz`. Inside is one folder per language and `CONNECTING.md`, the guide to pointing a client at
your node.

## Python

The Python client has no dependencies beyond the standard library. Install it from the unpacked archive with
`pip install -e clients/python`, then:

```python
import os
from semurg import Client

with Client("http://localhost:4000", token=os.environ["SEMURG_API_TOKEN"]) as client:
    print(client.health())

    client.remember("hello", facts={
        "entities": [{"name": "Ada", "type": "Person"}, {"name": "Acme", "type": "Company"}],
        "relations": [{"source": "Ada", "target": "Acme", "type": "WORKS_AT"}],
    })

    answer = client.recall("hello", subject="Ada")
    print(answer["state"])
    for item in answer.get("items", []):
        print(item.get("text"))
```

The first call says whether the node is up. The second stores two entities and the relationship between them in a scope called
`hello`. The third finds Ada and returns what is connected to her, starting with `state`: `answered` when something matched,
`nothing_stored` when nothing did.

## Elixir

The Elixir client needs Elixir `1.18` or newer. From the folder that holds the unpacked archive, save this as `hello.exs` and run it
with `elixir hello.exs`:

```elixir
Mix.install([{:semurg, path: "clients/elixir"}])

client = Semurg.new("http://localhost:4000", token: System.fetch_env!("SEMURG_API_TOKEN"))

{:ok, health} = Semurg.health(client)
IO.inspect(health, label: "health")

{:ok, _} =
  Semurg.Client.remember(client, %{
    scope: "hello",
    facts: %{
      entities: [%{name: "Ada", type: "Person"}, %{name: "Acme", type: "Company"}],
      relations: [%{source: "Ada", target: "Acme", type: "WORKS_AT"}]
    }
  })

{:ok, answer} = Semurg.Client.recall(client, %{scope: "hello", subject: "Ada"})
IO.inspect(answer, label: "recall")
```

Every call returns `{:ok, term}` or `{:error, %Semurg.Error{}}`, and the error carries a kind you can match on, such as `:unprocessable`
for a refused call or `:timeout`.

## The other languages

The archive also holds clients for Go, Java, C#, F#, Erlang, Rust, OCaml, Julia and C++, each with its own README showing the first
calls and how to build it. What each one covers today:

- Health, status, ingest and query are in all eleven.
- The memory calls (status, remember, recall, relate, forget and context) are in Python, Go, Java, C#, F#, Elixir, Erlang, Rust and OCaml; Julia has remember, recall and context; the C++ client reaches them over plain HTTP.
- Rust needs a `2024`-edition toolchain, C++ needs the libcurl development package, Erlang needs rebar3 and OCaml needs dune.

Some methods described in the archive's READMEs (`fetch_batch` among them) call routes the node no longer serves and are being removed.
The calls above, and the memory calls, are the ones to build on.

## When a call fails

Every client passes on the node's own refusal, and the node names what to change. A missing or wrong token is `401`; a memory call
without a scope is refused with `422` "missing scope".

## Next

- [Connecting over REST](/blog/connect-over-rest): the same calls without a client library.
- [Look after your node](/blog/look-after-your-node): the calls that tell you how it is doing.
