LateLate API

Changelog


Track all updates to the Late API. We announce significant changes here and on our Telegram channel.

New Feature
Reddit posting now supports post flairs via flairId in platformSpecificData.

Some subreddits require a flair; you can now fetch available flairs and set the one you want on the post.

New endpoint: GET /v1/accounts/{accountId}/reddit-flairs
Required query: subreddit (without r/)

New field: platformSpecificData.reddit.flairId (string)
If omitted, the API will attempt to use the first available flair as a fallback.
Improvement
Instagram conversations now include optional participant profile context via instagramProfile.

This lets you show follower/verification info (and follower count) alongside DMs, and use it in routing/automation.

Added to:
GET /v1/inbox/conversationsdata[].instagramProfile
GET /v1/inbox/conversations/{conversationId}data.instagramProfile

Fields:
isFollower, isFollowing, followerCount, isVerified, fetchedAt

Webhook update:
WebhookPayloadMessage.message.sender.instagramProfile (Instagram only) with isFollower, isFollowing, followerCount, isVerified.
New Feature
Interactive messaging support for the Inbox API.

POST /v1/inbox/conversations/{conversationId}/messages now supports:

Quick replies (quickReplies) - Up to 13 quick reply buttons (Instagram, Facebook, Telegram)
Buttons (buttons) - Up to 3 action buttons: URL, postback, or phone (Instagram, Facebook, Telegram)
Carousels (template) - Generic template with up to 10 elements (Instagram, Facebook)
Telegram keyboards (replyMarkup) - Native inline or reply keyboards
Message tags (messageTag) - Send outside the 24h window: HUMANAGENT (Instagram), CONFIRMEDEVENTUPDATE, POSTPURCHASEUPDATE, ACCOUNTUPDATE, HUMAN_AGENT (Facebook)
Reply to (replyTo) - Reply to a specific message (Telegram)

Incoming messages now include metadata with quickReplyPayload, postbackPayload, postbackTitle, and callbackData to identify interactive message taps.

Also added: PATCH /v1/inbox/conversations/{conversationId}/messages/{messageId} to edit sent Telegram messages (text and inline keyboard).
New Feature
New Account Settings endpoints for managing platform-specific messaging features.

Facebook Persistent Menu (/v1/accounts/{accountId}/messenger-menu)
GET/PUT/DELETE to manage the persistent menu shown in Facebook Messenger conversations. Max 3 top-level items, max 5 nested items.

Instagram Ice Breakers (/v1/accounts/{accountId}/instagram-ice-breakers)
GET/PUT/DELETE to manage ice breaker prompts shown when users start a new Instagram DM. Max 4 ice breakers, question max 80 chars.

Telegram Bot Commands (/v1/accounts/{accountId}/telegram-commands)
GET/PUT/DELETE to manage the bot command menu shown in Telegram chats.
Minor
Added 2 new endpoints:

GET /v1/posts/logs - Get publishing logs
GET /v1/connections/logs - Get connection logs
New Feature
New Google Business Profile endpoints are now available for managing your GMB listings programmatically.

Location Details (/v1/accounts/{accountId}/gmb-location-details)
GET/PUT to read and update business hours, special hours, description, phone numbers, and website. Use readMask and updateMask to specify fields.

Media (/v1/accounts/{accountId}/gmb-media)
GET/POST/DELETE to manage photos. Upload via public URL with categories:
COVER, PROFILE, LOGO, EXTERIOR, INTERIOR, FOODANDDRINK, MENU, PRODUCT, TEAMS, ADDITIONAL

Attributes (/v1/accounts/{accountId}/gmb-attributes)
GET/PUT to manage amenities and services like hasdelivery, hastakeout, hasoutdoorseating, has_wifi, payment types, etc.

Place Actions (/v1/accounts/{accountId}/gmb-place-actions)
GET/POST/DELETE to manage booking and ordering buttons. Types include:
APPOINTMENT, DININGRESERVATION, FOODORDERING, FOODDELIVERY, FOODTAKEOUT, SHOP_ONLINE
New Feature
New endpoints for Google Business Profile food menus:

GET /v1/accounts/{accountId}/gmb-food-menus
Fetch the full menu structure for a connected GBP location.

PUT /v1/accounts/{accountId}/gmb-food-menus
Update food menus with sections, items, pricing, dietary info, and allergens.

Menu items support:
price with currency code
dietaryRestriction - VEGETARIAN, VEGAN, GLUTEN_FREE, etc.
allergen - DAIRY, GLUTEN, SHELLFISH, etc.
spiciness, servesNumPeople, preparationMethods

Only available for GBP locations with food menu support (restaurants, cafes, etc.).

Also: PostAnalytics now includes saves for tracking bookmarks on Instagram and Pinterest.
New Feature
The Inbox API now supports Twitter/X for conversations, comments, and comment interactions.

