Overview
The Social API exposes influData's database of 28M+ analyzed creator and brand profiles, with audience demographics, performance metrics and content data, through a single REST interface. All endpoints return JSON, use the same authentication and share platform-agnostic response structures: an integration built for one platform works for all of them.
https://app.infludata.com/api/externalAPILarge content responses (getContent) are gzip-compressed when the client sends Accept-Encoding: gzip. All timestamps are ISO 8601 in UTC.
Authentication
Every request is authenticated with a Bearer token in the Authorization header:
Authorization: Bearer YOUR_API_KEYThere are two kinds of keys:
- Trial keys — self-serve, free, issued via createTrialKey + verifyTrialKey with email verification. 250 requests, valid 14 days. When you later book a plan with the same email address, your trial key is automatically upgraded to a production key — no code changes needed.
- Organization keys — for production use. Book a plan directly via the self-serve checkout on the Social API page — your production key arrives by email right after the purchase. Customers on influData app plans with API access can also generate keys in the app settings. Monthly request volumes depend on your plan.
Request budget & costs
Each key has a request budget (trial: total budget; production: monthly volume). Endpoints deduct from it as follows. Failed requests are not charged.
| Endpoint | Cost |
|---|---|
| GET /getUserData | 1 request — or 20 with includeAudienceReport=true |
| GET /discovery | 1 request per search (20 results) |
| GET /getContent | 1 request per content piece returned |
| GET /getCollections · /getCollection | 1 request per call |
| POST /createCollection · /addToCollection · /removeFromCollection | 1 request per call |
| POST /renameCollection · /deleteCollection | Free |
| GET /getCampaigns · /getCampaign | 1 request per call |
| POST /createCampaign | 1 request + 1 per creator added or newly queued for indexing |
| POST /addToCampaign | 1 request per creator added or newly queued for indexing, at least 1 |
| POST /updateCampaign · /removeFromCampaign · /archiveCampaign · /deleteCampaign | 1 request per call |
| GET /getContentDownloadLink | 1 request |
| GET /watchlist/… (all watchlist reads) · labels · DELETE /watchlist/creators/… | 1 request per call |
| POST /watchlist/creators | App only — always 403 app_only, not charged |
| POST /watchlist/creators/…/deep-dive | 10 requests |
| GET /checkDataStatus | Free — 1 request when a new data refresh is actually queued |
| POST /bulkAddToEnrich | 1 request per creator newly queued (duplicates within 48h are free) |
| GET /getUsage | Free |
| GET /getClientInfo | Free |
| GET /getCitiesForCountry | Free |
Check your remaining balance anytime — organization keys use getUsage, trial keys use getClientInfo. Both are free.
Rate limits
| Key type | Burst limit | Volume |
|---|---|---|
| Trial | 2 req/s · 60 req/min | 250 requests total, 14 days |
| Developer | 5 req/s · 300 req/min | 15,000 requests / month |
| Startup | 10 req/s · 600 req/min | 60,000 requests / month |
| Business | 25 req/s · 1,000 req/min | 250,000 requests / month |
Exceeding a burst limit returns 429. Organization keys that exhaust their monthly volume also receive 429 with a resetDate field. Implement exponential backoff for retries.
The tier limits above apply to keys booked via the self-serve Social API checkout. Organization keys generated in the influData app settings run at the default burst limit (25 req/s · 1,000 req/min) unless configured otherwise.
Media URLs
Every media field we return (profilePicURL, imageUrl, videoUrl, campaignLogo, watchlist thumbnails) points at private object storage. By default these are signed URLs that expire after 24 hours, which is why links kept in your own database later render as broken images. Signed URLs cannot be issued for longer than 7 days, that is a hard limit of the S3 signature standard.
Pick one of three ways to handle this:
- Stable media URLs. Add
mediaUrls=stableto any request and every media field comes back as a permanent URL on/api/externalAPI/media/…. It never expires, needs no authentication, and works straight in an<img src>. Requesting it redirects (302) to a freshly signed storage URL, so your client only has to follow redirects, which browsers and common HTTP libraries do by default. These requests cost no requests from your budget. We can switch this on permanently for your organization, then every endpoint returns stable URLs andmediaUrls=signedrestores the old behaviour per request. - Re-sign on demand. Store the link without its query string and hand it back to
/signInfluDataAWSLink?link=…when you need it. You get a fresh 24-hour URL, and it costs no requests. - Mirror the files. Download the bytes once and serve them from your own storage. The most robust option regardless of URL lifetimes, because creator media also disappears when the creator deletes the post.
GET /api/externalAPI/getUserById?platform=instagram&userId=248312442&mediaUrls=stable
{
"profilePicURL": "https://app.infludata.com/api/externalAPI/media/aHxpZy9wcm9maWxlcGljcy8…",
...
}
<!-- store it, embed it, it stays valid -->
<img src="https://app.infludata.com/api/externalAPI/media/aHxpZy9wcm9maWxlcGljcy8…" />Never build URLs against our storage hosts yourself, and never strip the signature from a signed URL and request it directly. Both return 403.
Create trial key — step 1: request a verification code
/createTrialKeyCost: Free, unauthenticated
Starts the self-serve trial signup. Runs abuse checks and emails a 6-digit verification code to the given address — the key itself is issued by verifyTrialKey. The code expires after 15 minutes; re-calling this endpoint sends a fresh code.
Body parameters (JSON)
| Parameter | Type | Description |
|---|---|---|
| emailrequired | string | Your work email. Disposable email domains are rejected; one trial per inbox (plus-aliases count as the same inbox). |
| company | string | Optional company name (max 120 characters). |
curl -X POST "https://app.infludata.com/api/externalAPI/createTrialKey" \
-H "Content-Type: application/json" \
-d '{"email": "you@company.com", "company": "Your Company"}'
{
"success": true,
"message": "A 6-digit verification code was sent to you@company.com. ...",
"nextStep": {
"method": "POST",
"url": "https://app.infludata.com/api/externalAPI/verifyTrialKey",
"body": { "email": "you@company.com", "code": "<6-digit code from the email>" }
},
"codeExpiresInMinutes": 15
}Response codes
| 200 | Verification code sent. |
| 400 | Invalid or disposable email address. |
| 409 | A trial key was already issued for this email. |
| 429 | Per-IP or signup rate limit reached. |
| 503 | Global trial signup caps reached — retry later. |
Verify trial key — step 2: exchange the code for your key
/verifyTrialKeyCost: Free, unauthenticated
Validates the emailed code and returns your API key directly in the response (a copy is also emailed). Maximum 5 attempts per code.
Body parameters (JSON)
| Parameter | Type | Description |
|---|---|---|
| emailrequired | string | The email used in step 1. |
| coderequired | string | The 6-digit code from the verification email. |
curl -X POST "https://app.infludata.com/api/externalAPI/verifyTrialKey" \
-H "Content-Type: application/json" \
-d '{"email": "you@company.com", "code": "123456"}'
{
"success": true,
"apiKey": "your-trial-api-key",
"clientId": "trial-aB3xK9pQz1",
"expiresAt": "2026-06-25T00:00:00.000Z",
"requestsIncluded": 250,
"rateLimit": { "perSecond": 2, "perMinute": 60 },
"baseUrl": "https://app.infludata.com/api/externalAPI",
"quickstart": "curl -H \"Authorization: Bearer <apiKey>\" \"https://app.infludata.com/api/externalAPI/getUserData?platform=instagram&username=cristiano\""
}Response codes
| 201 | Key issued — returned in the response body. |
| 400 | Missing or malformed email/code. |
| 401 | Incorrect code (response includes attemptsRemaining). |
| 404 | No pending verification — request a code first. |
| 410 | Code expired — request a new one. |
| 429 | Too many incorrect attempts or verify rate limit reached. |
Get creator profile
/getUserDataCost: 1 request — 20 with includeAudienceReport=true
Returns a full creator profile: bio, follower/following counts, engagement metrics, verification status, creator demographics (country, city, language, gender), CPM estimates and the follower-growth history (dataLogTimePeriods with all/12-month/30-day series plus monthlyGrowthFollowers). With showDatalogAndScore=true the response additionally carries the quality scores (profileScore), the raw growth dataLog and the brand/creator collaboration timelines. With includeAudienceReport=true it includes audience demographics (age, gender, geo breakdown), interests and follower-quality metrics — audience age/gender splits live here, not on the core profile.
Organization keysadditionally get the creator's workspace data hydrated inline — no extra request needed to resolve names: collections ({ collectionId, collectionName }), campaigns ({ campaignId, campaignName, isActive }), the plain id arrays collectionArray / campaignArray with collectionCount / campaignCount, plus the org-internal creator data known from getCollection: commentThread, additionalFields, stars, isFav and isBlack. Trial and legacy keys receive these fields as empty defaults.
Parameters
| Parameter | Type | Description |
|---|---|---|
| platformrequired | string | instagram, tiktok, youtube, twitch, facebook or snapchat. |
| username / userId / _idrequired | string | Exactly one identifier. username: platform handle (e.g. "adidas", "@MrBeast"). userId: platform-native ID (Instagram numeric ID, TikTok secUserId, YouTube channelId, Twitch ID). _id: influData internal ID — works without the platform parameter. |
| includeAudienceReport | boolean | true to include the full audience report (costs 20 requests). Available for Instagram, TikTok and YouTube. Default: false. |
| showDatalogAndScore | boolean | true to include profileScore, the raw growth dataLog and brand/creator collaboration timelines (collaborations on Instagram, TikTok and YouTube). Default: false. |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/getUserData?platform=instagram&username=adidas&includeAudienceReport=true"
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/getUserData?platform=youtube&username=@MrBeast"
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/getUserData?_id=507f1f77bcf86cd799439011"
# Response excerpt (organization key) — workspace assignments come inline:
{
"_id": "507f1f77bcf86cd799439011",
"username": "creatorhandle",
"followers": 125000,
...profile fields...,
"collections": [
{ "collectionId": "aB3xK9pQz1", "collectionName": "Q4 Fitness Prospects" }
],
"collectionArray": ["aB3xK9pQz1"],
"collectionCount": 1,
"campaigns": [
{ "campaignId": "mK4nP8qR2s", "campaignName": "Winter Launch 2026", "isActive": true }
],
"campaignArray": ["mK4nP8qR2s"],
"campaignCount": 1,
"commentThread": [ ...internal notes... ],
"additionalFields": [ { "code": "xY9zW2vU4t", "value": "3500" } ],
"stars": 4
}Response codes
| 200 | Profile data returned. |
| 201 | Creator not in database yet — queued for enrichment, nothing charged. Retry within 24–48h. |
| 202 | Creator found but audience analysis still processing (nothing charged) — retry later. |
| 400 | Missing/invalid platform or identifier. |
| 403 | Insufficient request balance, or audience reports not enabled for this key. |
| 404 | Creator not found on the platform. |
| 422 | Platform has no automatic enrichment (Twitch/Facebook usernames not yet in the database cannot be queued). |
| 429 | Monthly request limit exceeded (organization keys; includes resetDate). |
Check data status
/checkDataStatusCost: Free for the metadata — 1 request when a new data refresh is actually queued (duplicates within 48h are free)
Returns metadata about a creator: whether they exist in the database, data freshness, audience-report availability and timeline coverage. Also queues an instant data refresh (Instagram, TikTok, YouTube, LinkedIn — for Twitch the call is metadata-only), and optionally adds the creator to the weekly refresh schedule. Use it before getUserData to avoid spending requests on incomplete data.
Parameters
| Parameter | Type | Description |
|---|---|---|
| platformrequired | string | instagram, tiktok, youtube, twitch or linkedin. |
| username / userId / _idrequired | string | Exactly one identifier (same formats as getUserData). |
| addToWeeklyEnrichment | boolean | true to add the creator to the weekly refresh schedule. Not available for trial keys. Default: false. |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/checkDataStatus?platform=instagram&username=cristiano"
{
"isInDatabase": true,
"creatorId": "507f1f77bcf86cd799439011",
"username": "cristiano",
"platform": "instagram",
"followers": 125000000,
"lastRefreshDate": "2026-06-10T10:30:00Z",
"lastAudienceDataRefresh": "2026-06-08T08:00:00Z",
"hasAudienceData": true,
"timelineDatapoints": 180,
"isAddedToRefresh": true,
"isAddedToWeeklyRefresh": false,
"tokensDeducted": 0,
"tokensRemaining": 230
}Creators not in the database yet return isInDatabase: false with isBeingProcessed: true once the enrichment row is queued.
Response codes
| 200 | Metadata returned — tokensDeducted shows whether a refresh was queued (1) or deduped (0). |
| 402 | Insufficient request balance to queue a refresh. |
| 429 | Too many creators already queued for enrichment on this key — retry after the queue drains. |
Bulk enrichment
/bulkAddToEnrichCost: 1 request per creator newly queued — duplicates within 48h are free
Queues multiple creators for enrichment in one call — useful when onboarding creator lists. New creators are typically available within 24–48 hours.
Body parameters (JSON)
| Parameter | Type | Description |
|---|---|---|
| platformrequired | string | instagram, tiktok, youtube or linkedin. |
| usernames | string[] | Usernames to process (can be combined with userIds). Creators not yet in the database can only be added by username. |
| userIds | string[] | Platform-native user IDs to process — works for creators already in the database only. |
| addToWeeklyEnrichment | boolean | true to also add creators to the weekly refresh schedule (existing creators only). Not available for trial keys. Default: false. |
Limits: maximum 100 items per request (usernames + userIds combined); 10 for trial keys.
curl -X POST "https://app.infludata.com/api/externalAPI/bulkAddToEnrich" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"platform": "instagram", "usernames": ["cristiano", "leomessi"], "addToWeeklyEnrichment": false}'
{
"processed": [
{ "identifier": "cristiano", "type": "username", "isNewUser": false, "creatorId": "...", "addedToInstant": true, "addedToWeekly": false }
],
"failed": [],
"summary": { "total": 2, "existingInDatabase": 2, "newlyAdded": 0, "addedToInstant": 2, "addedToWeekly": 0, "failed": 0 },
"tokensDeducted": 2,
"tokensRemaining": 228
}Response codes
| 200 | Batch processed — tokensDeducted = creators newly queued (addedToInstant). |
| 402 | Insufficient request balance for the batch size. |
| 429 | Monthly limit reached, or too many creators already queued for enrichment on this key. |
Discovery search
/discoveryCost: 1 request per search (20 results per page)
Search the creator database with filters for keywords, categories, location, language, audience size, engagement, growth and audience demographics. The audience filters (audienceCountries, audienceLanguages, audienceGender, audienceAgeRanges, audienceRealPeople) match against audience reports that already exist, so they cost nothing beyond the search itself and never generate a report — the report for a single creator comes from getUserData with includeAudienceReport=true. Returns 20 creators per page — paginate with skipCount (0, 20, 40, …). The response includes a total count and a relevance score (0–100) per result when keywords are used.
Parameters
| Parameter | Type | Description |
|---|---|---|
| platformrequired | string | instagram, tiktok, youtube, twitch, facebook or snapchat. |
| skipCount | number | Pagination offset in increments of 20. Default: 0. |
| keywords | string | Comma-separated search terms, OR-combined. Wrap a term in double quotes for an exact phrase ("personal trainer") — unquoted spaces split into individual OR'd words. Prefix + to require a term (AND) and - to exclude it: keywords=fitness,+coach,-yoga. |
| keywordFields | string | Restrict keyword search to specific fields: bio, hashtags, content, website (comma-separated). Default: bio + hashtags (display name and username are always searched). Honored on Instagram, TikTok and YouTube. |
| categories | string | Comma-separated creator categories — see the categories reference below. |
| country | string | Creator country (full name, e.g. "Germany", "United States"). |
| city | string | Creator city (combine with country; Instagram and TikTok). Valid values via getCitiesForCountry. |
| language | string | Creator language as 2-letter ISO code (e.g. en, de, fr). |
| gender | string | m (male) or w (female). |
| followerMin / followerMax | number | Follower/subscriber count range. |
| engagementRate | number | Minimum engagement rate (1 = 1%). Valid range 1–50; values outside are ignored. |
| engagementRateMax | number | Maximum engagement rate — combine with engagementRate for a range. |
| growthRate | number | Minimum monthly growth rate in percent. Valid range 1–30; values outside are ignored. |
| viewsMin / viewsMax | number | Average views per post/video range (platform-dependent). |
| businessSearch | boolean | true to focus on business/brand accounts (Instagram). |
| audienceCountries | string | Audience country with a minimum share: Country_percent, comma-separated — audienceCountries=Germany_10 returns creators with at least 10% of their audience in Germany; several entries must all match (Germany_10,Austria_10). Country as full English name, like the country filter. Instagram and TikTok. Only creators with an existing audience report can match; the filter itself costs nothing extra. |
| audienceLanguages | string | Audience language with a minimum share: code_percent using 2-letter ISO codes, comma-separated (e.g. de_50). Instagram and TikTok. |
| audienceGender | string | Minimum share of one gender in the audience: percent_gender, e.g. 60_female or 70_male. Instagram and TikTok. |
| audienceAgeRanges | string | Median audience age range as min,max (e.g. 25,34). Instagram and TikTok. |
| audienceRealPeople | number | Minimum share of real people in the audience in percent (e.g. 70). Instagram only. |
| sorting | string | Direction prefix + field: e.g. descFollowers, ascUsername. Fields: relevance, username, profileScore, followers, viewsPost, engagementMean, growthRate; plus totalViews (TikTok) and averageViewers (Twitch). Default: profile score. |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/discovery?platform=instagram&country=Germany&followerMin=10000&categories=fitness"
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/discovery?platform=tiktok&keywords=%22personal%20trainer%22,%22fitness%20coach%22&keywordFields=bio&sorting=descFollowers"
{
"users": [
{
"_id": "profile_id_123",
"username": "example_user",
"displayName": "Example User",
"followers": 125000,
"platform": "instagram",
"country": "Germany",
"engagementMean": 4.2,
"score": 95.8
}
],
"count": 1842,
"dataSuccess": { "status": true, "error": "" }
}Note: unlike most endpoints, discovery signals failures inside a 200 response — an exhausted budget or an empty result set returns { "status": false, "error": "…" }. Check the body, not just the HTTP status. Failed searches are not charged.
Get content
/getContentCost: 1 request per content piece returned
Query content pieces (posts, reels, stories, videos) with captions, hashtags, mentions, performance metrics and media URLs (24h-valid signed by default, permanent with mediaUrls=stable). Supports cursor-based pagination for large pulls and watermarks for incremental syncs.
Pagination parameters
| Parameter | Type | Description |
|---|---|---|
| limit | number | Content pieces per page. Default and maximum: 100. |
| cursor | string | Opaque cursor from the previous response (next_cursor). Can also be sent via the X-Cursor header to avoid long URLs. |
| offset / skipCount | number | Legacy offset pagination — still supported, but cursor pagination is recommended. |
Filter parameters
| Parameter | Type | Description |
|---|---|---|
| platform | string | Comma-separated platforms. Default: instagram,tiktok. |
| username | string | Filter by creator username(s), comma-separated. |
| keywords | string | Comma-separated keywords searched in captions, hashtags, mentions — and also video/audio transcriptions, tagged locations and AI-derived image descriptions. Terms with spaces are phrase-matched. |
| tags | string | Comma-separated hashtags (e.g. fashion,style). |
| min_followers | number | Minimum creator follower count. Default: 10000. (followerMin is the offset-mode alias.) |
| created_at_gte / uploadedFrom | string | Earliest upload date (ISO format). |
| created_at_lte / uploadedTo | string | Latest upload date (ISO format). |
| contentTypes | string | Comma-separated: post, reel, story (Instagram); video (TikTok/YouTube); short (YouTube). |
| sorting | string | uploaded (default), reach or viral. In cursor mode "uploaded" pages oldest-first (ideal for syncs); in offset mode newest-first. |
| followerMax | number | Maximum creator follower count. Offset pagination mode only. |
| viewsMin / viewsMax | number | Content reach/views range. Offset pagination mode only. |
| country / gender / language | string | Creator demographics filters (gender: m or w; language: 2-letter code). Offset pagination mode only. |
# First page
curl -H "Authorization: Bearer YOUR_API_KEY" -H "Accept-Encoding: gzip" \
"https://app.infludata.com/api/externalAPI/getContent?platform=instagram,tiktok&tags=fashion,style&min_followers=10000&limit=100"
# Next page: pass next_cursor from the previous response
curl -H "Authorization: Bearer YOUR_API_KEY" -H "X-Cursor: eyJwaXRJZCI6..." \
"https://app.infludata.com/api/externalAPI/getContent?limit=100"
{
"items": [
{
"contentId": "IG_12345678901234567",
"platform": "instagram",
"contentType": "reel",
"uploaded": "2026-05-15T10:30:00Z",
"reach": 125000, "likes": 8500, "comments": 342,
"engagementRate": 0.0745, "viralFactor": 1.23,
"username": "fashioninfluencer", "followers": 45000,
"captions": "Check out this amazing outfit! #fashion",
"hashtags": ["fashion", "style"], "mentions": ["@brandname"],
"imageUrl": "https://signed-url...", "videoUrl": "https://signed-url..."
}
],
"next_cursor": "eyJwaXRJZCI6...",
"watermark": { "created_at_max": "2026-05-15T10:30:00Z", "last_id": "65abc123def456789" },
"tokensDeducted": 100,
"tokensRemaining": 9900
}For incremental syncs, store the watermark after a full pull and use created_at_gte with sorting=uploaded on the next run.
- Passing
offset/skipCountswitches to the legacy offset mode, which returns a different shape —{ content, count, limit, offset, … }instead of items/next_cursor — and answers empty result sets with404. New integrations should use cursor pagination. imageUrl/videoUrlarenullwhen media delivery is disabled for your key — the metrics and captions are unaffected.
Organization data
Beyond the public creator database, the API exposes your organization's own workspace — the same data your team works with in the influData app: collections (saved creator lists, including saved content pieces), campaigns (creator rosters, tracking setup, custom-field definitions), internal notes (per-creator comment threads) and custom fields (attributes your organization defines per creator). Use it to sync influData into your own CRM, data warehouse or reporting, or to set up collections and campaigns from your own tools.
Availability: requires an organization API key. Trial keys receive 403 on every endpoint in this group. No add-on needed — included with every organization key.
- Organization-scoped. Every endpoint reads and writes only the calling key's organization — other organizations' data is never accessible.
- Also available as MCP tools. The same campaigns, collections and metrics are exposed to Claude, ChatGPT and other LLM clients through the influData MCP server (read-only there, authenticated with the same API key).
- Signed URLs: profile pictures, note attachments and upload-type custom-field values come as short-lived signed URLs — fetch them immediately, or request permanent links instead (see Media URLs).
List collections
/getCollectionsCost: 1 request
Returns all creator collections of your organization. Collections with restricted access that the API principal cannot see are omitted.
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/getCollections"
{
"collections": [
{
"collectionId": "aB3xK9pQz1",
"collectionName": "Q4 Fitness Prospects",
"name": "Q4 Fitness Prospects",
"description": "Shortlist for the winter campaign",
"elementCount": 34,
"access": "organization",
"color": "#22c55e",
"created": "2026-05-02T09:14:00.000Z",
"folderId": null,
"pipelineColumns": null,
"pipelineColumnOrder": null,
"autoAddToPipeline": true,
"accessTeams": [{ "orgId": "…", "orgName": "Your Team", "logoUrl": null }]
}
],
"count": 12
}collectionNameandnamecarry the same value (both kept for backwards compatibility).pipelineColumns/pipelineColumnOrderdescribe the collection's kanban stages when pipeline mode is enabled;accessTeamslists the owning team plus teams the collection is shared with.- The list also contains collections shared into your team by sibling teams (marked
isSharedIn: truewithsharedFromOrgId/sharedFromOrgName) and — when audience reports were unlocked — the virtualunlockedcollection.
Get collection — creators with notes, fields & saved content
/getCollectionCost: 1 request
Returns the creators saved in one collection as full profile objects — and hydrates each creator with your organization's internal data: commentThread (internal notes), additionalFields (custom-field values), stars (your team's rating) and collectionArray (which other collections the creator is saved in). Content pieces saved to the collection are returned in contentData.
Parameters
| Parameter | Type | Description |
|---|---|---|
| collectionIdrequired | string | From getCollections. Special values: "unlocked" (all creators with unlocked audience reports) and "blacklist". |
| page | number | Optional. Collections with more than 100 creators are paginated in blocks of 100: page=1 returns the first 100, page=2 the next 100, and so on. Default (omitted) returns the whole collection up to 1,000 creators. |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/getCollection?collectionId=aB3xK9pQz1"
{
"userdata": [
{
"_id": "65abc123def456789abc1234",
"_index": "instagram",
"username": "creatorhandle",
"displayName": "Creator Name",
"followers": 125000,
"country": "Germany",
"engagementMean": "4.2 %",
"profilePicURL": "https://... (signed, short-lived)",
...core profile fields...,
"commentThread": [
{
"code": "k2j4h6g8s0",
"user": "anna@yourcompany.com",
"comment": "Met at OMR — open to a Q4 cooperation",
"isPinned": false,
"linkToResources": null,
"timeStamp": "2026-07-02T10:15:00.000Z"
}
],
"additionalFields": [
{ "code": "xY9zW2vU4t", "value": "3500" },
{ "code": "pQ7rS5tU3v", "value": ["Confirmed"] }
],
"stars": 4,
"collectionArray": ["aB3xK9pQz1", "cD5eF7gH9i"],
"collectionCount": 2
}
],
"contentData": [ ...content pieces saved to this collection... ],
"metadata": {
"additionalFields": [
{ "code": "xY9zW2vU4t", "label": "Budget (EUR)", "type": "number", "allowedValues": null },
{ "code": "pQ7rS5tU3v", "label": "Status", "type": "singleselect", "allowedValues": ["Contacted", "Confirmed", "Declined"] }
],
"isOwner": true,
"color": "#22c55e",
"audienceReport": { ...aggregated audience of the collection... }
},
"count": 34
}metadata.additionalFieldsholds your organization's custom-field definitions — resolve each value'scodeagainst it (see Notes & custom fields).collectionArrayis hydrated for collections up to 50 creators; larger collections skip it for speed. Collections with more than 50 creators additionally omit the heavy per-creator fields (profileScore,cpms,mentionsand the latest-content arrays) — fetch those per creator via getUserData when needed.- An unknown
collectionIdreturns an empty200response (emptyuserdata), not a 404 — validate ids against getCollections.
Manage collections
Cost: 1 request each — renameCollection and deleteCollection are free
Create collections and manage their members from your own tooling. Changes appear in the influData app immediately.
POST https://app.infludata.com/api/externalAPI/createCollection {"collectionName": "Q4 Prospects", "description": "…", "color": "#22c55e", "access": "organization"}
POST https://app.infludata.com/api/externalAPI/addToCollection {"collectionId": "…", "objectIds": ["<creator _id>", "…"]}
POST https://app.infludata.com/api/externalAPI/removeFromCollection {"collectionId": "…", "objectIds": ["<creator _id>"]}
POST https://app.infludata.com/api/externalAPI/renameCollection {"collectionId": "…", "name": "New name", "description": "…"}
POST https://app.infludata.com/api/externalAPI/deleteCollection {"collectionId": "…"}objectIdsare influData creator_ids as returned by getUserData, discovery or getCollection. To save content pieces instead of creators, sendcontentIds(from getContent) in place of objectIds.- New collections are visible organization-wide by default (
access: "organization"— the optionalaccessparameter acceptsrestrictedfor a private collection). The favorites collection cannot be deleted.
Response codes
| 201 | Collection created — response carries the new collectionId. |
| 200 | Members added/removed, collection renamed or deleted ({ "ok": true }). |
| 400 | Missing collectionId / name / ids. |
| 403 | Collection limit or collection element limit reached, or not an organization key. |
List campaigns
/getCampaignsCost: 1 request
Returns all campaigns of your organization with their creator rosters. Campaigns that another team of your account shares with you are not included, and neither are private campaigns, which the app shows only to the user who created them. For a single creator, the reverse lookup is even simpler: getUserData returns the creator's campaign memberships (with names) directly in campaigns.
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/getCampaigns"
{
"campaigns": [
{
"campaignId": "mK4nP8qR2s",
"campaignName": "Winter Launch 2026",
"campaignDescription": null,
"campaignLogo": "https://... (signed, short-lived)",
"startingDate": "2026-10-01T00:00:00.000Z",
"campaignPeriod": { "from": "2026-10-01T00:00:00.000Z", "to": null },
"isActive": true,
"creatorCount": 8,
"creators": [
{
"creatorId": "65abc123def456789abc1234",
"_id": "65abc123def456789abc1234",
"username": "creatorhandle",
"platform": "instagram",
"overwriteName": null,
"isActive": true,
"isArchived": false,
"isOnboarding": false
}
]
}
],
"count": 3
}creatorIdis the influData profile id — pass it to getUserData (_idis the same value, kept as an alias) or to addToCollection. Deleted roster entries are excluded.- A campaign is
isActivewhen it has started and is not archived; per creator,isActivemeans currently tracked (neither archived nor still onboarding).
Get campaign
/getCampaignCost: 1 request
Returns one campaign in full detail: the creator roster with per-creator settings (pricing, individual custom-field values, contact preferences), campaign-level custom-field definitions, tracked terms and campaign goals.
Parameters
| Parameter | Type | Description |
|---|---|---|
| campaignIdrequired | string | From getCampaigns. |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/getCampaign?campaignId=mK4nP8qR2s"
{
"campaign": {
"campaignId": "mK4nP8qR2s",
"campaignName": "Winter Launch 2026",
"campaignDescription": null,
"campaignLogo": "https://... (signed, short-lived)",
"startingDate": "2026-10-01T00:00:00.000Z",
"setInactiveOn": null,
"campaignPeriod": { "from": "2026-10-01T00:00:00.000Z", "to": null },
"isActive": true,
"folderId": null,
"contentLabels": [],
"campaignGoals": [ ... ],
"customFields": [
{ "customFieldId": "aB3xK9pQz1", "customFieldName": "Fee (EUR)", "dataFormat": "number", "applyLevel": "creator", "trackingMethod": "manual" }
],
"defaultCustomFields": [ ...built-in metric fields... ],
"trackedMetrics": [
{ "metricId": "tR8kW3mN1p", "type": "hashtag", "value": "winterlaunch", "isExact": true, "isBrandTerm": false, "startingDate": "2026-10-01T00:00:00.000Z" }
],
"creatorCount": 8,
"creators": [
{
"creatorId": "65abc123def456789abc1234",
"_id": "65abc123def456789abc1234",
"username": "creatorhandle",
"platform": "instagram",
"overwriteName": null,
"profilePicURL": "https://... (signed, short-lived)",
"dateAdded": "2026-09-20T08:00:00.000Z",
"isActive": true,
"isArchived": false,
"isOnboarding": false,
"pricing": 3500,
"enablePricing": true,
"individualCustomFields": [ { "customFieldId": "aB3xK9pQz1", "value": "3500" } ],
"customCreatorGoals": [],
"shouldContactCreator": false,
"creatorContactMethods": []
}
]
}
}trackedMetricsholds the campaign's tracked terms — each entry has a type of hashtag, mention, text or url. App-internal state (dashboards, notification settings, roles) is not part of the API response.
Response codes
| 200 | The campaign document. |
| 400 | Missing campaignId. |
| 404 | Campaign not found, belongs to another organization or is private (the app shows it only to the user who created it). |
To create campaigns and manage their creators and tracked terms through the API, see Manage campaigns. Campaign performance metrics (reach, views, engagement per creator and per content piece) are currently exposed through the MCP server (get_campaign_metrics).
Manage campaigns
Cost: createCampaign 1 request + 1 per creator added or newly queued for indexing · addToCampaign 1 per creator added or newly queued, at least 1 · updateCampaign, removeFromCampaign, archiveCampaign and deleteCampaign 1 each
Create campaigns, set their tracked terms and manage their creators from your own tooling. The endpoints below work on the same campaigns as the influData app, and every change shows up there right away. The rules are the same as in the app:
- Tracking seats. Every creator in a running campaign is tracked and uses one tracking seat (a creator in two running campaigns uses two). The seats of your plan are shared by all teams of your account and by campaigns, the watchlist and social listening; a team can also have its own allocation of campaign seats. Creators added to a campaign that has not started yet or is archived are added as onboarding: they are not tracked and use no seat. When the free seats cannot cover the creators a request would add, the request changes nothing (addToCampaign adds no creator, createCampaign does not create the campaign) and answers 403 with
reason: "tracking_seats_exceeded". Requests of your account that add tracked creators run one after the other, so two requests sent at the same time cannot use the same free seats. When your plan limits the number of campaigns, createCampaign waits its turn too, so two campaigns created at the same time cannot both take the last free one. A request that would have to wait more than about 10 seconds for another one answers 409 withreason: "concurrent_write"and changes nothing; send it again a few seconds later. - Which campaigns. The endpoints change your organization's own campaigns, the ones getCampaigns lists. Private campaigns (the app shows them only to the user who created them) are not part of the API: getCampaigns does not list them, getCampaign answers 404, and these endpoints answer 403 with
reason: "campaign_not_writable". Change private campaigns in the influData app. Demo campaigns answer the same 403 and cannot be changed. Campaigns that another team shares with you are not your organization's campaigns: like an unknown campaignId, they answer 404 withreason: "campaign_not_found". - Creators are passed as
{ "creatorId": "…" }(the influData id from getUserData, discovery or getCampaign, for every platform influData indexes) or as{ "username": "creatorhandle", "platform": "instagram" }with platform instagram, tiktok or youtube, up to 100 per request. An entry with a creatorId ignores username and platform. Instagram and TikTok usernames may start with @ and are matched in lowercase; they may only contain letters, digits, . and _ (1 to 30 characters). For YouTube, pass the handle, the channel id (UC…) or the channel URL. - Creators not in the database yet come back as
not_found. For an entry with a username we queue the profile for indexing (queuedForIndexing: true). Like bulkAddToEnrich, this costs 1 request when your request creates the queue entry (counted in queuedCount); a profile that is already waiting for indexing from the last 48 hours stays queued and costs nothing. Add the creator again once the profile is indexed. queuedForIndexing is false when we could not queue the profile, for example when too many creators are already waiting for indexing (the same limit as for bulkAddToEnrich), or for a YouTube channel URL (pass the handle or channel id instead). - Dates (startingDate, endingDate) are YYYY-MM-DD (midnight UTC) or a date and time with Z or an offset, for example 2026-10-01T09:00:00Z or 2026-10-01T11:00:00+02:00. A time without Z or offset is rejected, as are dates before 2000-01-01.
- Start in the past. startingDate starts a new campaign in the past (createCampaign) or moves the start of a campaign earlier (updateCampaign). Like in the app, both need a plan that includes campaigns starting in the past; otherwise the request answers 403 with
reason: "past_start_not_enabled"and changes nothing. - Costs. Every campaign write costs at least 1 request. Creators added as onboarding count as added; creators that are already in the campaign, unavailable or already waiting for indexing cost nothing. Every successful response carries the charged amount in
cost. Before a write runs, your remaining budget has to cover the most it can cost (createCampaign: 1 plus the number of creators you send, addToCampaign: the number of creators you send, the others: 1), otherwise it answers 429 and changes nothing.
Errors come as JSON with error and reason plus details, and are never charged:
Response codes
| 400 | invalid_input: a parameter is missing or invalid. error says what is wrong; field names the parameter when the error is about one, for example creators[2].username. |
| 403 | tracking_not_enabled (createCampaign, addToCampaign): your plan does not include campaign tracking. past_start_not_enabled (startingDate in createCampaign or updateCampaign, carries field: "startingDate"): your plan does not include campaigns that start in the past. campaign_not_writable: a private campaign (change it in the influData app) or a demo campaign (cannot be changed). tracking_seats_exceeded: not enough free tracking seats for the creators of this request, nothing was changed. It carries requested (the seats the request needs), available (the seats still free) and scope: account when the seats of your plan run short, team when the campaign seats allocated to your team do. |
| 404 | campaign_not_found: no campaign with this campaignId in your organization. Campaigns another team shares with you answer this too. |
| 409 | campaign_limit_reached (createCampaign): the campaign limit of your plan is reached (carries maxCampaigns). Every campaign that is not deleted counts, archived ones too. concurrent_write (createCampaign, addToCampaign): another createCampaign or addToCampaign request of your account is still running. Nothing was changed. Retry in a few seconds. |
| 429 | Every campaign write: your monthly request budget cannot cover the call (carries resetDate and upgradeUrl). |
| 503 | entitlements_unavailable (createCampaign, addToCampaign, updateCampaign with startingDate): your plan or your seat usage could not be checked right now. Nothing was changed. Retry in a moment. |
Create campaign
/createCampaignCost: 1 request + 1 per creator added or newly queued for indexing
Creates a campaign and, in the same call, its tracked terms and first creators. All checks run before anything is created: a request that answers with an error creates nothing.
Parameters
| Parameter | Type | Description |
|---|---|---|
| campaignNamerequired | string | Name of the campaign, up to 200 characters. |
| campaignDescription | string | Optional description, up to 2,000 characters. |
| startAsInactive | boolean | true creates the campaign without starting it: creators are added as onboarding and use no tracking seats until you start the campaign in the influData app. Default: false, the campaign starts right away. Must be true or false, not a string. |
| startingDate | string | A date in the past, to start the campaign retroactively: matching posts from that date on count for the campaign. Default: now. Needs a plan that includes campaigns starting in the past (403 past_start_not_enabled otherwise). A future date is rejected, and so is startingDate together with startAsInactive: true. |
| endingDate | string | A date after the start. Content posted after it is not added to the campaign. Default: no end date. |
| trackedMetrics | array | Up to 200 terms that assign posts to the campaign (a creator's post is added when it matches one of them), each { type, value, isExact, isBrandTerm }. type: mention, hashtag, text or url. value: up to 200 characters; a leading # on hashtags and @ on mentions is dropped, and only text terms may contain spaces. isExact (default true): for text terms, match whole words and phrases only; false also matches inside longer words. isBrandTerm (default false) marks a term that names your brand itself: when the campaign also tracks other terms, posts that match only brand terms go to "Needs review" in the app instead of straight into the campaign. A term listed twice (same type, ignoring case) is kept once; one invalid term rejects the request, and field names it. |
| creators | array | Up to 100 creators to add right away, each { creatorId } or { username, platform }, see Manage campaigns. |
curl -X POST "https://app.infludata.com/api/externalAPI/createCampaign" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"campaignName": "Spring Launch 2027",
"trackedMetrics": [
{ "type": "hashtag", "value": "springlaunch" },
{ "type": "mention", "value": "@yourbrand", "isBrandTerm": true }
],
"creators": [
{ "creatorId": "65abc123def456789abc1234" },
{ "username": "newcreator", "platform": "tiktok" }
]
}'
HTTP 201 (trimmed)
{
"campaign": {
"campaignId": "pX7wQ2kL9d",
"campaignName": "Spring Launch 2027",
"startingDate": "2026-10-22T09:30:00.000Z",
"isActive": true,
"trackedMetrics": [
{ "metricId": "tR8kW3mN1p", "type": "hashtag", "value": "springlaunch", "isExact": true, "isBrandTerm": false, ... },
{ "metricId": "vB2nQ7xL4k", "type": "mention", "value": "yourbrand", "isExact": true, "isBrandTerm": true, ... }
],
"creatorCount": 1,
"creators": [ ... ],
...
},
"creatorResults": [
{
"input": { "creatorId": "65abc123def456789abc1234" },
"creatorId": "65abc123def456789abc1234",
"username": "creatorhandle",
"platform": "instagram",
"status": "added"
},
{
"input": { "username": "newcreator", "platform": "tiktok" },
"username": "newcreator",
"platform": "tiktok",
"status": "not_found",
"queuedForIndexing": true
}
],
"addedCount": 1,
"queuedCount": 1,
"cost": 3
}campaign has the same fields as in getCampaign. creatorResults has one entry per creator you sent, in the same order, with the statuses of addToCampaign. addedCount counts the creators added, queuedCount the creators this request newly queued for indexing.
Response codes
| 201 | Campaign created, with one result per creator. Costs 1 request plus 1 per creator added (addedCount) and 1 per creator newly queued for indexing (queuedCount). |
| Errors | See Manage campaigns. Not charged, and no campaign is created. |
Update campaign
/updateCampaignCost: 1 request
Changes the name, description, dates or tracked terms of a campaign. Only the fields you send change, and at least one besides campaignId is required.
Parameters
| Parameter | Type | Description |
|---|---|---|
| campaignIdrequired | string | From getCampaigns. |
| campaignName | string | New name, up to 200 characters. |
| campaignDescription | string | null | New description, up to 2,000 characters. null or an empty string removes the description. |
| startingDate | string | Moves the start of a started campaign earlier, so that matching posts from the new date on count for the campaign. Needs a plan that includes campaigns starting in the past (403 past_start_not_enabled otherwise). A date after the current start is rejected, as are null and a campaign that has not started yet. |
| endingDate | string | null | A date after the campaign start (for a campaign that has not started yet: after now). null removes the end date. |
| trackedMetrics | array | Replaces all tracked terms with this list, same rules as in createCampaign. A term that stays in the list (same type and value, ignoring case) keeps its metricId, and keeps its current isExact and isBrandTerm unless you send them. New terms get the defaults. [] removes all terms, null is rejected. Sending the current list again changes nothing. |
curl -X POST "https://app.infludata.com/api/externalAPI/updateCampaign" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"campaignId": "mK4nP8qR2s", "campaignName": "Winter Launch 2026 DE", "endingDate": "2026-12-31"}'
{
"campaign": { "campaignId": "mK4nP8qR2s", "campaignName": "Winter Launch 2026 DE", ... },
"updatedFields": ["campaignName", "endingDate"],
"cost": 1
}Response codes
| 200 | Saved. campaign has the same fields as in getCampaign, updatedFields lists the fields you sent. Costs 1 request. |
| Errors | See Manage campaigns. Not charged. |
Add creators to campaign
/addToCampaignCost: 1 request per creator added or newly queued for indexing, at least 1
Adds up to 100 creators to a campaign. Every creator gets its own result, so a creator we do not know yet does not fail the whole request. In a campaign that has not started yet or is archived, creators are added as onboarding and need no seats.
Parameters
| Parameter | Type | Description |
|---|---|---|
| campaignIdrequired | string | From getCampaigns. |
| creatorsrequired | array | 1 to 100 creators, each { creatorId } or { username, platform } with platform instagram, tiktok or youtube, see Manage campaigns. |
curl -X POST "https://app.infludata.com/api/externalAPI/addToCampaign" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"campaignId": "mK4nP8qR2s", "creators": [{"creatorId": "65abc123def456789abc1234"}, {"username": "newcreator", "platform": "tiktok"}]}'
{
"campaign": { "campaignId": "mK4nP8qR2s", "campaignName": "Winter Launch 2026", "creatorCount": 9 },
"results": [
{
"input": { "creatorId": "65abc123def456789abc1234" },
"creatorId": "65abc123def456789abc1234",
"username": "creatorhandle",
"platform": "instagram",
"status": "added"
},
{
"input": { "username": "newcreator", "platform": "tiktok" },
"username": "newcreator",
"platform": "tiktok",
"status": "not_found",
"queuedForIndexing": true
}
],
"addedCount": 1,
"queuedCount": 1,
"cost": 2
}creatorCount counts every creator on the roster after the call, archived and onboarding ones included. addedCount counts the creators added, queuedCount the creators this request newly queued for indexing. results has one entry per creator you sent, in the same order. Each entry echoes your entry in input, carries creatorId, username and platform when they are known, and has its own status:
added: added and tracked. Uses a tracking seat.added_onboarding: added as onboarding, because the campaign has not started yet or is archived. Uses no seat.already_in_campaign: the creator is already on the roster (also when archived), or an earlier entry of the same request added it. Nothing changed.not_found: the creator is not in the influData database yet.queuedForIndexing(only for entries with a username) says whether the profile is queued for indexing. It costs 1 request when this request queued it, nothing when it was already waiting, see Manage campaigns.unavailable: the creator was not added.reasonsays why: not_addable (this creator cannot be tracked in campaigns), tracking_seats_exceeded (the seats ran out while the request was running, for example because a change in the influData app used them at the same time) or internal_error (the add failed on our side, try again).
Response codes
| 200 | One result per creator. Costs 1 request per creator added (addedCount) or newly queued for indexing (queuedCount), and at least 1 request, also when nothing was added. |
| Errors | See Manage campaigns. Not charged, and no creator is added. |
Remove or archive creators
/removeFromCampaignCost: 1 request per call
Takes creators off a campaign, or archives them so the content collected so far stays.
Parameters
| Parameter | Type | Description |
|---|---|---|
| campaignIdrequired | string | From getCampaigns. |
| creatorIdsrequired | string[] | 1 to 100 influData creator ids (creatorId from getCampaign). An id sent twice counts once. |
| archive | boolean | true archives the creators: they stay on the roster with the content collected so far, are no longer tracked and free their tracking seats. A creator that is already archived keeps its archive date. Default: false, the creators are taken off the roster, together with what is set for them in this campaign, such as pricing and custom field values. Their content collected so far is not deleted, but the campaign no longer shows it. |
curl -X POST "https://app.infludata.com/api/externalAPI/removeFromCampaign" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"campaignId": "mK4nP8qR2s", "creatorIds": ["65abc123def456789abc1234", "65abc123def456789abc5678", "65abc123def456789abc9012"], "archive": true}'
{
"results": [
{ "creatorId": "65abc123def456789abc1234", "username": "creatorhandle", "platform": "instagram", "status": "archived" },
{ "creatorId": "65abc123def456789abc5678", "username": "othercreator", "platform": "tiktok", "status": "archived", "alreadyArchived": true },
{ "creatorId": "65abc123def456789abc9012", "status": "not_in_campaign" }
],
"removedCount": 1,
"cost": 1
}Response codes
| 200 | One status per creator: removed, archived (with alreadyArchived: true when it was archived before this call) or not_in_campaign. removedCount counts only the creators this call changed. Costs 1 request, also when nothing changed. |
| Errors | See Manage campaigns. Not charged. |
Archive or delete a campaign
Cost: 1 request per call
archiveCampaign ends a campaign: tracking stops for all its creators and their tracking seats are freed, while the content collected so far stays in the campaign. A campaign that is already archived or has not started yet is left as it is, and the response carries its current setInactiveOn. deleteCampaign removes the campaign and frees its creators' seats; it no longer shows up in getCampaigns or in the app. Neither can be undone through the API. Each costs 1 request, also for a campaign that is already archived.
POST https://app.infludata.com/api/externalAPI/archiveCampaign {"campaignId": "mK4nP8qR2s"}
POST https://app.infludata.com/api/externalAPI/deleteCampaign {"campaignId": "mK4nP8qR2s"}Response codes
| 200 | archiveCampaign: { campaignId, isActive: false, setInactiveOn, cost: 1 }. deleteCampaign: { campaignId, deleted: true, cost: 1 }. |
| Errors | See Manage campaigns. Not charged. |
Internal notes & custom fields
Notes and custom fields are the org-internal data your team maintains on creators in the influData app. The API returns them on every creator inside getCollection responses and — for organization keys — on getUserData:
- Notes —
commentThread: the per-creator comment thread. Each entry carries the author (user), text, pin state, timestamp and — when a file was attached — a short-lived signed URL inlinkToResources. - Custom-field definitions —
metadata.additionalFields: the fields your organization defined in the app, each withcode,label,type(string, number, boolean, date, singleselect, multiselect, upload) andallowedValuesfor the select types. - Custom-field values — the per-creator
additionalFieldsarray:{ "code": "…", "value": … }pairs — join oncodewith the definitions. Upload-type values resolve to signed, short-lived URLs. - Rating & flags —
stars(0–5 team rating),isBlack(on your blacklist). - Membership — per creator,
collectionsandcampaignslist the creator's memberships including their names (collectionArray/campaignArraycarry the plain ids) — returned by both getUserData and getCollection.
Notes, custom-field values and ratings are currently read-only via the API — your team edits them in the influData app. If your integration needs write access here, talk to us.
Content download links
/getContentDownloadLinkCost: 1 request (404s are not charged)
Resolves a fresh, direct CDN link for an Instagram or TikTok content piece — for downloading media into your own asset pipeline (transcription, archiving, reporting).
Parameters
| Parameter | Type | Description |
|---|---|---|
| platformrequired | string | instagram or tiktok. |
| coderequired | string | Instagram shortcode (e.g. CeLgPLAg14Q) or TikTok content id. |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/getContentDownloadLink?platform=instagram&code=CeLgPLAg14Q"
{
"platform": "instagram",
"code": "CeLgPLAg14Q",
"links": [
{ "type": "video_1", "link": "https://... (CDN, valid ~6h)" },
{ "type": "image_1", "link": "https://..." }
]
}Links are valid for roughly 6 hours — download immediately, never store the URL. Multi-image posts return one entry per slide (image_1, image_2, …).
Watchlist monitoring
The watchlist is a curated roster of Instagram and TikTok creators your organization monitors continuously: fresh follower and engagement stats, a live content feed (posts, reels, stories), comment monitoring with flag terms, AI sentiment and brand-safety deep dives, and alert events (early-viral detection, follower spikes, keyword hits).
Availability: every organization API key (no add-on needed). Trial keys get 403.
- Creators are added in the influData app only. Adding a creator starts daily crawling, a content backfill and an AI deep dive, so the add stays in the app (app.infludata.com/watchlist), where the seat pool and the removal lock are visible.
POST /watchlist/creatorsanswers 403 withreason: "app_only". The API reads the roster and its monitoring signals, manages labels and removes creators. - 30-day removal lock. A creator cannot be removed for 30 days after being added — the history import and the AI deep dive run in that window, and the tracking seat stays reserved. Every roster entry carries
removalLockedandremovalLockedUntil; while the lock holds,DELETEanswers 403 withreason: "removal_locked". - One watchlist per organization. The API operates on the same watchlist as the influData app, and both share the same creator seat pool (sized by your plan). Seats are counted per person: verified sibling accounts of the same creator (e.g. their TikTok) are auto-linked into a person group and don't consume an extra seat.
- Costs: all reads and roster mutations (labels, remove) cost 1 request from your monthly budget. Manually re-running a deep dive costs 10 (it re-runs the AI report pipelines).
- Signed media URLs: avatar and image/thumbnail URLs in responses are short-lived signed URLs (valid ~6–24 hours);
videoUrlis the platform's own expiring CDN URL. Fetch the media immediately when importing, or request permanent links instead (see Media URLs).
https://app.infludata.com/api/externalAPI/watchlistGet watchlist
/watchlistCost: 1 request
Returns your organization's roster with labels, flag terms and seat usage.
Parameters
| Parameter | Type | Description |
|---|---|---|
| withGrid | boolean | true to hydrate each creator with live signals (follower deltas, activity, engagement, latest pieces). Slower; still costs 1. |
| days / from & to | string | Stats window for withGrid (relative days or absolute ISO range). Default: 30 days. |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/watchlist"
{
"watchlist": {
"name": "Watchlist",
"creators": [
{
"platform": "instagram",
"referenceId": "65abc123def456789abc1234",
"username": "creatorhandle",
"displayName": "Creator Name",
"profilePicURL": "https://... (signed, short-lived)",
"followers": 125000,
"country": "DE",
"categories": ["media"],
"labels": ["<labelId>"],
"groupId": "66def...",
"addedAt": "2026-07-01T09:00:00.000Z",
"addedByMail": "teammate@yourcompany.com",
"addedVia": "app",
"removalLocked": true,
"removalLockedUntil": "2026-07-31T09:00:00.000Z"
}
],
"labels": [{ "id": "...", "name": "VIP", "color": "#1e88e5" }],
"flagTerms": [{ "term": "scandal", "createdAt": "2026-07-01T09:00:00.000Z" }],
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-07-15T00:00:00.000Z"
},
"seatsUsed": 12,
"maxSeats": 25,
"poolUsed": 19,
"removalLockDays": 30
}maxSeats is null if the plan lookup is temporarily unavailable (reads still succeed). poolUsed is the tracking-seat occupancy across campaigns, watchlist and social listening (omitted when the lookup is unavailable). removalLockedUntil is null for legacy entries without addedAt — those never lock.
Add creator to watchlist (app only)
/watchlist/creatorsCost: not charged
Creators are added in the influData app only: open app.infludata.com/watchlist, search the handle and add it there. The add starts continuous monitoring, a content backfill (12 months on Instagram; TikTok history builds forward from the daily crawls) and an AI deep dive (sentiment + brand safety, 24–48h SLA), auto-links verified sibling platform accounts under the same person seat and starts the 30-day removal lock. Within minutes the creator shows up on GET /watchlist with addedVia: "app".
curl -X POST "https://app.infludata.com/api/externalAPI/watchlist/creators" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"platform": "instagram", "username": "creatorhandle"}'
HTTP 403
{
"error": "Creators are added to the watchlist in the influData app only. Open https://app.infludata.com/watchlist to add a creator; the API then reads the roster, its monitoring signals and alert events.",
"reason": "app_only",
"appUrl": "https://app.infludata.com/watchlist",
"removalLockDays": 30
}Response codes
| 403 | Always — reason "app_only". Not charged. |
Remove creator from watchlist
/watchlist/creators/{platform}/{referenceId}Cost: 1 request
Creators stay on the watchlist for 30 days after being added (the history import and the AI deep dive run in that window). Check removalLocked / removalLockedUntil on GET /watchlist before deleting.
Parameters
| Parameter | Type | Description |
|---|---|---|
| wholeGroup | boolean | true removes every platform account of the person group (frees the whole seat). The person unlocks when its last-added account unlocks. |
curl -X DELETE -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/watchlist/creators/instagram/65abc123def456789abc1234?wholeGroup=true"
{ "success": true, "removed": [{ "platform": "instagram", "referenceId": "65abc..." }], "modified": true }
HTTP 403 (inside the 30-day window)
{
"error": "@creatorhandle can't be removed yet: creators stay on the watchlist for 30 days after being added — the 12-month history import and the AI deep dive run in that window. Removal is possible from 2026-07-31.",
"reason": "removal_locked",
"removalLockDays": 30,
"removalLockedUntil": "2026-07-31T09:00:00.000Z",
"creator": { "platform": "instagram", "referenceId": "65abc...", "username": "creatorhandle", ... }
}Response codes
| 200 | Removed. Idempotent: modified is false when the creator was not on the roster (still costs 1). |
| 403 | Removal locked — reason "removal_locked" with removalLockedUntil. Not charged. |
| 400 | Unsupported platform or malformed referenceId. |
Labels
Cost: 1 request each
Organize the roster with labels (max 20 per watchlist; colors are assigned automatically). Setting a creator's labels replaces the whole list; unknown label ids are silently dropped.
GET https://app.infludata.com/api/externalAPI/watchlist/labels
POST https://app.infludata.com/api/externalAPI/watchlist/labels {"name": "VIP"}
DELETE https://app.infludata.com/api/externalAPI/watchlist/labels/{labelId}
PUT https://app.infludata.com/api/externalAPI/watchlist/creators/{platform}/{referenceId}/labels {"labels": ["<labelId>"]}Response codes
| 200 | Label list / updated labels. |
| 400 | Missing name or invalid parameters. |
| 403 | Label cap reached (20 per watchlist). |
| 404 | No watchlist yet, or label not found. |
| 409 | Duplicate label name (the existing label is returned). |
Content feed
/watchlist/contentCost: 1 request
Reverse-chronological content stream across the whole roster — posts, reels and stories with captions, performance metrics and links to the original piece. This is the endpoint for syncing watchlist content into your CMS or tooling.
Parameters
| Parameter | Type | Description |
|---|---|---|
| days / from & to | string | Window (relative days or absolute ISO range). Default: 30 days, max 365. |
| platform | string | instagram or tiktok. Default: both. |
| contentTypes | string | Comma-separated: post, reel, story (Instagram); video (TikTok). |
| limit | number | 1–100 pieces per page. Default: 30. |
| before | string | ISO cursor — return only pieces older than this (paging back). |
| after | string | ISO cursor — return only pieces newer than this. Use for incremental syncs. |
# Full pull, then remember newestISO from the response
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/watchlist/content?days=7&limit=100"
# Next poll: only pieces newer than the last one you saw
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/watchlist/content?after=2026-07-27T15:28:11.000Z"
{
"pieces": [
{
"contentId": "3949132417417327988",
"contentType": "story",
"imageUrl": "https://... (signed, valid ~6-24h)",
"videoUrl": null,
"platformLink": null,
"postUrl": "https://www.instagram.com/stories/creatorhandle/3949132417417327988/",
"uploaded": "2026-07-28T09:15:00.000Z",
"caption": "…",
"reach": 12500, "likes": 830, "comments": 41, "shares": 0, "saves": 0,
"commentPositivityRate": 92,
"language": "de",
"locationString": null,
"viralScore": 3.4, "viralMetric": "views",
"creator": {
"platform": "instagram",
"referenceId": "65abc123def456789abc1234",
"username": "creatorhandle",
"displayName": "Creator Name"
}
}
],
"hasMore": false,
"newestISO": "2026-07-28T09:15:00.000Z",
"timeframe": { "fromISO": "...", "toISO": "...", "days": 7 }
}- postUrl is the canonical link to the piece on its platform — use this field.
platformLink(the crawled permalink) is kept for backwards compatibility but isnullfor Instagram stories; postUrl covers stories with a constructed story URL that resolves while the story is live (~24h — afterwards Instagram redirects to the creator's profile). imageUrl/videoUrlare signed and short-lived — import the media right away, or use permanent links (see Media URLs).- Pieces the early-viral detector currently flags carry
viralScoreandviralMetric. commentPositivityRateis the share of positive comments on a 0–100 scale;nullwhen comment analysis has not run for the piece.
Content piece by ID
/watchlist/content/{contentId}Cost: 1 request (404s are free)
Fetch a single content piece by its influData contentId — the id returned by the content feed and on content-bearing alert events. Same piece shape as the feed, including postUrl and fresh signed media URLs. Typical use: an alert event names a piece and you pull its full data with one call.
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/watchlist/content/3949132417417327988"
{
"contentId": "3949132417417327988",
"contentType": "story",
"postUrl": "https://www.instagram.com/stories/creatorhandle/3949132417417327988/",
"uploaded": "2026-07-28T09:15:00.000Z",
"reach": 12500, "likes": 830, "comments": 41,
"creator": { "platform": "instagram", "referenceId": "65abc...", "username": "creatorhandle", "displayName": "Creator Name" }
}Response codes
| 200 | The piece. |
| 400 | Malformed contentId. |
| 404 | The piece does not exist or does not belong to a creator on your watchlist (not charged). |
Creator details (deep dive)
/watchlist/creators/{platform}/{referenceId}/detailsCost: 1 request
The full per-creator payload: core profile fields, follower growth series with milestones, activity stats, the creator's content in the window, audience demographics, sentiment and brand-safety summaries, and the deep-dive pipeline status.
Parameters
| Parameter | Type | Description |
|---|---|---|
| days / from & to | string | Content + chart window. Default: 90 days. |
| contentLimit | number | 1–200 content pieces. Default: 30. |
{
"creator": { ...profile fields... },
"growth": { "points": [...], "deltas": {...}, "milestones": [...] },
"activity": { "postsLast7d": 4, "postsLast30d": 19, "engagementWindow": 2.4, ... },
"content": [{ "contentId": "...", "postUrl": "...", "platformLink": "...", ... }],
"sentiment": { ... },
"audience": { ... },
"brandSafety": { ... },
"reportStatus": { ... },
"timeframe": { ... }
}Audience demographics, sentiment and brand safety require the creator to be on your watchlist (the seat is the entitlement) and their deep-dive reports to have completed — reportStatus shows the pipeline progress.
Per-creator monitoring reads
Cost: 1 request each
GET https://app.infludata.com/api/externalAPI/watchlist/creators/{platform}/{referenceId}/sentiment-timeline ?granularity=week|month &sinceDays=42..365 (default 56)
GET https://app.infludata.com/api/externalAPI/watchlist/creators/{platform}/{referenceId}/brand-mentions ?days=90
GET https://app.infludata.com/api/externalAPI/watchlist/creators/{platform}/{referenceId}/flagged-comments ?days=30 &limit=1..200 (default 50)
GET https://app.infludata.com/api/externalAPI/watchlist/creators/{platform}/{referenceId}/top-comments ?days=30 &limit=1..100 (default 20)
GET https://app.infludata.com/api/externalAPI/watchlist/creators/{platform}/{referenceId}/flagged-content ?days=30 &limit=1..100 (default 50)The windowed reads also accept absolute from & to ISO ranges instead of days. Flagged comments/content are matched against your organization's flag terms (managed in the influData app). Creators not on your watchlist return empty payloads, not errors.
Re-run deep dive
/watchlist/creators/{platform}/{referenceId}/deep-diveCost: 10 requests
Re-enqueues the sentiment + brand-safety analysis for a rostered creator (deduped server-side against already-running pipelines). Use after major events when you want fresh AI summaries before the next scheduled run. The call costs 10 even when the dedupe reports an analysis is already active/exists — check the returned deepDive statuses before retrying. Creators not on the watchlist return 404 (not charged).
Alert events
/watchlist/alert-eventsCost: 1 request
Recent alert events from your watchlist's alert rules: early-viral detection, viral posts, new content, keyword matches, mentions by other accounts, follower spikes and sentiment drops.
Parameters
| Parameter | Type | Description |
|---|---|---|
| since | string | ISO 8601 timestamp — only events created after it. Poll incrementally: store the newest createdAt you have seen and pass it on the next call (recommended interval: 5–15 minutes). |
| platform | string | instagram or tiktok. |
| referenceId | string | Limit to one creator. |
| limit | number | 1–100 events. Default: 30. |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/watchlist/alert-events?since=2026-07-28T09:00:00Z"
{
"events": [
{
"id": "66a1b2c3d4e5f6a7b8c9d0e1",
"ruleId": "rule-1",
"ruleType": "early_viral",
"ruleName": "Early viral detector",
"platform": "instagram",
"referenceId": "65abc123def456789abc1234",
"creatorUsername": "creatorhandle",
"creatorDisplayName": "Creator Name",
"title": "A reel by Creator Name is taking off",
"description": "Views growing 4.2× faster than usual — …",
"link": "https://app.infludata.com/watchlist/instagram/65abc...",
"contentId": "3949132417417327988",
"contentUrl": "https://www.instagram.com/stories/creatorhandle/3949132417417327988/",
"payload": { ... },
"createdAt": "2026-07-28T09:21:33.000Z"
}
],
"count": 1
}Content-bearing events (viral_post, early_viral, new_content, keyword_match, mentioned_by_others) identify the triggering piece via contentId and contentUrl (direct link to the piece; for Instagram stories a constructed story URL that resolves while the story is live). Fetch the full piece via content piece by ID. Both fields are null for rule-level events (follower_change, sentiment_drop) and for keyword_match events triggered by comment hits — those carry payload.commentId (and payload.connectedContent when the parent piece is known) instead. True push webhooks (signed deliveries to your URL) are on the roadmap — polling since is the supported integration until then.
Client info & balance
/getClientInfoCost: Free
Returns your account information and remaining request balance.
Parameters
| Parameter | Type | Description |
|---|---|---|
| clientIdrequired | string | Your client ID — returned when your key was issued (trial keys: "trial-..." from verifyTrialKey). |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/getClientInfo?clientId=YOUR_CLIENT_ID"
{
"clientId": "YOUR_CLIENT_ID",
"reportsLeft": 230,
"reports": [],
"createdDate": "2026-06-11T14:00:00.000Z",
"expiresAt": "2026-06-25T00:00:00.000Z"
}expiresAtis present for trial keys only. A clientId that doesn't match the key returns 400.
Org usage & limits
/getUsageCost: Free
Returns your organization's monthly request budget: plan limit, requests used this month, remaining budget, the next reset date and your active keys (masked). Organization keys only — trial keys use getClientInfo.
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/getUsage"
{
"orgId": "YOUR_CLIENT_ID",
"monthlyLimit": 15000,
"currentMonthUsed": 4210,
"remaining": 10790,
"resetDate": "2026-08-01T00:00:00.000Z",
"audienceReportsEnabled": true,
"keys": [
{ "id": "aB3xYz9QwE", "name": "Production", "maskedKey": "••••••••••••••••••••••••••x7Kd", "createdAt": "2026-07-01T09:00:00.000Z" }
]
}monthlyLimit, remaining and resetDate are null for keys on unmetered or lifetime-budget contracts.
Cities for country
/getCitiesForCountryCost: Free
Returns the list of cities available for the discovery city filter in a given country.
Parameters
| Parameter | Type | Description |
|---|---|---|
| countryrequired | string | Country name, e.g. Germany, United States (case-sensitive). |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://app.infludata.com/api/externalAPI/getCitiesForCountry?country=Germany"
["Berlin", "Munich", "Hamburg", "Cologne", "Frankfurt am Main", ...]Unknown or misspelled countries return an empty array with 200, not an error.
Creator categories
Values for the categories parameter in discovery (comma-separate multiple values):
fashion — Fashion & Stylefitness — Fitness & Wellnessbeauty — Beauty & Cosmeticssports — Athletics & Sportsfood — Food & Drinkdiet — Healthy Nutrition & Dietveganism — Veganism & Vegetarianismtravel — Travel & Adventurebooks — Books & Literatureinterior — Home & Interior Designcomedy — Comedytech — Technology & Gadgetsart — Art & Creativitylifestyle — Lifestyleeducation — Education & Learningfamily — Parenting & Familymedia — Entertainment & Mediamusic — Musiclgbtq — LGBTQ+gaming — Gamingbusiness — Business & Financeautomotive — Automotive & Vehiclessustainability — Sustainability & Environmentanimals — Animals & Petscharity — Charity & Activismpolitics — PoliticsPlatform coverage
| Feature | TikTok | YouTube | Twitch | Snapchat | ||
|---|---|---|---|---|---|---|
| Creator profiles (getUserData) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Discovery search | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Audience reports | ✓ | ✓ | ✓ | — | — | — |
| Content data (getContent) | ✓ | ✓ | ✓ | — | — | — |
| Watchlist monitoring | ✓ | ✓ | — | — | — | — |
| Data status (checkDataStatus) | ✓ | ✓ | ✓ | ✓ | — | — |
| On-demand enrichment | ✓ | ✓ | ✓ | — | — | ✓ |
| City / gender / age filters | ✓ | ✓ | — | — | — | — |
| Business account mode | ✓ | — | — | — | — | — |
LinkedIn profiles can additionally be queued for enrichment via checkDataStatus and bulkAddToEnrich (profile retrieval for LinkedIn is not yet part of the public API). On-demand enrichment for Snapchat works when a username lookup misses; Twitch and Facebook profiles are served from the existing database only.
Error handling
Errors are returned as JSON with an error field and a standard HTTP status code:
Response codes
| 400 | Bad request — invalid or missing parameters. |
| 401 | Unauthorized — invalid, missing or expired API key. |
| 402 | Insufficient request balance on the enrichment endpoints (checkDataStatus, bulkAddToEnrich). |
| 403 | Forbidden — insufficient request balance, or the feature is not enabled for your key. |
| 404 | Not found — the requested creator or content does not exist. |
| 409 | Conflict: a plan limit is reached (campaign_limit_reached on createCampaign), another campaign write of your account is still running (concurrent_write, retry in a few seconds) or the item already exists (duplicate watchlist label). |
| 422 | Platform not supported for automatic enrichment. |
| 429 | Rate limit or monthly volume exceeded — back off and retry later. |
| 500 | Server error — retry with exponential backoff. |
| 503 | Temporarily unavailable, for example when your plan cannot be checked right now (entitlements_unavailable). Retry with exponential backoff. |
Recommended retry strategy: exponential backoff starting at 1 s with a maximum of 3 retries; never retry 4xx responses except 429 and 409 concurrent_write. Exception: discovery signals failures inside a 200 response via { "status": false } — check the body there.
Ready to build?
Get a free trial key in minutes: 250 requests, every supported platform, full production data. Ready for production? Book a plan self-serve and your key arrives right after checkout.
Get your trial key