<?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: Ruben</title>
    <description>The latest articles on DEV Community by Ruben (@inside_dc_pulse).</description>
    <link>https://dev.to/inside_dc_pulse</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%2F4010119%2F56d498f7-9e46-4588-9fac-eea486fc5ee2.png</url>
      <title>DEV Community: Ruben</title>
      <link>https://dev.to/inside_dc_pulse</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/inside_dc_pulse"/>
    <language>en</language>
    <item>
      <title>I published an npm SDK for my free WhatsApp API (TypeScript, zero deps)</title>
      <dc:creator>Ruben</dc:creator>
      <pubDate>Sun, 05 Jul 2026 14:58:43 +0000</pubDate>
      <link>https://dev.to/inside_dc_pulse/i-published-an-npm-sdk-for-my-free-whatsapp-api-typescript-zero-deps-2flo</link>
      <guid>https://dev.to/inside_dc_pulse/i-published-an-npm-sdk-for-my-free-whatsapp-api-typescript-zero-deps-2flo</guid>
      <description>&lt;h2&gt;
  
  
  What we just shipped
&lt;/h2&gt;

&lt;p&gt;After the &lt;a href="https://whatsusernames.link/blog/api-whatsapp-link-gratis" rel="noopener noreferrer"&gt;free WhatsApp link API&lt;/a&gt; and the &lt;a href="https://whatsusernames.link/blog/api-whatsapp-business-bsuid" rel="noopener noreferrer"&gt;Business Platform (BSUID) API&lt;/a&gt;, one piece was missing: a ready-to-install client, so you don't have to hand-write &lt;code&gt;fetch&lt;/code&gt; calls and error parsing every time you use the API from TypeScript or JavaScript.&lt;/p&gt;

&lt;p&gt;It's called &lt;strong&gt;&lt;a href="https://www.npmjs.com/package/whatsusernames-sdk" rel="noopener noreferrer"&gt;whatsusernames-sdk&lt;/a&gt;&lt;/strong&gt; — open source (MIT), zero runtime dependencies, covering all 12 endpoints: the 7 link/QR/validation ones and the 5 Business Platform ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install and use
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;whatsusernames-sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;whatsusernames-sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shortLink&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;usernameLink&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;joao.silva&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;qr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;qr&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;joao.silva&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// qr.body is a Uint8Array, qr.contentType is "image/svg+xml"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And for the Business Platform:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;business&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bsuid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;bsuid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;US.13491208655302741918&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// { countryCode: "US", id: "13491208655302741918", isParent: false }&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;business&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;joao.silva&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;normalized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;business&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webhook&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rawCloudApiWebhookPayload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why an SDK, not just the REST API
&lt;/h2&gt;

&lt;p&gt;The REST API itself is already free and keyless — any &lt;code&gt;fetch&lt;/code&gt; call reaches it. The SDK exists for anyone who wants:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ready-made TypeScript types&lt;/strong&gt; for all 12 responses (&lt;code&gt;UsernameLinkResult&lt;/code&gt;, &lt;code&gt;ResolvedContact&lt;/code&gt;, &lt;code&gt;NormalizedWebhook&lt;/code&gt;, and more), no hand-written interfaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent errors&lt;/strong&gt;: any non-200 response throws &lt;code&gt;WhatsUsernamesApiError&lt;/code&gt; with &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;code&lt;/code&gt;, and &lt;code&gt;message&lt;/code&gt; — one &lt;code&gt;catch&lt;/code&gt; covers everything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero dependencies&lt;/strong&gt;: uses only native &lt;code&gt;fetch&lt;/code&gt;, works on Node 18+, browsers, and edge runtimes, without bloating your &lt;code&gt;node_modules&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ESM and CommonJS&lt;/strong&gt;: &lt;code&gt;import&lt;/code&gt; or &lt;code&gt;require()&lt;/code&gt;, both work with no extra config.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Self-hosted
&lt;/h2&gt;

