← Back to API Documentation

API v2 Changelog

This page summarizes all changes between API v1 and v2. The new API is available at /api/v2/. The existing v1 API at /api/v1/ remains available in parallel.

New Base URL

v1
/api/v1/...
v2
/api/v2/...

Endpoint Overview (v2)

  • GET /api/v2/{network}
  • GET /api/v2/{network}/{profileId}
  • GET /api/v2/{network}/{profileId}/{endpoint}
  • GET /api/v2/profiles/connected
  • GET /api/v2/profiles/queried
  • GET /api/v2/docs

Available endpoints per profile: profile, profile/daily, posts, stories

Supported networks: facebook, instagram, x, youtube, linkedin, pinterest, tiktok, threads, bluesky

August 2026 — Limits Are Now Explainable

Breaking EXCEEDED_ACCESS_LIMIT now returns HTTP 403 instead of 429

An exhausted profile quota used to be indistinguishable from an hourly rate limit, since both returned 429. The two are not the same: the quota only resets once per billing cycle, so waiting never helps — clients retrying on 429 kept hitting the wall until the cycle ended. The API documentation already listed 403 for this error code.

Breaking Further Status Codes Aligned With the Documentation

Error Code Before Now
EXCEEDED_ACCESS_LIMIT429403
INVALID_TOKEN403401
INVALID_ENDPOINT400404
INVALID_PROFILE_ID400404
ENDPOINT_NOT_AVAILABLE_FOR_NETWORK403400

Integrations that branch on error.code rather than the HTTP status are unaffected by all five changes.

Breaking Error responses no longer carry profile_name / username

When a request is rejected because of the profile quota, the API now stops before refreshing the profile, so metadata no longer contains profile_name and username. network, profile_id and endpoint are still present, and successful responses are unchanged. The reason is response time: previously a full report was computed and then discarded — a rejection took 10.5 seconds in the case that triggered this change, and now takes under one.

New error.details

Limit errors now carry machine-readable numbers, so an integration no longer has to parse the message text.

{
"error": {
"code": "EXCEEDED_ACCESS_LIMIT",
"message": "Your API access is configured for 50 profiles, and 50 are already in use. ...",
"details": {
"quota_unit": "profiles",
"quota_max": 50,
"quota_used": 50,
"quota_required": 1,
"quota_resets_at": "2026-09-01",
"requested_profile_is_new": true
}
}
}

With an ENTERPRISE licence quota_unit is credits and quota_required states what the requested network costs (TikTok 3, X 5, otherwise 1). For RATE_LIMIT_EXCEEDED the object contains limit, remaining, reset, window and days_requested.

New Retry-After

429 responses now include a Retry-After header with the seconds until the limit resets at the top of the hour. Quota-related 403 responses deliberately omit it — their reset date is returned as quota_resets_at instead.

Correction: Rate-Limit Table

The documented rate-limit tiers did not match the actual behaviour. For /profile and /profile/daily, the limit of 365 requests per hour applies to date ranges of less than 8 days; from 8 days onwards it is 75 (previously documented as 365 up to and including 13 days). The tiers for /posts and /stories are also at 8 and 14 days. The API behaviour is unchanged — only the documentation was wrong.

Breaking Changes

The following changes in v2 are intentionally breaking and require updates to existing integrations.

Breaking 1. Authentication via Bearer Header

The API token is no longer passed as a query parameter. Use the Authorization header instead.

v1
?token=YOUR_TOKEN
v2
Authorization: Bearer YOUR_TOKEN

Example:

curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://app.fanpagekarma.com/api/v2/facebook/6815841748/profile"

Breaking 2. period Replaced by from / to

The period=YYYY-MM-DD_YYYY-MM-DD parameter is removed in v2. Use separate from and to parameters instead.

v1
?period=2026-01-01_2026-01-31
v2
?from=2026-01-01&to=2026-01-31

Rules:

  • If both from and to are omitted: default period (last 28 full days, excluding today).
  • If only from is set: to defaults to yesterday (UTC).
  • If to is set, from must also be set.

Breaking 3. Network Path twitterx

The twitter network path has been removed in v2. Use x instead.

v1
/api/v1/twitter/...
v2
/api/v2/x/...

Breaking 4. Intentional Breaking Changes

v2 is a new major version with intentional breaking changes. It is not backwards-compatible with v1.

Breaking 5. KPI Alias Names Removed

In v2, only the current metric key names are returned. Legacy alias key names from the v1 fallback are no longer included in the response.

Breaking 6. Field Name kpimetrics

In v2, the nested metrics object in post and story responses uses the field name metrics instead of kpi.

v1
{
"kpi": { ... }
}
v2
{
"metrics": { ... }
}

Breaking 7. Field Name taskendpoint

In v2, the metadata field for the requested path is named endpoint instead of task.

v1
{
"task": "profile"
}
v2
{
"endpoint": "profile"
}

Breaking 8. Structured Error Object

The metadata.error string field is removed. Instead, a top-level error object with code and message is returned.