Conversations (GET /v1/inbox/conversations):
Filter by platform=twitter to fetch Twitter/X DMs.

Comments (GET /v1/inbox/comments):
Twitter/X posts with replies are now included. Also added Threads support for comments listing.

Like/Unlike comments:
POST and DELETE /v1/inbox/comments/{postId}/{commentId}/like now work with Twitter/X replies.
New Feature
The GET /v1/analytics endpoint now supports a source query parameter to filter posts by origin.

Values:
late - only posts scheduled/published via Late API
external - only posts synced from the platform (not posted via Late)
all - all posts (default)

This makes it easier to separate analytics for posts you scheduled through Late from posts that were published directly on the platform.
New Feature
The PlatformTarget schema now includes detailed error information when posts fail to publish.

Three new fields are available:

errorMessage - Human-readable explanation of why the publish failed

errorCategory - Programmatic category for handling:
auth_expired - token expired, reconnect needed
user_content - content doesn't meet platform requirements
user_abuse - rate limits or spam detection
account_issue - account configuration problems
platform_rejected - policy violation
platform_error - platform-side issues
system_error - Late infrastructure issues
unknown - unclassified

errorSource - Who caused the error:
user - user action required
platform - platform-side issue
system - Late system issue

These fields are populated when a platform's status is failed. Posts with mixed results now return status: "partial" at the post level.
New Feature
YouTube uploads now support video categories via the new categoryId field in platformSpecificData.

You can now specify which category your video belongs to. Defaults to 22 (People & Blogs) if not set.

Common category IDs:
1 - Film & Animation
10 - Music
20 - Gaming
24 - Entertainment
27 - Education
28 - Science & Technology
New Feature
Multi-page/multi-location posting is now supported for Facebook, LinkedIn, and Google Business.

You can now post to multiple pages, organizations, or locations from a single account connection by using the same accountId multiple times with different targets in platformSpecificData:

• Facebook: pageId - post to multiple Pages
• LinkedIn: organizationUrn - post to multiple organizations
• Google Business: locationId - post to multiple locations

List available targets via:
GET /v1/accounts/{id}/facebook-page
GET /v1/accounts/{id}/linkedin-organizations
GET /v1/accounts/{id}/gmb-locations

Also: content is now optional when media is attached or all platforms have customContent set.
New Feature
New endpoint: POST /v1/inbox/comments/{postId}/{commentId}/private-reply

Send a private DM to the author of a comment on your Instagram post. Useful for handling customer inquiries or sensitive matters privately.

Required body:
accountId - Instagram social account ID
message - text to send as DM

Limitations:
• Instagram only (not available on other platforms)
• One private reply per comment
• Must be sent within 7 days of the comment
• Only works for comments on posts you own
• Requires the Inbox addon
New Feature
New endpoints for managing Facebook Pages and Google Business Profile locations.

GET /v1/accounts/{accountId}/facebook-page
List all Facebook pages the connected account can access, see which one is currently selected.

GET /v1/accounts/{accountId}/gmb-locations
List all Google Business Profile locations available to the account.

PUT /v1/accounts/{accountId}/gmb-locations
Change the selected GBP location by passing selectedLocationId in the request body.

Useful if you manage multiple pages/locations and need to switch between them programmatically.
Improvement
POST /v1/posts now returns 409 Conflict when duplicate content is detected.

If you post identical content to the same account within 24 hours, you'll get:
{
"error": "This exact content was already posted...",
"details": {
"accountId": "...",
"platform": "...",
"existingPostId": "..."
}
}


Additionally, 429 responses now include detailed context about which limit was hit:
Velocity limit: 15 posts/hour per account
Account cooldown: Escalating delays (10min → 24h) after repeated errors
Daily post limits: Platform-specific (X: 20, Pinterest: 25, Instagram/Facebook: 100, Threads: 250, others: 50)

New headers on 429: Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining

These changes also apply to POST /v1/posts/bulk-upload and POST /v1/posts/{postId}/retry.
New Feature
YouTube uploads now support madeForKids in platformSpecificData.youtube.

This COPPA compliance field declares whether your video is child-directed content. Defaults to false.

Set to true if your video is made for kids. Note: kid-directed videos have restricted features (no comments, no notifications, limited ad targeting).

Important: YouTube requires this to be explicitly set. If omitted, the video defaults to not made for kids, but may be blocked from views until configured in YouTube Studio.
Improvement
Analytics responses now include latePostId field.

When an external post originated from a Late-scheduled post, the response now includes the original Late Post ID directly. This makes it easier to correlate analytics data with posts created via POST /v1/posts.

The field appears in both single post queries and paginated list responses. It's null for posts that weren't scheduled through Late.
Breaking Change
LinkedIn headless OAuth flow updated

