curl

curl - 설치 없이, 같은 메서드.

설치할 SDK가 없습니다 - 어떤 HTTP 클라이언트든 됩니다. 키만 한 번 설정하면 SDK가 감싸는 그 엔드포인트를 그대로 호출합니다. Base URL https://api.wontopos.com, 인증은 X-API-Key, 입출력은 JSON.

# set your key once (never hard-code it)
export WOS_API_KEY="wos-live-..."

쓰기

store

기억 하나 저장. 적재 시 색인 - LLM 호출 없음.

curl -X POST https://api.wontopos.com/api/v1/memory/store \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","content":"she prefers tea over coffee"}'
실제 응답
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}

store-turn

대화 한 턴(사용자+어시스턴트)을 단기·장기에 한 번에 저장.

curl -X POST https://api.wontopos.com/api/v1/memory/store-turn \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","user_msg":"hi","assistant_msg":"hello!"}'
실제 응답
{"status": "ok"}

speaker

모든 기억에 누가 한 말인지 담을 수 있습니다. 사람은 한 번 등록하고, 그다음부터 이름을 speaker로 넘기세요. "me"(어시스턴트 자신의 말)는 등록이 필요 없습니다. 검색에도 speaker를 주면 그 사람의 말만 회수합니다.

curl -X POST https://api.wontopos.com/api/v1/memory/speakers \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","speaker":"Bob"}'   # once per person

curl -X POST https://api.wontopos.com/api/v1/memory/store \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","content":"I promised to send the report on Friday","metadata":{"speaker":"me"}}'

curl -X POST https://api.wontopos.com/api/v1/memory/store \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","content":"Bob said the deadline moved to Tuesday","metadata":{"speaker":"Bob"}}'

curl -X POST https://api.wontopos.com/api/v1/memory/search \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","query":"what did Bob say about deadlines?","speaker":"Bob"}'
화자는 저장소처럼 명시적입니다. 사람을 먼저 등록하고 그 이름으로 저장합니다. 오타가 조용히 새 사람이 되는 일이 없습니다. 저장소당 시작 기준 50명까지 등록되고(차차 늘릴 예정), "me"는 등록도 카운트도 필요 없습니다.

supersede

사실이 바뀌면 - 옛 기억은 superseded로 마킹, 새 기억이 회수에서 그 자리를 차지.

curl -X POST https://api.wontopos.com/api/v1/memory/supersede \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","old_memory_id":"576700aa-...","new_content":"she switched to coffee this year"}'
실제 응답
{"new_memory_id": "07e94433-...", "old_memory_id": "576700aa-...", "status": "superseded"}

bulk-store

긴 기록을 한 번에 적재합니다 - 서버에서 나누어 색인합니다.

curl -X POST https://api.wontopos.com/api/v1/memory/bulk-store \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","content":"...a long history...","category":"general"}'
실제 응답
{"elapsed_secs": 0.138589761, "status": "ok", "stored": 1, "total_chunks": 1}

Idempotency-Key

쓰기 하나를 다시 보내도 안전하게 만듭니다. 재시도가 내 쪽에서 일어날 때 씁니다 - 죽었다 다시 돈 작업, 다시 전달하는 큐.

# same key + same body = the FIRST response is replayed, nothing is stored twice
curl -X POST https://api.wontopos.com/api/v1/memory/store \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: import:row-42" \
  -d '{"user_id":"alice","content":"she prefers tea over coffee"}'
키는 저장하려는 대상에서 뽑아 만드세요(import:row-42). 상수를 쓰면 안 됩니다 - 서로 다른 두 쓰기에 같은 키를 쓰면 첫 응답이 재생되고 두 번째 쓰기는 조용히 사라집니다. 형식: [A-Za-z0-9._:-] 1~128 자.

읽기

search

의미 검색, 관련도 순. 어떤 언어로 물어도 기억을 찾음.

