UGC campaign analytics
A UGC campaign spread over 30 creator accounts on four platforms produces hundreds of posts. Clients want one answer: what did it get? This guide covers which numbers to report, how to pull them per post, account and campaign, and how to use them to pick winners.
Updated
The numbers that matter
UGC is a volume game, so report on totals and spread, not single posts. These are the metrics UGC API reads back from each platform for every published post:
| Metric | What it tells you |
|---|---|
| Views | Reach of the content. The main number for top-of-funnel UGC. |
| Likes | Basic approval. Useful for comparing hooks. |
| Comments | Conversation. High comments on a product post often mean questions worth answering. |
| Shares | The strongest signal of a clip that travels. |
| Saves | Intent to come back. Strong for how-tos and carousels. |
| Reach | Unique people who saw it, where the platform reports it. |
Numbers come from TikTok, Instagram, Facebook and YouTube and refresh hourly. Not every platform reports every metric, so a post may have views and likes but no saves.
Three levels of reporting
Per post
GET /v1/posts/:id returns each result with its own metrics and metrics_at, the time the numbers were last read. Use it when a client asks about one video.
Per account
GET /v1/stats?account_id=acc_tt_04 returns one creator's totals for the date range. Use it to compare creators and to spot accounts that underperform over weeks, not days.
Per campaign
GET /v1/posts?campaign_id=cmp_xyz lists every post in a campaign, each with a metrics summary. Page through with cursor and sum the numbers. Add platform=tiktok to split by platform.
The stats endpoint
For a period report across everything, call GET /v1/stats with from and to. Add account_id for one creator.
curl "https://ugcapi.dev/v1/stats?from=2026-11-01&to=2026-12-01" -H "Authorization: Bearer ugc_live_..."{
"deliveries": { "published": 412, "failed": 6, "scheduled": 80 },
"by_platform": { "tiktok": { "published": 220, "failed": 4 }, "instagram": { "published": 192, "failed": 2 } },
"credits_used": 412,
"engagement": { "views": 184200, "likes": 9310, "comments": 412, "shares": 655, "saves": 380, "reach": 120400, "posts_measured": 398 },
"top_posts": [{ "post_id": "post_abc", "platform": "tiktok", "username": "creator_one", "url": "https://www.tiktok.com/@creator_one/video/123", "metrics": { "views": 48200, "likes": 2900 } }]
}deliveriescounts results, not posts. One clip to three accounts is three.credits_usedis spent minus refunds, so failed posts don't count.engagement.posts_measuredtells you how many posts the totals cover. New posts may not have numbers yet.top_postslists the five posts with the most views.by_daygives published and failed counts per day for a chart.
Numbers refresh hourly. If you need them now, POST /v1/metrics/refresh reads them again, at most every 5 minutes. Field list in the stats doc.
Cost per 1,000 views
Clients compare UGC to paid ads, so give them a cost per 1,000 views (CPM). For distribution cost alone, the math is simple: posts cost $10 per 1,000, so divide credits used by views.
const s = await fetch("https://ugcapi.dev/v1/stats?from=2026-11-01&to=2026-12-01", {
headers: { "Authorization": "Bearer " + process.env.UGCAPI_KEY },
}).then((r) => r.json());
const postingCost = s.credits_used * 0.01; // $10 per 1,000 posts
const cpm = postingCost / (s.engagement.views / 1000);
console.log("Posting cost $" + postingCost.toFixed(2), "CPM $" + cpm.toFixed(3));With the example above, 412 credits is $4.12 for 184,200 views, a posting CPM of about 2 cents. For a full CPM, add creator fees and production cost to the posting cost. That full number is the one to put next to a paid social CPM.
A client reporting workflow
- Run each client's work in its own team workspace, and give each campaign a clear
name. - Tag each post with an
external_idthat maps to your brief, likebrandx-hook-014. - Once a week, pull
GET /v1/statsfor the period andGET /v1/posts?campaign_id=...for each campaign. - Report totals, the top five posts with links, published versus failed counts, and the CPM.
- Add one line on what you'll change next week. Clients value the decision more than the chart.
Wait 3 to 7 days before judging a post. Most short-form views arrive in the first days, but some clips pick up later. Compare posts of the same age.
Keep the report short. One page with totals, the five best posts, the posting cost and next week's plan is enough for most clients. Link each top post to its public URL so the client can watch it. Long tables of every post are better as an attachment for the few clients who ask.
Spot winners and post them again
UGC campaigns are tests. A few clips will do far better than the rest. Find them and give them more distribution.
- Rank posts by views per account, not raw views. A post on a big account isn't a winner just because the account is big.
- Look at shares and saves next to views. A clip with high shares on a small account is often the best one to scale.
- Read the caption and first frame of each winner. Often the hook, not the product, made the difference.
Then re-post the winners to more accounts. Take the media URLs of the top posts, change the caption or first frame a little, and create a new campaign across accounts that haven't posted them. Our cadence guide covers how often to reuse a concept.
Compare platforms fairly
The same clip often gets very different numbers on each platform. That doesn't always mean one platform is better. Each counts a view differently, and each account has a different audience size. Compare a platform against itself over time, and compare the same clip across platforms only as a rough guide.
| Question | Where to look |
|---|---|
| Which platform gave the most views this month? | engagement.by_platform in GET /v1/stats |
| Which creator performed best? | GET /v1/stats?account_id=... per account |
| Which clip should we scale? | top_posts, then views per account in the campaign's posts |
| Did the campaign post on time? | deliveries and by_day |
Reporting without code
The dashboard shows the same numbers per post and per account, so small teams can report straight from it. For a weekly sheet, the n8n-nodes-ugcapi node can read stats on a schedule and append a row. You can also ask Claude or ChatGPT through the remote MCP server, for example "which five clips got the most views last week".
Health checks next to results
A campaign with low views might just have failed posts. Check deliveries.failed and top_errors in the same stats call before you blame the content. A cluster of failures on one account usually means its login expired. Subscribe to the account.disconnected webhook to catch it early.
FAQ
Which platforms return engagement metrics?
TikTok, Instagram, Facebook and YouTube. Each reports a slightly different set, so some posts have saves or reach and others don't.
How often are views and likes updated?
Hourly for published posts. POST /v1/metrics/refresh reads them again on demand, at most every 5 minutes.
Can I get analytics for one campaign?
Yes. List its posts with GET /v1/posts?campaign_id=... Each item carries a metrics summary you can add up.
How do I calculate cost per 1,000 views?
Multiply credits used by $0.01 for the posting cost, then divide by views over 1,000. Add creator and production costs for a full CPM.