FSL-1.1Free to self-host, source available

Every sale gets a receipt.

See which ad earned each payment, on your own server.

your-adledger.com/
AdLedger overview: revenue, ad spend, ROAS, MER, customers and unattributed revenue with a chart of revenue against the previous period
  1. Product tour

    One ledger. Every piece earns its place.

    Real screens from the demo workspace, taken apart.

  2. 01Overview

    Six numbers that run the business.

    Against the previous period, with a one-line briefing.

    • Revenue
    • ROAS & MER
    • CAC
    KPI tiles for revenue, ad spend, ROAS, MER, customers and unattributed revenue
  3. 02Revenue trend

    The trend, not a snapshot.

    This period drawn over the last one, for any range.

    • Any range
    • Any platform
    • Your layout
    Revenue chart for the last 30 days against the previous period
  4. 03Attribution

    Every ad, ranked by money.

    Spend to revenue, down to the single ad.

    • First, last, linear
    • Verified sales
    • CSV export
    Performance table with spend, leads, customers, revenue and ROAS per campaign
  5. 04Live

    Watch sales land in real time.

    Clicks, leads and payments as they happen.

    • Live feed
    • Sale alerts
    • Streamer mode
    Live activity feed with ad clicks, leads and payments
  6. 05CRM & pipeline

    Every lead knows its ad.

    A pipeline tied to the click that started it.

    • Drag to Won
    • One timeline
    • No seats
    Pipeline board with contacts in stages from New lead to Won
  7. 06Reports

    Reports clients can check.

    Branded PDFs from the same SQL as the dashboard.

    • Scheduled
    • Fingerprinted
    • Your logo
    Executive summary report card with a PDF download button
  8. 07Ask AI & MCP

    Ask. Every number is checked.

    Answers read from your ledger, never invented.

    • Any model
    • Local LLMs
    • MCP server
    Ask tab with suggested questions about campaigns, spend and platforms
  9. 08Security layer

    Security you can see.

    On by default, free for everyone.

    • 2FA
    • Audit chain
    • AES-256-GCM
    Security checklist for this install
  10. Put it back together. It’s yours.

    One ledger, on a server you control.

Ad platforms grade their own homework. AdLedger checks it against your bank.

  • 9ad platforms
  • 7payment sources
  • 1.7 KBfirst-party pixel
  • $0unlimited seats
Inside

Built for one question: which ad made money?

Ad receipts

Every payment shows the ads that earned it.

Truth gap

Platform claims, checked against real payments.

Profit per ad

After refunds, fees and cost of goods.

Alerts & goals

Hear about a bad day before the invoice does.

CRM pipeline

Every lead remembers the ad that brought it.

API, webhooks & MCP

Every number is one request away.

Integrations

Plugs into what you already use.

  1. 1Click
  2. 2Lead
  3. 3Payment
  4. 4Ad spend

Ad platforms9 native

Payments & stores7 native

Anything elseCSV + API

Your websitepixel + plugins

Notifications6 channels

AI modelsbring your own

Every integration has a demo mode. Brand marks from Simple Icons (CC0); trademarks belong to their owners. Connectors other than Meta, Google Ads and Stripe are in beta.

Security & compliance

Your server. Your data. Your audit trail.

  • GDPR & UK GDPR
  • CCPA / CPRA
  • ePrivacy & PECR
  • SOC 2-aligned controls
  • ISO 27001 mapping
  • OWASP ASVS
  • Two-factor sign-in and custom roles
  • Hash-chained audit log with Verify
  • AES-256-GCM secrets, hashed emails
  • Non-root, scanned image with an SBOM

No certification badges: you run AdLedger, so the audit is yours. Compliance mapping · Trust & Security

Install your way

Running in minutes, whoever you are.

Every path ends in your browser. No config files.

Deploy to a cloud platform

Render or Railway, next to a managed database.

Show every step

On Render

  1. Click Deploy to Render and sign in to Render.
  2. Review the blueprint. Render reads render.yaml: a web service, a PostgreSQL 16 database and a randomly generated APP_SECRET. Pick a name and apply it.
  3. Wait for the first build. It usually takes 5 to 10 minutes. The service turns live once the health check at /api/v1/health passes.
  4. Open your .onrender.com address and create your owner account. Choose Explore with demo data to look around first.

On Railway

  1. Fork AdLedger to your GitHub account.
  2. New project → Deploy from GitHub repo, and pick your fork. railway.json tells Railway to build the Dockerfile and watch /api/v1/health.
  3. Add a PostgreSQL database to the project, then add this variable to the AdLedger service:
    DATABASE_URL=${{Postgres.DATABASE_URL}}
  4. Generate a domain under the service’s networking settings, open it, and create your account.

