---
title: "Billing, ad-server fees and referral billing"
description: "Record advertiser and publisher payments, track balances, read your network's ad-server fees and AI assistant usage, and run referral-program billing."
type: "howto"
audience: [admin, network-manager]
keywords: [billing, payments, balances, ad server fees, billing statistics, overage, referral billing, revenue, accounting period, confirmation status, preliminary confirm, confirm, finalize, reopen, finalized, aggregate data, recalculate, AI assistant usage]
ui_path: "Account → Billing"
---

Fetch the complete documentation index at: https://epom.com/ad-server/docs/llms.txt. Use this file to discover all available pages before exploring further. Append .md to any documentation page URL to get its markdown version.

# Billing, ad-server fees and referral billing

Money reaches three screens. **Account → Billing** is where you record real-world payments
and watch what each advertiser and publisher owes. **Admin → Billing & fees → Ad server fees**
shows what Epom charges your network: the plan in force, the monthly billing statistics and
the AI assistant usage. *Referral program billing*, in the same group, pays commission to
users who brought clients in.

None of these screens computes anything live. Every figure on them is read out of a
pre-aggregated table or re-derived by a scheduled job — see
[Where the numbers come from](#where-the-numbers-come-from) before you reconcile
anything against an analytics report.

## Who this is for

Network administrators. Each screen is gated separately — Billing by the
network user's role, the admin pages by the admin role. See
[Manage users, roles and permissions](https://epom.com/ad-server/docs/guides/admin/users-and-roles.md). Two things to know before you
hand out access:

- **Billing is not an admin page.** It lives under `/account/**`, which an admin-role
  session cannot reach at all. An administrator who needs Billing must be on a network-side
  role (Network Manager and friends), not an admin role.
- **Ad server fees is read-only for you.** The plan, its prices and quotas are agreed with
  Epom; to change plan, or to question a month's figures, contact Epom support or your account manager.

Billing also obeys share-based visibility: a user whose campaign or inventory *view*
permission is **shared** rather than **all** — an account manager, typically — sees
payments and balances only for the advertisers and sites shared with them, and can record
or remove payments only for those.

The network billing management permission (*Billing Tab*) covers only the network's own books with its
advertisers and publishers. The [AI assistant](https://epom.com/ad-server/docs/guides/collaboration/ai-assistant.md) is billed to the
network on Epom's invoice instead, so its usage report sits on the **Ad Server Fees** page and, like
the right to set per-user assistant limits, takes the *Ad-server fees* admin permission.

## Prerequisites

- Aggregate data populated. Balances and the summary cards read the publisher and advertiser
  aggregate tables, which scheduled jobs refill from the ad logs — they are never computed on
  page load.
- For referral billing: the referral program enabled and bracket percentages agreed. See
  [Referral program](https://epom.com/ad-server/docs/guides/collaboration/referral-program.md).

## Steps

### Record payments and track balances

1. Go to **Account → Billing**.
   ![Billing page with monthly summary cards, revenue trend and the advertiser payments panel](https://epom.com/docs-images/ad-server/finances-and-billing/billing-page.webp)
2. Read **Current month summary** and **Last month summary**. Each shows up to five lines;
   you see the advertiser lines, the publisher lines, or both, depending on which half of
   Billing your role holds, and **Network net revenue** only with both:

   | Line | What it is |
   |---|---|
   | Network net revenue | Advertisers charged minus Publishers net revenue |
   | Publishers paid-off | Sum of the publisher payouts you recorded this month |
   | Advertisers credits | Sum of the advertiser payments you recorded this month |
   | Advertisers charged | Advertiser spend for the month, from the aggregate table |
   | Publishers net revenue | Publisher earnings for the month, from the aggregate table |

   **Last six months trends** plots Network net revenue per month and only appears when you
   hold both halves.
3. Record money that actually moved. In **Advertisers funds**, pick the advertiser, type an
   **Amount**, set the **Date** and an optional **Comment**, then click **Add payment**.
   **Publishers payments** works the same way for payouts. A green *Done* toast confirms the
   save, the grid reloads, and the entity's balance is adjusted for that month and every
   month after it.
4. To correct a mistake, tick the payment rows and click **Delete**. You are asked to
   confirm; the balance is adjusted back by the same amount. There is no edit — remove and
   re-add.
5. Read the **Network financial balance** panel. It holds two grids side by side, both of
   them for the **Year** and **Month** you pick at the top of the panel:

   | Advertiser grid | Publisher grid |
   |---|---|
   | Advertiser, Start balance, Payments, Charges, **End balance** | Publisher, Balance, Paid, **To be paid** |
   | End balance = Start balance − Charges + Payments | To be paid = Balance − Paid |

   Each grid has its own name search, a **Category** filter and an eye toggle that hides
   rows with no activity in the month.
6. Click **Recalculate balances** (top right of the panel) after you have backfilled
   or corrected analytics, and confirm. This rebuilds **all** balances for
   **all** months, not the year and month selected above, and it runs in the background —
   expect it to take a while. A plain error toast means it could not start; try again later,
   and ask Epom support or your account manager if it keeps failing. It works with either half's permission.

> **Note:** rebuilding the advertiser and publisher aggregates from the first day of logs is
> done by Epom support, not from a button you have. Ask them, then click **Recalculate
> balances**.

### Read your ad-server fees

1. Go to **Admin → Billing & fees → Ad server fees**.
   ![Ad server fees page with the active plan card and the billing statistics grid](https://epom.com/docs-images/ad-server/finances-and-billing/fees-dashboard.webp)
2. Read the plan card of the plan marked **ACTIVE** — the one your network is billed on:
   its monthly price, the impression and traffic quotas it includes, and the overage prices
   charged above them.
3. Read **Billing statistics** at the bottom of the page. One row per month, filtered by
   multi-select **Year** and **Month**: the impression counts, traffic in GB, the overage
   amounts, **Charges**, **Custom charges** and **Total**.
4. Read **AI assistant usage** below it: pick a month to see what each user's
   [AI assistant](https://epom.com/ad-server/docs/guides/collaboration/ai-assistant.md) chats cost — one row per user and key
   (own, network or platform), with requests, input and output tokens, the amount spent and the
   user's effective monthly limit. Only rows on the platform's key carry a charge; the total
   above the grid is what the assistant adds to the network's invoice for that month.

> **Note:** the plan, its prices and quotas, and the AI assistant billing terms are set by
> Epom. To change plan, or to have a month's record recalculated after a data correction,
> contact Epom support or your account manager.

### Run referral billing

Commission rows are not created by hand. A scheduled job regenerates the **current** month's
rows every hour, and a second job regenerates the **previous** calendar month four times a
day, at 01:23, 02:23, 03:23 and 04:23 server time — every day, not only at the start of the
month. A row is only ever rewritten while it is still *Unconfirmed*, so the moment you mark
one *Confirmed*, *Paid* or *Declined* the job leaves it alone. Commissions below one cent
produce no row. Everything below is about steering and settling those rows.

1. Go to **Admin → Billing & fees → Referral program billing**.
   ![Referral program billing page with bracket editors, the payment filter and the commission ledger](https://epom.com/docs-images/ad-server/finances-and-billing/referral-ledger.webp)
2. Maintain two bracket tables side by side. The left one, *Currently active brackets — in
   effect since \<the 1st of this month\>*, saves with **Apply now**. The right one,
   *Brackets — activates on \<the 1st of next month\>*, saves with **Schedule for next
   month**. Each row is an **Upper bound ($)** and a **Share (%)**; **Add bracket** inserts a
   row above the trailing *and above* row, which is always open-ended. Neither table is ever
   empty: a network that has never configured brackets shows one open-ended row carrying the
   network's flat referral rate, and adding rows above it turns that flat rate into the top
   band.
3. Rates are **marginal**: each bracket's share applies only to the slice of revenue inside
   that bracket, the way an income-tax band works — not to the whole amount.
4. Optionally tick **Hide referral details** in the **Referral display preferences**
   section and click its own **Save**. The checkbox does not save by itself.
5. Use **Filter / add payment** to narrow the ledger by referral user, referred user, year,
   month and status. **Year** starts at the current year. The same row adds a manual payment:
   pick both users, type an **Amount** and optional **Comments**, then click **Add**. **Add**
   stays disabled until a referral user, a referred user and an amount are all set.
   **Reset** returns the filters to that starting state.

   > **Note:** the **Referral users** list is not every user who has referred someone. A
   > referrer only appears there when their own role has the **Manage Referral Program**
   > permission enabled. With that permission off for every role, the list is empty and no
   > manual payment can be added — even though the ledger below may be full of rows. The
   > **Referred users** list then fills from whoever the chosen referrer actually referred.
6. Work the ledger grid. Columns are Referral, Referred users, Year, Month, Amount,
   **Status**, **Analytics status** and Comments. Tick rows and pick a **New status** +
   **Apply** to bulk-update, **Export to CSV** to download the filtered ledger, or
   **Delete** to remove rows. Double-click a row to edit its amount, status and comments in
   a dialog.
7. Read the footer: **Total** is every row except *Declined*, **Confirmed** is only the
   *Confirmed* rows, **Paid** only the *Paid* rows — all three over the current filter.

## Where the numbers come from

Every money figure on these screens is a sum over the same daily table the General analytics
report reads. Nothing here has hour resolution and nothing here is
current as of now.

| Figure | Source | Refreshed |
|---|---|---|
| Advertisers charged, and the advertiser grid's **Charges** | The sum of *Gross* per advertiser per day, kept in a daily advertiser summary | Scheduled job every 4 hours, rewriting the last **14 days** |
| Publishers net revenue, and the publisher grid's balances | The sum of *Net* per site per day, each row floored at its minimal revenue, kept in a daily publisher summary | Scheduled job every 4 hours, rewriting the last **14 days** |
| Network net revenue | Derived on read: Advertisers charged − Publishers net revenue | With the two above |
| Ad server fees impression counts | A General analytics report for the calendar month, grouped by placement type, run as the network user | Nightly |
| Ad server fees **Traffic (gb)** | CDN traffic for your network as measured by Epom | With the above |
| Referral commission base | The sum of the Publisher-family *Revenue* for the referred user's sites, each row floored at its minimal revenue, read straight from the daily statistics | Live at generation time — no aggregate in between |

Three things follow from that table and they cause most reconciliation tickets:

**Fee impressions are bucketed by placement type, and the mapping is not obvious.**

| Bucket | Placement types counted into it |
|---|---|
| Desktop | Site Placement, Non-standard Placement, Email Placement, Click-through Placement, **Native Placement** |
| Video | Video Placement |
| Mobile | Everything else — Mobile Site Placement, Application Placement, and any placement type added in future |

**Money is stored at six decimals and rounded once, at the end.** Every summary and balance
figure is kept to six decimal places; the fee charge is computed at full precision and scaled to
six decimals, half-up. The screens then format to exactly two decimals for display. Nothing
is rounded before it is summed.

**Analytics rounds in the opposite order,** which is why a report and a balance can differ
by cents. An analytics report rounds *each result row* to the report's funds precision
(2 decimals on screen; the network's export precision, or 8 decimals, in an export) and then
recomputes Profit from the already-rounded Gross and Net. Group a report by day and you
accumulate one rounding per day; Billing subtracts at full precision and rounds once. When
the two disagree by small amounts, this is almost always why.

> **Corner case:** the referral ledger and the Billing page do not read the same figure.
> Publisher revenue on Billing comes from *Net*; the referral commission base comes from the
> Publisher-family *Revenue*. On a network that populates the split advertiser/publisher column family
> these two are genuinely different numbers, and referral commissions will not reconcile
> against Billing's *Publishers net revenue* no matter how fresh the data is.

> **Corner case:** the advertiser and publisher aggregate fills are switched separately. The
> publisher fill is a server-side setting that is off by default (ask Epom support or your account manager to turn
> it on), while the advertiser fill always runs. The symptom is
> distinctive: *Advertisers charged* climbs normally, *Publishers net revenue* stays at 0.00,
> and *Network net revenue* therefore equals *Advertisers charged*. If you see that shape, the
> data is not missing — the publisher job never ran.

> **Corner case:** the scheduled fills only rewrite the **last 14 days**. A correction to a
> day older than that will never reach Billing on its own. Ask Epom support or your account manager to rebuild the
> aggregates from the first day of logs, then click **Recalculate balances**.

## Accounting periods

An **accounting period** is one advertiser's revenue for one day, carrying a *confirmation
status* that says how settled that day's money is. You move a day up the ladder as you
reconcile it, and **Finalized** seals it.

The controls are not on this page. They are per-row buttons on an **Analytics** report
grouped by **Advertiser** alone, or by Advertiser + Advertiser owner — see
[Run a report](https://epom.com/ad-server/docs/guides/analytics/run-report.md). Select advertiser rows there, and the buttons
act on those advertisers across the report's whole date range.

### The states

| Id | State | How a day gets there |
|---|---|---|
| 0 | Unidentified | No status recorded |
| 1 | Incomplete Data | The day is still accruing |
| 2 | Up-to-Date Data | Tracked data for the day is complete |
| 3 | Preliminary Confirmed | **Preliminary confirm** |
| 4 | Confirmed | **Confirm** |
| 5 | Finalized | **Finalize accounting period** |

Only the last three transitions have buttons. Nothing on the report moves a day from
*Incomplete Data* to *Up-to-Date Data*. Saving an advertiser re-evaluates that advertiser's
days against its own confirmation-delay setting, but only when the user saving it holds the
*Manage Completeness Delay for Advertisers* permission. A row still at *Incomplete Data*
shows every period button greyed out.

Each forward step needs its own permission, and each button additionally checks the **share
level** of every
selected advertiser against the network's sharing-type requirement for that step. Those
requirements are set in the **Accounting period management** card on **Admin → Inventory &
campaigns settings**, as three separate lists: *Sharing type requirement for preliminary
confirming*, *…for confirming* and *…for finalizing*.

### Reopening a finalized period

Step the period back down with the paired **Undo** buttons on the same report: **Undo
finalize period** takes Finalized → Confirmed, **Undo confirm** takes Confirmed →
Preliminary Confirmed, **Undo preliminary confirm** takes it one step further back. An undo
needs the permission of the status you are leaving, so reopening a finalized day needs the
finalize permission, exactly as sealing it did. Once the day is below Finalized, run your
correction and climb the states again.

> **Note:** the undo buttons are the only reopen mechanism — there is no separate "reopen
> period" screen. Each click moves the stored status by exactly one level.

## Options and fields

### Monthly statistics row

| Column | What it is |
|---|---|
| Global / Desktop / Mobile / Video | Impressions counted in each bucket for the month |
| Traffic (gb) | CDN traffic for the month |
| …overage columns | Money charged for usage above each quota |
| Charges | The plan's fixed monthly charges |
| Custom charges | A manual adjustment stored on the month record |
| Total | Every overage + Charges + Custom charges |

### Concepts

| Concept | Notes |
|---|---|
| Payment row | A bookkeeping fact about money that moved outside the platform. It adjusts balances; it moves no money |
| Balance recalculation | Full re-derivation of every balance from the aggregates, run in the background |
| Billing plan | Epom's fee package for your network. Exactly one is active at a time |
| Referral bracket | A revenue range and a commission share. Marginal — each share applies only to its own slice |
| Accounting period | One advertiser × one day, with a confirmation status. Finalized locks it |

## Corner cases and gotchas

> **Corner case:** the two halves of the Billing page are gated independently, but the
> **balance grids are not**. A user holding only *Publishers Payments* loses the
> *Advertisers funds* panel, the *Advertisers credits* and *Advertisers charged* summary
> lines and the trend chart — but still sees the full **advertiser** balance grid, because
> that one is gated by *Billing Tab* alone.

> **Corner case:** a fee month stops being rebuilt four days in. The current month is
> re-derived every night, and the *previous* month only while today is within the first four
> days of the new month. From the fifth onwards last month's row is frozen; raise a question
> about it with Epom support or your account manager.

> **Corner case:** a period button acts only on rows that are all at the same status. Select
> a mix and the button greys out. If you force the request anyway it is refused rather than
> partially applied, and days inside the range that are not at the expected status are
> silently left alone — there is no per-row report of what did or did not move.

> **Corner case:** an invalid bracket set is rejected as a whole — if any row fails, nothing
> is saved. The error toast restates the rules rather than naming the offending row:
> *"Brackets are invalid. Upper bounds must increase. Share must be between 0 and 100. Last
> bracket may be unbounded."* With more than two or three bands, check them yourself against
> those three rules; the message will not point at the one that broke.

> **Corner case:** a referral user with a per-user share configured does not use the bracket
> table at all — their commission is a flat percentage of the referred user's revenue. The
> brackets on this page apply only to referral users without that override.

> **Corner case:** an *Unconfirmed* commission amount is not stable. The hourly job
> recomputes it from the month's revenue so far and overwrites the row, so a figure you noted
> this morning can be larger by the afternoon. Move a row to *Confirmed* before you treat its
> amount as settled — that is what stops the job rewriting it.

> **Corner case:** editing brackets does not restate a month that has already been
> generated with the old ones. **Apply now** changes what the current month's *Unconfirmed*
> rows are recomputed to on the next hourly run; rows already Confirmed or Paid, and closed
> earlier months, keep the numbers they were generated with.

> **Corner case:** the **Analytics status** column in the referral ledger is not the payment
> status. It is the *lowest* accounting-period confirmation status across every advertiser
> whose traffic ran on that referred publisher's sites that month — the weakest link. It
> stays at *Incomplete Data* until every contributing advertiser's days have moved up, and
> reads *Unidentified* when no status has been recorded for them.

## Over the API

An advertiser's payments are listed, added and removed per advertiser, with the same permissions, share checks and
balance bookkeeping as the **Advertiser payments** grid:

- `GET /rest-api/advertiser/{advertiserId}/payments.do` — the payments newest first (`year`, `month` narrow them,
  `start` / `limit` page them), `totalAmount` over everything the filters match, and `balance` — the advertiser's
  balance row (start balance, charges, payments, end-of-month balance) for `balanceMonth` (`yyyy-MM`, the current
  month when left out), or `null` while none has been calculated for that month.
- `POST /rest-api/advertiser/{advertiserId}/payments.do` with `amount` (greater than 0), `date` (`yyyy-MM-dd`,
  today when left out) and an optional `comment` (up to 200 characters). The balance rows from that month on move by
  the amount, exactly as when you add a row on the page. A field the server refuses comes back under `errors.<field>`.
- `DELETE /rest-api/advertiser/{advertiserId}/payments/{paymentId}.do` — removes it and takes it back out of the
  balances.

There is no currency or payment-type field — payments are in the network's currency — and no edit: remove the payment
and add it again, as on the page. The calls need the same permissions as the page's
advertiser half; an advertiser that is not shared with you, a payment of another advertiser
or an unknown payment answers *not found*.

Publisher payouts work the same way, per site, with the **Publisher payments** grid's rules:
`GET /rest-api/site/{siteId}/payouts.do` (payouts newest first, `totalAmount`, and `balance` — balance, paid out and
still to be paid for `balanceMonth`), `POST` on the same path to book one (`amount`, `date`, `comment`, as above) and
`DELETE /rest-api/site/{siteId}/payouts/{paymentId}.do` to remove one. They need the same
permissions as the page's publisher half; a site that is not shared with you answers *not
found*.

## Per-role notes

- **Administrator** — reaches the fee and referral pages its admin role grants, never Account →
  Billing; switch into a network user to see Billing.
- **Network manager** — reaches Billing only with *Billing Tab* enabled; otherwise the page
  shows *Permission denied*.
- **Shared or half-only roles** — see only the advertisers and sites shared with them, and only
  the half (advertiser funds or publisher payments) they hold; the server refuses the other
  half, over the API too.
- **Publisher, advertiser** — no Billing section.

Exact grants: see [Manage users, roles and permissions](https://epom.com/ad-server/docs/guides/admin/users-and-roles.md).

## Related

- [Referral program](https://epom.com/ad-server/docs/guides/collaboration/referral-program.md)
- [Pricing](https://epom.com/ad-server/docs/guides/delivery/pricing.md)
- [Rules and default settings](https://epom.com/ad-server/docs/guides/admin/rules-and-defaults.md)
- [Run a report](https://epom.com/ad-server/docs/guides/analytics/run-report.md)