Skip to main content

Audience Insights

Get Analytics answers how did my posts do. This endpoint answers the other half: who follows this account, when they are online, what they tap on the profile and how it compares to its category.

It is one endpoint with a platform, exactly like /comments and /post-analytics: the question is the same for every network, so the URL is too. Adding a network never changes your integration — the same call starts answering for a new value of platform.

The field to build a scheduler on is activity_by_hour — the number of followers connected in each hour of the day, added up over the window. That is the answer to "when should I publish", and it comes from your own audience rather than from a generic best-time-to-post table.

  • Method: GET
  • Endpoint: /api/uploadposts/audience
  • Authentication:
    • API Key in the Authorization header.
      • Authorization: Apikey <YOUR_API_KEY>

Query Parameters

ParameterTypeRequiredDescriptionDefault
platformstringYesThe network to ask. Today only tiktok answers; anything else is a 400 naming the platforms that do.-
userstringYesThe profile's username. Must have an account of that platform connected.-
start_datestringNoFirst day of the window, ISO YYYY-MM-DD.end_date − 29 days
end_datestringNoLast day of the window, ISO YYYY-MM-DD. Must be earlier than today.yesterday
benchmark_categorystringNoOne of the 25 categories in benchmark_categories, case-insensitive. Adds the benchmark block to the answer.-
Supported platforms

platform=tiktok today. Any other value answers 400 with error_code: "platform_not_supported" and a message listing what is supported, so a client can branch on the code instead of on a hard-coded list.

Window rules. The platform refuses a window that ends today or later, and it keeps at most 60 days of history. Rather than forwarding a request that is guaranteed to fail, Upload-Post trims what you asked for to what the platform accepts: an end_date of today becomes yesterday, and a start_date older than 60 days becomes the oldest day available. Render the range that comes back, not the one you sent — they are not always the same window. A value that is not an ISO date is a hard 400.

Example Request

curl -G 'https://api.upload-post.com/api/uploadposts/audience' \
-H 'Authorization: Apikey your-api-key-here' \
-d 'platform=tiktok' \
-d 'user=your_profile' \
-d 'start_date=2026-08-01' \
-d 'end_date=2026-08-30'

Successful Response (200 OK)

{
"success": true,
"platform": "tiktok",
"range": { "start_date": "2026-08-01", "end_date": "2026-08-30" },
"audience": {
"countries": [
{ "country": "ES", "percentage": 0.588 },
{ "country": "MX", "percentage": 0.161 },
{ "country": "AR", "percentage": 0.074 }
],
"cities": [
{ "city": "Madrid", "percentage": 0.121 },
{ "city": "Barcelona", "percentage": 0.083 }
],
"ages": [
{ "age": "18-24", "percentage": 0.372 },
{ "age": "25-34", "percentage": 0.411 },
{ "age": "35-44", "percentage": 0.145 }
],
"genders": [
{ "gender": "female", "percentage": 0.624 },
{ "gender": "male", "percentage": 0.376 }
]
},
"activity_by_hour": [
{ "hour": "2", "followers_online": 456 },
{ "hour": "9", "followers_online": 981 },
{ "hour": "14", "followers_online": 1494 },
{ "hour": "21", "followers_online": 1327 }
],
"followers_daily": [
{ "date": "2026-08-01", "total": 12480, "new": 63, "lost": 11 },
{ "date": "2026-08-02", "total": 12539, "new": 71, "lost": 12 }
],
"profile_actions": {
"bio_link_clicks": 318,
"address_clicks": null,
"app_download_clicks": null,
"email_clicks": 12,
"phone_number_clicks": null,
"lead_submissions": null
},
"bio_description": "Corrijo exámenes con IA 📸",
"benchmark_categories": [
"PERSONAL_BLOG",
"MACHINERY_AND_EQUIPMENT",
"HEALTH_AND_WELLNESS",
"PETS",
"AUTOMOTIVE_AND_TRANSPORTATION",
"EDUCATION_AND_TRAINING",
"FOOD_AND_BEVERAGE",
"REAL_ESTATE",
"ELECTRONICS",
"SHOPPING_AND_RETAIL",
"PUBLIC_ADMINISTRATION",
"ART_AND_CRAFTS",
"BABY",
"GAMING",
"RESTAURANTS_AND_BARS",
"HOME_FURNITURE_AND_APPLIANCES",
"PROFESSIONAL_SERVICES",
"SOFTWARE_AND_APPS",
"MEDIA_AND_ENTERTAINMENT",
"BEAUTY",
"SPORTS_FITNESS_AND_OUTDOORS",
"CLOTHING_AND_ACCESSORIES",
"TRAVEL_AND_TOURISM",
"OTHERS",
"FINANCE_AND_INVESTING"
]
}
FieldDescription
platformThe network the answer came from, echoed back.
rangeThe window actually queried, after trimming. Read this one, not your input.
audience.countries / .cities / .ages / .gendersFollower distribution. percentage is a fraction of 1, not a number out of 100 — 0.588 means 58.8%. Percentages cannot be added across days, so each distribution is the most recent one reported inside the window.
activity_by_hourAlways 24 entries, "0""23" in the account's local time, ordered numerically so 9 comes before 10. followers_online is the sum over the window: in the example the audience bottoms out at 456 at 2 a.m. and peaks at 1494 at 2 p.m., which is the hour to publish into.
followers_dailyOne row per day, oldest first: total followers at the end of the day, new gained and lost. A field is null when the platform did not report it for that day.
profile_actionsSix counters totalled over the window: bio_link_clicks, address_clicks, app_download_clicks, email_clicks, phone_number_clicks, lead_submissions. null is not 0 — it means the platform answered nothing for this account, while 0 means it answered "nobody clicked". Do not coalesce one into the other in a dashboard.
bio_descriptionThe account's current bio text.
benchmark_categoriesThe 25 values benchmark_category accepts. Always present, so a UI can build its picker without a second call.