&lt;p&gt;Running your own instance (or testing against &lt;code&gt;localhost&lt;/code&gt;)? Point the client there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:3000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Open source
&lt;/h2&gt;

&lt;p&gt;The SDK is on GitHub, MIT licensed: &lt;a href="https://github.com/insidedcpulse-spec/whatsusernames-sdk" rel="noopener noreferrer"&gt;github.com/insidedcpulse-spec/whatsusernames-sdk&lt;/a&gt;. Issues and PRs welcome — it's the first concrete step toward making WhatsUsernames.link an open platform for developers, not just a closed product.&lt;/p&gt;

&lt;p&gt;Full docs at &lt;a href="https://whatsusernames.link/developers" rel="noopener noreferrer"&gt;whatsusernames.link/developers&lt;/a&gt; and the &lt;a href="https://whatsusernames.link/api/v1/openapi.json" rel="noopener noreferrer"&gt;OpenAPI 3.1 specification&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>api</category>
      <category>npm</category>
      <category>typescript</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I added BSUID and business-username support to my free WhatsApp API</title>
      <dc:creator>Ruben</dc:creator>
      <pubDate>Sun, 05 Jul 2026 13:05:46 +0000</pubDate>
      <link>https://dev.to/inside_dc_pulse/i-added-bsuid-and-business-username-support-to-my-free-whatsapp-api-320g</link>
      <guid>https://dev.to/inside_dc_pulse/i-added-bsuid-and-business-username-support-to-my-free-whatsapp-api-320g</guid>
      <description>&lt;h2&gt;
  
  
  What we just shipped
&lt;/h2&gt;

&lt;p&gt;After launching the &lt;a href="https://whatsusernames.link/blog/api-whatsapp-link-gratis" rel="noopener noreferrer"&gt;free WhatsApp link API&lt;/a&gt;, we expanded to the other side of WhatsApp: the &lt;strong&gt;Business Platform / Cloud API&lt;/strong&gt;. Five new endpoints, all &lt;code&gt;POST&lt;/code&gt; with a JSON body, for anyone building integrations, bots, or CRMs on top of Meta's official Cloud API.&lt;/p&gt;

&lt;p&gt;This API solves a concrete problem: the Cloud API recently introduced &lt;strong&gt;BSUID&lt;/strong&gt; (Business-Scoped User ID) and &lt;strong&gt;business usernames&lt;/strong&gt;, and both now show up in message and status webhooks — but with no ready-made tooling to validate, parse, or normalize that data. That's the gap we filled.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a BSUID is
&lt;/h2&gt;

&lt;p&gt;A BSUID is a unique user identifier, built so you can message someone without knowing their phone number. Format: ISO 3166 country code + period + up to 128 alphanumeric characters — for example &lt;code&gt;US.13491208655302741918&lt;/code&gt;. Managed accounts with multiple eligible portfolios use a "parent" variant: &lt;code&gt;US.ENT.11815799212886844830&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;BSUIDs are &lt;strong&gt;scoped to a portfolio&lt;/strong&gt;: only business phone numbers inside the same portfolio can use a given BSUID. It's opaque — not meant to be split apart for use in requests — but sometimes you need to parse it for debugging, logging, or an internal dashboard. That's what the first two endpoints are for.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five endpoints
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /api/v1/business/bsuid/validate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Checks whether a BSUID has the correct format&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /api/v1/business/bsuid/parse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Extracts country code, id, and whether it's a "parent" account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /api/v1/business/username/validate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Validates the structure of a business username&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /api/v1/business/contact/resolve&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Resolves a contact from bsuid, phone, or username — always the same shape&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /api/v1/business/webhook/normalize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Normalizes a raw Cloud API webhook payload into consistent events&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Same guarantees as the original API: no API key, no signup, CORS enabled, 60 requests per minute per IP, errors always JSON with a stable code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick examples
&lt;/h2&gt;

