<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Waslo</title>
    <description>The latest articles on DEV Community by Waslo (@waslo).</description>
    <link>https://dev.to/waslo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4192398%2F2d9e9a23-1c5c-4a35-a2a5-b12a755a129c.png</url>
      <title>DEV Community: Waslo</title>
      <link>https://dev.to/waslo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/waslo"/>
    <language>en</language>
    <item>
      <title>Add an AI agent that remembers your users, with one REST call</title>
      <dc:creator>Waslo</dc:creator>
      <pubDate>Mon, 19 Oct 2026 10:16:02 +0000</pubDate>
      <link>https://dev.to/waslo/add-an-ai-agent-that-remembers-your-users-with-one-rest-call-3mdc</link>
      <guid>https://dev.to/waslo/add-an-ai-agent-that-remembers-your-users-with-one-rest-call-3mdc</guid>
      <description>&lt;p&gt;Most "add AI to your support" tutorials stop at a chat completion. The model answers, and then you discover the real work: remembering who the user is between messages, answering from &lt;em&gt;your&lt;/em&gt; documents instead of the internet, knowing when a message is a hot lead, booking a slot without double-booking, and not charging twice when your client retries a request.&lt;/p&gt;

&lt;p&gt;We built all of that for our own product, an AI agent that answers customers on WhatsApp, Instagram, Messenger, Telegram, email and website chat. The same engine is available as a REST API, so you can run it inside your own app without any of those channels. This post shows what one call looks like and what comes back.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one call
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.waslo.io/v1/agent/reply &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wsk_live_..."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Idempotency-Key: 8f1c2e40-msg-001"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "message": "Do you have a morning slot on Thursday?",
    "userId": "customer_8842",
    "tools": ["calendar"]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three fields matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;message&lt;/code&gt;&lt;/strong&gt;: what your user typed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;userId&lt;/code&gt;&lt;/strong&gt;: any stable id from your system. It is how the agent remembers a person. Send the same id tomorrow and the conversation continues where it left off; send a new id and it starts fresh. There is no session object to create or store.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tools&lt;/code&gt;&lt;/strong&gt;: what the agent may do on this turn. &lt;code&gt;calendar&lt;/code&gt; lets it check real availability and book; &lt;code&gt;catalog&lt;/code&gt; lets it look up and send products. Leave it out and the agent only talks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What comes back
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reply"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Yes, Thursday at 9:30 or 11:00 is free. Which one suits you?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"classification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HOT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"citations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"documentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"opening-hours.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"preview"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Thursday 09:00–13:00..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"usage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"credits_charged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"credits_remaining"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;597&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"request_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"req_..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;reply&lt;/code&gt;&lt;/strong&gt; is ready to show. It already used the user's history and your knowledge base.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;classification&lt;/code&gt;&lt;/strong&gt; scores the lead &lt;code&gt;HOT&lt;/code&gt;, &lt;code&gt;WARM&lt;/code&gt; or &lt;code&gt;COLD&lt;/code&gt; on every turn (or with your own stage names, if you set them), so your app can route a hot conversation to a person straight away. If you define your own topic labels, a &lt;code&gt;topic&lt;/code&gt; field comes back too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;citations&lt;/code&gt;&lt;/strong&gt; tell you which of your documents the answer came from. That is useful for debugging and for showing users where an answer came from.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;usage&lt;/code&gt;&lt;/strong&gt; tells you what the call cost and what is left. No surprise invoices.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Teaching it about your business
&lt;/h2&gt;

&lt;p&gt;The agent answers from documents you upload. That can be price lists, FAQs, policies or product sheets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.waslo.io/v1/kb/documents &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wsk_live_..."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s2"&gt;"file=@pricing-faq.pdf"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s2"&gt;"name=Pricing FAQ"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;GET /v1/kb/documents&lt;/code&gt; lists them and &lt;code&gt;DELETE /v1/kb/documents/:id&lt;/code&gt; removes one. The same workspace is visible in the Waslo dashboard, so a non-technical teammate can add documents there and your code sees them immediately.&lt;/p&gt;