LinkedIn headless mode now uses a token-based approach to retrieve OAuth data, preventing URITOOLONG errors for users with many organizations.

What changed:
After OAuth redirect, you now receive pendingDataToken instead of tempToken, userProfile, and organizations in the URL.

Call the new endpoint to fetch the data:
GET /v1/connect/pending-data?token=PENDINGDATATOKEN

Returns: tempToken, refreshToken, expiresIn, userProfile, organizations, selectionType

Important:
• One-time use: data is deleted after fetching
• Data expires after 10 minutes if not fetched
• No authentication required, just the token

Other platforms (Facebook, Pinterest, Google Business, Snapchat) are unchanged.
New Feature
Instagram Reels now support thumbnail offset selection via thumbOffset in platformSpecificData.

Specify a millisecond offset from the start of the video to use as the Reel cover image. Defaults to 0 (first frame).

thumbOffset: integer, minimum 0 (milliseconds)

If you provide a custom thumbnail URL via instagramThumbnail in mediaItems, it takes priority and this offset is ignored.
New Feature
New webhook event: account.connected

You can now subscribe to notifications when a social account is connected to a profile. The webhook payload includes accountId, profileId, platform, username, and displayName.

Add it to your events array when creating or updating webhooks.
New Feature
YouTube daily views breakdown is now available via GET /v1/analytics/youtube/daily-views. This endpoint returns historical daily view counts for a specific YouTube video, including views, watch time, and subscriber changes. Required parameters include videoId and accountId, with optional date range parameters startDate and endDate.
Improvement
Late now automatically compresses media that exceeds platform limits during publishing, simplifying the upload process.

Image compression thresholds are set for platforms like Twitter/X: >5 MB, Instagram: >8 MB, Facebook: >10 MB, and more.

Video compression thresholds include Twitter/X: >512 MB, Instagram Stories: >100 MB, Facebook: >4 GB, among others.
Breaking Change
The endpoint POST /v1/profiles/{profileId}/clone-connection has been removed. This endpoint was used to clone an existing connection to a profile, allowing users to manage multiple brands with the same underlying social media account.
Improvement
YouTube now supports AI-generated content disclosure via containsSyntheticMedia in YouTubePlatformData.

Set containsSyntheticMedia to true if your video contains AI-generated or synthetic content that could be mistaken for real people, places, or events. YouTube may add a label to videos when this is set.
Improvement
Instagram now supports custom audio names for Reels via audioName in platformSpecificData.

You can set a custom name for the original audio, replacing the default "Original Audio" label. This can only be set once during creation or later from the Instagram audio page in the app.
Improvement
InstagramPlatformData Schema Update

The InstagramPlatformData schema has been updated to include a new parameter: trialParams. This parameter allows for configuration of trial Reels, which are initially shared only with non-followers.

Here are the details of the new trialParams field:
- trialParams: object (optional)
- graduationStrategy: string (required)
- Possible values: MANUAL, SS_PERFORMANCE
- This field determines how a trial reel transitions to a regular reel:
- MANUAL: Requires manual graduation via the Instagram app.
- SS_PERFORMANCE: Automatically graduates based on performance metrics with non-followers.

The rest of the schema remains unchanged, including the parameters contentType, shareToFeed, collaborators, firstComment, and userTags.

This update enhances your ability to manage Reels effectively, allowing for strategic sharing and performance-based visibility adjustments. Keep this in mind as you plan your content strategy.
New Feature
New Endpoints Available:

1. GET /v1/logs
- This endpoint allows you to retrieve publishing logs for all posts. You can filter logs by status (status), platform (platform), and action (action). The logs include detailed information about each publishing attempt, such as API requests, responses, and timing data.
- status (string, optional): Filter by log status (options: success, failed, pending, skipped, all).
- platform (string, optional): Filter by platform (options include tiktok, instagram, facebook, etc.).
- action (string, optional): Filter by action type (options: publish, retry, media_upload, etc.).
- days (integer, optional): Number of days to look back (max 7, default 7).
- limit (integer, optional): Maximum number of logs to return (max 100, default 50).
- skip (integer, optional): Number of logs to skip for pagination (default 0).
- The response includes an array of logs and pagination details.

2. GET /v1/logs/{logId}
- Use this endpoint to retrieve detailed information about a specific log entry, including full request and response bodies for debugging purposes.
- logId (string, required): The ID of the log entry you want to retrieve.
- The response contains the log entry details, including the full context of the publishing attempt.

3. GET /v1/posts/{postId}/logs
- This endpoint retrieves all publishing logs for a specific post, showing the complete history of publishing attempts across all platforms.
- postId (string, required): The ID of the post for which you want to retrieve logs.
- limit (integer, optional): Maximum number of logs to return (max 100, default 50).
- The response includes an array of logs specific to the post and the count of logs returned.
New Feature
New Endpoints for Pinterest Integration