What to expect

  • HTTPS is automatic on the platform address, and you can add your own domain in its settings.
  • Costs are the platform’s: the Render blueprint uses a paid starter service and a small database, and Railway bills by usage. Check their pricing pages.
  • Updates: redeploy from the platform dashboard. Database migrations run on start.
  • Your data lives in the platform’s managed PostgreSQL, in your account.

Recommended on Railway

  • Also set APP_SECRET to a long random value, so the encryption key isn’t stored next to your data. Render generates one for you.

Docker Desktop on your computer

The easiest way to try it for real.

docker compose up -d
Show every step
  1. Install Docker Desktop from docker.com and open it. Wait until it says the engine is running. It’s free for personal use, education and small businesses.
  2. Download AdLedger. Download the ZIP and unzip it (the folder is called adledger-main), or clone it with Git:
    git clone https://github.com/ShubhamVankalas/adledger
  3. Open a terminal in that folder. On Windows, right-click the folder and choose Open in Terminal. On a Mac, open Terminal, type cd and a space, drag the folder into the window and press Return.
  4. Start AdLedger with one command:
    docker compose up -d
    The first start downloads or builds the app and its database, which takes a few minutes. After that it starts in seconds.
  5. Open localhost:3000 and create your owner account. Passwords need at least 15 characters.
  6. Explore. Choose Explore with demo data for 90 days of realistic data, or follow the setup checklist to connect your site, payments and ads.

What to expect

  • Stop and start with docker compose stop and docker compose start. Your data stays in a Docker volume.
  • Update with docker compose pull then docker compose up -d. Migrations run on start.
  • Going live? Your laptop is perfect for trying it. Real tracking needs a public HTTPS address for the pixel and payment webhooks, so move to a server or a platform then.
Shortcut: a demo with no setup screen (Mac or Linux terminal)
ADMIN_EMAIL=admin@example.com \
ADMIN_PASSWORD=adledger-demo-123 \
DEMO_DATA=true docker compose up -d

One line on any Linux server

With free HTTPS, on 1 GB of RAM.

curl -fsSL https://raw.githubusercontent.com/ShubhamVankalas/adledger/main/install.sh | DOMAIN=ads.yourcompany.com sh
Show every step
  1. Point your domain. Create a DNS A record, for example ads.yourcompany.com, pointing at your server’s IP address. Do this first so the HTTPS certificate can be issued.
  2. Connect and check Docker. SSH into the server. No Docker yet? Install it with:
    curl -fsSL https://get.docker.com | sh
  3. Run the installer with your domain:
    curl -fsSL https://raw.githubusercontent.com/ShubhamVankalas/adledger/main/install.sh | DOMAIN=ads.yourcompany.com sh
  4. Open https://ads.yourcompany.com and create your account.

What to expect

  • What the script does: creates ./adledger with docker-compose.yml and a .env of random secrets, starts PostgreSQL, AdLedger and Caddy, and gets a free Let’s Encrypt certificate.
  • Firewall: allow ports 80 and 443.
  • No domain yet? Leave out DOMAIN= to run on http://SERVER-IP:3000 for a trial.
  • Upgrades: run the same command again, or docker compose pull and docker compose up -d in ./adledger.
  • Backups: back up the database volume, and keep APP_SECRET somewhere else.
  • Better tracking: use a subdomain of your shop, such as t.yourshop.com, so cookies are first-party.

Run from source

One Node process with an embedded database.

pnpm install && pnpm dev
Show every step
  1. Clone and install. corepack enable provides pnpm if you don’t have it.
    git clone https://github.com/ShubhamVankalas/adledger
    cd adledger
    corepack enable
    pnpm install
  2. Start the dev server and open localhost:3000. With no DATABASE_URL, it uses an embedded PostgreSQL (PGlite) in ./.data.
    pnpm dev
  3. Configure only if you want to. Every environment variable is optional and documented in .env.example: DATABASE_URL for your own Postgres, CONNECTOR_MODE=mock for mock connectors, LLM_MODEL for an AI model.
  4. Check your change. Tests run on an embedded Postgres with every connector mocked; set TEST_DATABASE_URL to use a real one.
    pnpm lint && pnpm typecheck && pnpm test

Good to know

  • Stack: Next.js 16, React 19, TypeScript, PostgreSQL 16 with Drizzle, Tailwind v4.
  • Read first: Architecture, API, MCP and Contributing.
  • Your own image: docker compose up -d --build builds the production container locally.
