Skip to content

Run one complete workflow in your language

Carry a synthetic preference into a later task using the backend you already have. Complete the account and Nucleus setup, then export NEUTRON_API_TOKEN, NEUTRON_NUCLEUS_ID and NEUTRON_SCOPE_ID in that server environment. Use only a disposable evaluation Scope. These examples call public REST directly; they do not require an unpublished Neutron SDK package.

Each example remembers an invented preference, requests bounded context and finally tombstones its own memory. Expect an accepted memory, a promptContext containing the preference and a confirmed tombstone. This is two billable memory requests plus one unbilled forget request. The example does not call your application model provider. To verify separate requested Scopes, positive recall and post-delete absence, use the repeatable evaluation.

Keep tokens server-side. Your application must authorise the Nucleus and Scope before invoking these calls. A client-selected Scope is not an end-user permission check. Never print or store raw credentials in logs. Follow framework wiring for LangChain, LangGraph, Laravel and Vercel boundaries.

TypeScript / JavaScript

Save as first-result.mjs; Node.js 22.18+ runs the same JavaScript from a TypeScript backend. Run node first-result.mjs.

import { randomUUID } from "node:crypto";
const { NEUTRON_API_TOKEN: token, NEUTRON_NUCLEUS_ID: nucleusId, NEUTRON_SCOPE_ID: scopeId } = process.env;
if (!token || !nucleusId || !scopeId) throw new Error("Set the three NEUTRON environment variables");
const post = async (route, body) => {
  const response = await fetch(`https://neutronai.dev/api/v1/memory/${route}`, {
    method: "POST", headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
    body: JSON.stringify({ nucleusId, ...body }), signal: AbortSignal.timeout(15000), redirect: "error",
  });
  if (!response.ok) throw new Error(`${route}: HTTP ${response.status}`);
  return response.json();
};
const memory = await post("remember", { scopeId, type: "preference", text: `Aster ${randomUUID()} prefers weekly support email.`, privacyClass: "tenant" });
try {
  if (!memory.accepted || !memory.memoryId) throw new Error("Remember not accepted");
  const pack = await post("agent-context", { scopeIds: [scopeId], task: "Find the support email preference", include: ["preferences"], privacyClasses: ["tenant"], tokenBudget: 400 });
  console.log(pack.promptContext);
} finally {
  const result = await post("forget", { scopeId, memoryId: memory.memoryId, reason: "evaluation_cleanup" });
  if (!result.tombstoned) throw new Error("Confirm cleanup in your evaluation Scope");
}

Python

Save as first_result.py; Python 3.10+ uses only its standard library. Run python3 first_result.py.

import json, os, uuid
from urllib.request import Request, urlopen

token = os.environ["NEUTRON_API_TOKEN"]
nucleus = os.environ["NEUTRON_NUCLEUS_ID"]
scope = os.environ["NEUTRON_SCOPE_ID"]

def post(route, body):
    payload = json.dumps({"nucleusId": nucleus, **body}).encode()
    request = Request("https://neutronai.dev/api/v1/memory/" + route, data=payload,
                      headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"}, method="POST")
    with urlopen(request, timeout=15) as response:
        return json.load(response)

memory = post("remember", {"scopeId": scope, "type": "preference", "text": f"Aster {uuid.uuid4()} prefers weekly support email.", "privacyClass": "tenant"})
try:
    if not memory.get("accepted") or not memory.get("memoryId"):
        raise RuntimeError("Remember not accepted")
    pack = post("agent-context", {"scopeIds": [scope], "task": "Find the support email preference", "include": ["preferences"], "privacyClasses": ["tenant"], "tokenBudget": 400})
    print(pack["promptContext"])
finally:
    result = post("forget", {"scopeId": scope, "memoryId": memory["memoryId"], "reason": "evaluation_cleanup"})
    if not result.get("tombstoned"):
        raise RuntimeError("Confirm cleanup in your evaluation Scope")

PHP / Laravel

Save as first-result.php; PHP 8.2+ needs the cURL extension. Run php first-result.php, or move the HTTP helper into an authenticated Laravel service.

<?php
declare(strict_types=1);
$token = getenv('NEUTRON_API_TOKEN');
$nucleus = getenv('NEUTRON_NUCLEUS_ID');
$scope = getenv('NEUTRON_SCOPE_ID');
if (!$token || !$nucleus || !$scope) throw new RuntimeException('Set the three NEUTRON environment variables');
function post(string $route, array $body): array {
    global $token, $nucleus;
    $curl = curl_init('https://neutronai.dev/api/v1/memory/' . $route);
    curl_setopt_array($curl, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15,
        CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, 'Content-Type: application/json'],
        CURLOPT_POSTFIELDS => json_encode(['nucleusId' => $nucleus] + $body, JSON_THROW_ON_ERROR)]);
    $response = curl_exec($curl);
    $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);
    if ($response === false || $status < 200 || $status >= 300) throw new RuntimeException($route . ': HTTP ' . $status);
    return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
}
$memory = post('remember', ['scopeId' => $scope, 'type' => 'preference', 'text' => 'Aster ' . bin2hex(random_bytes(8)) . ' prefers weekly support email.', 'privacyClass' => 'tenant']);
try {
    if (empty($memory['accepted']) || empty($memory['memoryId'])) throw new RuntimeException('Remember not accepted');
    $pack = post('agent-context', ['scopeIds' => [$scope], 'task' => 'Find the support email preference', 'include' => ['preferences'], 'privacyClasses' => ['tenant'], 'tokenBudget' => 400]);
    echo $pack['promptContext'] . PHP_EOL;
} finally {
    $result = post('forget', ['scopeId' => $scope, 'memoryId' => $memory['memoryId'], 'reason' => 'evaluation_cleanup']);
    if (empty($result['tombstoned'])) throw new RuntimeException('Confirm cleanup in your evaluation Scope');
}

