saascode
Vacanta

Vacanta

The niche job board you own outright — employers pay to post, candidates never do, and the moderation queue is yours.

inside the product
01· Landing
02· Employers
03· Pricing
04· Job Alerts
05· About
06· Jobs
07· Accessibility
08· Employer
09· Employer Vacancies
the complete operation

Vacanta is a niche job board that you run. Employer companies publish vacancies you moderate, pay for the right to publish them, and manage the applicants they receive on a stage board only they can see. Job seekers search the board publicly, keep a profile, apply and track what happens.

Vacanta in depth

Every listing on your board is there because you approved it.

A niche board is worth exactly what is on it, and what erodes that is never the vacancy somebody rejected. It is the one that got in through a side door nobody remembered existed — an admin form added for support, a bulk import built for a migration, a direct edit on a record that was already live. Each of those looks harmless the day it is added and each is a route around the review. You find out which one it was after the listing is public, an employer has screenshotted it, and you are spending the week defending a standard you were not actually enforcing.

  • Submit for moderation
  • Moderation and publish
  • Vacancy draft/edit
  • CSV vacancy bootstrap

Salary and workplace are on every listing before anyone applies.

Salary-disclosure rules differ by jurisdiction and change on their own schedule, so the real question on a board is not whether you know the rule. It is what happens at six in the evening when an important employer's posting is blocked and somebody asks for an exception just this once. A policy with a switch has already answered that question. What the switch costs is not the one exception — it is that afterwards the rule is a suggestion, and nobody can tell you what is actually on your board any more.

  • Jurisdiction/Launch Free Mode
  • Moderation and publish
  • Google syndication

Every employer who buys a posting gets a working hiring tool with it.

The obvious way to build tiers on a job board is to meter the applicant workflow: put stages, notes and ratings behind the subscription and let the one-off buyer stare at a list of names. It is also the way the board dies. An employer who paid to attract applicants and then cannot work through them does not upgrade — they leave, and they explain why to the next employer you were about to sign. A tier has to sell more room to someone who is already succeeding, never the ability to succeed at all.

  • Posting entitlement
  • Spotlight promotion
  • Employer analytics

Each employer sees only the candidates who applied to their own vacancies.

The moment recruiters can browse the candidate pool, the product stops being a job board and quietly becomes a resume database that happens to carry listings. That is a different business with a different data-protection surface, and it is almost never a decision somebody made on purpose. It is what happens when candidates are modelled as belonging to the companies they applied to, because then the permission simply follows the model. This is not a bug you patch once it shows up; it is the shape of the data, and it is decided before the first vacancy is posted.

  • Candidate profile/resume
  • Apply / withdraw / timeline
  • Pipeline stages/notes/rating
  • Saved vacancies and alerts
complete feature inventory
Vacancy search/detail/companyJob seekers search the public board with weighted full-text ranking and hard filters, then read vacancy and company pages without signing in. Search uses no external service or model call, stays available when other systems are degraded, and can show which candidate skills and constraints matched a result.

Publication is checked against a transparency policy, and it fails closed. Every vacancy resolves a jurisdiction profile from its work location and eligible regions. The one that ships requires a salary minimum, maximum, currency and period, and forbids asking a candidate about their salary history. If a vacancy is missing a required field, or no active profile resolves for it, it does not publish. There is no override switch. When an employer complains that their posting will not go live, the answer is almost always a missing salary range.

Vacancy draft/editRecruiters draft and edit vacancies inside their own company's workspace, where nothing is public yet. Every vacancy carries its own lifecycle history, so one that was written, submitted, sent back and resubmitted still shows what happened to it and when.
Submit for moderationSubmitting moves an employer's draft to pending review, where it waits in the moderation queue and remains invisible outside the employer's company. It does not publish the vacancy; approval is the separate step that consumes a posting entitlement and makes it live.

Approving does several things in one indivisible step: it re-checks that the vacancy is still eligible, consumes exactly one posting entitlement (unless Launch Free Mode is on), makes the canonical version live, and appends to the ledger and the lifecycle history. Then, after the write is safely committed, it refreshes the public pages, queues the Google projection and notifies the employer. Those later steps can fail without undoing the publication — if the Google projection does not go out, the vacancy is still live and the syndication task retries it.

Rejecting records a reason. The employer sees it, can fix the vacancy and resubmit. A rejection does not consume their credit.

Moderation and publishThe board operator reviews a submitted vacancy with its employer and the entitlement that would be consumed, then approves or rejects it. Approval re-checks eligibility, consumes one posting entitlement unless Launch Free Mode is on, publishes the canonical vacancy and records it in the entitlement ledger and lifecycle history; rejection records a reason the employer can address before resubmitting.

