API Key Client Grouping for Resellers and Multi-Tenant SaaS
If you're an agency, contracting firm, or SaaS operator embedding a PDF generation API into a service used by multiple clients, the most painful monthly task is usually the same: figuring out which key belongs to which client, and how much each client used.
FUNBREW PDF solves this with client labels and tags on every API key. Generated PDFs, API logs, and usage data can all be filtered and aggregated per client, with CSV exports that include the client label so you can produce billing-allocation evidence in one click. See the full reseller patterns on the use cases page.
This guide walks through the operational pattern and best practices for reseller scenarios.
Why API key grouping matters
Common operational pain points
- Manual invoice allocation: spending the last day of every month aggregating "Acme used 10,000, Beta used 3,000" by hand
- Logs that can't be sliced: when something breaks for one client, you have to search the entire log stream
- Tribal knowledge: "wait, whose key is
sk-xxxxxagain?" — newcomers can't tell
What grouping fixes
| Pain point | After grouping |
|---|---|
| Manual invoice allocation | Just look at the client_label column in the CSV |
| Filtering logs | One click per client |
| Tribal knowledge | Visible at a glance in the dashboard |
When to use client_label vs tags
When in doubt, use the table below. The rule of thumb: the unit you want to split invoices by goes in client_label; everything else is a tag.
client_label |
tags |
|
|---|---|---|
| Count | Exactly one | Multiple allowed |
| Role | Primary axis for billing and aggregation | Sub-classification (environment, use case, etc.) |
| Example | Acme Inc |
production, invoice-pdf |
| CSV export | Included as the client_label column (invoice evidence) |
Not exported today — dashboard-only |
| Naming drift | Breaks filtering — use a strict convention | More forgiving |
How to use it
Step 1: Tag each API key with client information
Dashboard → API Keys → "New key" or "Edit" on an existing key.
- Key name: an internal label (e.g.
Acme Production) - Client / Project: the client company or project name (e.g.
Acme Inc) - Tags: environment or purpose (e.g.
production,invoice-pdf)
Tip: When you issue several keys for the same client (per environment, per use case), set the same
client_labelon all of them. The dashboard will then aggregate them into a single client view.
Step 2: Filter PDFs and logs by client
The PDF list and API log pages now have a "Client" filter.
If multiple keys share the same client_label (e.g. Acme's production key and staging key), the filter shows PDFs from both keys combined. The aggregation happens at the client level, not the key level.
Step 3: Export CSV for billing allocation
Running CSV export from the PDF list produces:
filename,original_name,source_type,file_size,download_count,...,api_key,client_label
abc123.pdf,"acme-invoice-2026-04.pdf",html,254078,1,...,Acme Production,Acme Inc
def456.pdf,"beta-contract.pdf",html,128400,2,...,Beta Production,Beta Corp
Pivot on client_label and you instantly have per-client generation counts, file sizes, and download counts. Monthly billing becomes nearly self-serve.
Best practices by reseller scenario
Scenario 1: Agency model (separate billing per client)
client_label: "Acme Inc" tags: ["production"]
client_label: "Acme Inc" tags: ["staging"]
client_label: "Beta Corp" tags: ["production"]
client_label: "Gamma Studio" tags: ["production", "trial"]
- Group monthly CSV by
client_label→ use as the basis for each client's invoice - Mark trials with a
trialtag and update toproductionon conversion
Scenario 2: Multi-tenant SaaS
client_label: "tenant_001" tags: ["plan:pro", "production"]
client_label: "tenant_002" tags: ["plan:enterprise", "production"]
- Use the tenant ID as
client_labelso it joins cleanly against your own DB - Keep plan info in tags to detect overage candidates
Scenario 3: Project-based contracting
client_label: "Project Alpha" tags: ["delivered", "support-2026"]
client_label: "Project Beta" tags: ["development"]
- Tag delivered projects with
delivered, and usesupport-yyyyfor active warranty windows - Pull only the relevant logs when a support ticket lands
Design considerations
Grouping is a management label
client_label and tags are metadata for filtering and aggregation in the dashboard. They do not change API behavior (rate limiting, billing, scopes). To enforce per-client rate limits, keep using separate keys; grouping just makes them easier to manage.
Keep keys safe
Rather than handing API keys directly to clients, the recommended reseller pattern is to proxy client requests through your own backend, which holds the FUNBREW PDF key. Issue separate keys per client, label them, and a leak only impacts one client — rotation stays surgical.
Decide on a naming convention up front
When several people manage keys, label drift (Acme Inc / acme inc / Acme Inc.) breaks filtering. Agree on a convention (e.g. legal name, single space, no honorifics) before you start tagging.
Summary
For anyone reselling a PDF generation API, key grouping makes three things dramatically easier: invoice allocation, support response, and operational handoffs.
client_labelaggregates per clienttagsslice further by environment or purpose- CSV exports automate billing allocation
Already issued keys? Just edit them in the dashboard to add client_label and tags — past PDFs and logs are filterable retroactively.
Read the full documentation or head to the API keys dashboard to start grouping. To experiment with the API itself first, try the playground. For a broader take on invoice automation, see the invoice API guide.
Cost allocation patterns
Beyond simple per-client grouping, many resellers need to track costs at a finer granularity — by cost center, billing period, or service tier. The patterns below combine client_label with tags to build a lightweight cost allocation system without external tooling.
Pattern: per-department cost centers
When a single enterprise client has multiple internal departments, issue one key per department and set the department name as a tag. Keep the client_label consistent across all departmental keys so the CSV rolls up cleanly at the account level.
client_label: "Acme Corp" tags: ["dept:finance", "production"]
client_label: "Acme Corp" tags: ["dept:legal", "production"]
client_label: "Acme Corp" tags: ["dept:marketing", "production"]
At month end, export the CSV and pivot first by client_label (for the invoice to Acme Corp) and then filter by the dept:* tags to produce per-department breakdowns for their internal showback reports. No extra infrastructure needed.
Pattern: tiered pricing with usage caps
SaaS operators who resell PDF generation at different plan tiers can encode the tier in a tag and enforce limits programmatically.
client_label: "tenant_A" tags: ["plan:starter", "production"] # cap: 500 PDFs/mo
client_label: "tenant_B" tags: ["plan:growth", "production"] # cap: 5 000 PDFs/mo
client_label: "tenant_C" tags: ["plan:enterprise", "production"] # cap: unlimited
Your billing service queries the FUNBREW PDF API for monthly usage per key, compares it against the cap for each plan, and either blocks generation or triggers an upsell flow. Because the plan is in the tag, plan changes only require updating one field — no structural changes to your key topology.
Pattern: project-lifecycle cost tracking
For agencies billing project-by-project, you often need to distinguish pre-production spend (scoping, prototyping) from production spend billed to the client.
client_label: "Project Omega" tags: ["phase:prototype", "internal"]
client_label: "Project Omega" tags: ["phase:production", "billable"]
Filter the CSV for billable to produce the client-facing invoice. Keep the internal rows for your own P&L tracking. When the project closes, add a delivered tag and stop rotating the keys — the label history stays in the CSV archive.
Usage alert patterns
Proactive usage monitoring prevents bill shock and helps you enforce plan limits before they become support incidents. Because FUNBREW PDF exposes usage data through its API, you can build lightweight alerting with standard tooling.
Alerting with a cron script
// scripts/usage-alert.js
// Run daily via cron or a scheduled Lambda to warn before clients hit their caps
import axios from 'axios';
const API_KEY = process.env.FUNBREW_API_KEY;
const API_URL = process.env.FUNBREW_API_URL || 'https://api.pdf.funbrew.cloud/v1';
const SLACK_WEBHOOK = process.env.SLACK_WEBHOOK_URL;
// Map client labels to their monthly PDF caps
const LIMITS = {
'Acme Inc': 5000,
'Beta Corp': 1000,
'Gamma LLC': 2500,
};
async function checkUsage() {
const { data } = await axios.get(`${API_URL}/usage/monthly`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
for (const [client, usage] of Object.entries(data.byClient)) {
const cap = LIMITS[client];
if (!cap) continue;
const pct = (usage.count / cap) * 100;
if (pct >= 90) {
await sendSlackAlert(client, usage.count, cap, pct);
}
}
}
async function sendSlackAlert(client, used, cap, pct) {
const msg = `*PDF usage alert* — ${client}: ${used.toLocaleString()} / ${cap.toLocaleString()} PDFs (${pct.toFixed(0)}%)`;
await axios.post(SLACK_WEBHOOK, { text: msg });
}
checkUsage().catch(console.error);
Wire this to a cron job or an AWS EventBridge rule and you get a Slack ping when any client exceeds 90% of their cap — before they hit the wall.
Using webhook events for real-time tracking
If you prefer event-driven monitoring, the FUNBREW PDF webhook integration fires on every successful PDF generation. Subscribe to the pdf.created event and pipe it to your counting logic:
// Pseudocode: increment a Redis counter per client on every pdf.created event
app.post('/webhooks/pdf', async (req, res) => {
const { event, payload } = req.body;
if (event !== 'pdf.created') return res.sendStatus(204);
const client = payload.client_label;
const key = `usage:${client}:${currentMonth()}`;
await redis.incr(key);
await redis.expire(key, 60 * 60 * 24 * 35); // keep for ~35 days
// Check against cap
const count = await redis.get(key);
const cap = LIMITS[client];
if (cap && count >= cap * 0.9) {
await triggerAlert(client, count, cap);
}
res.sendStatus(204);
});
This gives you sub-second usage counters per client without polling the API. See the webhook payload guide for the full event schema.
Client onboarding flow
Bringing a new client online consistently is harder than it sounds when you have a dozen keys in flight. The following checklist and code snippet standardize onboarding to three minutes or less.
Onboarding checklist
- Create API key(s) — one per environment (production + staging minimum)
- Set
client_label— use the client's legal entity name or tenant ID (decide convention first) - Set tags — environment (
production,staging), plan tier (plan:growth), and any other axes you filter on - Add to LIMITS map — update your usage-alert script with the client's cap
- Share credentials securely — do not email raw keys; use a secrets manager or a one-time-link tool
- Smoke-test — generate one PDF via the playground with the new key to confirm it works
- Document — add the client to your internal key registry (even a spreadsheet works if the naming is consistent)
Automating key creation
For high-volume onboarding, create keys via the FUNBREW PDF REST API rather than the dashboard:
# Create a production key for a new client
curl -X POST https://api.pdf.funbrew.cloud/v1/api-keys \
-H "Authorization: Bearer $FUNBREW_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Inc — Production",
"client_label": "Acme Inc",
"tags": ["production", "plan:growth"]
}'
Store the returned key value in your secrets manager immediately — it is shown only once. Then update your LIMITS map and alert subscriptions before the client sends their first request.
Offboarding a client
When a client relationship ends, rotate or revoke the key(s) from the dashboard. The historical CSV data remains queryable by client_label even after the key is revoked, so you can still produce a final usage report for the closing invoice.
# Revoke a key (replace KEY_ID with the actual key ID)
curl -X DELETE https://api.pdf.funbrew.cloud/v1/api-keys/KEY_ID \
-H "Authorization: Bearer $FUNBREW_MASTER_KEY"
After revocation, export a final CSV filtered to that client_label and archive it alongside the project files. Any future support queries can be answered from the archive without needing live API access.
Putting it all together
The three capabilities above — grouping, cost allocation, and alerting — compose naturally into a lightweight client management layer on top of the FUNBREW PDF API.
| Capability | Mechanism | Maintenance effort |
|---|---|---|
| Per-client visibility | client_label on every key |
Once at onboarding |
| Invoice evidence | CSV export, pivot by client_label |
Monthly, ~5 minutes |
| Sub-client chargebacks | tags like dept:finance |
Once per cost center |
| Plan enforcement | Usage API + cron script | One-time setup |
| Real-time tracking | Webhook → Redis counter | One-time setup |
| New client onboarding | Dashboard or REST API | Per client, ~3 minutes |
For teams generating high PDF volumes, also review the batch processing guide and the rate limiting guide — both become relevant once a single client starts pushing thousands of PDFs per hour.
For security considerations around key storage and rotation across multiple clients, the API security guide covers secret management, proxy patterns, and audit logging in detail.