&lt;p&gt;Parsing a BSUID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://whatsusernames.link/api/v1/business/bsuid/parse"&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;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"bsuid": "US.13491208655302741918"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&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;"countryCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"US"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"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;"13491208655302741918"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"isParent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;p&gt;Resolving a contact from a username (or a phone, or a bsuid — always exactly one of the three):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://whatsusernames.link/api/v1/business/contact/resolve"&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;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"username": "joao.silva"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normalizing a webhook received straight from the Cloud API, without writing your own payload parser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://whatsusernames.link/api/v1/business/webhook/normalize"&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;-d&lt;/span&gt; @webhook-payload.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why normalizing webhooks matters
&lt;/h2&gt;

&lt;p&gt;The Cloud API exposes the BSUID and username in slightly different shapes depending on webhook type: incoming messages carry &lt;code&gt;from_user_id&lt;/code&gt; and a &lt;code&gt;contacts&lt;/code&gt; block; status updates carry &lt;code&gt;recipient_user_id&lt;/code&gt;; failures omit the &lt;code&gt;contacts&lt;/code&gt; block entirely. The &lt;code&gt;webhook/normalize&lt;/code&gt; endpoint absorbs that variation and always returns the same shape — &lt;code&gt;kind&lt;/code&gt;, &lt;code&gt;bsuid&lt;/code&gt;, &lt;code&gt;phone&lt;/code&gt;, &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;displayName&lt;/code&gt;, &lt;code&gt;raw&lt;/code&gt; — so your webhook handler doesn't need to know every case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full documentation
&lt;/h2&gt;

&lt;p&gt;All five endpoints are documented at &lt;a href="https://whatsusernames.link/developers" rel="noopener noreferrer"&gt;whatsusernames.link/developers&lt;/a&gt;, with JSON body examples for each, and in the &lt;a href="https://whatsusernames.link/api/v1/openapi.json" rel="noopener noreferrer"&gt;OpenAPI 3.1 specification&lt;/a&gt; — now twelve paths total, including the new schemas (&lt;code&gt;BsuidValidation&lt;/code&gt;, &lt;code&gt;BsuidParse&lt;/code&gt;, &lt;code&gt;ResolvedContact&lt;/code&gt;, &lt;code&gt;NormalizedWebhook&lt;/code&gt;, and more).&lt;/p&gt;

&lt;p&gt;If you're building on top of the Cloud API and this saves you work, I'd love to hear about it.&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>showdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>I built a free, keyless API for generating WhatsApp links and QR codes</title>
      <dc:creator>Ruben</dc:creator>
      <pubDate>Sun, 05 Jul 2026 07:15:29 +0000</pubDate>
      <link>https://dev.to/inside_dc_pulse/i-built-a-free-keyless-api-for-generating-whatsapp-links-and-qr-codes-3j3o</link>
      <guid>https://dev.to/inside_dc_pulse/i-built-a-free-keyless-api-for-generating-whatsapp-links-and-qr-codes-3j3o</guid>
      <description>&lt;p&gt;I run &lt;a href="https://whatsusernames.link" rel="noopener noreferrer"&gt;WhatsUsernames.link&lt;/a&gt;, a free WhatsApp link + QR code generator. This week I shipped everything the site does as a &lt;strong&gt;public REST API&lt;/strong&gt; — and made three decisions I wish more small APIs made:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No API key, no signup.&lt;/strong&gt; Call the endpoint, get the response. No dashboard, no token, no confirmation email.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free&lt;/strong&gt;, with per-IP rate limits generous enough for real use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CORS enabled on every endpoint&lt;/strong&gt; — call it straight from the browser on a static site, no backend needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The endpoints
&lt;/h2&gt;

