Build Hypefury

KINDAreplaces $29/mosaves $348/yrback to the verdict

0%0 of 17 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A scheduling queue whose design is dictated by current platform economics: posts cost money per item, links cost far more, several capabilities are simply unavailable below Enterprise, and a queue that does not know this will produce an unexpected bill or a silent failure.

estimated effort multi-daythe files for this build are in the project pack

PublishingOfficial APIs only, one adapter per platformCostPer-post cost estimated before scheduling and tracked afterCapabilityA declared capability map per platform and tierQueueSlots with per-platform rate awareness and a budget checkRuntimeTypeScript with PostgreSQL and a worker

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Runs the server and the publishing worker.

    Get it nodejs.org, or nvm install 22. open ↗

    Verify node --version prints v22 or higher

  2. installfree locally

    Why Queue state, spend tracking and idempotency records.

    Get it Docker or your package manager. open ↗

    Verify psql connects and a unique constraint enforces idempotency

  3. pay per use; a link post costs many times a plain one

    Why Pricing and capabilities changed substantially in 2026, and building against a tutorial's description of the old tiers produces a tool that fails at send time.

    Get it Apply for access, read the current pricing and endpoint availability for your tier, and record both with the date you checked. open ↗

    Verify A test post publishes and the recorded capability map matches what your tier actually allows

  4. decidefree to decide

    Why Writes cost money per item and a queue that ignores that produces a bill rather than a surprise you can undo.

    Get it Decide a monthly figure, and work out how many posts that is at the URL and non-URL prices.

    Verify A figure is written down and the post count it implies is calculated

  5. have readyfree

    Why Slot behaviour, empty queue handling and the cost difference between link and non-link posts only become visible with a real queue running for a while.

    Get it Write or gather enough posts to fill your slots for two weeks, including several with links.

    Verify A queue exists with at least a third of posts containing links

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- accounts(id, platform, handle, tier, connected_at, capabilities_json)
- posts(id, account_id, body, media_ids_json, contains_url, thread_parent_id, state, scheduled_for, posted_at, external_id)
- cost_estimates(post_id, currency, amount_minor, basis) · basis records which price rule applied
- spend(account_id, period, estimated_minor, actual_minor)
- capabilities(platform, tier, endpoint, available, checked_on, source_url) · dated, because this is what changed
- slots(id, account_id, day_of_week, time_local, timezone) · the recurring queue
- failures(post_id, at, kind, detail, retryable) · kind is rate_limit, capability, auth or content
- A post records whether it contains a URL, because that single fact changes its cost by more than an order of magnitude.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
DATABASE_URLsecretrequiredpostgres://localhost:5432/queueQueue state, spend and platform tokens by reference.
PLATFORM_API_KEYsecretrequireda platform-issued keyOfficial API only. Browser automation is not part of this build.
PRICING_PATHrequired./config/pricing.jsonDated per-write pricing including the URL surcharge.
CAPABILITIES_PATHrequired./config/capabilities.jsonDated endpoint availability per tier. This is what changed in 2026.
MONTHLY_BUDGET_MINORrequired3000Checked before scheduling. Writes cost money per item.
RECYCLE_OLD_POSTSrequiredneverPresent as a constant. An empty slot is information; a recycled post is noise.

The build, in order

  1. Knowing what your tier can actually do

    An unavailable capability fails when you schedule, not when it sends.

    1. They changed in 2026 without grandfathering. Constants go quietly wrong.

      Files config/capabilities.json

    2. A failure at send is a failure you find out about afterwards.

      Files src/capability.ts

    3. Between scheduling and sending, a tier can change.

      Files src/publish.ts

    done when · tick each as it passes
    watch out
    • Discovering that your tier no longer has an endpoint at the moment a scheduled post tries to send means a silent failure at the worst possible time, and the removals in 2026 came without grandfathering. Check capability at scheduling time, and treat the map as dated data that goes stale rather than as constants.
  2. Costing a post before you queue it

    You know what a week's queue will cost before it runs.

    1. A link costs over ten times a plain post. That belongs in the interface.

      Files src/cost.tssrc/cost.test.ts

    2. Before the week runs, not on the invoice.

      Files src/projection.ts

    3. Divergence means the pricing table is stale.

      Files src/spend.ts

    done when · tick each as it passes
    watch out
    • A post containing a link costs many times one without, which is invisible in an interface that treats all posts the same, and a queue full of link posts produces a bill nobody predicted. Detect the URL, price accordingly, and show the difference at the point where someone is deciding whether to include a link.
  3. A queue that fills slots sensibly

    Content flows into recurring slots without you scheduling each item.

    1. Test both daylight transitions. A post an hour early is visible.

      Files src/slots.tssrc/slots.test.ts

    2. An empty queue is information. A recycled post is noise.

      Files src/queue.ts

    3. Moving an item should not lose its scheduled position.

      Files src/queue.ts

    done when · tick each as it passes
    watch out
    • Automatically recycling old posts when the queue runs dry is the feature that turns a scheduling tool into a repetition machine, and followers notice long before the operator does. Leave the slot empty and say the queue is empty, since an empty slot is information and a recycled post is noise.
  4. Publishing, and failing usefully

    Posts go out through the official API and failures are explicable.

    1. A timeout that actually succeeded is the common duplicate.

      Files src/publish.ts

    2. Rate limit, capability, auth, content. Four different responses.

      Files src/failures.ts

    3. Rather than failing every queued post in sequence.

      Files src/accounts.ts

    done when · tick each as it passes
    watch out
    • Retrying every failure identically will repost after a timeout that actually succeeded, producing a duplicate, and will retry a content rejection forever. Use an idempotency key, classify the failure, and retry only the classes where retrying can help.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more social media.