- Python 88%
- HTML 8.2%
- JavaScript 2.4%
- CSS 1.1%
- Dockerfile 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks failed
CI / Unit tests and coverage (Python 3.14) (pull_request) Successful in 16m10s
CI / Checks: lint, migrations, catalogues, settings, built files (pull_request) Successful in 2m15s
CI / Database tests on PostgreSQL (pull_request) Successful in 4m40s
CI / Security audit (pull_request) Successful in 32s
CI / Browser tests (Chromium) (pull_request) Successful in 36m5s
CI / Unit tests and coverage (Python 3.14) (push) Successful in 15m10s
CI / Checks: lint, migrations, catalogues, settings, built files (push) Successful in 1m56s
CI / Database tests on PostgreSQL (push) Successful in 4m34s
CI / Security audit (push) Successful in 24s
README / README language tables (push) Successful in 21s
CI / Browser tests (Chromium) (push) Successful in 34m48s
Dev image / Dev image: build, scan, push (push) Failing after 40m39s
French and Portuguese (Portugal) filled for every string added since the last merge, the 0.5 languages kept as Weblate has them, and the wiki unchanged here. Built as a signed merge with main as first parent, because main takes signed commits only and Weblate's own commit is not signed. Closes #1240 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
| .forgejo | ||
| .github | ||
| assets | ||
| catalogue/official | ||
| docker | ||
| docs | ||
| scripts | ||
| src/postulo | ||
| tests | ||
| .dockerignore | ||
| .editorconfig | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| .python-version | ||
| ACCESSIBILITY.md | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.md | ||
| FUNDING.md | ||
| LICENSE | ||
| manage.py | ||
| package-lock.json | ||
| package.json | ||
| pyproject.toml | ||
| README.md | ||
| SECURITY.md | ||
| THIRD-PARTY.md | ||
| TRADEMARKS.md | ||
| uv.lock | ||
Postulo
Self-hosted job application manager, from the applicant's side of the table.
Every applicant tracking system is built for the company doing the hiring. Postulo is built for the person applying: your applications, your CVs, your cover letters, your data, on your server.
From the Latin postulō — "I apply for". First person, deliberately.
Status: pre-1.0. Usable and used, but not battle-tested: it has recorded real applications, by one person, for weeks rather than years. Releasing here is a deliberate act rather than something that happens on a schedule, so
mainmay be ahead of the last tag — the changelog says by how much.
![]() |
![]() |
![]() |
![]() |
These pictures are of a demo instance filled with a fictional job search, and are retaken by
scripts/screenshots.py rather than by hand. There is no public demo to try: it would be
something to host, reset and secure, and nobody's data belongs on it. Run your own with
manage.py seed_demo <email>; the wiki
shows every page.
Never paywalled
No feature of Postulo is, or ever will be, behind a paywall. People looking for work are, more often than not, people who cannot afford to pay for the tools to find it. Everything this software does is available in full to everyone who runs it: no paid tier, no "pro" edition, no licence key, no feature that unlocks later. The licence guarantees that for the code; this paragraph guarantees it for the project's intentions.
If it is worth something to you
Voluntary support is this project's only income. Not its main one — its only one. There is no company behind Postulo, no funding round, no paid tier waiting to appear once enough people depend on it. One person writes it, and what it costs to keep going comes from people who decided it was worth something.
Nothing is owed. Nothing is unlocked by it, now or later — that is what the paragraph above promises and it is not negotiable. And nothing a person is shown while using Postulo to look for work will ever ask for money: no banner in the interface, no prompt, no reminder on the dashboard. The one place inside the application that mentions support at all is Server settings → Overview, the page addressed to whoever runs the instance, where it is said once and in these words. Otherwise this is where the question is put, which is why it is put plainly here.
If money is the wrong thing to give — and for a lot of people looking for work, it is — then a bug report, a translation reviewed by somebody who actually speaks the language, or telling one person who needs this that it exists are all worth as much.
FUNDING.md is the long version: what support pays for, what it will never buy, and why money does not move an issue up the list.
Secure, because of what it holds
Postulo holds the most personal documents a person has while looking for work, and it is built as if that were the only thing that mattered. A CV carries a home address, a phone number and a full employment history; a timeline says who has and has not replied. So the code and the data are kept as secure as the project knows how to make them: every record is owned and every query is scoped -- No one sees another person's data unless that person granted it -- explicitly, for a stated scope, revocably, and visibly to them at any time. Superusers can see and change any company, contact or listing, including private ones, but never anyone's notes, applications or documents. Files are never served without a permission check, the browser is held to a strict content security policy, nothing is fetched from the network without a deliberate decision, and the test suite includes security tests — ownership sweeps, policy checks, the things an attacker would try — that fail the build. Dependencies are checked for known vulnerabilities on every run and on a schedule, so a fresh disclosure is noticed without anyone having to remember to look. A security report is handled before any feature is; see SECURITY.md.
Built for everyone
Postulo is meant to be usable by everyone, at its fullest, including people with disabilities. Looking for work is hard enough without the tool getting in the way. So the interface is server-rendered HTML that works with scripts off, every control can be reached and operated from the keyboard, images and icons carry names or are marked as decorative, colour never carries a meaning on its own, changes on the page are announced to screen readers, and the pages are checked against the accessibility guidelines (WCAG 2.2, level AA) as part of the browser tests rather than as an afterthought. When a feature cannot be made to work for someone, that is a bug, and it is filed as one. ACCESSIBILITY.md is the accessibility statement: what is checked and how, what is known not to work yet, and how to report a barrier.
What it does
- Track applications end to end — from a posting you spotted to an offer, with an append-only timeline that records what actually happened and when.
- Manage CVs as structured, reusable career content: write an experience once, then compose targeted CV variants from it without copy-pasting between documents.
- Manage cover letters from reusable templates with per-application placeholders.
- Keep what you actually sent. Every document is snapshotted to PDF at send time, so six months later you know exactly which version that employer read.
- Bring your own files. Externally authored PDFs and DOCX files are stored and versioned alongside generated ones.
- Capture postings from a URL — Postulo reads the page and asks you to confirm it before recording anything. Extensible through plugins, and reachable through a small API for scripts and browser extensions.
- See what is working — how far applications get, what share are answered, how long employers take, and which sources convert. Read from the timeline, so an interview that ended in a rejection still counts as an interview.
- Take everything with you — one zip holding a readable JSON document of every record and every file, which imports back.
Principles
- Your data is yours. Full JSON + media export, always one command away.
- No telemetry. Outbound requests only for the features listed in the wiki's Hardening page.
- Private by default. Uploaded documents are never publicly served.
- Secure by obligation. Ownership-scoped queries, permission-checked files, a strict content security policy, security tests in the suite, and dependency vulnerability checks in CI. See SECURITY.md.
- Accessible to everyone. Keyboard-operable, screen-reader-announced, usable with scripts off, and checked against WCAG 2.2 AA in the browser tests.
- Boring, durable stack. Django, SQLite or PostgreSQL, server-rendered HTML.
- Modular by design. Anything that could reasonably vary — where a posting is read from, how you are told about things, how a PDF is produced — sits behind an interface that a separately installed package can implement. Postulo's own implementations are plugins that happen to ship in the box. See Writing a plugin.
Written with AI, answered for by people
Much of Postulo is written with an AI assistant, and contributions made the same way are welcome. The rule is simple: a person proposes the change, has read it, can explain it, and answers for it. The assistant is a tool; the contributor is accountable. See CONTRIBUTING.md and AGENTS.md.
In your language
The interface is a setting per person; the documentation is in English, and the table below says what Postulo is in each language so nobody has to guess. Translations are made, corrected and reviewed at translate.tiagoagueda.com (docs/TRANSLATING.md), where the live progress of every language is.
Postulo speaks 57 languages, each named here as its speakers write it.
| Language | What Postulo is | |
|---|---|---|
| azərbaycan | Postulo öz serverinizdə yerləşdirilən iş müraciətləri meneceridir: müraciətləriniz, CV-ləriniz və müşayiət məktublarınız öz serverinizdə, heç bir ödənişli funksiya olmadan. | |
| Bahasa Indonesia | Postulo adalah pengelola lamaran kerja yang dihosting sendiri: lamaran, CV, dan surat lamaran Anda di server Anda sendiri, tanpa fitur berbayar. | |
| bosanski | Postulo je upravitelj prijava za posao koji hostujete sami: vaše prijave, CV-ovi i propratna pisma na vašem vlastitom serveru, bez plaćenih funkcija. | |
| català | Postulo és un gestor de candidatures autoallotjat: les vostres candidatures, CV i cartes de presentació al vostre propi servidor, sense funcions de pagament. | |
| crnogorski | Postulo je samostalno hostovan menadžer prijava za posao: vaše prijave, CV-jevi i propratna pisma na vašem sopstvenom serveru, bez plaćenih funkcija. | |
| Cymraeg | Rheolwr ceisiadau am swyddi hunanletyol yw Postulo: eich ceisiadau, eich CVs a'ch llythyrau eglurhaol ar eich gweinydd eich hun, heb unrhyw nodweddion taledig. | |
| dansk | Postulo er et selvhostet værktøj til at styre jobansøgninger: dine ansøgninger, CV'er og ansøgningsbreve på din egen server, uden betalingsfunktioner. | |
| Deutsch | Postulo ist eine selbst gehostete Verwaltung für Bewerbungen: Ihre Bewerbungen, Lebensläufe und Anschreiben auf Ihrem eigenen Server, ohne kostenpflichtige Funktionen. | |
| eesti | Postulo on isehostitav kandideerimiste haldur: teie kandideerimised, CV-d ja motivatsioonikirjad teie enda serveris, ilma tasuliste funktsioonideta. | |
| English (Canada) | Postulo is a self-hosted job application manager: your applications, résumés and cover letters on your own server, with no paid features. | |
| English (United Kingdom) | Postulo is a self-hosted job application manager: your applications, CVs and cover letters on your own server, with no paid features. | |
| español | Postulo es un gestor de candidaturas de empleo autoalojado: sus candidaturas, CV y cartas de presentación en su propio servidor, sin funciones de pago. | |
| español (México) | Postulo es un administrador de solicitudes de empleo de alojamiento propio: sus solicitudes, currículums y cartas de presentación en su propio servidor, sin funciones de pago. | |
| euskara | Postulo norberaren zerbitzarian ostatatzen den hautagaitza-kudeatzaile bat da: zure hautagaitzak, CVak eta aurkezpen-gutunak zure zerbitzarian, ordainpeko funtziorik gabe. | |
| français (Canada) | Postulo est un gestionnaire de candidatures auto-hébergé : vos candidatures, CV et lettres de présentation sur votre propre serveur, sans fonction payante. | |
| français (France) | Postulo est un gestionnaire de candidatures auto-hébergé : vos candidatures, CV et lettres de motivation sur votre propre serveur, sans fonction payante. | |
| føroyskt | Postulo er ein sjálvhýstur umsitari av starvsumsóknum: umsóknir tínar, lívsrásir og umsóknarbrøv á tínum egna ambætara, uttan nakrar eginleikar, sum skulu gjaldast fyri. | |
| Gaeilge | Is bainisteoir iarratas poist féinóstáilte é Postulo: d’iarratais, do CVanna agus do litreacha cumhdaigh ar do fhreastalaí féin, gan aon ghnéithe íoctha. | |
| galego | Postulo é un xestor de candidaturas de emprego autoaloxado: as túas candidaturas, CV e cartas de presentación no teu propio servidor, sen funcións de pago. | |
| hrvatski | Postulo je samostalno hostiran upravitelj prijava za posao: vaše prijave, životopisi i popratna pisma na vašem vlastitom poslužitelju, bez plaćenih značajki. | |
| italiano | Postulo è un gestore di candidature self-hosted: le tue candidature, i tuoi CV e le tue lettere di presentazione sul tuo server, senza funzioni a pagamento. | |
| latviešu | Postulo ir savā serverī mitināts darba pieteikumu pārvaldnieks: jūsu pieteikumi, CV un pieteikuma vēstules jūsu pašu serverī, bez maksas funkcijām. | |
| lietuvių | Postulo yra savarankiškai talpinama darbo paraiškų tvarkyklė: jūsų paraiškos, gyvenimo aprašymai ir motyvaciniai laiškai jūsų pačių serveryje, be mokamų funkcijų. | |
| Lëtzebuergesch | Postulo ass e selwer gehosten Organisateur fir Kandidaturen: Är Kandidaturen, CVen a Motivatiounsbréiwer op Ärem eegene Server, ouni bezuelt Funktiounen. | |
| magyar | A Postulo egy saját üzemeltetésű álláspályázat-kezelő: a jelentkezései, önéletrajzai és motivációs levelei a saját szerverén, fizetős funkciók nélkül. | |
| Malti | Postulo huwa maniġer tal-applikazzjonijiet għax-xogħol li tospita int stess: l-applikazzjonijiet, is-CVs u l-ittri ta' akkumpanjament tiegħek fuq is-server tiegħek, mingħajr ebda funzjoni bi ħlas. | |
| Nederlands | Postulo is een zelfgehost programma om sollicitaties te beheren: uw sollicitaties, cv’s en sollicitatiebrieven op uw eigen server, zonder betaalde functies. | |
| norsk bokmål | Postulo er et selvhostet verktøy for jobbsøknader: søknadene, CV-ene og søknadsbrevene dine på din egen server, uten betalte funksjoner. | |
| norsk nynorsk | Postulo er eit sjølvdrifta verktøy for jobbsøknader: søknadene, CV-ane og søknadsbreva dine på din eigen tenar, utan betalte funksjonar. | |
| polski | Postulo to samodzielnie hostowany menedżer aplikacji o pracę: Twoje aplikacje, CV i listy motywacyjne na Twoim własnym serwerze, bez płatnych funkcji. | |
| português (Brasil) | O Postulo é um gerenciador de candidaturas a vagas auto-hospedado: suas candidaturas, currículos e cartas de apresentação no seu próprio servidor, sem recursos pagos. | |
| português (Portugal) | O Postulo é um gestor de candidaturas de emprego alojado por si: as suas candidaturas, CV e cartas de apresentação no seu próprio servidor, sem funcionalidades pagas. | |
| română | Postulo este un manager de candidaturi auto-găzduit: candidaturile, CV-urile și scrisorile de intenție pe propriul dumneavoastră server, fără funcții plătite. | |
| rumantsch | Postulo è in administratur da candidaturas ch'ins ospitescha sez: Vossas candidaturas, Voss CV e Vossas brevs d'accumpagnament sin Voss agen server, senza funcziuns a pajament. | |
| shqip | Postulo është një menaxher aplikimesh për punë që e strehoni vetë: aplikimet, CV-të dhe letrat e motivimit tuaja në serverin tuaj, pa veçori me pagesë. | |
| slovenčina | Postulo je správca žiadostí o miesto, ktorý si hostujete sami: vaše žiadosti, životopisy a motivačné listy na vašom vlastnom serveri, bez platených funkcií. | |
| slovenščina | Postulo je samostojno gostovan upravitelj prijav na delovna mesta: vaše prijave, življenjepisi in spremna pisma na vašem lastnem strežniku, brez plačljivih funkcij. | |
| suomi | Postulo on itse ylläpidettävä työhakemusten hallintasovellus: hakemuksesi, ansioluettelosi ja saatekirjeesi omalla palvelimellasi, ilman maksullisia ominaisuuksia. | |
| svenska | Postulo är en självhostad hanterare för jobbansökningar: dina ansökningar, CV:n och personliga brev på din egen server, utan betalfunktioner. | |
| Türkçe | Postulo kendi sunucunuzda barındırılan bir iş başvurusu yöneticisidir: başvurularınız, CV'leriniz ve ön yazılarınız kendi sunucunuzda; ücretli özellik yok. | |
| íslenska | Postulo er sjálfhýst kerfi til að halda utan um atvinnuumsóknir: umsóknirnar þínar, ferilskrár og kynningarbréf á þínum eigin netþjóni, án nokkurra greiddra eiginleika. | |
| čeština | Postulo je správce žádostí o místo, který si hostujete sami: vaše žádosti, životopisy a motivační dopisy na vašem vlastním serveru, bez placených funkcí. | |
| Ελληνικά | Το Postulo είναι ένα αυτοφιλοξενούμενο εργαλείο διαχείρισης αιτήσεων εργασίας: οι αιτήσεις, τα βιογραφικά και οι συνοδευτικές επιστολές σας στον δικό σας διακομιστή, χωρίς επί πληρωμή λειτουργίες. | |
| беларуская | Postulo — менеджар заявак на працу для самастойнага размяшчэння: вашы заяўкі, рэзюмэ і суправаджальныя лісты на вашым уласным серверы, без платных функцый. | |
| български | Postulo е самостоятелно хостван инструмент за управление на кандидатури за работа: вашите кандидатури, автобиографии и мотивационни писма на собствения ви сървър, без платени функции. | |
| македонски | Postulo е самостојно хостиран менаџер за пријави за работа: вашите пријави, CV и мотивациски писма на вашиот сопствен сервер, без платени функции. | |
| српски | Postulo је менаџер пријава за посао који сами хостујете: ваше пријаве, CV-ови и пропратна писма на вашем сопственом серверу, без плаћених функција. | |
| українська | Postulo — це самостійно розміщуваний менеджер заявок на роботу: ваші заявки, резюме й супровідні листи на вашому власному сервері, без платних функцій. | |
| қазақ тілі | Postulo — өз серверіңізде орнатылатын жұмыс өтінімдерін басқару құралы: өтінімдеріңіз, түйіндемелеріңіз және ілеспе хаттарыңыз өз серверіңізде, ақылы мүмкіндіктерсіз. | |
| հայերեն | Postulo-ն աշխատանքի դիմումների կառավարիչ է, որը տեղակայում եք ինքներդ․ ձեր դիմումները, CV-ները և մոտիվացիոն նամակները՝ ձեր սեփական սերվերում, առանց վճարովի գործառույթների։ | |
| اردو | Postulo ایک سیلف ہوسٹڈ ملازمت کی درخواستوں کا منیجر ہے: آپ کی درخواستیں، CV اور کور لیٹر آپ کے اپنے سرور پر، بغیر کسی ادائیگی والی خصوصیت کے۔ | |
| العربية | Postulo مدير لطلبات التوظيف تستضيفه بنفسك: طلباتك وسيرك الذاتية وخطابات التقديم على خادمك الخاص، دون ميزات مدفوعة. | |
| हिन्दी | Postulo एक सेल्फ़-होस्टेड नौकरी आवेदन मैनेजर है: आपके आवेदन, CV और कवर लेटर आपके अपने सर्वर पर, बिना किसी पेड फ़ीचर के। | |
| বাংলা | Postulo একটি স্ব-হোস্টেড চাকরির আবেদন ব্যবস্থাপক: আপনার আবেদন, সিভি ও কভার লেটার আপনার নিজের সার্ভারে, কোনো পেইড ফিচার ছাড়াই। | |
| ქართული | Postulo არის საკუთარ სერვერზე განსათავსებელი სამუშაო განაცხადების მართვის პროგრამა: თქვენი განაცხადები, CV-ები და თანმხლები წერილები თქვენს საკუთარ სერვერზე, ფასიანი ფუნქციების გარეშე. | |
| 简体中文 | Postulo 是一款自托管的求职申请管理工具:你的申请、简历和求职信都保存在你自己的服务器上,没有任何付费功能。 | |
| 繁體中文 | Postulo 是自行架設的求職應徵管理工具:您的應徵、履歷和求職信都在您自己的伺服器上,沒有任何付費功能。 |
Documentation
- The wiki — installing, configuring and using Postulo. Its pages are their own repository, postulo.wiki.
- Implementation plan — architecture, data model, and milestones
- Writing a plugin — the plugin contract, and every name a plugin may import
Running it
git clone https://source.tiagoagueda.com/postulo/postulo.git
cd postulo
git checkout vX.Y.Z # the latest release tag, see the releases page
cp .env.example .env # set POSTULO_SECRET_KEY and POSTULO_ALLOWED_HOSTS
docker compose -f docker/compose.yml up -d
docker compose -f docker/compose.yml exec postulo python manage.py createsuperuser
That pulls the published image. To build it from the checkout instead, add the build
override: docker compose -f docker/compose.yml -f docker/compose.build.yml up -d --build.
Then put a reverse proxy in front of it for TLS. See Installing Postulo for the full instructions, including installing without a container.
Development
Requires Python 3.12.4 or newer and uv.
uv sync # install dependencies
cp .env.example .env # configure (a dev SECRET_KEY is generated if unset)
uv run manage.py migrate
uv run manage.py createsuperuser
uv run manage.py runserver
PDF export uses WeasyPrint, which is installed with Postulo. On Linux it needs Pango:
sudo apt install libpango-1.0-0 libpangoft2-1.0-0 libharfbuzz-subset0 # Debian and Ubuntu
Those libraries are awkward to obtain on Windows, so a fallback renderer exists there:
uv sync --extra chromium
uv run playwright install chromium
Postulo uses whichever works, preferring WeasyPrint. Export is optional: tracking applications and writing letters need no renderer at all.
Node is not required to run Postulo: the compiled stylesheet and the page script the browser is served are committed. It is only needed to change the CSS, to add a Tailwind class a template did not use before, or to change the page script, in which case:
npm install
npm run watch:css # or `npm run build:css` for a one-off
npm run build:js # after a change to assets/js/app.js
To see it with data rather than an empty screen, fill an account with a fictional search — thirty applications over six months, with documents:
uv run manage.py seed_demo you@example.org
Tests and linting:
uv run pytest
uv run ruff check .
uv run ruff format .
Licence
Copyright (C) 2026 Postulo contributors. AGPL-3.0-or-later. If you run a modified Postulo as a network service, your users are entitled to its source.
Some of what ships in the repository is somebody else's work under a licence of its own: the Lucide icons, the flag-icons country flags, Tailwind CSS and basecoat-css compiled into the stylesheet, htmx and zxcvbn served as scripts. All of it is copied into the repository, so nothing is fetched from anybody else's server at runtime, and each carries its notice beside it. THIRD-PARTY.md is the register.
The name and the logo are not covered by that licence. TRADEMARKS.md
says what you may do without asking — which is nearly everything, including naming a plugin
postulo-something and calling your instance whatever you like — and the one case where a
fork should use another name. It also names the marks belonging to other people that appear
here, and none of their owners is involved with this project.
Where this lives
Developed on Forgejo and mirrored to GitHub. Issues and pull requests belong on the Forgejo repository; the GitHub copy is a read-only mirror. A bug or a request has a form there (see CONTRIBUTING.md); a security problem does not go in an issue, see SECURITY.md. Everyone taking part is held to the code of conduct.





