Vibecode BulkPublish
track this build5 steps, step by step0%The part people picture is a weekend: a list of posts, a timer, one API call each. The part that eats the next six months is everything after the first successful post · staying authenticated to a dozen networks, learning each one's media rules the hard way, publishing that reports success and then quietly fails minutes later, retries that must never post twice, and a review process before some networks will accept a post at all. Build it for two accounts you control and it works. Build it for every network on the marketing page and you have taken a job.
You are building a lean indie version of BulkPublish. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # BulkPublish indie build ## Goal Build the smallest trustworthy replacement for the core BulkPublish workflow for one developer or a tiny team. ## Scope Import a spreadsheet of captions and images, point each row at one or more connected accounts, and let it publish on schedule with a log of what landed. ## Quick start 1. Install the documented dependencies. 2. Copy `.env.example` to `.env`. 3. Run the development command chosen during implementation. 4. Complete the acceptance checks in `BUILD_PLAN.md`. ## Honest limits This build deliberately does not replace: - staying connected · networks expire your auth and someone has to notice - knowing a post is malformed before the network rejects it, not after - an honest publish status when a network accepts the upload and fails minutes later - analytics pulled back per post - approvals, teams and multiple client workspaces - the platform review process that gates posting on some networks entirely If those capabilities are essential, use Postiz instead of pretending the gap is solved. ===== AGENTS.md ===== # Agent instructions - Optimize for a working, understandable weekend build. - Prefer the fewest moving parts that satisfy the brief. - Do not invent cryptography, security guarantees, APIs, or compliance claims. - Keep secrets out of source control and logs. - Add focused tests for destructive, security-sensitive, and data-loss paths. - Run the project checks before declaring the build complete. - Record any deliberate shortcut in the README under "Tradeoffs". ===== BUILD_PLAN.md ===== # Build plan ## Original build brief Build me a personal bulk social scheduler to replace BulkPublish. Requirements: - Python 3.12 + FastAPI + SQLite, Jinja templates, no JavaScript framework. One process on an always-on box, APScheduler ticking once a minute. - Two networks only: Mastodon (access token) and Bluesky (app password). One small module per network behind a single publish(post, account) function so a third is addable later. Scaffold nothing I do not use. - The main screen is a CSV importer. Columns: caption, image, send_at, accounts. Show me every parsed row with a per-network character count and a red flag on anything too long or missing a file, and import only the rows that pass. - Rows with no send_at fall into posting times I configure per account (weekdays 09:00 and 17:00 in my timezone) and take the next free one. - Each tick picks up due rows one at a time and flips the row to "sending" in its own transaction before any network call, so a crash or a double tick can never post the same row twice. Then "sent" with the live post URL, or "failed" with the error text. Three retries, backing off, and never a retry once a send is confirmed. - Images copied into media/ beside the database, checked for type and size at import, removed 90 days after the row sends. - A history page: last 200 rows, status, error, link to the live post, and a retry button. - Out of scope, and say so plainly in the README: X, Instagram, LinkedIn and TikTok (paid, approval-gated or review-gated APIs), analytics, approvals, and more than one user. - README covers getting a Mastodon token and a Bluesky app password. Secrets in .env, localhost only, no accounts, no telemetry. ## Required capabilities - a developer app and API credentials per network (several need review before they will publish anything) - somewhere always on for the schedule to fire - somewhere to keep the posts and the media - patience for the retry and duplicate-post edge cases ## Delivery order 1. Scaffold the smallest runnable application and document its commands. 2. Implement the primary data model and core workflow. 3. Add validation, safe failure states, and persistence. 4. Cover the critical path with automated tests. 5. Exercise a clean install from the README and fix every missing step. ## Done when - A new user can go from clone to first successful workflow using only the README. - The core workflow works without paid infrastructure unless the brief requires it. - Tests cover the highest-risk behavior. - Known limitations are explicit rather than hidden. ===== .env.example ===== # Copy to .env and document every variable when it is introduced. # Never put real credentials in this file. APP_ENV=development # Add only values required by the selected implementation.
You are building a lean indie version of BulkPublish. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # BulkPublish indie build ## Goal Build the smallest trustworthy replacement for the core BulkPublish workflow for one developer or a tiny team. ## Scope Import a spreadsheet of captions and images, point each row at one or more connected accounts, and let it publish on schedule with a log of what landed. ## Quick start 1. Install the documented dependencies. 2. Copy `.env.example` to `.env`. 3. Run the development command chosen during implementation. 4. Complete the acceptance checks in `BUILD_PLAN.md`. ## Honest limits This build deliberately does not replace: - staying connected · networks expire your auth and someone has to notice - knowing a post is malformed before the network rejects it, not after - an honest publish status when a network accepts the upload and fails minutes later - analytics pulled back per post - approvals, teams and multiple client workspaces - the platform review process that gates posting on some networks entirely If those capabilities are essential, use Postiz instead of pretending the gap is solved. ===== AGENTS.md ===== # Agent instructions - Optimize for a working, understandable weekend build. - Prefer the fewest moving parts that satisfy the brief. - Do not invent cryptography, security guarantees, APIs, or compliance claims. - Keep secrets out of source control and logs. - Add focused tests for destructive, security-sensitive, and data-loss paths. - Run the project checks before declaring the build complete. - Record any deliberate shortcut in the README under "Tradeoffs". ===== BUILD_PLAN.md ===== # Build plan ## Original build brief Build me a personal bulk social scheduler to replace BulkPublish. Requirements: - Python 3.12 + FastAPI + SQLite, Jinja templates, no JavaScript framework. One process on an always-on box, APScheduler ticking once a minute. - Two networks only: Mastodon (access token) and Bluesky (app password). One small module per network behind a single publish(post, account) function so a third is addable later. Scaffold nothing I do not use. - The main screen is a CSV importer. Columns: caption, image, send_at, accounts. Show me every parsed row with a per-network character count and a red flag on anything too long or missing a file, and import only the rows that pass. - Rows with no send_at fall into posting times I configure per account (weekdays 09:00 and 17:00 in my timezone) and take the next free one. - Each tick picks up due rows one at a time and flips the row to "sending" in its own transaction before any network call, so a crash or a double tick can never post the same row twice. Then "sent" with the live post URL, or "failed" with the error text. Three retries, backing off, and never a retry once a send is confirmed. - Images copied into media/ beside the database, checked for type and size at import, removed 90 days after the row sends. - A history page: last 200 rows, status, error, link to the live post, and a retry button. - Out of scope, and say so plainly in the README: X, Instagram, LinkedIn and TikTok (paid, approval-gated or review-gated APIs), analytics, approvals, and more than one user. - README covers getting a Mastodon token and a Bluesky app password. Secrets in .env, localhost only, no accounts, no telemetry. ## Required capabilities - a developer app and API credentials per network (several need review before they will publish anything) - somewhere always on for the schedule to fire - somewhere to keep the posts and the media - patience for the retry and duplicate-post edge cases ## Delivery order 1. Scaffold the smallest runnable application and document its commands. 2. Implement the primary data model and core workflow. 3. Add validation, safe failure states, and persistence. 4. Cover the critical path with automated tests. 5. Exercise a clean install from the README and fix every missing step. ## Done when - A new user can go from clone to first successful workflow using only the README. - The core workflow works without paid infrastructure unless the brief requires it. - Tests cover the highest-risk behavior. - Known limitations are explicit rather than hidden. ===== .env.example ===== # Copy to .env and document every variable when it is introduced. # Never put real credentials in this file. APP_ENV=development # Add only values required by the selected implementation.
You are building a production product version of BulkPublish. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== PRODUCT.md ===== # BulkPublish product brief ## Problem The part people picture is a weekend: a list of posts, a timer, one API call each. The part that eats the next six months is everything after the first successful post · staying authenticated to a dozen networks, learning each one's media rules the hard way, publishing that reports success and then quietly fails minutes later, retries that must never post twice, and a review process before some networks will accept a post at all. Build it for two accounts you control and it works. Build it for every network on the marketing page and you have taken a job. ## Product outcome Import a spreadsheet of captions and images, point each row at one or more connected accounts, and let it publish on schedule with a log of what landed. ## Target user A serious builder who needs a maintainable product foundation rather than a one-off demo. ## Required capabilities - a developer app and API credentials per network (several need review before they will publish anything) - somewhere always on for the schedule to fire - somewhere to keep the posts and the media - patience for the retry and duplicate-post edge cases ## Explicit non-goals for v1 - staying connected · networks expire your auth and someone has to notice - knowing a post is malformed before the network rejects it, not after - an honest publish status when a network accepts the upload and fails minutes later - analytics pulled back per post - approvals, teams and multiple client workspaces - the platform review process that gates posting on some networks entirely ## Success criteria - The primary workflow is measurable end to end. - Setup is reproducible in a clean environment. - Failure, recovery, and support paths are documented. - Product claims match what the implementation actually guarantees. ===== ARCHITECTURE.md ===== # Architecture ## Starting brief Build me a personal bulk social scheduler to replace BulkPublish. Requirements: - Python 3.12 + FastAPI + SQLite, Jinja templates, no JavaScript framework. One process on an always-on box, APScheduler ticking once a minute. - Two networks only: Mastodon (access token) and Bluesky (app password). One small module per network behind a single publish(post, account) function so a third is addable later. Scaffold nothing I do not use. - The main screen is a CSV importer. Columns: caption, image, send_at, accounts. Show me every parsed row with a per-network character count and a red flag on anything too long or missing a file, and import only the rows that pass. - Rows with no send_at fall into posting times I configure per account (weekdays 09:00 and 17:00 in my timezone) and take the next free one. - Each tick picks up due rows one at a time and flips the row to "sending" in its own transaction before any network call, so a crash or a double tick can never post the same row twice. Then "sent" with the live post URL, or "failed" with the error text. Three retries, backing off, and never a retry once a send is confirmed. - Images copied into media/ beside the database, checked for type and size at import, removed 90 days after the row sends. - A history page: last 200 rows, status, error, link to the live post, and a retry button. - Out of scope, and say so plainly in the README: X, Instagram, LinkedIn and TikTok (paid, approval-gated or review-gated APIs), analytics, approvals, and more than one user. - README covers getting a Mastodon token and a Bluesky app password. Secrets in .env, localhost only, no accounts, no telemetry. ## Boundaries Separate the product into replaceable modules for interface, application logic, persistence, external integrations, and operational concerns. Keep domain logic independent from delivery frameworks and vendors. ## Production baseline - Configuration: validated at startup with safe local defaults where possible. - Security: least privilege, input validation, secret redaction, rate limits on abuse-prone paths, and no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore instructions. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, and timeouts. - Observability: structured logs with request or operation IDs, an error-tracking hook, and health/readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, and one end-to-end critical-path test. ## Decision records For each major dependency, document why it was chosen, its failure mode, and how it can be replaced. Do not introduce infrastructure until a requirement justifies it. ===== AGENTS.md ===== # Agent instructions - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. - Implement milestone by milestone; keep each change reviewable and leave the application runnable. - Treat authentication, payments, encryption, imports, webhooks, and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a test pass. - Use provider interfaces for external services and deterministic fakes in tests. - Add migrations and rollback or recovery notes for persistent data changes. - Log useful operational context without credentials, tokens, passwords, or personal data. - Update documentation and run all checks before completing a milestone. ===== MILESTONES.md ===== # Delivery milestones ## M0 — Decisions and scaffold - Confirm the runtime, persistence model, threat boundaries, and deployment target. - Create a reproducible local environment and continuous checks. ## M1 — Core workflow - Implement the smallest end-to-end product path with validation and tests. - Keep integrations behind interfaces. ## M2 — Trust layer - Add secure failure behavior, recovery paths, audit-relevant events, and data safeguards. - Test abuse cases and destructive operations. ## M3 — Operability - Add structured logs, error reporting hooks, health signals, backup/restore documentation, and deployment configuration. ## M4 — Release gate - Run a clean-install test, critical-path end-to-end test, dependency review, and documented rollback exercise. - Compare the shipped behavior with `PRODUCT.md` and publish remaining limitations. ===== OPERATIONS.md ===== # Operations ## Before release - Validate configuration and secrets at startup. - Define backup, restore, and rollback procedures and test them. - Document logs, error tracking, health signals, and alert ownership. - Set dependency update and vulnerability review expectations. ## Incident checklist 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified source when needed. 5. Document the root cause, remediation, and regression test. ## Launch constraint Do not market omitted BulkPublish capabilities as implemented. The v1 non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered.
# BulkPublish indie build ## Goal Build the smallest trustworthy replacement for the core BulkPublish workflow for one developer or a tiny team. ## Scope Import a spreadsheet of captions and images, point each row at one or more connected accounts, and let it publish on schedule with a log of what landed. ## Quick start 1. Install the documented dependencies. 2. Copy `.env.example` to `.env`. 3. Run the development command chosen during implementation. 4. Complete the acceptance checks in `BUILD_PLAN.md`. ## Honest limits This build deliberately does not replace: - staying connected · networks expire your auth and someone has to notice - knowing a post is malformed before the network rejects it, not after - an honest publish status when a network accepts the upload and fails minutes later - analytics pulled back per post - approvals, teams and multiple client workspaces - the platform review process that gates posting on some networks entirely If those capabilities are essential, use Postiz instead of pretending the gap is solved.
# Agent instructions - Optimize for a working, understandable weekend build. - Prefer the fewest moving parts that satisfy the brief. - Do not invent cryptography, security guarantees, APIs, or compliance claims. - Keep secrets out of source control and logs. - Add focused tests for destructive, security-sensitive, and data-loss paths. - Run the project checks before declaring the build complete. - Record any deliberate shortcut in the README under "Tradeoffs".
# Build plan ## Original build brief Build me a personal bulk social scheduler to replace BulkPublish. Requirements: - Python 3.12 + FastAPI + SQLite, Jinja templates, no JavaScript framework. One process on an always-on box, APScheduler ticking once a minute. - Two networks only: Mastodon (access token) and Bluesky (app password). One small module per network behind a single publish(post, account) function so a third is addable later. Scaffold nothing I do not use. - The main screen is a CSV importer. Columns: caption, image, send_at, accounts. Show me every parsed row with a per-network character count and a red flag on anything too long or missing a file, and import only the rows that pass. - Rows with no send_at fall into posting times I configure per account (weekdays 09:00 and 17:00 in my timezone) and take the next free one. - Each tick picks up due rows one at a time and flips the row to "sending" in its own transaction before any network call, so a crash or a double tick can never post the same row twice. Then "sent" with the live post URL, or "failed" with the error text. Three retries, backing off, and never a retry once a send is confirmed. - Images copied into media/ beside the database, checked for type and size at import, removed 90 days after the row sends. - A history page: last 200 rows, status, error, link to the live post, and a retry button. - Out of scope, and say so plainly in the README: X, Instagram, LinkedIn and TikTok (paid, approval-gated or review-gated APIs), analytics, approvals, and more than one user. - README covers getting a Mastodon token and a Bluesky app password. Secrets in .env, localhost only, no accounts, no telemetry. ## Required capabilities - a developer app and API credentials per network (several need review before they will publish anything) - somewhere always on for the schedule to fire - somewhere to keep the posts and the media - patience for the retry and duplicate-post edge cases ## Delivery order 1. Scaffold the smallest runnable application and document its commands. 2. Implement the primary data model and core workflow. 3. Add validation, safe failure states, and persistence. 4. Cover the critical path with automated tests. 5. Exercise a clean install from the README and fix every missing step. ## Done when - A new user can go from clone to first successful workflow using only the README. - The core workflow works without paid infrastructure unless the brief requires it. - Tests cover the highest-risk behavior. - Known limitations are explicit rather than hidden.
# Copy to .env and document every variable when it is introduced. # Never put real credentials in this file. APP_ENV=development # Add only values required by the selected implementation.
# BulkPublish product brief ## Problem The part people picture is a weekend: a list of posts, a timer, one API call each. The part that eats the next six months is everything after the first successful post · staying authenticated to a dozen networks, learning each one's media rules the hard way, publishing that reports success and then quietly fails minutes later, retries that must never post twice, and a review process before some networks will accept a post at all. Build it for two accounts you control and it works. Build it for every network on the marketing page and you have taken a job. ## Product outcome Import a spreadsheet of captions and images, point each row at one or more connected accounts, and let it publish on schedule with a log of what landed. ## Target user A serious builder who needs a maintainable product foundation rather than a one-off demo. ## Required capabilities - a developer app and API credentials per network (several need review before they will publish anything) - somewhere always on for the schedule to fire - somewhere to keep the posts and the media - patience for the retry and duplicate-post edge cases ## Explicit non-goals for v1 - staying connected · networks expire your auth and someone has to notice - knowing a post is malformed before the network rejects it, not after - an honest publish status when a network accepts the upload and fails minutes later - analytics pulled back per post - approvals, teams and multiple client workspaces - the platform review process that gates posting on some networks entirely ## Success criteria - The primary workflow is measurable end to end. - Setup is reproducible in a clean environment. - Failure, recovery, and support paths are documented. - Product claims match what the implementation actually guarantees.
# Architecture ## Starting brief Build me a personal bulk social scheduler to replace BulkPublish. Requirements: - Python 3.12 + FastAPI + SQLite, Jinja templates, no JavaScript framework. One process on an always-on box, APScheduler ticking once a minute. - Two networks only: Mastodon (access token) and Bluesky (app password). One small module per network behind a single publish(post, account) function so a third is addable later. Scaffold nothing I do not use. - The main screen is a CSV importer. Columns: caption, image, send_at, accounts. Show me every parsed row with a per-network character count and a red flag on anything too long or missing a file, and import only the rows that pass. - Rows with no send_at fall into posting times I configure per account (weekdays 09:00 and 17:00 in my timezone) and take the next free one. - Each tick picks up due rows one at a time and flips the row to "sending" in its own transaction before any network call, so a crash or a double tick can never post the same row twice. Then "sent" with the live post URL, or "failed" with the error text. Three retries, backing off, and never a retry once a send is confirmed. - Images copied into media/ beside the database, checked for type and size at import, removed 90 days after the row sends. - A history page: last 200 rows, status, error, link to the live post, and a retry button. - Out of scope, and say so plainly in the README: X, Instagram, LinkedIn and TikTok (paid, approval-gated or review-gated APIs), analytics, approvals, and more than one user. - README covers getting a Mastodon token and a Bluesky app password. Secrets in .env, localhost only, no accounts, no telemetry. ## Boundaries Separate the product into replaceable modules for interface, application logic, persistence, external integrations, and operational concerns. Keep domain logic independent from delivery frameworks and vendors. ## Production baseline - Configuration: validated at startup with safe local defaults where possible. - Security: least privilege, input validation, secret redaction, rate limits on abuse-prone paths, and no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore instructions. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, and timeouts. - Observability: structured logs with request or operation IDs, an error-tracking hook, and health/readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, and one end-to-end critical-path test. ## Decision records For each major dependency, document why it was chosen, its failure mode, and how it can be replaced. Do not introduce infrastructure until a requirement justifies it.
# Agent instructions - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. - Implement milestone by milestone; keep each change reviewable and leave the application runnable. - Treat authentication, payments, encryption, imports, webhooks, and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a test pass. - Use provider interfaces for external services and deterministic fakes in tests. - Add migrations and rollback or recovery notes for persistent data changes. - Log useful operational context without credentials, tokens, passwords, or personal data. - Update documentation and run all checks before completing a milestone.
# Delivery milestones ## M0 — Decisions and scaffold - Confirm the runtime, persistence model, threat boundaries, and deployment target. - Create a reproducible local environment and continuous checks. ## M1 — Core workflow - Implement the smallest end-to-end product path with validation and tests. - Keep integrations behind interfaces. ## M2 — Trust layer - Add secure failure behavior, recovery paths, audit-relevant events, and data safeguards. - Test abuse cases and destructive operations. ## M3 — Operability - Add structured logs, error reporting hooks, health signals, backup/restore documentation, and deployment configuration. ## M4 — Release gate - Run a clean-install test, critical-path end-to-end test, dependency review, and documented rollback exercise. - Compare the shipped behavior with `PRODUCT.md` and publish remaining limitations.
# Operations ## Before release - Validate configuration and secrets at startup. - Define backup, restore, and rollback procedures and test them. - Document logs, error tracking, health signals, and alert ownership. - Set dependency update and vulnerability review expectations. ## Incident checklist 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified source when needed. 5. Document the root cause, remediation, and regression test. ## Launch constraint Do not market omitted BulkPublish capabilities as implemented. The v1 non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered.
$ choose a build depth, inspect the files, then open the complete pack in your agent
Because a scheduler is only worth anything when it is boring, and a self-built one stops being boring the first time a token expires overnight or a network changes its video rules without telling anyone. People pay so that maintenance is somebody else's Tuesday.
xstaying connected · networks expire your auth and someone has to notice
xknowing a post is malformed before the network rejects it, not after
xan honest publish status when a network accepts the upload and fails minutes later
xanalytics pulled back per post
xapprovals, teams and multiple client workspaces
xthe platform review process that gates posting on some networks entirely
Don't feel like building it? These folks already made it free.
all 6 free alternatives to BulkPublish →· no votes, no pay-to-list · just what's real
BulkPublish pricing
| plan | monthly | annual (per mo) | what you get |
|---|---|---|---|
| free | $0/workspace | $0/workspace | 3 channels (1/platform); 3 posts/day and 30/month; 10 scheduled posts; 100 MB media; 30 API requests/day; 1 organization; 50 AI captions/month plus credits; 1 RSS draft feed; no repeat posts. |
| pro | $13.99/workspace | $11.89/workspace | 2 channels/platform; 30 posts/day (900/month); 30 scheduled/day; 2 GB media; 5 API keys; 5,000 API requests/day; 3 organizations; 10 repeat posts; 300 AI captions/month; 10 RSS auto-publish feeds. |
| business | $39.99/workspace | $33.99/workspace | 5 channels/platform; unlimited posts; 100 scheduled/day; 10 GB media; 10 API keys; 50,000 API requests/day; 10 organizations; unlimited repeats; 1,000 AI captions/month; 50 RSS auto-publish feeds. |
free tier3 channels (1/platform); 3 posts/day and 30/month; 10 scheduled posts; 100 MB media; 30 API requests/day; 1 organization; 50 AI captions/month plus credits; 1 RSS draft feed; no repeat posts
billingmonthly + annual (15% lower on annual billing)
hidden costsPublishing to X uses separate pay-as-you-go credits, and additional AI credits can add cost; current public unit prices were not exposed.
verified 2026-08-14 · source ↗
Is BulkPublish free?
The free plan covers three channels, thirty posts a month, ten scheduled at a time and 100 MB of media, with repeat posts and RSS auto-publishing held back for paid plans. Paid is Pro at $13.99/mo (checked 2026-08-08).
Vibecode BulkPublish
Kinda. The core of BulkPublish is buildable in a weekend with the prompt on this page, but there are real gaps: staying connected · networks expire your auth and someone has to notice, knowing a post is malformed before the network rejects it, not after. Read the honest list above before committing.
How much does BulkPublish cost?
BulkPublish costs about $13.99/month (Pro, checked 2026-08-08), which is $167.88 per year.
What do I lose by replacing BulkPublish?
Honestly: staying connected · networks expire your auth and someone has to notice; knowing a post is malformed before the network rejects it, not after; an honest publish status when a network accepts the upload and fails minutes later; analytics pulled back per post; approvals, teams and multiple client workspaces; the platform review process that gates posting on some networks entirely. If any of those are load-bearing for you, keep paying.
Is there an open-source alternative to BulkPublish?
Yes: Postiz (The broadest open scheduler here; free means running PostgreSQL, Redis, Temporal and your own platform credentials.) Mixpost Lite (A polished single-user scheduler with queues and basic analytics; the team features live in the paid edition.) Publer Free (Three non-X accounts and ten queued posts each, with a bulk CSV importer that is the closest free match for the actual job.) All 6 curated free alternatives are at vibecodeit.com/bulkpublish/alternatives. The prompt is for when you want it exactly your way.