Fedica API Documentation

Base URL: https://fedica.com/api

Authorization

All API endpoints require authentication using a Bearer token. Include your API token in the Authorization header of every request. The API is available on premium plans; if your API key has IP restrictions, requests must come from one of the allowed IP addresses.

Header Format

Authorization: Bearer YOUR_API_TOKEN

Example Request

curl -X POST https://fedica.com/api/publish/post \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "Posts": [...]
  }'

Important: Keep your API token secure and never expose it in client-side code or public repositories. Requests without a valid token will receive a 401 Unauthorized response.

Supported Platforms

The Platform value returned by the accounts endpoints is one of these names.

Twitter
LinkedIn
Instagram
Facebook
Pinterest
Tiktok
Mastodon
BlueSky
MetaThreads
Youtube
Pixelfed
Tumblr
PeerTube
Telegram

Error Handling

All endpoints return a consistent error response format. Always check the Success field: validation errors (a missing parameter, an account or report that isn't found, and so on) are returned with HTTP status 200 and "Success": false.

{
  "Success": false,
  "Error": "Error message describing what went wrong"
}

HTTP Status Codes:

  • 200 OK: Request processed; check Success and Error for the outcome
  • 401 Unauthorized: Invalid or missing bearer token, a non-premium account, or a request from an IP address the API key doesn't allow
  • 500 Internal Server Error: Server error occurred

Accounts Endpoints

Base path: /api/accounts

GET

/accounts/list

Retrieve the social media accounts connected to your Fedica account. The Id of each account is the accountId used by the publishing, analytics and research endpoints.

Request

No parameters required.

Response

{
  "Success": true,
  "Error": null,
  "Accounts": [
    {
      "Platform": "Twitter",
      "Username": "fedica",
      "Id": "1-12345"
    }
  ]
}

Platform: Platform name, one of the supported platforms

Username: The account's username on the platform

Id: Account identifier to use as accountId in other endpoints

Publishing Endpoints

Base path: /api/publish

POST

/publish/post

Publish a post now, schedule it for a later date, or add it to a pipeline, on one or multiple social media accounts.

Request Body

{
  "PipelineId": 123,
  "DateTime": "2026-10-01T12:00:00Z",
  "Posts": [
    {
      "AccountIds": ["1-12345", "2-67890"],
      "Messages": ["Your post content here"],
      "MediaId": ["media-id-1", "media-id-2"]
    }
  ]
}

Request Fields

Id

Type: string (optional)

Used for editing existing posts. Do not provide when creating new posts.

PipelineId

Type: integer (optional)

The ID of a pre-configured publishing pipeline (see /publish/pipelines). When provided, the post is added to the pipeline and published according to its schedule, and DateTime is ignored.

DateTime

Type: string (optional)

The date and time when the post should be published, in ISO 8601 format with timezone information (e.g., "2026-10-01T12:00:00Z"). It cannot be in the past. If neither DateTime nor PipelineId is provided, the post is published immediately.

Posts *

Type: array of Post objects

Array of post configurations. Each post can target different accounts and contain different content. If the same post goes to multiple accounts, use only one post object; if you wish to customize the post for different platforms, use a separate post object per platform.

AccountIds *

Type: array of strings

The Id of each account where this post will be published, as returned by /accounts/list.

Messages *

Type: array of strings

Array of message content strings. Multiple messages can be provided for platforms that support threads.

MediaId

Type: array of strings (default: empty array)

Array of media file IDs obtained from the media upload endpoints. Attach images, videos, or other media to your post.

Accounts legacy

Type: array of objects with Platform and AccountId (username)

Kept for backward compatibility and used only when AccountIds is not provided. New integrations should use AccountIds.

Response

{
  "Success": true,
  "Error": null,
  "Id": "12345"
}

Success: Boolean indicating if the operation was successful

Error: Error message if operation failed, null otherwise

Id: Content ID of the scheduled post. When a post is saved but publishing it immediately fails, Success is false and Id is still returned.

GET

/publish/posts/pending

Retrieve the posts waiting to be published, earliest first, one page at a time.

Query Parameters

page

Type: integer (optional, default: 1)

1-based page number.

pageSize

Type: integer (optional, default: 20)

Number of posts per page, between 1 and 100.

Response

{
  "Success": true,
  "Error": null,
  "Count": 42,
  "Page": 1,
  "PageSize": 20,
  "Posts": [
    {
      "Id": "12345",
      "PipelineId": null,
      "DateTime": "2026-10-01T12:00:00Z",
      "Posts": [
        {
          "AccountIds": ["1-12345"],
          "Messages": ["Your post content here"],
          "MediaId": ["stored-media-id"]
        }
      ]
    }
  ]
}

Count: Total number of pending posts, across all pages

Page / PageSize: The page returned and its size

Posts: Pending posts in the same shape as the /publish/post request, with DateTime in UTC. MediaId holds the IDs of the media stored with the post, which are not upload file IDs and can't be reused in a new post.

GET

/publish/pipelines

Retrieve a list of available publishing pipelines.

Request

No parameters required.

Response

{
  "Success": true,
  "Error": null,
  "Pipelines": [
    {
      "Id": "123",
      "Name": "Marketing Pipeline"
    }
  ]
}

Pipelines: Array of pipeline objects with Id and Name properties. Use the Id as PipelineId in /publish/post.

GET

/publish/accounts

legacy

Retrieve a list of connected social media accounts. This endpoint is kept for backward compatibility; use /accounts/list, which also returns the account Id.

Request

No parameters required.

Response

{
  "Success": true,
  "Error": null,
  "Accounts": [
    {
      "Platform": "Twitter",
      "AccountId": "fedica"
    }
  ]
}

Accounts: Array of connected account objects with Platform and AccountId (the account's username) properties

POST

/publish/media/init

Initialize a media upload session. Call this endpoint before uploading media chunks.

Request

No request body required.

Response

{
  "Success": true,
  "Error": null,
  "Id": "file-abc123"
}

Id: File ID to use for subsequent upload and finalize operations

POST

/publish/media/upload

Upload a chunk of media data. For large files, split the file into chunks and call this endpoint multiple times.

Request Body (Form Data)

Content-Type: multipart/form-data

chunkIndex: 0
fileId: file-abc123
file: [binary data]

Alternatively, this endpoint accepts a JSON object with the file data in base64:

Request Body (JSON)

{
  "chunkIndex": 0,
  "fileId": "file-abc123",
  "file": "base64-encoded-data"
}

Request Fields

chunkIndex *

Type: integer

Zero-based index of the current chunk. Start with 0 for the first chunk and increment for each subsequent chunk.

fileId *

Type: string

File ID obtained from the /publish/media/init endpoint. This associates the chunk with the upload session.

file *

Type: binary (form data) or string (JSON)

The file chunk: binary data when sent as form data, or base64-encoded when sent as JSON.

Response

{
  "Success": true,
  "Error": null
}
POST

/publish/media/finalize

Complete the media upload process and provide metadata about the uploaded file.

Request Body

{
  "fileId": "file-abc123",
  "metadata": {
    "altText": "Description for accessibility",
    "mimeType": "image/jpeg",
    "fileName": "photo.jpg",
    "size": 1048576,
    "width": 1920,
    "height": 1080,
    "aspectRatio": 1.777,
    "duration": 30.5,
    "frameRate": 30.0,
    "bitRate": 5000000.0
  }
}

Request Fields

fileId *

Type: string

File ID from the initialization step.

metadata *

Type: MediaMetaData object

Comprehensive metadata about the uploaded media file.

altText *

Type: string

Alternative text description for accessibility. Describes the content of images or videos for screen readers.

mimeType *

Type: string

MIME type of the file (e.g., "image/jpeg", "video/mp4", "image/png").

fileName *

Type: string

Original filename of the uploaded media.

size *

Type: long (integer)

File size in bytes.

width

Type: integer (optional)

Width in pixels (for images and videos).

height

Type: integer (optional)

Height in pixels (for images and videos).

aspectRatio

Type: double (optional)

Aspect ratio calculated as width/height (e.g., 1.777 for 16:9).

duration

Type: double (optional)

Duration in seconds (for video and audio files).

frameRate

Type: double (optional)

Video frame rate in frames per second (e.g., 30.0, 60.0).

bitRate

Type: double (optional)

Bitrate in bits per second (for video and audio files).

Response

{
  "Success": true,
  "Error": null
}

Complete Upload Workflow

1

Initialize Upload

Call POST /publish/media/init to get a file ID

2

Upload Chunks

Call POST /publish/media/upload for each chunk of your file

3

Finalize Upload

Call POST /publish/media/finalize with metadata

4

Schedule Post

Use the file ID in MediaId of POST /publish/post to publish

Analytics Endpoints

Base path: /api/analytics

Analytics for one of your own connected accounts. Every endpoint takes the accountId query parameter: the Id of the account from /accounts/list. If the account isn't found, the error is "Account not found"; if Fedica has no data for the account yet, the error is "This capability is not available for this account".

GET

/analytics/overview

Key metrics for the account: follower quality, activity, follower and following counts, new followers and unfollows, and the best and least performing country and city.

Query Parameters

accountId *

Type: string

Account Id from /accounts/list.

Response

{
  "Success": true,
  "Error": null,
  "overview": {
    "quality": 82,
    "activity_score": 64,
    "followers": 15230,
    "following": 870,
    "new": 312,
    "unfollows": 45,
    "best_country": "United States",
    "least_country": "Canada",
    "best_city": "New York",
    "least_city": "Toronto"
  }
}

quality: Follower quality score (0-100), null when not available

activity_score: Follower activity score, null when not available

followers / following: Current follower and following counts

new / unfollows: New followers and unfollows over the most recent period (your email digest period, 7 days by default)

best_country / least_country, best_city / least_city: Locations with the most and least follower growth over the same period

GET

/analytics/audience

Demographics and distributions of the account's followers.

Query Parameters

accountId *

Type: string

Account Id from /accounts/list.

Response

{
  "Success": true,
  "Error": null,
  "audience": {
    "languages": [{ "Name": "English", "Count": 9800 }],
    "timezones": [{ "Name": "Eastern Time", "Count": 4100 }],
    "gender": {
      "ErrorMessage": null,
      "Items": [{ "Name": "Male", "Count": 6200 }, { "Name": "Female", "Count": 5400 }]
    },
    "occupation": [{ "Name": "Marketing", "Count": 1200 }],
    "age": {
      "ErrorMessage": null,
      "Items": [{ "Name": "25-34", "Count": 4300 }]
    },
    "follower_distribution": [...],
    "follower_tweets": [...],
    "follower_activity": [...],
    "follower_account_age": [...],
    "follower_quality": [...]
  }
}

Each list is an array of { "Name", "Count" } items. gender and age are groups with Items and an ErrorMessage explaining when the data isn't available.

languages, timezones, occupation: Followers by language, timezone and occupation

follower_distribution: Followers by their own follower count

follower_tweets: Followers by the number of posts they have made

follower_activity: Followers by how recently they were active

follower_account_age: Followers by account age

follower_quality: Followers by quality category

GET

Growth History

Counts over time for the account. All four endpoints take the same parameters and return the same response shape.

  • /analytics/follower_history - follower count over time
  • /analytics/follower_changes - change in followers from one data point to the next
  • /analytics/following_history - following count over time
  • /analytics/post_history - post count over time

Query Parameters

accountId *

Type: string

Account Id from /accounts/list.

Response

{
  "Success": true,
  "Error": null,
  "Title": "Followers",
  "Labels": ["Followers"],
  "Points": [
    { "Label": "2026-09-01", "Values": [15010] },
    { "Label": "2026-09-02", "Values": [15042] }
  ]
}

Title: Chart title

Labels: Name of each series

Points: One data point per date; Values holds one value per series, in the order of Labels

GET

/analytics/best_time_to_post

When the account's audience is most likely to see and engage with a post. Returns the error "Account does not support best_time_to_post" for platforms without this feature. When there's no data yet, only Success is returned.

Query Parameters

accountId *

Type: string

Account Id from /accounts/list.

Response

{
  "Success": true,
  "Error": null,
  "BestTime": [
    [{ "Name": "0", "Count": 12 }, { "Name": "1", "Count": 8 }, ...],
    ...
  ],
  "BestTimeSegmented": {
    "Americas": [[...], ...],
    "Europe & Middle East": [[...], ...],
    "Asia & Australia": [[...], ...]
  },
  "ColumnNames": ["ID", "Time of the day", "Day of the week", "", "Reach"],
  "DayIndex": 3,
  "BestHourToday": "2 PM",
  "BestHourThisWeek": "Tuesday 3 PM",
  "BestDay": "Tuesday",
  "Tz": "UTC"
}

BestTime: 7 arrays, one per day of the week starting with Sunday, each holding the audience reach for each hour of the day

BestTimeSegmented: The same grid for each audience region, when available

ColumnNames: Column titles for charting the grid

DayIndex: Index of today in BestTime (0 = Sunday)

BestHourToday, BestHourThisWeek, BestDay: The best hour today, best hour this week and best day to post

Tz: Timezone of the times returned

GET

/analytics/engagements

Interactions, impressions, engagement rates and top posts for a date range, compared with the previous period of the same length. Returns the error "Account does not support engagements" for platforms without post analytics.

Query Parameters

accountId *

Type: string

Account Id from /accounts/list.

startDate *

Type: date (e.g., 2026-09-01)

First day of the range. Must not be after endDate.

endDate *

Type: date (e.g., 2026-09-30)

Last day of the range, inclusive.

Example Request

curl "https://fedica.com/api/analytics/engagements?accountId=1-12345&startDate=2026-09-01&endDate=2026-09-30" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Response

{
  "Success": true,
  "Error": null,
  "TotalEngagements": "1.2K",
  "TotalCounts": 1240,
  "TotalImpressions": 58000,
  "TotalPosts": 30,
  "DeltaCount": 180,
  "PrevCount": 1060,
  "PrevPosts": 27,
  "PrevImpressions": 51000,
  "Interactions": [{ "Name": "Likes", "Count": 900 }, ...],
  "Impressions": [{ "Name": "2026-09-01", "Count": 1800 }, ...],
  "Posts": [{ "Name": "2026-09-01", "Count": 1 }, ...],
  "Rates": [{ "Name": "Engagement rate", "Count": 2 }, ...],
  "LastInteractions": [...],
  "TopInteractions": [
    {
      "Id": "1839201",
      "Text": "Your top post",
      "Retweets": 40,
      "Replies": 12,
      "Favorites": 210,
      "QuoteTweets": 3,
      "Impressions": 9100,
      "TotalEngagements": 265
    }
  ],
  "NoInteractionsMessage": null,
  "DataDateMessage": null
}

TotalEngagements: Total engagements, formatted for display

TotalCounts, TotalImpressions, TotalPosts: Totals for the requested range

PrevCount, PrevImpressions, PrevPosts: Totals for the previous period of the same length

DeltaCount: Change in engagements compared with the previous period

Interactions, Impressions, Posts, Rates, LastInteractions: Breakdowns as { "Name", "Count" } items

TopInteractions: The posts with the most engagement in the range

NoInteractionsMessage, DataDateMessage: Informational messages, e.g. when there are no interactions or about how recent the data is

Research Endpoints

Base path: /api/research

Access the research reports you've created in Fedica. Each report type has a list endpoint, which returns the reports created from one of your accounts, and a get endpoint, which returns a report's results by its id. A report must have the status Complete before its results can be retrieved; otherwise the error is "Report is not complete".

GET

List Reports

List the reports of one type created from an account. All four endpoints take the same parameters and return the same response shape.

  • /research/analyze/reports - analyze reports on third-party accounts
  • /research/compare/reports - follower overlap between accounts
  • /research/audit/reports - follower quality audits
  • /research/search/reports - keyword and hashtag searches

Query Parameters

accountId *

Type: string

Account Id from /accounts/list; only reports created from this account are returned.

Response

{
  "Success": true,
  "Error": null,
  "Reports": [
    {
      "Id": 98765,
      "Name": "competitor",
      "Status": "Complete"
    }
  ]
}

Id: Report id, used by the matching get endpoint

Name: Report name

Status: Complete, Inprogress or Error

GET

/research/analyze/report/{id}

The overview and audience analytics of the account an analyze report is about, in the same shape as /analytics/overview and /analytics/audience.

Path Parameters

id *

Type: integer

Report id from /research/analyze/reports.

Response

{
  "Success": true,
  "Error": null,
  "overview": { "quality": 75, "followers": 48200, ... },
  "audience": { "languages": [...], "gender": {...}, ... }
}
GET

/research/compare/report/{id}

The follower overlap between the accounts in a compare report. One result is returned for each pair of accounts; when the report compares more than two accounts, the first result is the overlap across all of them.

Path Parameters

id *

Type: integer

Report id from /research/compare/reports.

Response

{
  "Success": true,
  "Error": null,
  "Models": [
    {
      "UserIds": ["111", "222"],
      "UserNames": ["fedica", "competitor"],
      "Totals": [15230, 48200],
      "IntersectionCount": 3100,
      "IntersectionCountShort": "3.1K",
      "Title": "Common followers",
      "Lines": ["..."],
      "CommonLine": [{ "Id": "111", "Text": "fedica", "Count": 3100 }],
      "Data": [
        { "Sets": ["111"], "Size": 15230 },
        { "Sets": ["222"], "Size": 48200 },
        { "Sets": ["111", "222"], "Size": 3100 }
      ]
    }
  ]
}

UserIds / UserNames / Totals: The accounts compared and their follower counts

IntersectionCount / IntersectionCountShort: Followers the accounts have in common, as a number and formatted for display

Title, Lines, CommonLine: Summary text of the comparison

Data: Set sizes for drawing a Venn diagram

GET

/research/audit/report/{id}

The follower quality breakdown and final score of an audit report.

Path Parameters

id *

Type: integer

Report id from /research/audit/reports.

Response

{
  "Success": true,
  "Error": null,
  "Categories": [
    { "Name": "Real", "Count": 12100 },
    { "Name": "Inactive", "Count": 2300 },
    ...
  ],
  "Total": 15230,
  "FinalScore": {
    "Score": 82,
    "Label": "Good"
  }
}

Categories: Followers in each quality category

Total: Total followers audited

FinalScore: Overall quality score and its label