Docs / Start

Architecture

Araldo turns "announce this" requests from your products into published posts on every platform your users read. This page is the map; the decision records hold the reasons.

The shape

 your product ──HTTP (API key)──▶ araldo server ──▶ Postgres ◀── araldo worker ──▶ Bluesky, Mastodon,
 a person     ──browser (session)─▶  (API + dashboard)             (publisher,         Discord, Telegram,
                                                                     webhooks, tasks)   sandbox …
                                                                          │
                                                                          └──signed webhooks──▶ your product

The life of a post

  1. A product calls POST /v1/posts with a template and data (or finished text), any images it uploaded to /v1/media, and a time: now, next_slot, or a timestamp. A next_slot post that needs approval takes its slot when approved; posts can be moved or swapped until they start publishing (ADR 0022).
  2. core renders the text for every channel with that platform's rules (ADR 0010), refuses it with every problem listed if anything does not fit, and otherwise stores the post and one target per channel, with the text frozen. An event post.created is written in the same transaction (ADR 0012).
  3. If the brand requires approval, targets wait (held) until an admin approves.
  4. The worker claims due targets, one per channel at a time, records the attempt, and calls the platform adapter (ADR 0009). The outcome decides what happens next (ADR 0011): published, retried later, failed, or needs_attention when the platform may or may not have posted it and retrying could post it twice.
  5. Each outcome is an event; webhook endpoints that subscribe get a signed delivery, retried for up to three days.

Words

Term Meaning
Org A tenant: members, brands, keys. Nothing crosses orgs.
Brand A product or voice in an org, with its own channels, templates, slots, approval policy and the sites whose links get UTM parameters (ADR 0016).
Channel A connected account on a platform, under a brand. Test mode has sandbox channels only.
Template Versioned text with a JSON Schema for its data and per-platform bodies.
Post Something to publish, to one or more channels.
Media An image or video a post attaches; checked against each channel's platform.
Engagement A published target's likes, reposts, replies and quotes, read on a schedule (ADR 0018).
Target One channel's copy of a post: the unit of publishing work.
Event A record of something that happened, kept 30 days, delivered to webhooks.
Mode Test or live. Decided by the API key (or the dashboard switch).
Ad account An account on an ad network whose spend and results are read, under a brand (ADR 0023).
Analytics source A site's web analytics (Plausible, GA4) whose signups are read, under a brand (ADR 0025).
Issue A newsletter, handed to a brand's mail accounts' providers to send (ADR 0024).
Report A brand's month beside the one before, across everything above (ADR 0026).
Operator Whoever runs the server: araldo admin and the operator API, outside any org (ADR 0028, ADR 0031).

Code layout

See ADR 0002. In short: internal/core holds every use case and is the only thing the API (internal/api), the dashboard (internal/web) and the CLI (internal/cli) call; internal/store holds all SQL; platform adapters live in internal/platform/<name>.

Security in one screen

Edit this page on GitHub