v1
{
"data": {},
"metadata": {
"error": "Invalid token."
}
}
v2
{
"data": {},
"metadata": {
"version": "v2"
},
"error": {
"code": "INVALID_TOKEN",
"message": "Invalid token."
}
}

Possible error codes:

UNEXPECTED_ERROR, INVALID_ENDPOINT, NO_BEARER_TOKEN,
INVALID_BEARER_HEADER, INVALID_TOKEN, NO_PROFILE_ID,
INVALID_PROFILE_ID, NO_USER_FOR_ACCOUNT, EXCEEDED_ACCESS_LIMIT,
ACCOUNT_SUSPENDED, DATABASE_ERROR,
ENDPOINT_NOT_AVAILABLE_FOR_NETWORK, RATE_LIMIT_EXCEEDED,
INVALID_DATE_RANGE, MISSING_METRICS

Breaking 9. Date Format Changed to ISO 8601

All date fields now use ISO 8601 format.

v1 — Metadata dates
"Thu Jan 22 00:00:00 UTC 2026"
v2 — Metadata dates
"2026-01-22"
v1 — Post/Story timestamps
"Thu Jan 22 14:30:00 UTC 2026"
v2 — Post/Story timestamps
"2026-01-22T14:30:00Z"

Breaking 10. Metric description Field Removed

The description field has been removed from metric objects in data responses. Use the dedicated metrics catalog endpoint to retrieve metric descriptions.

v1
{
"engagement": {
"title": "Engagement",
"description": "Average number of interactions...",
"value": 0.042,
"formatted_value": "4.2%"
}
}
v2
{
"engagement": {
"title": "Engagement",
"value": 0.042,
"formatted_value": "4.2%"
}
}

Metric descriptions are available via:

GET /api/v2/{network}/{endpoint}/metrics

New Features

New Profile Daily Endpoint

The /profile/daily endpoint returns daily time series data for profile metrics.

  • from and to are both required parameters (YYYY-MM-DD)
  • metrics is a required parameter — comma-separated list of metric API names
  • Response contains a time series per metric with title and values: [{date, value}]
  • Response data key is "daily"
  • Available metric keys can be discovered via the /profile endpoint

Example:

curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://app.fanpagekarma.com/api/v2/facebook/6815841748/profile/daily?from=2026-01-01&to=2026-01-31&metrics=page_follower,engagement"

New Metrics Filter for All Endpoints

The metrics query parameter is now supported on all data endpoints (/profile, /posts, /stories), not just /profile/daily. Pass a comma-separated list of metric API names to return only the specified metrics.

  • Required for /profile/daily, optional for all other endpoints
  • If omitted on /profile, /posts, /stories: all metrics are returned (same as before)
  • Use GET /api/v2/{network}/{endpoint}/metrics to discover available metric keys

Example — only return engagement and page_follower for a profile:

curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://app.fanpagekarma.com/api/v2/facebook/6815841748/profile?metrics=page_follower,engagement"

New Pagination for Posts/Stories

Posts and stories endpoints now support limit and offset query parameters.

  • limit — Maximum number of returned items (default and max: 1000)
  • offset — Number of items to skip (default: 0)
  • Metadata includes: total_count, limit, offset

Example:

curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://app.fanpagekarma.com/api/v2/facebook/6815841748/posts?limit=5&offset=10"

New Rate-Limit Headers

All authenticated responses to /{network}/{profileId}/{endpoint} now include rate-limit information as HTTP headers:

  • X-RateLimit-Limit — Maximum requests per hour for this token/endpoint/profile combination
  • X-RateLimit-Remaining — Remaining requests in the current hour
  • X-RateLimit-Reset — Unix timestamp (seconds) when the limit resets

New OpenAPI Documentation

The OpenAPI specification at /api/v2/docs now includes:

  • Security schema (Bearer Token)
  • Parameter descriptions with example values and allowed values
  • Response documentation for all endpoints

Unchanged in v2

  • API rate limits remain the same.
  • Public demo profiles remain available; a demo token is no longer required for these.

Migration Checklist

Follow these steps to migrate your integration from v1 to v2:

  1. Change your base URL to /api/v2/.
  2. Remove the token query parameter and set the Authorization: Bearer <token> header instead.
  3. Replace period with separate from and to parameters.
  4. Change the twitter network path to x.
  5. Update post/story parsing: rename kpi to metrics.
  6. Update metadata parsing: rename task to endpoint.
  7. Update error handling: parse error.code / error.message instead of metadata.error.
  8. Update date parsing to ISO 8601 format (YYYY-MM-DD and YYYY-MM-DDTHH:mm:ssZ).
  9. Optionally integrate the new OpenAPI spec at /api/v2/docs.
  10. For daily time series data, use the new /profile/daily endpoint. Requires from, to, and metrics parameters.
  11. Remove any code that reads the description field from metric objects. Use GET /api/v2/{network}/{endpoint}/metrics to retrieve metric descriptions separately.