&lt;p&gt;If you sell products, &lt;code&gt;/v1/catalog&lt;/code&gt; lets you list, create, update and delete items in the catalogue the agent sells from, including photos and PDFs it can send.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory you can inspect and delete
&lt;/h2&gt;

&lt;p&gt;Every remembered fact about a user is readable and deletable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# what does the agent remember about this user?&lt;/span&gt;
curl https://api.waslo.io/v1/memory/customer_8842 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wsk_live_..."&lt;/span&gt;

&lt;span class="c"&gt;# forget them (privacy request, test cleanup, account deletion)&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; DELETE https://api.waslo.io/v1/memory/customer_8842 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wsk_live_..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Being able to delete memory with one call matters more than it sounds. It is what you need when a user asks you to forget them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Controlling behaviour
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;PUT /v1/config&lt;/code&gt; sets the agent's system prompt and behaviour persistently. You can also pass &lt;code&gt;systemPrompt&lt;/code&gt; on a single request with &lt;code&gt;promptMode: "append"&lt;/code&gt; or &lt;code&gt;"replace"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;replyLanguage&lt;/code&gt; is the setting people ask about most. &lt;code&gt;"auto"&lt;/code&gt; answers each user in the language they wrote in. A code like &lt;code&gt;"es"&lt;/code&gt; or &lt;code&gt;"ar"&lt;/code&gt; always answers in that language.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boring parts that save you a weekend
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Idempotency.&lt;/strong&gt; Send an &lt;code&gt;Idempotency-Key&lt;/code&gt; header and a retried request within 24 hours returns the original response instead of generating, and billing, a second reply.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spend cap.&lt;/strong&gt; Set a monthly cap and requests are refused with &lt;code&gt;spend_cap_reached&lt;/code&gt; once you hit it, so a runaway loop stops at your cap instead of draining your balance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scoped keys.&lt;/strong&gt; Keys carry scopes (&lt;code&gt;agent&lt;/code&gt;, &lt;code&gt;memory&lt;/code&gt;, &lt;code&gt;kb&lt;/code&gt;, &lt;code&gt;catalog&lt;/code&gt;, &lt;code&gt;config&lt;/code&gt;, &lt;code&gt;usage&lt;/code&gt;) and are stored hashed. Keep them server-side; never ship one in a browser or mobile bundle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One error envelope.&lt;/strong&gt; Every error has the same shape and a &lt;code&gt;request_id&lt;/code&gt;. &lt;code&gt;402&lt;/code&gt; means out of credits or capped, &lt;code&gt;403&lt;/code&gt; means the key lacks a scope, and &lt;code&gt;429&lt;/code&gt; means slow down (the header tells you for how long).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Media in.&lt;/strong&gt; Replies can read images, audio, video and PDFs sent by the user, and can answer with a voice note.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it costs
&lt;/h2&gt;

&lt;p&gt;The API bills credits per call: 2 for a text reply, 3 when it used a tool, 5 when it read media, plus 2 for voice output. A standalone classification is 1 credit. New accounts start with 75 free credits, enough to build and test an integration before paying anything. API credit packs start at $49 for 5,000 credits.&lt;/p&gt;

&lt;h2&gt;
  
  
  When you should not use this
&lt;/h2&gt;

&lt;p&gt;If all you want is an AI agent on WhatsApp or Instagram, you don't need the API. Connecting the channel in the dashboard takes a few minutes. The API is for when the conversation happens &lt;strong&gt;inside your product&lt;/strong&gt;: a SaaS that wants an assistant for its own customers, an agency running agents for clients, or a team that wants lead scoring and knowledge-base retrieval without building them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Create a key in the developer portal at &lt;a href="https://waslo.io/developers" rel="noopener noreferrer"&gt;waslo.io/developers&lt;/a&gt;. The full reference is in the &lt;a href="https://waslo.io/docs/agent-api" rel="noopener noreferrer"&gt;Agent API docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you build something with it, I'd like to hear what broke first. That's usually the most useful feedback we get.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
