<?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: ambolt</title>
    <description>The latest articles on DEV Community by ambolt (@ambolt).</description>
    <link>https://dev.to/ambolt</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%2F4160113%2Ffd6078f9-a9a8-421c-a15d-fd6d6749e0f9.png</url>
      <title>DEV Community: ambolt</title>
      <link>https://dev.to/ambolt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ambolt"/>
    <language>en</language>
    <item>
      <title>Check SSL certificates and domain expiry for a whole list of domains</title>
      <dc:creator>ambolt</dc:creator>
      <pubDate>Sun, 04 Oct 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/ambolt/check-ssl-certificates-and-domain-expiry-for-a-whole-list-of-domains-35b9</link>
      <guid>https://dev.to/ambolt/check-ssl-certificates-and-domain-expiry-for-a-whole-list-of-domains-35b9</guid>
      <description>&lt;p&gt;An expired certificate or a lapsed domain takes a site down at the worst time, and it is almost always avoidable. If you look after more than a handful of domains, the useful question is not "what are the details for each?" but "which ones need attention this month?".&lt;/p&gt;

&lt;h2&gt;
  
  
  One request
&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://api.ambolt.dev/v1/domain-ssl-sweep?domain=sitemaps.org&amp;amp;warnDays=30&amp;amp;free=1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The answer has a summary and one result per domain:&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;"checked"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"readable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"flagged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"warnDays"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"results"&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;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sitemaps.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ssl"&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;"issuer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Microsoft Corporation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"notAfter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-12-07T04:56:13.000Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"trusted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"daysLeft"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"expired"&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;span class="nl"&gt;"registration"&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;"registered"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"expiresAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2027-08-12T23:51:55Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"daysToExpiry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;313&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"registrar"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MarkMonitor Inc."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nameservers"&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="s2"&gt;"ns3-02.azure-dns.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ns1-02.azure-dns.com"&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;"flags"&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="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;Recorded 2026-10-03; fields trimmed. &lt;code&gt;flags&lt;/code&gt; stays empty until something expires inside the window you set with &lt;code&gt;warnDays&lt;/code&gt;, so a scheduled job only has to look at &lt;code&gt;flagged&lt;/code&gt; and the flags.&lt;/p&gt;

&lt;h2&gt;
  
  
  A whole list
&lt;/h2&gt;

&lt;p&gt;Pass &lt;code&gt;domains&lt;/code&gt; with a list instead of &lt;code&gt;domain&lt;/code&gt;, or run the Apify Actor on a schedule and send the flagged rows to your alerting. You are billed per domain checked; a domain that cannot be reached is listed with the reason and not charged.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does not return
&lt;/h2&gt;

&lt;p&gt;Registrant details are never returned. SSL data comes from the certificate the server presents, and domain data from the registry's RDAP service, so a registry that does not publish an expiry date shows no date rather than a guess.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://ambolt.dev/catalog" rel="noopener noreferrer"&gt;catalog&lt;/a&gt; for the tool and its price.&lt;/p&gt;

</description>
      <category>api</category>
      <category>devops</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>PDF and DOCX to Markdown and tables, without an LLM</title>
      <dc:creator>ambolt</dc:creator>
      <pubDate>Sat, 03 Oct 2026 17:46:48 +0000</pubDate>
      <link>https://dev.to/ambolt/pdf-and-docx-to-markdown-and-tables-without-an-llm-55jc</link>
      <guid>https://dev.to/ambolt/pdf-and-docx-to-markdown-and-tables-without-an-llm-55jc</guid>
      <description>&lt;p&gt;Language models can read documents, but they give a different answer on a different day and charge by the token. For invoices, reports and contracts that you process in volume, a deterministic parser is often the better tool: the same file gives the same output, and the price does not depend on how long the answer is.&lt;/p&gt;

&lt;p&gt;DocToJSON reads PDF and DOCX files from a public URL and returns three things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Markdown with structure
&lt;/h2&gt;

&lt;p&gt;Headings and lists become Markdown. Text keeps the order it has on the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tables as data
&lt;/h2&gt;

&lt;p&gt;Every table is returned as rows and as CSV, so it can go straight into a sheet or a database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Named fields
&lt;/h2&gt;

&lt;p&gt;You can pass hints such as &lt;code&gt;invoice number&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt; or &lt;code&gt;total&lt;/code&gt;. The tool finds a value by its label and returns it together with the line it came from. &lt;strong&gt;A field that is not found is reported as not found&lt;/strong&gt;, never guessed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scans
&lt;/h2&gt;