&lt;p&gt;Base URL: &lt;code&gt;https://whatsusernames.link&lt;/code&gt;. Everything is GET.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/username-link&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;WhatsApp link + short link from a username&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/phone-link&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Official wa.me link from a phone number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/validate/username&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Validates username structure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/validate/key&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Validates a Username Key (4-8 letters/numbers)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/validate/phone&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Validates an international phone number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/qr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;QR code (PNG or SVG), custom size and colors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/openapi.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAPI 3.1 spec of the API itself&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://whatsusernames.link/api/v1/username-link?username=joao.silva"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"joao.silva"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"link"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://wa.me/joao.silva"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"shortLink"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://whatsusernames.link/joao.silva"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"notice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"As of 2026-07-04, wa.me/&amp;lt;username&amp;gt; links do not yet open a chat for most accounts..."&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;p&gt;From the browser, no library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://whatsusernames.link/api/v1/phone-link?phone=351912345678&amp;amp;text=hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// https://wa.me/351912345678?text=hello&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A WhatsApp-green QR code as SVG, ready to drop into an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://whatsusernames.link/api/v1/qr?username=joao.silva&amp;amp;format=svg&amp;amp;color=25d366
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Design decisions that might interest you
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stable error codes.&lt;/strong&gt; Errors are always JSON with a machine-readable code that never changes within v1:&lt;br&gt;
&lt;/p&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;"error"&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;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"username_length"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Username must be 3-35 characters."&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Honest responses about a moving target.&lt;/strong&gt; WhatsApp's &lt;code&gt;@username&lt;/code&gt; feature is in a phased regional rollout, and &lt;code&gt;wa.me/&amp;lt;username&amp;gt;&lt;/code&gt; links don't open a chat for most accounts yet (I verified this empirically — server-side redirects and real-device taps). Instead of pretending otherwise, the &lt;code&gt;username-link&lt;/code&gt; response includes a &lt;code&gt;notice&lt;/code&gt; field with the current status, so your app is never caught off guard. Phone-number links (&lt;code&gt;wa.me/&amp;lt;number&amp;gt;&lt;/code&gt;) are officially documented and work for everyone today.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anti-phishing QR restriction.&lt;/strong&gt; The QR endpoint only encodes wa.me links built from a validated username or phone number — never arbitrary content. You can't use it to mint QR codes pointing anywhere else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rate limiting that fails open.&lt;/strong&gt; 60 req/min per IP for JSON, 20/min for QR (sliding window via Upstash Redis). Responses carry &lt;code&gt;X-RateLimit-*&lt;/code&gt; headers, and 429s include &lt;code&gt;Retry-After&lt;/code&gt;. If Redis is ever slow or down, requests proceed — availability over strictness for a free utility API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Machine-readable spec.&lt;/strong&gt; The &lt;a href="https://whatsusernames.link/api/v1/openapi.json" rel="noopener noreferrer"&gt;OpenAPI 3.1 document&lt;/a&gt; means you can codegen a client — or just point an AI agent at it and it knows how to build WhatsApp links correctly. There's also an &lt;code&gt;llms.txt&lt;/code&gt; on the site for the same reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  What people are building with it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Landing pages that generate contact links dynamically, no backend&lt;/li&gt;
&lt;li&gt;CRM/internal tools validating numbers before outreach campaigns&lt;/li&gt;
&lt;li&gt;Print-material generators needing brand-colored SVG QR codes&lt;/li&gt;
&lt;li&gt;n8n/Zapier/scripts building WhatsApp links on the fly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docs live at &lt;a href="https://whatsusernames.link/developers" rel="noopener noreferrer"&gt;whatsusernames.link/developers&lt;/a&gt;. Stack, for the curious: Next.js 15 route handlers on Vercel, Upstash Redis for rate limiting, &lt;code&gt;qrcode&lt;/code&gt; for server-side QR generation, all TDD'd with Vitest.&lt;/p&gt;

