<?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: Agrici Daniel</title>
    <description>The latest articles on DEV Community by Agrici Daniel (@agricidaniel).</description>
    <link>https://dev.to/agricidaniel</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%2F3979633%2Fbebad882-f3c6-4567-bbcf-12316214ec8f.jpg</url>
      <title>DEV Community: Agrici Daniel</title>
      <link>https://dev.to/agricidaniel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/agricidaniel"/>
    <language>en</language>
    <item>
      <title>The Open-Source AI Marketing OS I Am Building in Public</title>
      <dc:creator>Agrici Daniel</dc:creator>
      <pubDate>Fri, 31 Jul 2026 06:00:00 +0000</pubDate>
      <link>https://dev.to/agricidaniel/the-open-source-ai-marketing-os-i-am-building-in-public-22h1</link>
      <guid>https://dev.to/agricidaniel/the-open-source-ai-marketing-os-i-am-building-in-public-22h1</guid>
      <description>&lt;h1&gt;
  
  
  The Open-Source AI Marketing OS I Am Building in Public
&lt;/h1&gt;

&lt;p&gt;My AI marketing stack is not one giant agent.&lt;/p&gt;

&lt;p&gt;It is a set of small systems with clear jobs. Context retrieves evidence. SEO and ads skills perform bounded analysis. Content skills turn research into structured assets. Media tools adapt owned material. Postiz receives approved platform-native drafts. A human stops execution when the claim, destination, or output is not ready.&lt;/p&gt;

&lt;p&gt;The shared layer is evidence.&lt;/p&gt;

&lt;p&gt;This is the install order and operating model I use to keep the stack inspectable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the bottleneck, not the tool count
&lt;/h2&gt;

&lt;p&gt;An operating system does not become useful because it contains more repositories.&lt;/p&gt;

&lt;p&gt;It becomes useful when one component removes a measurable bottleneck without hiding the source, the failure boundary, or the human decision.&lt;/p&gt;

&lt;p&gt;Pick one job first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retrieve the right company context&lt;/li&gt;
&lt;li&gt;audit one owned page&lt;/li&gt;
&lt;li&gt;structure one ad review&lt;/li&gt;
&lt;li&gt;turn one research packet into a brief&lt;/li&gt;
&lt;li&gt;cut one owned video into a Short&lt;/li&gt;
&lt;li&gt;create one approved social draft&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run that job end to end. Measure the review load. Add the next component only when the workflow needs it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: source-cited context
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/AgriciDaniel/claude-obsidian" rel="noopener noreferrer"&gt;Claude Obsidian&lt;/a&gt; is the context layer.&lt;/p&gt;

&lt;p&gt;Its job is not to store the largest possible pile of notes. Its job is to retrieve the relevant source when work begins, show the date and status of that source, and produce a bounded next action.&lt;/p&gt;

&lt;p&gt;A working context loop looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;question
  -&amp;gt; retrieve candidate pages
  -&amp;gt; inspect source and date
  -&amp;gt; answer with a bounded action
  -&amp;gt; store a reviewed correction
  -&amp;gt; retrieve that correction in a later task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last step matters. Persistent files are not the same as learning. A correction becomes operational memory only when a later task can retrieve it in the right scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2: reusable marketing skills
&lt;/h2&gt;

&lt;p&gt;The skill layer splits marketing work into inspectable jobs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/AgriciDaniel/claude-seo" rel="noopener noreferrer"&gt;Claude SEO&lt;/a&gt; routes SEO audits, content checks, technical tasks, and structured research.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/AgriciDaniel/codex-seo" rel="noopener noreferrer"&gt;Codex SEO&lt;/a&gt; adapts the same builder-led SEO approach for a Codex workflow.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/AgriciDaniel/claude-ads" rel="noopener noreferrer"&gt;Claude Ads&lt;/a&gt; separates paid-media review by platform, attribution, budget, creative, tracking, and validation.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/AgriciDaniel/claude-blog" rel="noopener noreferrer"&gt;Claude Blog&lt;/a&gt; separates research, briefs, drafting, fact checks, images, localization, and post-write quality control.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repository name is not the proof. The useful proof is a bounded run with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one defined input&lt;/li&gt;
&lt;li&gt;a visible method&lt;/li&gt;
&lt;li&gt;a reviewable output&lt;/li&gt;
&lt;li&gt;a known failure boundary&lt;/li&gt;
&lt;li&gt;a decision about what happens next&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stars can show attention. They cannot replace that test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: owned media production
&lt;/h2&gt;

