openapi: 3.2.0 info: title: Publora LinkedIn Analytics API description: 'Affordable REST API for scheduling and publishing social media posts across X/Twitter, LinkedIn, Instagram, Threads, TikTok, YouTube, Facebook, Bluesky, Mastodon, and Telegram. All plans include full API access. Starting at $5.40/month (yearly) or $9/month. 14-day free trial, no credit card needed. ## Workspace API The Workspace API allows you to manage multiple users under a single account. **To enable Workspace access, please contact Publora support at serge@publora.com.**' version: 1.0.0 contact: email: serge@publora.com url: https://publora.com servers: - url: https://api.publora.com/api/v1 description: Production security: - ApiKeyAuth: [] tags: - name: LinkedIn Analytics description: LinkedIn-specific analytics and interactions paths: /linkedin-post-statistics: parameters: - $ref: '#/components/parameters/XPubloraClient' post: summary: Get LinkedIn post analytics description: 'Retrieve analytics for a LinkedIn post: impressions, reach, reactions, comments, reshares. Results are cached for 2 hours. Use queryTypes: "ALL" to get all 5 metrics at once.' operationId: getLinkedInPostStatistics tags: - LinkedIn Analytics requestBody: required: true content: application/json: schema: type: object required: - postedId - platformId properties: postedId: type: string description: LinkedIn URN or share ID example: urn:li:share:7123456789012345678 platformId: type: string description: LinkedIn connection ID example: linkedin-Tz9W5i6ZYG queryType: type: string enum: - IMPRESSION - MEMBERS_REACHED - RESHARE - REACTION - COMMENT description: Single metric to fetch queryTypes: oneOf: - type: array items: type: string enum: - IMPRESSION - MEMBERS_REACHED - RESHARE - REACTION - COMMENT - type: string enum: - ALL description: Multiple metrics or ALL example: ALL responses: '200': description: Statistics retrieved content: application/json: schema: oneOf: - type: object description: Single metric response properties: success: type: boolean count: type: integer example: 1542 cached: type: boolean - type: object description: Multiple metrics response properties: success: type: boolean metrics: type: object properties: IMPRESSION: type: integer MEMBERS_REACHED: type: integer RESHARE: type: integer REACTION: type: integer COMMENT: type: integer cached: type: boolean '400': description: Bad request - missing or invalid parameters content: application/json: schema: $ref: '#/components/schemas/Error' examples: missingFields: value: error: postedId and platformId are required invalidQueryType: value: error: 'Invalid queryType. Must be one of: IMPRESSION, MEMBERS_REACHED, RESHARE, REACTION, COMMENT' '404': description: LinkedIn connection not found content: application/json: schema: $ref: '#/components/schemas/Error' example: error: LinkedIn connection not found '500': description: Server error content: application/json: schema: $ref: '#/components/schemas/Error' example: error: Failed to fetch LinkedIn post statistics /linkedin-account-statistics: parameters: - $ref: '#/components/parameters/XPubloraClient' post: summary: Get aggregated LinkedIn account analytics description: Get total metrics across all published LinkedIn posts for an account. operationId: getLinkedInAccountStatistics tags: - LinkedIn Analytics requestBody: required: true content: application/json: schema: type: object required: - platformId properties: platformId: type: string example: linkedin-Tz9W5i6ZYG queryType: type: string enum: - IMPRESSION - MEMBERS_REACHED - RESHARE - REACTION - COMMENT description: Single metric to fetch queryTypes: oneOf: - type: array items: type: string enum: - IMPRESSION - MEMBERS_REACHED - RESHARE - REACTION - COMMENT - type: string enum: - ALL description: Multiple metrics or ALL example: ALL aggregation: type: string enum: - TOTAL - DAILY default: TOTAL description: 'Aggregation type: TOTAL (default) or DAILY' dateRange: type: object description: Optional date range filter properties: start: type: object properties: year: type: integer month: type: integer day: type: integer end: type: object properties: year: type: integer month: type: integer day: type: integer responses: '200': description: Account statistics content: application/json: schema: type: object properties: success: type: boolean metrics: type: object description: Flexible object with dynamic metric keys (e.g., IMPRESSION, REACTION, etc.) additionalProperties: type: integer aggregation: type: string enum: - TOTAL - DAILY cached: type: boolean '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' examples: missingPlatformId: value: error: platformId is required invalidQueryType: value: error: Invalid queryType invalidAggregation: value: error: Invalid aggregation '404': description: LinkedIn connection not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' /linkedin-profile-summary: parameters: - $ref: '#/components/parameters/XPubloraClient' post: summary: Get LinkedIn profile summary description: 'Retrieve a summary of your LinkedIn profile analytics including follower counts and aggregated post engagement metrics. Optionally filter by date range to track follower growth over a specific period.' operationId: getLinkedInProfileSummary tags: - LinkedIn Analytics requestBody: required: true content: application/json: schema: type: object required: - platformId properties: platformId: type: string description: 'LinkedIn connection ID (format: linkedin-{id})' example: linkedin-Tz9W5i6ZYG dateRange: type: object description: Optional date range for filtering metrics and calculating follower growth properties: start: type: object properties: year: type: integer example: 2026 month: type: integer example: 1 day: type: integer example: 1 end: type: object properties: year: type: integer example: 2026 month: type: integer example: 1 day: type: integer example: 31 responses: '200': description: Profile summary retrieved content: application/json: schema: type: object properties: success: type: boolean example: true partialData: type: boolean description: True if some data failed to fetch but partial results are available profile: type: object properties: followers: type: object properties: total: type: integer description: Total follower count example: 5000 periodGrowth: type: integer description: Follower growth during date range (only present when dateRange is provided) example: 150 posts: type: object properties: totalImpressions: type: integer example: 25000 totalReactions: type: integer example: 500 totalComments: type: integer example: 75 totalReshares: type: integer example: 30 totalMembersReached: type: integer example: 12000 errors: type: array items: type: object required: - metric - error properties: metric: type: string error: type: string description: List of errors when partialData is true example: - metric: followers error: Failed to fetch followers '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' examples: missingPlatformId: value: error: platformId is required invalidDateRange: value: error: dateRange must be an object '401': description: Invalid API key content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: LinkedIn connection not found content: application/json: schema: $ref: '#/components/schemas/Error' example: error: LinkedIn connection not found '500': description: Unexpected error content: application/json: schema: $ref: '#/components/schemas/Error' '502': description: All requests to LinkedIn failed content: application/json: schema: $ref: '#/components/schemas/Error' example: error: Failed to fetch LinkedIn profile data /linkedin-followers: parameters: - $ref: '#/components/parameters/XPubloraClient' post: summary: Get LinkedIn follower statistics description: 'Retrieve follower statistics for your LinkedIn account. Use period="lifetime" (default) for total follower count, or period="daily" with a dateRange for daily growth data. Results are cached for improved performance.' operationId: getLinkedInFollowers tags: - LinkedIn Analytics requestBody: required: true content: application/json: schema: type: object required: - platformId properties: platformId: type: string description: LinkedIn connection ID example: linkedin-Tz9W5i6ZYG period: type: string enum: - lifetime - daily default: lifetime description: Type of statistics to retrieve example: lifetime dateRange: type: object description: Required when period is 'daily' properties: start: type: object properties: year: type: integer example: 2024 month: type: integer example: 1 day: type: integer example: 1 end: type: object properties: year: type: integer example: 2024 month: type: integer example: 1 day: type: integer example: 31 responses: '200': description: Follower statistics retrieved content: application/json: schema: oneOf: - type: object description: Lifetime response properties: success: type: boolean example: true followersCount: type: integer example: 1234 cached: type: boolean - type: object description: Daily response properties: success: type: boolean example: true data: type: array items: type: object properties: date: type: string example: '2024-01-15' count: type: integer example: 10 totalGrowth: type: integer example: 25 cached: type: boolean '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' examples: missingPlatformId: value: error: platformId is required invalidPeriod: value: error: Invalid period missingDateRange: value: error: dateRange is required for daily period '401': description: Invalid API key content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: LinkedIn connection not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Failed to fetch statistics content: application/json: schema: $ref: '#/components/schemas/Error' examples: fetchFailed: value: error: Failed to fetch LinkedIn followers statistics /linkedin-reactions: parameters: - $ref: '#/components/parameters/XPubloraClient' post: summary: Add a reaction to a LinkedIn post description: React to a LinkedIn post with LIKE, PRAISE, EMPATHY, INTEREST, APPRECIATION, or ENTERTAINMENT. operationId: addLinkedInReaction tags: - LinkedIn Analytics requestBody: required: true content: application/json: schema: type: object required: - postedId - reactionType - platformId properties: postedId: type: string description: LinkedIn URN (urn:li:share:*, urn:li:ugcPost:*, urn:li:activity:*) example: urn:li:share:7123456789012345678 reactionType: type: string enum: - LIKE - PRAISE - EMPATHY - INTEREST - APPRECIATION - ENTERTAINMENT example: LIKE platformId: type: string example: linkedin-Tz9W5i6ZYG responses: '201': description: Reaction added content: application/json: schema: type: object properties: success: type: boolean example: true reaction: type: object description: Reaction details properties: reactionType: type: string enum: - LIKE - PRAISE - EMPATHY - INTEREST - APPRECIATION - ENTERTAINMENT actor: type: string description: LinkedIn member URN object: type: string description: LinkedIn post URN urnTranslated: $ref: '#/components/schemas/LinkedInUrnTranslation' '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' examples: missingFields: value: error: postedId, reactionType, and platformId are required invalidReactionType: value: error: 'reactionType must be one of: LIKE, PRAISE, EMPATHY, INTEREST, APPRECIATION, ENTERTAINMENT' '404': description: LinkedIn connection not found content: application/json: schema: $ref: '#/components/schemas/Error' '409': description: The requested reaction already exists content: application/json: schema: type: object required: - error - message - requestedReactionType properties: error: type: string enum: - REACTION_ALREADY_EXISTS message: type: string requestedReactionType: type: string '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' delete: summary: Remove a reaction from a LinkedIn post description: 'Remove your reaction from a LinkedIn post. Parameters can be provided either as query parameters OR in the request body.' operationId: removeLinkedInReaction tags: - LinkedIn Analytics parameters: - name: postedId in: query description: LinkedIn URN (can also be provided in request body) schema: type: string example: urn:li:share:7123456789012345678 - name: platformId in: query description: LinkedIn connection ID (can also be provided in request body) schema: type: string example: linkedin-Tz9W5i6ZYG requestBody: required: false description: Alternative to query parameters - provide postedId and platformId in body content: application/json: schema: type: object properties: postedId: type: string description: LinkedIn URN (urn:li:share:*, urn:li:ugcPost:*, urn:li:activity:*) example: urn:li:share:7123456789012345678 platformId: type: string example: linkedin-Tz9W5i6ZYG responses: '200': description: Reaction removed content: application/json: schema: type: object properties: success: type: boolean example: true reaction: type: object description: Details of the removed reaction properties: reactionType: type: string actor: type: string object: type: string urnTranslated: $ref: '#/components/schemas/LinkedInUrnTranslation' '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' examples: missingFields: value: error: postedId and platformId are required '404': description: LinkedIn connection not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' /linkedin-reshare: parameters: - $ref: '#/components/parameters/XPubloraClient' post: summary: Reshare an existing LinkedIn post description: Reshare (repost) an existing LinkedIn post to your own feed with optional commentary. Works for personal and company-page connections (authored as the member or the organization automatically). operationId: createLinkedInReshare tags: - LinkedIn Analytics requestBody: required: true content: application/json: schema: type: object required: - platformId - parent properties: platformId: type: string description: LinkedIn connection ID example: linkedin-Tz9W5i6ZYG parent: type: string description: URN of the post to reshare (urn:li:share:* or urn:li:ugcPost:*) example: urn:li:share:7123456789012345678 commentary: type: string description: Optional text added above the reshare (max 3000 characters) example: Great read — sharing with my network! visibility: type: string enum: - PUBLIC - CONNECTIONS default: PUBLIC description: Optional visibility (case-insensitive). Defaults to PUBLIC. CONNECTIONS is personal-profile-only; organization/company-page reshares must use PUBLIC. example: PUBLIC responses: '201': description: Reshare created content: application/json: schema: type: object properties: success: type: boolean example: true reshare: type: object description: LinkedIn API response for the created reshare properties: id: type: string description: URN of the new reshare post example: urn:li:share:7123456789012345678 '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' examples: missingFields: value: error: platformId and parent are required invalidParent: value: error: parent must be a valid LinkedIn post URN (urn:li:share: or urn:li:ugcPost:) commentaryTooLong: value: error: commentary cannot exceed 3000 characters invalidVisibility: value: error: 'visibility must be one of: PUBLIC, CONNECTIONS' organizationConnectionsVisibility: value: error: LinkedIn organization reposts cannot use CONNECTIONS visibility; choose PUBLIC missingOrganizationId: value: error: LinkedIn company connection is missing organizationId. Please reconnect the LinkedIn page. '401': description: Invalid API key or expired LinkedIn token content: application/json: schema: $ref: '#/components/schemas/Error' examples: tokenExpired: value: error: LINKEDIN_TOKEN_EXPIRED '404': description: LinkedIn connection not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' /linkedin-comments: parameters: - $ref: '#/components/parameters/XPubloraClient' post: summary: Add a comment to a LinkedIn post description: 'Post a comment on a LinkedIn post. Supports replies to existing comments via the parentComment parameter. Raw input may be up to 10000 characters; after mention processing, the text sent to LinkedIn must be at most 1250 characters. Supports @mentions using @{urn:li:person:ID|Name} or @{urn:li:organization:ID|Company} syntax.' operationId: createLinkedInComment tags: - LinkedIn Analytics requestBody: required: true content: application/json: schema: type: object required: - postedId - message - platformId properties: postedId: type: string description: LinkedIn post URN (urn:li:share:*, urn:li:ugcPost:*, or urn:li:activity:*). Activity URNs are attempted directly, with same-ID ugcPost/share fallbacks for retryable LinkedIn target errors. example: urn:li:share:7123456789012345678 message: type: string description: Raw comment input (max 10000 characters); after mention conversion, the sent text is limited to 1250 characters. Supports @{urn:li:person:ID|Name} and organization mentions. example: Great insights @{urn:li:person:ACoAABcD1234EfG|Jane Smith}! Thanks for sharing. platformId: type: string description: LinkedIn connection ID example: linkedin-Tz9W5i6ZYG parentComment: type: string description: Optional parent comment URN for replies example: urn:li:comment:(urn:li:activity:123,456) responses: '201': description: Comment created content: application/json: schema: type: object properties: success: type: boolean example: true comment: type: object properties: id: type: string description: Comment URN message: type: string actor: type: string object: type: string '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' examples: missingFields: value: error: postedId, message, and platformId are required invalidUrn: value: error: postedId must be a valid LinkedIn URN emptyMessage: value: error: message cannot be empty rawMessageTooLong: value: error: comment text cannot exceed 10000 characters processedMessageTooLong: value: error: comment text cannot exceed 1250 characters after mention processing '404': description: LinkedIn connection not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Server error content: application/json: schema: $ref: '#/components/schemas/Error' delete: summary: Delete a comment from a LinkedIn post description: 'Remove a comment from a LinkedIn post. Parameters can be provided as query parameters or in the request body.' operationId: deleteLinkedInComment tags: - LinkedIn Analytics parameters: - name: postedId in: query description: LinkedIn post URN (can also be provided in request body) schema: type: string example: urn:li:share:7123456789012345678 - name: commentId in: query description: Comment ID or URN (can also be provided in request body) schema: type: string example: '6636062862760562688' - name: platformId in: query description: LinkedIn connection ID (can also be provided in request body) schema: type: string example: linkedin-Tz9W5i6ZYG requestBody: required: false content: application/json: schema: type: object properties: postedId: type: string commentId: type: string platformId: type: string responses: '200': description: Comment deleted content: application/json: schema: type: object properties: success: type: boolean example: true deleted: type: string description: Comment ID that was deleted '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' examples: missingFields: value: error: postedId, commentId, and platformId are required invalidUrn: value: error: postedId must be a valid LinkedIn URN '404': description: LinkedIn connection not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Server error content: application/json: schema: $ref: '#/components/schemas/Error' components: parameters: XPubloraClient: name: x-publora-client in: header required: false description: Optional client identifier accepted by every API-key-authenticated operation. Any non-empty value is preserved; `api` is used when absent. Setting `mcp` triggers the MCP access entitlement check. schema: type: string schemas: LinkedInUrnTranslation: type: object description: Present only when LinkedIn translated an activity URN before processing the reaction required: - from - to properties: from: type: string to: type: string Error: type: object properties: error: type: string description: Human-readable message. Do not match on this string — match on code where present. example: Invalid API key code: type: string description: 'Stable machine-readable error code. Present on the newer error paths (scheduling, platformSettings validation, idempotency); older errors return `error` only. Always prefer this over the `error` text. ' example: SCHEDULED_TIME_IN_PAST field: type: string description: '`PLATFORM_SETTING_UNKNOWN` only. The exact dotted path of the rejected key, relative to the `platformSettings` object (no `platformSettings.` prefix). ' example: youtube.thumbnail.typo serverTime: type: string format: date-time description: '`SCHEDULED_TIME_IN_PAST` only. Current server time (UTC) when the request was rejected — compare against your clock to diagnose skew. ' example: '2026-03-01T14:02:11.412Z' securitySchemes: ApiKeyAuth: type: apiKey in: header name: x-publora-key description: 'API key from Settings > API Keys. Format: sk_timestamp.hexstring'