&lt;p&gt;If you build something with it, I'd genuinely love to hear about it in the comments.&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>showdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>wa.me/username doesn't work yet — I verified it two ways</title>
      <dc:creator>Ruben</dc:creator>
      <pubDate>Sat, 04 Jul 2026 12:36:04 +0000</pubDate>
      <link>https://dev.to/inside_dc_pulse/wameusername-doesnt-work-yet-i-verified-it-two-ways-20fn</link>
      <guid>https://dev.to/inside_dc_pulse/wameusername-doesnt-work-yet-i-verified-it-two-ways-20fn</guid>
      <description>&lt;h1&gt;
  
  
  &lt;code&gt;wa.me/username&lt;/code&gt; doesn't work yet — I verified it two ways, here's what to use instead
&lt;/h1&gt;

&lt;p&gt;If you've tried to build a "share my WhatsApp" link using a &lt;code&gt;@username&lt;/code&gt; instead of a phone number, you've probably assumed &lt;code&gt;wa.me/username&lt;/code&gt; (or &lt;code&gt;wa.me/u/username&lt;/code&gt;) works the same way &lt;code&gt;wa.me/15551234567&lt;/code&gt; does. It doesn't — at least not yet, as of writing this.&lt;/p&gt;

&lt;p&gt;I wanted a definitive answer instead of trusting blog posts or AI chatbot answers (more on that below), so I tested it two independent ways.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test 1: server response
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; https://wa.me/u/some_real_reserved_username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every username path I tried — including a certified-real, currently-reserved username — 302-redirects to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api.whatsapp.com/resolve/?deeplink=...&amp;amp;not_found=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare that to the phone-number path, which redirects to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api.whatsapp.com/send/?phone=...&amp;amp;type=phone_number
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different resolver, different outcome. The server-side route for usernames exists, but every lookup currently resolves as "not found" — even for real, live usernames.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test 2: real device
&lt;/h2&gt;

&lt;p&gt;Server response alone doesn't rule out Universal Links / App Links intercepting the URL client-side before it ever hits a server — &lt;code&gt;curl&lt;/code&gt; can't see that. So I also opened all three link variants (&lt;code&gt;wa.me/username&lt;/code&gt;, &lt;code&gt;wa.me/u/username&lt;/code&gt;, and a redirect through my own domain) on a real phone with WhatsApp installed.&lt;/p&gt;

&lt;p&gt;None of them opened a chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters if you're building anything around WhatsApp usernames
&lt;/h2&gt;

&lt;p&gt;WhatsApp has rolled out &lt;code&gt;@username&lt;/code&gt; handles as a real, user-facing feature — but it hasn't published a public deep-link spec for opening a chat from one, the way it has for phone numbers for years. If you're building a tool, a profile page, a business card generator, anything that assumes &lt;code&gt;wa.me/username&lt;/code&gt; "just works," it doesn't, for anyone.&lt;/p&gt;

&lt;p&gt;One more data point: I asked Meta AI directly about this, with the counter-evidence above in hand. It kept asserting the link already works and didn't engage with the evidence when pushed. That's a useful reminder that chatbot answers about a fast-moving platform feature can be reciting stale/roadmap content rather than reflecting the live system — verify claims like this yourself before shipping something that depends on them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually works today
&lt;/h2&gt;

&lt;p&gt;Until WhatsApp ships the real format, there are two things that work with zero surprises:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Phone number link&lt;/strong&gt; — &lt;code&gt;wa.me/&amp;lt;countrycode&amp;gt;&amp;lt;number&amp;gt;&lt;/code&gt; still opens a chat directly, no manual step, no ambiguity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Username as a manual lookup&lt;/strong&gt; — share the &lt;code&gt;@username&lt;/code&gt; (plus the "Username Key" if the person set one, which disambiguates people who share a username) as text or a QR code, with an explicit "find me by username" instruction. One extra manual step, but it doesn't expose a phone number.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I built a small free tool that generates both — link + downloadable QR — and is explicit on-page about which one actually works right now instead of pretending the username link is live: &lt;a href="https://whatsusernames.link" rel="noopener noreferrer"&gt;whatsusernames.link&lt;/a&gt;. No signup, nothing stored server-side.&lt;/p&gt;