curl -X POST https://api.wontopos.com/api/v1/memory/search \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","query":"what does she drink?","max_results":1}'
실제 응답
{"memories": [{"id": "576700aa-...", "content": "she prefers tea over coffee",
   "similarity": 0.63, "is_superseded": false}], "search_ms": 315, "total_found": 1}

search + filters

검색을 저장소의 일부로 좁힙니다. 랭킹 전에 걸리므로 필터 안에서의 최선이 나옵니다 - 상위 N 을 걸러낸 것이 아닙니다.

curl -X POST https://api.wontopos.com/api/v1/memory/search \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","query":"what did we decide",
       "filters":{"categories":["work"],"event_from":"2026-01-01","event_to":"2026-06-30"}}'
키: categories · event_from / event_to (내용이 언제 일어났나 - metadata.event_date) · time_from / time_to (언제 적재됐나) · min_importance. 목록에 없는 키는 거부가 아니라 버려지므로, 오타는 조용히 검색을 넓힙니다.

get

store 나 list 가 돌려준 id 로 기억 하나를 읽습니다 - 원문과 메타데이터뿐입니다.

curl -X POST https://api.wontopos.com/api/v1/memory/get \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","memory_id":"576700aa-f0e0-4c26-99a0-10e2d5b0d624"}'

list

저장소 전체를 커서 단위로 넘겨 봅니다. 열람이나 내보내기에 씁니다.

curl -X POST https://api.wontopos.com/api/v1/memory/list \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","limit":100}'   # pass next_cursor back for the next page
실제 응답
{"count": 3, "memories": [{"id": "1a1cfc47-...", "content": "...", "category": "general",
   "created_at": "2026-07-31T18:04:51.937117314+00:00", "event_date": null, "is_superseded": false}],
 "next_cursor": "722c08e5-8998-4882-979e-d71995b5b4af", "user_id": "docs_livetest"}

recall

한 번의 왕복으로 단기 + 장기 + 문맥 + instruction. 프롬프트에 그대로 넣으면 됨.

curl -X POST https://api.wontopos.com/api/v1/memory/recall \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","query":"what does she drink?"}'
실제 응답 (구조)
{"short_term": {"count": 2, "turns": [...]},
 "long_term":  {"count": 4, "memories": [{"content": "she prefers tea over coffee", "similarity": 0.63}]},
 "context":    {"count": 4, "around_top_memory": ["[match] she prefers tea over coffee"]},
 "instruction": "Use short_term for recent context, long_term for relevant past memories..."}

삭제

forget

id로 기억 하나 삭제, 생략하면 사용자 전체 삭제(GDPR).

curl -X POST https://api.wontopos.com/api/v1/memory/forget \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice"}'  # omit memory_id = delete all
실제 응답
{"memories_deleted": 1, "status": "deleted", "user_id": "alice"}

엔드포인트 + 바디 필드 전부 보기 →

Rust 에만 있는 변형

Python 과 TypeScript 는 이것들을 선택 인자로 받습니다. 안정판 Rust 에는 기본값도 키워드 인자도 없어서, 마무리해야 하는 빌더 대신 각각을 별도 메서드로 뒀습니다.

mem.add_with(text, None, json!({}), extra)   // add + extra body fields
mem.search_opts(q, None, 10, &opts)            // search + verify / max_images
mem.search_with(q, None, 10, extra)            // search + any other field
mem.recall_with(q, None, extra)                // recall + extra
mem.search_self_with(q, None, 10, extra)       // self lane + extra
mem.engram_with(name, q, None, extra)          // engram + extra
mem.update_idempotent(old, new, None, key)     // update + Idempotency-Key
mem.add_turn_idempotent(u, a, None, key)
mem.add_bulk_idempotent(text, None, cat, key)
mem.revisions_page(None, "revised", 20, None, None)
mem.list_all_images(None, None)              // = iter_images, collected

list_all_imagesiter_images 라는 이름으로도 나갑니다. 다른 두 SDK 가 쓰는 이름이라, 그 문서를 보고 온 독자가 먼저 치는 것이 그쪽입니다.