Go

Save as main.go in an empty directory, run go mod init example.com/neutron-evaluation, then go run . with Go 1.25+. Imports, HTTP timeouts and error handling are included.

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
    "os"
    "time"
)

func run() error {
    token, nucleus, scope := os.Getenv("NEUTRON_API_TOKEN"), os.Getenv("NEUTRON_NUCLEUS_ID"), os.Getenv("NEUTRON_SCOPE_ID")
    if token == "" || nucleus == "" || scope == "" { return fmt.Errorf("set the three NEUTRON environment variables") }
    client := &http.Client{Timeout: 15 * time.Second, CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
    post := func(route string, body map[string]any) (map[string]any, error) {
        body["nucleusId"] = nucleus
        payload, err := json.Marshal(body); if err != nil { return nil, err }
        req, err := http.NewRequest(http.MethodPost, "https://neutronai.dev/api/v1/memory/"+route, bytes.NewReader(payload)); if err != nil { return nil, err }
        req.Header.Set("Authorization", "Bearer "+token); req.Header.Set("Content-Type", "application/json")
        response, err := client.Do(req); if err != nil { return nil, err }; defer response.Body.Close()
        if response.StatusCode < 200 || response.StatusCode >= 300 { return nil, fmt.Errorf("%s: HTTP %d", route, response.StatusCode) }
        var result map[string]any; err = json.NewDecoder(response.Body).Decode(&result); return result, err
    }
    memory, err := post("remember", map[string]any{"scopeId": scope, "type": "preference", "text": fmt.Sprintf("Aster %d prefers weekly support email.", time.Now().UnixNano()), "privacyClass": "tenant"})
    if err != nil { return err }
    id, ok := memory["memoryId"].(string); if !ok || memory["accepted"] != true { return fmt.Errorf("remember not accepted") }
    pack, contextErr := post("agent-context", map[string]any{"scopeIds": []string{scope}, "task": "Find the support email preference", "include": []string{"preferences"}, "privacyClasses": []string{"tenant"}, "tokenBudget": 400})
    cleanup, cleanupErr := post("forget", map[string]any{"scopeId": scope, "memoryId": id, "reason": "evaluation_cleanup"})
    if cleanupErr != nil { return cleanupErr }; if cleanup["tombstoned"] != true { return fmt.Errorf("confirm cleanup in your evaluation Scope") }
    if contextErr != nil { return contextErr }
    fmt.Println(pack["promptContext"]); return nil
}
func main() { if err := run(); err != nil { fmt.Fprintln(os.Stderr, err); os.Exit(1) } }

Rust

Create a Rust 2024 binary with Rust 1.85+ and this Cargo.toml; put the program in src/main.rs, then run cargo run. Only the general HTTP/JSON runtime dependencies below are needed.

[package]
name = "neutron-evaluation"
version = "0.1.0"
edition = "2024"

[dependencies]
reqwest = { version = "0.13.4", default-features = false, features = ["json", "rustls"] }
serde_json = "1.0"
tokio = { version = "1.53", features = ["macros", "rt-multi-thread"] }
use serde_json::{json, Value};
use std::{env, error::Error, time::{Duration, SystemTime, UNIX_EPOCH}};

async fn post(client: &reqwest::Client, token: &str, nucleus: &str, route: &str, mut body: Value) -> Result<Value, Box<dyn Error>> {
    body["nucleusId"] = json!(nucleus);
    let response = client.post(format!("https://neutronai.dev/api/v1/memory/{route}"))
        .bearer_auth(token).json(&body).send().await?;
    Ok(response.error_for_status()?.json().await?)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let token = env::var("NEUTRON_API_TOKEN")?;
    let nucleus = env::var("NEUTRON_NUCLEUS_ID")?;
    let scope = env::var("NEUTRON_SCOPE_ID")?;
    let client = reqwest::Client::builder().timeout(Duration::from_secs(15)).redirect(reqwest::redirect::Policy::none()).build()?;
    let nonce = SystemTime::now().duration_since(UNIX_EPOCH)?.as_nanos();
    let memory = post(&client, &token, &nucleus, "remember", json!({"scopeId":scope,"type":"preference","text":format!("Aster {nonce} prefers weekly support email."),"privacyClass":"tenant"})).await?;
    let id = memory["memoryId"].as_str().ok_or("remember returned no memoryId")?;
    let context = post(&client, &token, &nucleus, "agent-context", json!({"scopeIds":[scope],"task":"Find the support email preference","include":["preferences"],"privacyClasses":["tenant"],"tokenBudget":400})).await;
    let cleanup = post(&client, &token, &nucleus, "forget", json!({"scopeId":scope,"memoryId":id,"reason":"evaluation_cleanup"})).await?;
    if cleanup["tombstoned"] != true { return Err("confirm cleanup in your evaluation Scope".into()); }
    println!("{}", context?["promptContext"]); Ok(())
}

Check the result and failure boundary

These fixtures exercise the same remember/context/forget REST contract. They print synthetic supporting context; do not reuse that logging with private records. A timeout can leave a write accepted without a confirmed response: inspect the evaluation Scope before retrying. Process termination can interrupt cleanup.

On 401, verify the full Nucleus token; on 403, check Nucleus ownership and policy; on 402, stop and inspect allowance/credit. Keep the same application model and compare observed outcomes before migrating. For multi-language typed clients and newer knowledge/decision methods, consult the SDK readiness and parity guidance.