&lt;p&gt;If anyone finds a case where &lt;code&gt;wa.me/username&lt;/code&gt; &lt;em&gt;does&lt;/em&gt; resolve for them, I'd genuinely like to know — that would mean a staged rollout is underway.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>showdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I built a free event-sourced world model to stop multiple LLM agents from corrupting shared state</title>
      <dc:creator>Ruben</dc:creator>
      <pubDate>Tue, 30 Jun 2026 21:34:49 +0000</pubDate>
      <link>https://dev.to/inside_dc_pulse/how-i-built-a-free-event-sourced-world-model-to-stop-multiple-llm-agents-from-corrupting-shared-10dg</link>
      <guid>https://dev.to/inside_dc_pulse/how-i-built-a-free-event-sourced-world-model-to-stop-multiple-llm-agents-from-corrupting-shared-10dg</guid>
      <description>&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;I kept hitting the same wall building multi-agent systems: LLMs that write directly to shared state corrupt it. They hallucinate field values, conflict with each other, produce structurally invalid data. The more agents you add, the worse it gets — corruption compounds.&lt;/p&gt;

&lt;p&gt;Every framework I looked at assumed agents could be trusted to write directly. They cannot.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution: propose-validate-commit
&lt;/h2&gt;

&lt;p&gt;Agents &lt;strong&gt;never write directly&lt;/strong&gt;. They submit &lt;em&gt;visions&lt;/em&gt; — batches of proposed state-mutation ops. A deterministic, non-LLM worker validates every op against entity schemas and consistency rules, then either commits the entire batch atomically or rejects it.&lt;/p&gt;

&lt;p&gt;One bad op → entire vision rejected. No partial commits. No corruption.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent → POST /api/v1/world/vision → Validator → world_state (PostgreSQL)
                                         ↓
                                   knowledge graph (graph_nodes / graph_edges)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every accepted event is also projected into a causal knowledge graph in the same transaction — automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://insidedcpulse.com" rel="noopener noreferrer"&gt;InsideDCPulse&lt;/a&gt;&lt;/strong&gt; is an open-source, production-grade implementation of this pattern, live and free to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;FastAPI + PostgreSQL (event store + materialized &lt;code&gt;world_state&lt;/code&gt;) + Redis + nginx&lt;/li&gt;
&lt;li&gt;Prometheus + Grafana for observability&lt;/li&gt;
&lt;li&gt;Self-hostable via &lt;code&gt;docker compose up&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What is running live
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MCP server&lt;/strong&gt; — 11 tools at &lt;code&gt;https://insidedcpulse.com/mcp/&lt;/code&gt;, registered on &lt;a href="https://registry.modelcontextprotocol.io" rel="noopener noreferrer"&gt;MCP Registry&lt;/a&gt; and &lt;a href="https://smithery.ai" rel="noopener noreferrer"&gt;Smithery&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;7 autonomous LLM agents&lt;/strong&gt; running on hourly cron, continuously evolving the world state:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sre-agent&lt;/code&gt; (:05) — team/incident management&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;threat-intel-agent&lt;/code&gt; (:15) — CISA KEV CVE feed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;deploy-agent&lt;/code&gt; (:20) — deployments/services&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;agent-architect&lt;/code&gt; (:30) — A2A protocol proposals from arXiv&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;alert-agent&lt;/code&gt; (:35) — alerts/regions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ai-research-agent&lt;/code&gt; (:40) — AI systems arXiv papers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;research-agent&lt;/code&gt; (:50) — SRE/ops arXiv papers&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-agent reputation&lt;/strong&gt; (0–1): drops on rejected proposals, eventually blocks persistent bad actors&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The 11 MCP tools
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_world_state&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Current materialized world state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_world_memory&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Paginated event audit log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;simulate_action&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Dry-run ops, nothing persisted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;evaluate_vision&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Score a vision against validation rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;propose_vision&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Queue a vision for validation + commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;register_agent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Self-register, get &lt;code&gt;agent_id&lt;/code&gt; + &lt;code&gt;api_key&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_graph_node&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Knowledge-graph node + all edges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_graph_neighbors&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Immediate neighbors by edge type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;find_related_entities&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shortest path between two nodes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_event_timeline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Chronological event timeline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_causal_chain&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Walk CAUSED edges upstream/downstream&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;No registration needed — shared demo key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://insidedcpulse.com/api/v1/world/state &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: j9zRmojp8EqBSLaRZwJatcRQa0HwcXK9-sqY70eIxtY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or connect via MCP:&lt;br&gt;
&lt;/p&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;"mcpServers"&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;"insidedcpulse"&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;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://insidedcpulse.com/mcp/"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Get your own &lt;code&gt;agent_id&lt;/code&gt; + &lt;code&gt;api_key&lt;/code&gt; (no approval, no email):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://insidedcpulse.com/api/v1/agents/register-self &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;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "my-agent"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The causal knowledge graph
&lt;/h2&gt;