&lt;p&gt;The media layer should begin from an owned source asset.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/AgriciDaniel/claude-shorts" rel="noopener noreferrer"&gt;Claude Shorts&lt;/a&gt; turns long-form footage into short-form production steps. &lt;a href="https://github.com/AgriciDaniel/banana-claude" rel="noopener noreferrer"&gt;Banana Claude&lt;/a&gt; covers image-generation workflows.&lt;/p&gt;

&lt;p&gt;The source link stays attached to the derivative. That keeps the Short, visual, caption, and destination aligned with the same underlying claim.&lt;/p&gt;

&lt;p&gt;For video, the output contract is explicit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1080 by 1920&lt;/li&gt;
&lt;li&gt;H.264 video&lt;/li&gt;
&lt;li&gt;AAC audio&lt;/li&gt;
&lt;li&gt;burned-in captions&lt;/li&gt;
&lt;li&gt;no private paths or credentials on screen&lt;/li&gt;
&lt;li&gt;one CTA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For deterministic diagrams and carousels, the text and measurements remain editable. Generated illustrations stay textless so claims are not baked into an image that cannot be corrected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 4: connected publishing tools
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/gitroomhq/postiz-app" rel="noopener noreferrer"&gt;Postiz&lt;/a&gt; is the publishing layer in this setup.&lt;/p&gt;

&lt;p&gt;It is self-hosted on Railway with Redis, Postgres, and Temporal behind the application. The current instance exposes a Public API and MCP endpoint. Seven social integrations are connected.&lt;/p&gt;

&lt;p&gt;That is connection proof, not publication proof.&lt;/p&gt;

&lt;p&gt;The publishing path stays staged:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;local validation
  -&amp;gt; media upload
  -&amp;gt; representative provider draft
  -&amp;gt; rendered preview
  -&amp;gt; owner approval
  -&amp;gt; Week 1 schedule
  -&amp;gt; controlled public test
  -&amp;gt; Week 2 schedule
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pinterest is currently blocked because the connected integration returns no board. Its assets remain complete but unscheduled until Postiz returns a real board ID.&lt;/p&gt;

&lt;h2&gt;
  
  
  The approval layer wraps execution
&lt;/h2&gt;

&lt;p&gt;Approval is not a fifth tool beside the stack. It is the boundary around every action that changes public state.&lt;/p&gt;

&lt;p&gt;The reviewer checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;whether the source supports the claim&lt;/li&gt;
&lt;li&gt;whether mutable facts were refreshed&lt;/li&gt;
&lt;li&gt;whether the copy is native to the platform&lt;/li&gt;
&lt;li&gt;whether the media shows the same system described in the post&lt;/li&gt;
&lt;li&gt;whether the destination exists and matches the CTA&lt;/li&gt;
&lt;li&gt;whether the selected account and time are correct&lt;/li&gt;
&lt;li&gt;whether a rollback path exists&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The automation can prepare the decision. It does not inherit authority to publish every future derivative.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical install order
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Install the context layer
&lt;/h3&gt;

&lt;p&gt;Start with a small, source-cited vault. Put one recurring marketing decision inside it. Test whether the system can retrieve the right note, date, and next action.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Add one skill for one job
&lt;/h3&gt;

&lt;p&gt;Choose the bottleneck you can measure. An owned-page SEO audit is a better first test than “automate SEO.” One ad-account review is a better first test than “run paid media.”&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Define the output contract
&lt;/h3&gt;

&lt;p&gt;Write down what the component must return. Include the source, status, priority, limitation, and human checkpoint.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Connect publishing last
&lt;/h3&gt;

&lt;p&gt;Publishing multiplies mistakes. Connect it after the local output is stable, the media contract is validated, and the approval state is explicit.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Measure the quality cost
&lt;/h3&gt;

&lt;p&gt;Track editing time, corrections, failures, and review burden beside reach or clicks. A system that creates more cleanup than useful work has not earned another layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is public and what is still being connected
&lt;/h2&gt;