With benchmark_category

Averages tell you whether 3% engagement is good for what this account publishes. A number on its own means nothing; this is the comparison that gives it meaning.

curl -G 'https://api.upload-post.com/api/uploadposts/audience' \
-H 'Authorization: Apikey your-api-key-here' \
-d 'platform=tiktok' \
-d 'user=your_profile' \
-d 'benchmark_category=SOFTWARE_AND_APPS'

The same body as above, plus:

{
"benchmark": {
"category": "SOFTWARE_AND_APPS",
"average_comments": 19,
"average_engagement_rate": 0.0144,
"average_follower_count": 24713,
"average_follower_growth": 186,
"average_likes": 742,
"average_shares": 43,
"average_video_count": 17,
"average_video_views": 21508
}
}
FieldDescription
benchmark.categoryThe category you asked for, normalised to upper case.
benchmark.average_engagement_rateFraction of 1 — 0.0144 means 1.44%, the average for SOFTWARE_AND_APPS.
benchmark.average_likes / average_comments / average_sharesPer post, on average, for accounts in that category.
benchmark.average_video_viewsAverage views per video.
benchmark.average_follower_count / average_follower_growthAccount size and growth in the period the platform measures.
benchmark.average_video_countHow many videos a typical account in the category publishes in the period.

Only the metrics the platform actually returned are present, so read the keys you need defensively rather than assuming all eight are there. The category is not stored on the profile: pass it on every call, which also lets you compare one account against two categories when it straddles both.

Error Responses

  • 400 Bad Request — the platform does not answer this question yet. The message names the ones that do.
{
"success": false,
"message": "'instagram' does not support audience insights yet. Supported: tiktok.",
"error_code": "platform_not_supported"
}
  • 400 Bad Request — a date that is not ISO YYYY-MM-DD, a benchmark_category outside the 25 values, or a missing platform.
{
"success": false,
"message": "end_date must be an ISO date (YYYY-MM-DD).",
"error_code": "invalid_parameter"
}
  • 400 Bad Request — the profile's connection cannot serve this endpoint. Reconnect the account.
{
"success": false,
"message": "Profile 'your_profile' has no TikTok connection that supports this endpoint. Reconnect your TikTok account from Manage Users.",
"error_code": "tiktok_reconnect_required"
}
  • 404 Not Found — no profile with that username exists under your API key (error_code: "PROFILE_NOT_FOUND").
  • 409 Conflict — the token expired and the account must be reconnected ("reauth_required": true).
  • 502 Bad Gateway — the platform rejected the lookup; its message is returned verbatim in message.

Additional Notes

  • Which connections answer. On TikTok, the audience, the benchmark and hashtag suggestions work on any recently connected account (the profile_analytics capability). Only comments and type=keywords on Suggestions need the account to be reconnected — the comments and trend_search capabilities are granted at the moment of connecting, so an older connection does not carry them.
  • Percentages come from the platform as fractions of 1. Multiply by 100 before rendering.
  • audience.cities is the noisiest breakdown: small accounts often get an empty array while countries and ages are populated.
  • A brand-new connection has no history yet. Expect empty arrays for the first days rather than an error.

  • Suggestions — the hashtags and search terms to write the next post with.
  • Get Analytics — cross-platform account and per-post metrics, including the full TikTok per-post breakdown (retention, impression sources, audience types).
  • Account capabilities.