We have added two new endpoints to enhance your integration with Pinterest in headless mode:

1. GET /v1/connect/pinterest/select-board
- Summary: List Pinterest Boards after OAuth (Headless Mode)
- Description: This endpoint retrieves a list of Pinterest boards available for selection after initiating OAuth via /v1/connect/pinterest with headless=true. It allows you to build your own fully-branded board selector instead of using Late's hosted UI.
- Parameters:
- X-Connect-Token (header, required): Short-lived connect token from the OAuth redirect.
- profileId (query, required): Your Late profile ID.
- tempToken (query, required): Temporary Pinterest access token from the OAuth callback redirect.
- Responses:
- 200: Returns a list of Pinterest boards available for connection, including each board's ID, name, description, and privacy setting.
- 400: Missing required parameters.
- 401: Unauthorized access.
- 403: No access to profile.
- 500: Failed to fetch boards.

2. POST /v1/connect/pinterest/select-board
- Summary: Select a Pinterest Board to complete the connection (Headless Mode)
- Description: Use this endpoint to save the selected board and complete the Pinterest account connection after OAuth.
- Request Body: Must include the following fields:
- profileId (string, required): Your Late profile ID.
- boardId (string, required): The Pinterest Board ID selected by the user.
- boardName (string, optional): The board name for display purposes.
- tempToken (string, required): Temporary Pinterest access token from OAuth.
- userProfile (object, optional): User profile data from OAuth redirect.
- refreshToken (string, optional): Pinterest refresh token if available.
- expiresIn (integer, optional): Token expiration time in seconds.
- redirect_url (string, optional): Custom redirect URL after connection completes.
- Responses:
- 200: Pinterest Board connected successfully, returns a message and account details.
- 400: Missing required fields.
- 401: Unauthorized access.
- 403: No access to profile or profile limit exceeded.
- 500: Failed to save Pinterest connection.
Improvement
GET /v1/accounts/{accountId}/linkedin-mentions

This endpoint resolves a LinkedIn profile URL (for a person) or a company page URL (for an organization) to a URN that can be used to @mention them in posts.

Parameters:
- accountId (path, required): The LinkedIn account ID.
- url (query, required): LinkedIn profile URL, company URL, or vanity name. It supports:
- Person: miquelpalet, linkedin.com/in/miquelpalet
- Organization: company/microsoft, linkedin.com/company/microsoft
- displayName (query, optional): The exact display name as shown on LinkedIn. This is required for clickable person mentions. If not provided, the name is derived from the vanity URL, which may not match exactly.

Response:
On success (HTTP 200), the response contains:
- urn: The LinkedIn URN (either for a person or organization).
- type: The type of entity, which can be either person or organization.
- displayName: The display name (provided, from API, or derived from vanity URL).
- mentionFormat: Ready-to-use mention format for post content.
- vanityName: The vanity name/slug (only for organization mentions).
- warning: A warning about clickable mentions (only present for person mentions if displayName was not provided).

This change allows developers to mention organizations without needing to be an admin of a LinkedIn organization, which simplifies the process of tagging companies in posts. Person mentions still require admin access for the organization but now support a broader range of input formats.
Improvement
GET /v1/profiles
This endpoint lists profiles visible to the authenticated user. It now includes a new optional query parameter includeOverLimit (type: boolean, default: false). When set to true, it includes profiles that exceed the user's plan limit, which will have isOverLimit: true in the response. This is useful for managing or deleting profiles after a plan downgrade. The profiles are sorted by creation date (oldest first).

Response contains:
- profiles: an array of profile objects, each containing:
- id: string
- name: string
- color: string
- isDefault: boolean
- isOverLimit: boolean (only present when includeOverLimit=true)
- createdAt: string (date-time)

GET /v1/accounts
This endpoint lists connected social accounts. It now also includes the includeOverLimit parameter (type: boolean, default: false). When true, it includes accounts from profiles that exceed the user's plan limit, allowing users to disconnect accounts from over-limit profiles for deletion.

Response contains:
- accounts: an array of account objects, each containing:
-
id: string
- platform: string
- profileId: object containing profile details
- username: string
- displayName: string
- profileUrl: string
- isActive: boolean
- hasAnalyticsAccess: boolean (indicates if the user has analytics add-on access)
Improvement
The account.disconnected webhook payload now includes additional fields for better context:

- accountId - The account's unique identifier (same as used in /v1/accounts/{accountId})
- profileId - The profile's unique identifier this account belongs to
- disconnectionType - Either intentional (user disconnected manually) or unintentional (token expired or was revoked)

These fields help you understand why an account was disconnected and quickly look up related data.