&lt;p&gt;The seven AgriciDaniel repositories named above were public and reachable through the GitHub API on July 16, 2026. Their versions, install paths, licenses, and maintenance status must still be refreshed before a dated recommendation.&lt;/p&gt;

&lt;p&gt;The Postiz deployment is connected and healthy. The first provider previews and controlled public tests are still required. The two-week social batch is built around that boundary.&lt;/p&gt;

&lt;p&gt;I do not call the full stack autonomous. I call it inspectable.&lt;/p&gt;

&lt;p&gt;That is the operating advantage: every component owns one job, every claim keeps its source, and every public action stops for approval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/AgriciDaniel/claude-obsidian" rel="noopener noreferrer"&gt;Claude Obsidian&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AgriciDaniel/claude-seo" rel="noopener noreferrer"&gt;Claude SEO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AgriciDaniel/codex-seo" rel="noopener noreferrer"&gt;Codex SEO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AgriciDaniel/claude-ads" rel="noopener noreferrer"&gt;Claude Ads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AgriciDaniel/claude-blog" rel="noopener noreferrer"&gt;Claude Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AgriciDaniel/claude-shorts" rel="noopener noreferrer"&gt;Claude Shorts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AgriciDaniel/banana-claude" rel="noopener noreferrer"&gt;Banana Claude&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gitroomhq/postiz-app" rel="noopener noreferrer"&gt;Postiz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.postiz.com/public-api" rel="noopener noreferrer"&gt;Postiz Public API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Join the &lt;a href="https://www.skool.com/ai-marketing-hub/about" rel="noopener noreferrer"&gt;free AI Marketing Hub&lt;/a&gt; and start with the one marketing bottleneck you can measure.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>marketing</category>
      <category>opensource</category>
      <category>claude</category>
    </item>
    <item>
      <title>Build a Source-Grounded Social Engine With a Human Approval Gate</title>
      <dc:creator>Agrici Daniel</dc:creator>
      <pubDate>Fri, 24 Jul 2026 06:00:01 +0000</pubDate>
      <link>https://dev.to/agricidaniel/build-a-source-grounded-social-engine-with-a-human-approval-gate-5gpp</link>
      <guid>https://dev.to/agricidaniel/build-a-source-grounded-social-engine-with-a-human-approval-gate-5gpp</guid>
      <description>&lt;h1&gt;
  
  
  Build a Source-Grounded Social Engine With a Human Approval Gate
&lt;/h1&gt;

&lt;p&gt;I connected seven channels to a self-hosted Postiz instance.&lt;/p&gt;

&lt;p&gt;That was the easy part.&lt;/p&gt;

&lt;p&gt;The difficult part is preventing a research note, an outdated number, or a generic draft from moving straight into a public calendar. A healthy API connection proves that Postiz can reach an account. It does not prove that the claim is current, the copy fits the platform, the media is correct, or the publication time is approved.&lt;/p&gt;

&lt;p&gt;My workflow separates those decisions.&lt;/p&gt;

&lt;p&gt;The system is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Current research&lt;/li&gt;
&lt;li&gt;An evidence ledger&lt;/li&gt;
&lt;li&gt;Platform-native drafts&lt;/li&gt;
&lt;li&gt;Human approval&lt;/li&gt;
&lt;li&gt;A Postiz preview&lt;/li&gt;
&lt;li&gt;Controlled scheduling&lt;/li&gt;
&lt;li&gt;Measurement that changes the next batch&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nothing publishes automatically. The automation ends at a reviewable draft until a human approves the complete asset.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Start with a dated research record
&lt;/h2&gt;

&lt;p&gt;A trend is a time-bound observation, not a promise that a post will perform.&lt;/p&gt;

&lt;p&gt;For each topic, I keep:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the source URL&lt;/li&gt;
&lt;li&gt;the retrieval date&lt;/li&gt;
&lt;li&gt;what the source directly supports&lt;/li&gt;
&lt;li&gt;what I infer from it&lt;/li&gt;
&lt;li&gt;the confidence level&lt;/li&gt;
&lt;li&gt;the date the claim must be checked again&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mutable repository counts, versions, product behavior, prices, and social metrics expire quickly. A draft can stay useful while the number inside it becomes wrong. The refresh date makes that visible before publication.&lt;/p&gt;