Approving does several things in one indivisible step: it re-checks that the vacancy is still eligible, consumes exactly one posting entitlement (unless Launch Free Mode is on), makes the canonical version live, and appends to the ledger and the lifecycle history. Then, after the write is safely committed, it refreshes the public pages, queues the Google projection and notifies the employer. Those later steps can fail without undoing the publication — if the Google projection does not go out, the vacancy is still live and the syndication task retries it.

Rejecting records a reason. The employer sees it, can fix the vacancy and resubmit. A rejection does not consume their credit.

Newsletter/digestThe board operator sends a digest of the board on a schedule, and candidates decide for themselves whether they receive it. A Spotlight purchase makes an already-active vacancy eligible for one newsletter placement — the promotion and the mailing are the same offer.
CSV vacancy bootstrapA CSV import seeds vacancies in bulk when a board is starting out or migrating from somewhere else. It creates drafts only: imported rows enter the same moderation queue as everything else, so a bulk load can never put a listing on the public board.
Google syndicationActive vacancies are published as structured job data and listed in a job sitemap, so search engines can index them as jobs rather than as ordinary pages. That is the only distribution channel in this version — there is no feed to any third-party aggregator.

Vacancies also carry a promotion slot: a Spotlight buys a 14-day pin plus eligibility for one newsletter placement. Featured status is derived from an active promotion rather than a flag someone sets, so it expires on its own.

Candidate profile/resumeA candidate keeps one profile: structured résumé data they can edit by hand, plus the original file they uploaded. They can save vacancies, set up job alerts on stored criteria, apply, and follow every application on a timeline.

Search runs on the database's own full-text index with weighted ranking and hard filters. There is no external search service and no model call on the search path, which is why results are fast and why search keeps working when everything else is degraded. Results explain themselves — a listing can show which of the candidate's skills and constraints matched.

Matching is assistive only. Nothing in Vacanta automatically rejects a candidate, hides them from an employer, or makes an employment decision. A human moves every application.

Saved vacancies and alertsCandidates subscribe to alerts on saved search criteria. These are stored as their own thing, separate from ordinary notification preferences, so a candidate turning off product emails does not silently kill their job alerts.

A scheduled task materializes each due run, resolves the matching vacancies and the recipient list, and sends in bounded batches. One failed recipient never aborts the rest. Suppression, alert pause, unsubscribe, bounce and complaint events are all applied before the next send, and the transactional stream stays separate from the broadcast stream so a bad newsletter cannot damage the reputation that carries password resets.

Apply / withdraw / timelineOne active application per candidate per vacancy, enforced by the database rather than by a check that can be raced.

Submitting captures a snapshot: the vacancy as it stood, its screening questions as they stood, and the candidate's profile as it stood. That is what makes an application defensible months later — the posting can be edited or expire and the application still shows what was actually agreed to.

Screening questions use a fixed, constrained set of question types. This is a job board, not a form builder, and the constraint is what lets the jurisdiction policy reject a prohibited question — such as one asking for salary history — before the vacancy is ever published.

Pipeline stages/notes/ratingSix stages ship by default: Applied, Review, Interview, Offer, and the two terminal stages Hired and Rejected. Employers on the advanced workflow can configure their own.

Moving an application validates the target stage against that company's own stage set and appends a history row recording who moved it, from where, to where, when, and through which surface. The history is append-only — a stage can be corrected but the record of the earlier move is never erased. The candidate is notified according to the company's policy.

Recruiters see only their own company, and within it only the vacancies assigned to them. A company owner sees everything in their company. You see everything everywhere.

Notes and ratings attach to an application. A rating currently rides along with a note rather than being set on its own.

Resume parser configurationParsing runs on a separate worker process you deploy yourself. It is optional, and its absence is a supported state, not an outage.

With the worker configured, an uploaded file is queued and extracted into profile fields a few minutes later. The candidate reviews and confirms; anything they confirm is never overwritten by a later reparse.

Without it, three things still work exactly as before: uploading a file, editing the profile by hand, and submitting an application. Only automatic extraction is unavailable. That ordering is deliberate — an application is written to the database before any parsing is attempted, so a slow or dead worker can never cost a candidate their submission.

If parsing appears to do nothing, check that the worker is configured in the admin integrations area and reachable, and that the parse-dispatch scheduled task is running.

