Finance, jobs and time entries, ad accounts' log
Revenue net of pass-through, monthly cost allocated by deliverable
Margin by client and accrual month, effort by person
Partners' meeting, renegotiation and internal agent
What it solves
- A margin per client that ties to the agency's real cost and revenue.
- Effort comparable across clients, even without time entries.
- Every number says how much of the base it covers, so nobody decides on 1% of the data.
Business questions it answers
Ask your agent these questions once the case is live.
What you need
- The agency's finance data connected, with revenue and expense classification
- At least one source of effort: job ERP, task manager or the ad accounts' activity log
- Revenue per client from the portfolio case, with CNPJ as the key
What you get
- A client x accrual month table with revenue, allocated cost, margin and a reason when one side is missing
- Effort by client, person and activity type, with the measurement source declared
- A client ranking by window margin, not monthly margin
- An internal AI agent that answers about margin with the right caveats
Where to activate
Client ranking by window margin, with the margin without media commission alongside.
Revenue per estimated hour and the trend in the client's effort since the last price increase.
Answers about margin and effort with coverage and the nature of the cost already declared.
It needs classified finance data and an effort source with an identified client. Most of the time goes into matching clients across systems and deciding, in writing, how cost is allocated. The detailed view has the business rules, the pitfalls and the acceptance test. Or send everything straight to your agent with the Nekt MCP.
Almost no agency logs hours for real: in one real base, less than 1% of deliverables had any time recorded. Finance revenue mixes retainers, media commission and third-party money that only passes through the account, and the client appears under the legal name, which does not match the name in the job system. Whoever crosses logged hours with the whole invoice gets a margin with the wrong sign, and whoever uses an inner join loses half of the client-months without noticing.
How it is usually done, and the rule
Each row is a mistake that already happened in practice.
Ad delivery and boosting billed on the client's behalf, pass-through media budget and production paid to third parties stay out of both sides: they are neither revenue nor cost. Media commission is agency revenue; confirm it through the finance subcategory and by the absence of payments to the media vendor in the same base. Also show the margin without media commission, which measures how much the agency depends on it.
Allocate the month's real operating cost across the deliverables (pieces, jobs) recorded in the month. Where a deliverable has a list price, use it as a complexity weight within the priced subset; unpriced deliverables get the simple allocation. The sum of allocated cost ties exactly to the month's cost. Record each row's route (weighted or simple). Partner draws are not cost and come out after margin.
Treat a month as closed when its number of expense entries reaches at least 30% of the median of recent months. An open month gets a null cost with a written reason, never zero: zero would make the current month's margin explode.
Publish the coverage of each effort measure: hours logged over deliverables, actions over accounts. If hours cover a small fraction of deliverables, they cannot support cost per hour. Hourly cost and allocated cost sit side by side for comparison and are never added: they are the same cost by two paths.
Media agencies without timesheets can measure effort through the ad accounts' activity log: count only actions by people (actor_name different from Meta itself) and split ad creation, status changes and budget changes. Convert with a declared factor (for example, 1 action = 10 minutes) and call the result estimated hours until real hours exist.
The number of tasks, messages and actions measures operational energy, not results, and logged hours are not capacity. Read volume next to the client's results (leads, cost per result) and pressure signals (stalled tasks, tasks with no owner). Never rank people by count alone.
In finance, the client appears under the legal name, which often contains none of its brands. Match revenue and cost on CNPJ (company tax ID), or CPF (individual tax ID) for individual clients. When a source only has a name, normalize it (lowercase, no accents, letters and digits only) and keep an alias table. Deliverables with no identified client go on their own flagged row and never mix with a real client.
Use a full join between cost and revenue by client and accrual month. When revenue is missing in a month, the margin is not the negative cost; when deliverables are missing, it is not the whole revenue: the monthly margin is null, with the missing side written down. Because the deliverable lands in one month and the invoice in the next, the client ranking uses the margin summed over the whole window, not the monthly one.
Classify each time entry by the department of whoever logged it (creative, media, content, planning, production) and the free-text description by rules: client meeting, internal meeting, changes and jobs. Rework requested by the client and internal rework are different codes and are not added together as one thing.
The margin table exposes how much each relationship earns and which ones lose money. It never goes to the client portal or into the context of an agent that serves clients. Named payroll enters aggregated by month, so no employee data reaches the table.
How to measure effort, best to worst
Use the best measure the data supports and declare which one was used.
Definitions
Pitfalls that already happened
Without knowing whether media inflow was gross or commission, the first version published one positive and one negative margin and left the choice to the reader. The finance subcategory itself said it was commission.
Prove the nature of media revenue in the data before computing margin.
The deliverables data ran up to the current month, but expenses were only posted up to months earlier. Recent margin looked extremely high.
Cost only for closed months, detected by the number of entries.
Cost and revenue by client and month were joined with an inner join. Only part of the pairs had both sides, and the rest vanished without warning.
Full join, with the missing side flagged.
Media came with one client name and effort with another. Before normalization and the alias table, almost no rows matched.
Normalize names and keep an alias table until a shared client id exists.
Clients billed without any deliverable in the job system got zero cost and appeared at the top of the ranking.
Null cost, not zero, when no deliverable is recorded.
The accounts' activity log mixes actions by people with changes made by the platform itself, such as delivery started and billing.
Count only actions whose author is not the platform.
Acceptance test
The case is done when every item passes.
- In each closed month, the cost allocated to all clients (plus the no-document row) equals the month's operating cost (zero difference).
- The table has one row per client and accrual month, with no repeats.
- No row has a computed margin when revenue or cost is missing.
- A client's estimated hours for the week match the count of human actions in the log times the declared factor.
- No on-behalf billing enters agency revenue.
Agent package
Paste into Claude, ChatGPT or any client with the Nekt MCP connected.
Profitability per client (internal use, never for clients) - Agency revenue = retainer + media commission + own revenue. On-behalf billing and pass-through budget are neither revenue nor cost. - The client's cost is allocated: the month's real operating cost spread across the month's deliverables, weighted by list price when it exists. It is an allocation, not a measurement. - A month without complete expenses has no cost and no margin. Do not estimate. - Margin is null when revenue or cost is missing. For client rankings, use window margin. - Partner draws are not cost. - Effort without timesheets: human actions in the accounts' log (author other than the platform) x 10 minutes = estimated hours. Always say it is an estimate and report coverage. - Task or message volume is not productivity. - The client is the CNPJ. Do not join by name. Client exceptions: - <client>: group with CNPJs <list>, summed only on read. - <client>: retainer includes management of a <value> budget; the budget is pass-through.
Build the "Profitability per client" case in my Nekt workspace following the rules at https://academy.nekt.com/en/industrias/agencias/rentabilidade-por-cliente.md. 1) Find the source tables and confirm the columns the rules use. 2) Create a transformation at the stated grain applying every rule. 3) Run the acceptance test and show me the result of each item. 4) Create the case's context document in the workspace, leaving my clients' exceptions open for me to fill in.
Variations
Human actions per person and week, split into creation, status and budget, read alongside the accounts' results.
When time entries are reliable, hours by client, job and department, with meetings, changes and rework separated.
Fee per completed deliverable, using only the fee in the numerator, never the pass-through.