FAQ

Questions, answered honestly.

More in the FAQ on GitHub.

Where does my data go?

It stays on your server. AdLedger has no telemetry and sends nothing to us. The only outside calls are the ones you set up: ad platform syncs, payment backfills, notifications, and your AI model if you pick a cloud one.

Raw emails are kept in one table. Everywhere else, emails and phone numbers are stored as SHA-256 hashes. IP addresses are shortened before storage, the pixel doesn't fingerprint, and connector credentials are encrypted at rest. The pixel supports consent (adledger.consent(false)) and Do-Not-Track.

The AI model only sees campaign totals, never contacts. The MCP server is read-only and masks emails. As with any analytics tool, mention it in your privacy notice and cookie banner.

Does it still work after Apple's iOS tracking changes?

Mostly, because it doesn't rely on what Apple restricted. App Tracking Transparency limits tracking across apps, which hurts the ad platforms' own pixels. AdLedger uses a first-party pixel on your own site and gets payments straight from Stripe or your store by webhook, so a sale is recorded even when the ad platform can't see it.

Some limits remain. Safari keeps cookies set by scripts for 7 days at most, so if someone clicks an ad and comes back more than a week later without having filled in a form, the first click can be missed. Safari's Link Tracking Protection also strips click IDs such as gclid and fbclid in Mail, Messages and Private Browsing. UTM parameters are kept, which is why the recommended UTM templates carry campaign and ad IDs. Serving AdLedger from a subdomain of your site keeps the cookie first-party and makes ad blockers less likely to block it.

How accurate is it?

Exact about the money it can see, and open about what it can't. Every payment is stored to the cent, and split credit always adds up to the payment.

It counts clicks, not views. Someone who saw an ad and later typed your address directly isn't credited to that ad, and there are no estimated or modelled conversions. So your numbers won't match Meta's or Google's reports, which include view-throughs, modelled conversions and their own attribution windows. Ad blockers and strict browsers can hide some visits. Journeys across devices are joined only when the person leaves the same email (or phone number) on each one. Revenue without a tracked click is shown as unattributed rather than guessed.

There are three rule-based models (first touch, last touch and linear), with no data-driven model yet. Ad and payment connectors other than Meta, Google Ads and Stripe are in beta.

What does self-hosting cost?

The software is free to self-host (source available under FSL-1.1), with no per-seat or revenue-based pricing. You pay only for where it runs. It needs about 1 GB of RAM, which a small VPS covers for a few dollars a month. Render and Railway work too, at their own prices.

Your laptop is fine for trying it, but the pixel and payment webhooks need a public HTTPS address, so use a server for real tracking. The one-line installer sets up HTTPS for free. AI is optional: Ollama or LM Studio costs nothing, and a cloud model costs whatever its provider charges for one short note a week.

What is the licence?

AdLedger is source available under the Functional Source License (FSL-1.1-ALv2). You can install it, use it for your own business and read or change the code, all for free. You can't sell it or offer it as a competing product or hosted service. Two years after each release, that version becomes Apache-2.0. It is not an OSI-approved open source licence.

Do I need developer accounts?

Not to try it. The demo workspace fakes every integration, so you can explore everything first.

For real data, payment tools mostly need no developer account: you paste a key or webhook secret from the dashboard (for Stripe, one restricted key). PayPal is the exception, and needs a free REST app at developer.paypal.com. Ad platforms are stricter. Meta needs a free Business app to create a token with ads_read. Google Ads and Microsoft Ads need a developer token, and X needs Ads API access for your app. Google's and X's approvals can take a few days, so apply early. TikTok, LinkedIn, Pinterest, Snapchat and Reddit each need a free developer app. Each integration card in the app walks you through the steps.

Want to skip all of that? Export spend as a CSV from any ads manager and upload it, or send it to the Spend API.

Is AdLedger SOC 2, ISO 27001 or GDPR compliant?

No badges, on purpose. SOC 2 and ISO 27001 audit an organisation running a service, not a codebase. When you self-host AdLedger, you are the data controller, so there is nothing for us to certify.

What we can say: AdLedger is GDPR-ready and ships SOC 2-aligned controls, with a mapping to ISO 27001 themes. It is built to help you meet GDPR, UK GDPR, CCPA/CPRA, ePrivacy and PECR, and India’s DPDP. It is not designed for health data, card data or children’s data. The details are in the compliance mapping and on the Trust & Security page.