Posting entitlementA purchase creates an entitlement. Publishing consumes exactly one, in a single conditional step with an idempotency key. That design has a practical consequence: a payment webhook that arrives twice, or a publish that is retried, cannot mint a second credit or double-consume one. Balances, purchases and promotion windows all keep an auditable history, and a nightly task reconciles balances against the ledger.
Spotlight promotionSpotlight is a one-time promotion for an already-active vacancy: it adds a 14-day pin and eligibility for one newsletter placement. It does not include a posting credit, and featured status expires with the promotion rather than remaining as a permanent flag.
Employer analyticsEvery active vacancy comes with view, source and application metrics — the standard set, on any credit, including a free one. Employer Pro widens that into richer funnel analytics. A recruiter sees the vacancies assigned to them; the company owner sees the whole company.
Jurisdiction/Launch Free ModeOff by default. Turn it on at /admin/vacanta/settings to open the board at $0 while you build up traffic, optionally with an end date.

While it is on, an approved vacancy still creates and consumes a zero-price entitlement through the same ledger, the same moderation and the same expiry. Free publishing skips the payment, not the process. When you switch it off, entitlement checks apply from that moment.

what's included

The platform underneath the product — counted in this product's own source, not claimed from a template. Where a row carries a list, open it to read the names behind the number.

AlipayCoinbasedLocalFlutterwaveKakaoPayKomojuLemon SqueezyMercado PagoMollieNOWPaymentsOpnPaddlePagSeguroPayPalPaystackRazorpayStripeWeChat Pay
AlipayAppleBitbucketDiscordFacebookFigmaGitHubGitLabGoogleKakaoKeycloakLINELinkedInMicrosoft AzureNaverNotionQQSlackSnapchatSpotifyTwitchVKWeChatWeiboWorkOSXYandexZoom
the schema and build
91page modules
305http operations
85tables
119migrations
154,634lines of source
6roles
measured 2026-08-31release v1.0.9 · built 2026-08-16
85 tables · 138 relationships
organizations55 refsusers41 refsvacancies10 refsapplications3 refsactive_boostsadmin_notificationsalert_deliveriesalert_runsanalytics_dailyanalytics_eventsanalytics_funnelsannouncement_dismissalsannouncementsapi_key_logsapi_keysapplication_answersapplication_notesapplication_stage_historyassistant_actionsassistant_conversationsassistant_messagesassistant_usageaudit_logsauthautomation_logautomation_templatescandidate_profilescompany_profilescredit_balancescredit_transactionscurrenciesdata_exportsdata_importsfaq_categoriesfaq_itemsfeature_flagsinbound_webhook_eventsinbound_webhooksjob_alertsjsonbjurisdiction_profileslanguagesmarketing_audience_membersmarketing_audiencesmoderation_casesnewsletter_definitionsnewsletter_deliveriesnewsletter_runsnotification_lognotification_rulesnotificationsorganization_limit_overridespipeline_stagesplansplatform_secretsplatform_settingsposting_entitlementsproduct_purchasesproductsprovider_pricespush_devicesreport_templatesresume_documentsresume_parse_jobsrolessaved_vacanciesscheduled_tasksseo_metasubscriptionssyndication_statestheme_page_sectionstheme_section_librarytheme_sectionstranslationsuser_sessionsvacancy_assignmentsvacancy_import_jobsvacancy_import_rowsvacancy_lifecycle_historyvacancy_promotionsvacancy_screening_questionsvacanta_email_suppressionsvacanta_idempotency_keysvacanta_parse_callbacksvacanta_settingswebhook_logswebhooks

Hover a table to isolate what it touches; click one to read its relationships. The big nodes are what everything else hangs off. organizations is referenced by 55 tables because every single record in this product belongs to an organization, and that is what makes tenant isolation a property of the database rather than something the application has to remember on every query.

all 85 tables, as text

active_boosts · admin_notifications · alert_deliveries · alert_runs · analytics_daily · analytics_events · analytics_funnels · announcement_dismissals · announcements · api_key_logs · api_keys · application_answers · application_notes · application_stage_history · applications · assistant_actions · assistant_conversations · assistant_messages · assistant_usage · audit_logs · automation_log · automation_templates · candidate_profiles · company_profiles · credit_balances · credit_transactions · currencies · data_exports · data_imports · faq_categories · faq_items · feature_flags · inbound_webhook_events · inbound_webhooks · job_alerts · jurisdiction_profiles · languages · marketing_audience_members · marketing_audiences · moderation_cases · newsletter_definitions · newsletter_deliveries · newsletter_runs · notification_log · notification_rules · notifications · organization_limit_overrides · organizations · pipeline_stages · plans · platform_secrets · platform_settings · posting_entitlements · product_purchases · products · provider_prices · push_devices · report_templates · resume_documents · resume_parse_jobs · roles · saved_vacancies · scheduled_tasks · seo_meta · subscriptions · syndication_states · theme_page_sections · theme_section_library · theme_sections · translations · user_sessions · users · vacancies · vacancy_assignments · vacancy_import_jobs · vacancy_import_rows · vacancy_lifecycle_history · vacancy_promotions · vacancy_screening_questions · vacanta_email_suppressions · vacanta_idempotency_keys · vacanta_parse_callbacks · vacanta_settings · webhook_logs · webhooks