&lt;p&gt;Every accepted event automatically creates nodes and edges in a causal knowledge graph — no extra work from agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Causal rules&lt;/strong&gt; (heuristic, with confidence 0–1):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;R1&lt;/strong&gt;: explicit cross-entity references in op values → confidence 1.0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;R2&lt;/strong&gt;: alert-firing events precede incident-open events (recency-weighted)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;R3&lt;/strong&gt;: deployment events precede service degradation events (recency-weighted)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Query it:&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;# Causal chain from an incident&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://insidedcpulse.com/api/v1/graph/causal-chain?node_id=incident.inc1&amp;amp;direction=upstream"&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;"X-API-Key: j9zRmojp8EqBSLaRZwJatcRQa0HwcXK9-sqY70eIxtY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Entity schemas (validated deterministically)
&lt;/h2&gt;

&lt;p&gt;All keys follow &lt;code&gt;&amp;lt;entity&amp;gt;.&amp;lt;id&amp;gt;.&amp;lt;field&amp;gt;&lt;/code&gt;. Current supported types: &lt;code&gt;region&lt;/code&gt;, &lt;code&gt;service&lt;/code&gt;, &lt;code&gt;incident&lt;/code&gt;, &lt;code&gt;deployment&lt;/code&gt;, &lt;code&gt;team&lt;/code&gt;, &lt;code&gt;alert&lt;/code&gt;, &lt;code&gt;research&lt;/code&gt;, &lt;code&gt;finding&lt;/code&gt;, &lt;code&gt;vulnerability&lt;/code&gt;, &lt;code&gt;proposal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Validation is &lt;strong&gt;all-or-nothing&lt;/strong&gt;: one inconsistent op in a vision rejects the entire batch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Live: &lt;a href="https://insidedcpulse.com" rel="noopener noreferrer"&gt;https://insidedcpulse.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MCP endpoint: &lt;a href="https://insidedcpulse.com/mcp/" rel="noopener noreferrer"&gt;https://insidedcpulse.com/mcp/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Interactive API docs: &lt;a href="https://insidedcpulse.com/docs" rel="noopener noreferrer"&gt;https://insidedcpulse.com/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source (MIT): &lt;a href="https://github.com/insidedcpulse-spec/insidedcpulse-world-model" rel="noopener noreferrer"&gt;https://github.com/insidedcpulse-spec/insidedcpulse-world-model&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Context for AI systems: &lt;a href="https://insidedcpulse.com/llms.txt" rel="noopener noreferrer"&gt;https://insidedcpulse.com/llms.txt&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Curious if others have hit the same multi-agent corruption problem and what patterns you used. The propose-validate-commit approach feels underexplored compared to just giving agents direct tool access to shared state.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>mcp</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