&lt;p&gt;Qualitative discussions need another boundary. Three useful community threads can reveal language, objections, and workflow pain. They do not represent the entire market. I write “the discussions clustered around these jobs,” not “marketers want this.”&lt;/p&gt;

&lt;p&gt;That distinction is small in the copy and important for trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Put every public claim in an evidence ledger
&lt;/h2&gt;

&lt;p&gt;The evidence ledger is the handoff between research and production.&lt;/p&gt;

&lt;p&gt;A minimal record looks like this:&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;"claim_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;"postiz-seven-connections"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"claim"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Seven social integrations are connected and healthy."&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;"Postiz Public API integration list"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"observed_at"&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-07-16T14:00:00+03:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"high"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expires_at"&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-07-19T14:00:00+03:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"limitation"&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 provider has completed a controlled public test."&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;The limitation is part of the record. Seven healthy connections do not mean seven proven publishing paths.&lt;/p&gt;

&lt;p&gt;In my current setup, Pinterest is connected but Postiz returns no board. The ten Pin assets can be completed, reviewed, and stored. They cannot become schedules until the integration returns a real board ID.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Produce native assets from one evidence packet
&lt;/h2&gt;

&lt;p&gt;The core idea can stay consistent. The delivery should change.&lt;/p&gt;

&lt;p&gt;An X post needs a compact observation and one action. LinkedIn can explain the operating decision across a carousel. Mastodon needs enough context to stand alone. Pinterest needs a durable, keyword-forward title and a vertical visual. Dev.to should hold the full implementation, not a padded social caption.&lt;/p&gt;

&lt;p&gt;The same paragraph pasted across seven networks is distribution, not adaptation.&lt;/p&gt;

&lt;p&gt;I store each derivative as its own asset with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a unique ID&lt;/li&gt;
&lt;li&gt;the target integration&lt;/li&gt;
&lt;li&gt;the scheduled local time and UTC offset&lt;/li&gt;
&lt;li&gt;the copy path&lt;/li&gt;
&lt;li&gt;the media paths&lt;/li&gt;
&lt;li&gt;the provider settings&lt;/li&gt;
&lt;li&gt;the destination&lt;/li&gt;
&lt;li&gt;the source ledger&lt;/li&gt;
&lt;li&gt;approval and Postiz state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters because approval of the topic is not approval of every derivative. One Pin may have a weak destination. One carousel may contain a stale figure. One Short may expose a private screen. Every public asset needs its own decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Make the human gate explicit
&lt;/h2&gt;

&lt;p&gt;The reviewer approves the whole publication unit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;copy&lt;/li&gt;
&lt;li&gt;media&lt;/li&gt;
&lt;li&gt;claim source&lt;/li&gt;
&lt;li&gt;account&lt;/li&gt;
&lt;li&gt;destination&lt;/li&gt;
&lt;li&gt;provider settings&lt;/li&gt;
&lt;li&gt;time&lt;/li&gt;
&lt;li&gt;rollback plan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The state machine is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;researched
  -&amp;gt; drafted
  -&amp;gt; media-ready
  -&amp;gt; approved
  -&amp;gt; postiz-draft
  -&amp;gt; scheduled
  -&amp;gt; published
  -&amp;gt; measured
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An asset cannot skip from &lt;code&gt;drafted&lt;/code&gt; to &lt;code&gt;scheduled&lt;/code&gt; because a script can construct the payload.&lt;/p&gt;

&lt;p&gt;Representative previews come first. I create one draft for each provider, inspect the rendered result inside Postiz, and correct the shared template. Only then does the batch move forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Keep the Postiz operator dry-run by default
&lt;/h2&gt;

&lt;p&gt;The local operator uses the self-hosted Public API documented by Postiz. Media goes through &lt;code&gt;POST /public/v1/upload&lt;/code&gt;. Posts go through &lt;code&gt;POST /public/v1/posts&lt;/code&gt;. The API supports &lt;code&gt;draft&lt;/code&gt;, &lt;code&gt;schedule&lt;/code&gt;, and &lt;code&gt;now&lt;/code&gt; post types.&lt;/p&gt;

&lt;p&gt;The safe interface keeps network writes explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 scripts/postizctl.py health &lt;span class="nt"&gt;--skip-custom&lt;/span&gt;
python3 scripts/postizctl.py integrations
python3 scripts/postizctl.py batch production/manifest/2026-07-20--2026-08-02.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those commands inspect or validate. They do not create anything.&lt;/p&gt;