what you need to run Vacanta

The chassis, and anything particular to this product. 2 required, 1 optional.

Node hostrequired

Anything that runs Next.js 16. The scheduled work — vacancy expiry, job alerts, the newsletter — is a cron configuration on the host, not a service you procure. No platform lock-in.

Supabaserequired

The database. Every table, migration and row-level security policy ships with the product and applies itself on first deploy.

Résumé parsing workeroptional

The one thing here that is not an API key: a separate process you deploy and point the app at. It ships OFF, and off is a supported state — candidates enter and edit résumé data by hand, and an application is written before any parsing is attempted, so a slow or dead worker can never cost a candidate their submission.

Already built — plug and play

Every provider integration in this list ships wired into the product. You bring your own keys, connect them in the admin, and go live — there is no integration code to write. Nothing is resold through us: the ongoing cost is whatever these providers charge you. Capabilities marked plan-gated elsewhere on this page unlock by plan, not by extra code.

questions worth answering
What exactly do I receive after purchase?

The complete source repository behind the live demo — 154,634 lines across the application and its database, 85 tables defined by 119 migrations that the shipped scripts apply for you, plus the seed data, the demo accounts and the setup documentation. Not a subset and not a scaffold: the same code that runs the demo you just used.

Is the live demo the same product whose source I receive?

Yes. The Vacanta demo runs the delivered release (v1.0.9), and the build figures on this page are measured from that same source — not from a showcase build kept separately.

Can I test every account role before buying?

Yes — all 4 of them: Candidate, Employer admin, Recruiter, Platform admin. Each one is seeded in the live demo and reachable from the role board above, so you can inspect the product from the customer's side, the agent's side and the administrator's side before you decide.

Is this a complete product or a starter template?

Complete. 91 page modules and 305 HTTP operations, with authentication, roles, billing, an administration panel, background jobs and seeded demo data all wired and running. A template gives you the shape of an application; this is one you can deploy and start operating.

Can I rebrand and modify it?

Yes, without asking. The name, identity, copy, styling and code are yours to change. Rebranding and operating it as your own service is exactly what the licence is for.

What does the licence allow?

A perpetual, worldwide, non-exclusive, non-transferable licence to the product you bought and to every update released for it. The Standard licence covers one business — yours. If you deploy for clients, the Client licence covers up to five. You can modify it, rebrand it, deploy it and charge your own customers.

Can I resell the source code?

No. Reselling, redistributing, sublicensing or giving away the source itself is not permitted under either licence. You build and deliver products with it — the code stays with you.

What services and ongoing costs are required?

You bring your own accounts, so we never mark anything up and there is no ongoing cost to us beyond the purchase. Required: Node host, Supabase. Optional: Résumé parsing worker. The table above says exactly what stops working without each one; most have usable free tiers at low volume.

How difficult is deployment?

Two ways, and most buyers use the first. The installer in your saascode dashboard walks it: you create free accounts at Vercel and Supabase, connect them, and it provisions the database, applies 119 migrations, seeds the data, deploys and verifies the result — you watch the steps go green. Or take the source and do it yourself with the shipped scripts and docs, which is the same sequence run by hand.

What updates and support are included?

Updates to that product for as long as we maintain it — no renewal fee and no expiry date on your access. Support covers download problems, defects in the code as shipped, questions about what the product does and how it is structured, and licence questions. It does not cover debugging your own modifications, building features for you, or setting up your hosting and third-party accounts.

Why does a complete codebase cost $189?

Because it was built once and is distributed many times. SaaSCode builds each product and ships the same finished release through the catalog, so the price reflects repeatable distribution — not a reduced codebase, an unfinished template, or what the same work would cost commissioned.

Do I need to be a developer?

No, for the normal path. You create free accounts at Vercel and Supabase, connect them to the installer in your saascode dashboard, and it does the deployment for you — provision, migrate, seed, deploy, verify. What it asks of you is creating two accounts and copying a token, not writing code. If you would rather deploy it yourself, or host it somewhere else, the full source and the scripts are yours to do that with. Running the product day to day needs no technical skill at all: that happens through its own interface, which is what the demo shows.