&lt;p&gt;Scanned pages are read with OCR (Tesseract). The output warns you on every page where OCR was used, because text from a scan deserves a second look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Merged cells, multi-line headers and unusual layouts can need checking.&lt;/li&gt;
&lt;li&gt;Image-only pages give nothing unless OCR can read them.&lt;/li&gt;
&lt;li&gt;Files are fetched for the run and not kept beyond the platform's own run storage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Price
&lt;/h2&gt;

&lt;p&gt;It is billed per page, with a higher price for OCR pages, and failed files are not charged. Run it as an Apify Actor; see the &lt;a href="https://ambolt.dev/doctojson" rel="noopener noreferrer"&gt;DocToJSON page&lt;/a&gt; for inputs, outputs and current prices.&lt;/p&gt;

</description>
      <category>api</category>
      <category>pdf</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>EU and UK public tenders in one schema, with OCDS export</title>
      <dc:creator>ambolt</dc:creator>
      <pubDate>Sat, 03 Oct 2026 17:16:41 +0000</pubDate>
      <link>https://dev.to/ambolt/eu-and-uk-public-tenders-in-one-schema-with-ocds-export-452l</link>
      <guid>https://dev.to/ambolt/eu-and-uk-public-tenders-in-one-schema-with-ocds-export-452l</guid>
      <description>&lt;p&gt;Public tenders are published in several places with different fields. If you track them for a product, a bid team or an agent, you end up writing a parser per source. TenderFeed returns one record shape for TED (the EU's journal) and the UK's Find a Tender service; SAM.gov can be added with your own key.&lt;/p&gt;

&lt;h2&gt;
  
  
  One request
&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://api.ambolt.dev/v1/tender-feed?keyword=software&amp;amp;country=DEU&amp;amp;free=1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The answer starts with what each source did, then the notices:&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;"publishedSince"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-09-26"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sources"&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;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"totalMatches"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;285&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"returned"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&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;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"uk-fts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"totalMatches"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"returned"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&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;"count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"notices"&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;"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;"ted:681459-2026"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Germany – IT services: consulting, software development, Internet and support – …"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"buyer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Robert Koch-Institut, Beschaffung"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"buyerCountry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cpv"&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="s2"&gt;"72000000"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"noticeType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"can-standard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"publishedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-10-02"&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://ted.europa.eu/en/notice/-/detail/681459-2026"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"licence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TED reuse: acknowledge source"&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;Recorded 2026-10-03; fields trimmed. Fields a notice does not publish, such as the deadline or the estimated value, come back as &lt;code&gt;null&lt;/code&gt; rather than guessed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can filter on
&lt;/h2&gt;

&lt;p&gt;Keyword, CPV prefix, country and a start date, so a scheduled run only sees what is new. An OCDS 1.1 release package is available if your system already speaks that format.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does not return
&lt;/h2&gt;

&lt;p&gt;Contact persons and e-mail addresses are removed, descriptions included. The feed does not return supplier or award data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to get it
&lt;/h2&gt;

&lt;p&gt;As an HTTP endpoint with x402 (per call), as an Apify Actor on a schedule, and as daily alerts in Telegram. Details, sources and licences are on the &lt;a href="https://ambolt.dev/tenderfeed" rel="noopener noreferrer"&gt;TenderFeed page&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>api</category>
      <category>opendata</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Resolve a company to its official record with one call</title>
      <dc:creator>ambolt</dc:creator>
      <pubDate>Sat, 03 Oct 2026 17:06:43 +0000</pubDate>
      <link>https://dev.to/ambolt/resolve-a-company-to-its-official-record-with-one-call-ck</link>
      <guid>https://dev.to/ambolt/resolve-a-company-to-its-official-record-with-one-call-ck</guid>
      <description>&lt;p&gt;A company name in a form field is not an identity. "Equinor" could be the listed group, a subsidiary or a toastmasters club that shares the address. Before an agent enriches, scores or onboards anything, it needs the legal entity from the official register.&lt;/p&gt;

&lt;h2&gt;
  
  
  One request
&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://api.ambolt.dev/v1/entity-resolve?query=Equinor%20ASA&amp;amp;country=NO&amp;amp;free=1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The answer is the best match plus candidates, each with the register it came from:&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;"matched"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bestMatch"&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;"country"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"registry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Brønnøysundregistrene (Enhetsregisteret)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"registryId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"923609016"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EQUINOR ASA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"legalForm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allmennaksjeselskap"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"incorporationDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1972-09-18"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lei"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OW6OFBNCKXC4US5C7523"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sourceUrl"&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://data.brreg.no/enhetsregisteret/api/enheter/923609016"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"licence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NLOD 2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"matchScore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"matchReason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"exact normalised name"&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;Recorded 2026-10-03; fields trimmed. The record carries &lt;code&gt;sourceUrl&lt;/code&gt; and &lt;code&gt;licence&lt;/code&gt;, so you can show where a fact came from and under which terms it may be reused.&lt;/p&gt;

&lt;h2&gt;
  
  
  What goes in
&lt;/h2&gt;

&lt;p&gt;A company name, a website domain, a registry number, an LEI or a VAT number. The tool works out which one it got.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it looks
&lt;/h2&gt;

&lt;p&gt;The official registers of Norway, Finland, Czechia, Slovakia, France and the United Kingdom, Poland by KRS number, and any company with an LEI worldwide through GLEIF. Each register is queried directly; each record names its licence.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does not do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It returns &lt;strong&gt;companies only&lt;/strong&gt;: no officers, directors or owners, and no sole traders (their names are personal data).&lt;/li&gt;
&lt;li&gt;Scores under 90 are suggestions. Check the linked source record before acting on them.&lt;/li&gt;
&lt;li&gt;It does not replace an official extract or your own KYB process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;As an MCP tool: add &lt;code&gt;https://api.ambolt.dev/mcp&lt;/code&gt; to your agent and call &lt;code&gt;entity_resolve&lt;/code&gt; (free, 30 requests a minute).&lt;/li&gt;
&lt;li&gt;As an HTTP endpoint: a price in the 402 answer, paid in USDC with an x402 client. Add &lt;code&gt;free=1&lt;/code&gt; for one free call per tool and IP address per day.&lt;/li&gt;
&lt;li&gt;As an Apify Actor with batches of up to 100.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See the &lt;a href="https://ambolt.dev/resolve" rel="noopener noreferrer"&gt;EntityResolve page&lt;/a&gt; for inputs, sources and prices.&lt;/p&gt;

</description>
      <category>api</category>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How an agent pays per call with x402</title>
      <dc:creator>ambolt</dc:creator>
      <pubDate>Sat, 03 Oct 2026 17:06:17 +0000</pubDate>
      <link>https://dev.to/ambolt/how-an-agent-pays-per-call-with-x402-73a</link>
      <guid>https://dev.to/ambolt/how-an-agent-pays-per-call-with-x402-73a</guid>
      <description>&lt;p&gt;Most data APIs want an account, a key and a monthly plan. An agent that needs one answer once does not want any of that. x402 turns the HTTP status code 402 ("Payment Required") into a payment step that a program can complete on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  The flow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The client sends a normal request, for example &lt;code&gt;GET /v1/iban-validate?iban=…&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Without payment the server answers &lt;strong&gt;402&lt;/strong&gt; with the price and the payment options in a header: network, asset (USDC) and the receiving address.&lt;/li&gt;
&lt;li&gt;The client signs a payment for exactly that amount and sends the request again with the payment attached.&lt;/li&gt;
&lt;li&gt;The server checks the payment, runs the call and returns the result. &lt;strong&gt;If the call fails, nothing is charged.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On Base and Polygon the client needs a little USDC and no gas token: the wallet signs an authorisation for the exact amount and a payment service submits it. Solana is also supported.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it without a wallet
&lt;/h2&gt;

&lt;p&gt;Add &lt;code&gt;free=1&lt;/code&gt; and the call is free once per tool and IP address per day:&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="s2"&gt;"https://api.ambolt.dev/v1/iban-validate?iban=DK5000400440116243&amp;amp;free=1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without it you get the 402 answer with the price, which shows the protocol without paying anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  From code
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.npmjs.com/package/@ambolt/sdk" rel="noopener noreferrer"&gt;JavaScript&lt;/a&gt; and &lt;a href="https://pypi.org/project/ambolt/" rel="noopener noreferrer"&gt;Python&lt;/a&gt; clients wrap every endpoint as a method and work with any x402-capable fetch.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createAmbolt&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="s1"&gt;@ambolt/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;ambolt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createAmbolt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payingFetch&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ambolt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ibanValidate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;iban&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DK5000400440116243&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;p&gt;Prices start at $0.003 a call. The full list is in the &lt;a href="https://ambolt.dev/catalog" rel="noopener noreferrer"&gt;catalog&lt;/a&gt;, and every tool is also available as a free MCP tool at &lt;code&gt;https://api.ambolt.dev/mcp&lt;/code&gt;.&lt;/p&gt;

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