&lt;p&gt;A network write requires &lt;code&gt;--send&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 scripts/postizctl.py batch &lt;span class="se"&gt;\&lt;/span&gt;
  production/manifest/2026-07-20--2026-08-02.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--asset&lt;/span&gt; W1-05-LI &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--send&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The operator hashes every media file before upload. If the exact file already has a valid Postiz receipt, the upload is reused. The receipt stores the media ID, public path, hash, and upload time. It never stores the API key.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Validate provider rules before the request
&lt;/h2&gt;

&lt;p&gt;Each provider has a different contract.&lt;/p&gt;

&lt;p&gt;In this self-hosted instance, the live non-Premium X schema returns a 200-character limit. LinkedIn image carousels need at least two images. Pinterest requires media and a board. Dev.to needs a title and accepts up to four tags in the current schema. YouTube needs one MP4 plus a title and visibility setting.&lt;/p&gt;

&lt;p&gt;The manifest translates those differences into provider settings:&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;"platform"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"linkedin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"settings"&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;"__type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"linkedin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"post_as_images_carousel"&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="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;Local validation catches missing settings, wrong integration mappings, expired timestamps, missing media, character-limit failures, and duplicate asset IDs before the API sees the payload.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Roll out one provider at a time
&lt;/h2&gt;

&lt;p&gt;The first real post on each platform is a controlled test.&lt;/p&gt;

&lt;p&gt;After it publishes, I verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the public URL&lt;/li&gt;
&lt;li&gt;copy formatting&lt;/li&gt;
&lt;li&gt;media order and quality&lt;/li&gt;
&lt;li&gt;captions and thumbnails for video&lt;/li&gt;
&lt;li&gt;destination behavior&lt;/li&gt;
&lt;li&gt;provider-specific settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If X fails, the X rows stop. LinkedIn, Bluesky, Mastodon, Dev.to, and YouTube do not need to stop with it. Provider isolation keeps one integration problem from turning into a batch-wide incident.&lt;/p&gt;

&lt;p&gt;Week 2 stays on hold for a provider until its Week 1 controlled post succeeds.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Measure quality cost, not only reach
&lt;/h2&gt;

&lt;p&gt;The useful metrics depend on the job of the post.&lt;/p&gt;

&lt;p&gt;For reach, I track impressions or views. For interest, I track qualified replies, saves, profile visits, and completion rate where the platform exposes them. For trust, I track clicks to the full guide, repository visits, and video watch depth. For conversion, I track attributable Free Hub visits and join starts.&lt;/p&gt;

&lt;p&gt;I also track the cost of the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;editing time&lt;/li&gt;
&lt;li&gt;claim corrections&lt;/li&gt;
&lt;li&gt;upload failures&lt;/li&gt;
&lt;li&gt;provider failures&lt;/li&gt;
&lt;li&gt;reply burden&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A topic is not worth repeating when it creates more review and cleanup than useful action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current boundary
&lt;/h2&gt;

&lt;p&gt;As of July 16, 2026, the app, Public API, MCP endpoint, and seven integrations are healthy. Pinterest scheduling remains blocked because no board is returned. No provider has completed a controlled Postiz publish test. The two-week batch is a reviewed production system, not proof of an autonomous publishing loop.&lt;/p&gt;

&lt;p&gt;That is the point of the gate. It keeps the public claim equal to the system that exists today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.postiz.com/public-api/uploads/upload-file" rel="noopener noreferrer"&gt;Postiz: upload a file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.postiz.com/public-api/posts/create" rel="noopener noreferrer"&gt;Postiz: create a post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.postiz.com/public-api/posts/get-posts" rel="noopener noreferrer"&gt;Postiz: list posts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.postiz.com/public-api/posts/delete-post" rel="noopener noreferrer"&gt;Postiz: delete a post&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Join the &lt;a href="https://www.skool.com/ai-marketing-hub/about" rel="noopener noreferrer"&gt;free AI Marketing Hub&lt;/a&gt; and share the workflow you want to put behind a human approval gate.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>socialmedia</category>
      <category>opensource</category>
      <category>marketing</category>
    </item>
  </channel>
</rss>
