API Documentation

Authentication

All API requests require authentication using an API key in the Authorization header.

# Include your API key in the Authorization header
curl -H "Authorization: Bearer YOUR_API_KEY" https://api.getlate.dev/v1/posts

Plan Tiers & Limits

LATE offers 4 plan tiers with different usage limits. All limits are enforced at the API level and reset based on your billing period.

Free

0€/month
10 uploads/month
2 profiles

Basic

14€/month
120 uploads/month
10 profiles

Professional

MOST POPULAR
42€/month
Unlimited uploads
50 profiles

Advanced

126€/month
Unlimited uploads
150 profiles

Enterprise

HIGHEST TIER
249€/month
Unlimited uploads
250 profiles
20 posts/day per account

💡 Annual Billing

Save 40% with annual billing! Usage limits reset on your billing anniversary.

Usage Tracking

Your usage is tracked in real-time and enforced at every API call. Usage resets automatically based on your billing period.

Reset Schedule

  • Monthly Plans: Usage resets on your signup anniversary day each month
  • Annual Plans: Usage resets on your signup anniversary date each year
  • Free Users: Automatic reset based on signup date
  • Paid Users: Reset triggered by Stripe billing webhooks

What's Tracked

  • Uploads: Each successful post creation (drafts don't count) - resets with billing cycle
  • Profiles: Total number of profiles you currently have - decreases when you delete profiles
  • Last Reset: Timestamp of your last usage reset (uploads only)

Plan Limit Errors

When you exceed your plan limits, the API returns detailed error messages with upgrade suggestions.

Upload Limit Exceeded

HTTP 403 Forbidden
{
  "error": "Upload limit reached. Your Free plan allows 10 uploads per month. You have used 10.",
  "planName": "Free",
  "limit": 10,
  "current": 10,
  "billingPeriod": "monthly"
}

Profile Limit Exceeded

HTTP 403 Forbidden
{
  "error": "Profile limit reached. Your basic plan allows 10 profiles. You currently have 10.",
  "planName": "basic",
  "limit": 10,
  "current": 10,
  "details": {
    "resource": "profiles",
    "plan": "basic",
    "currentUsage": 10,
    "limit": 10,
    "window": "total"
  }
}

Quick Start

Here's how to set up profiles and schedule your first post:

1. Create a Profile

# Create a profile to organize your social accounts
curl -X POST https://api.getlate.dev/v1/profiles \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Personal Brand", "description": "My personal social media accounts", "color": "#ffeda0" }'

2. Connect Social Accounts

# Connect social accounts to your profile (redirects to OAuth)
curl "https://api.getlate.dev/v1/connect/twitter?profileId=PROFILE_ID" \\
  -H "Authorization: Bearer YOUR_API_KEY"

3. Schedule a Post

# Schedule a post using accounts from your profile
curl -X POST https://api.getlate.dev/v1/posts \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content": "Hello, world! 🌍", "scheduledFor": "2024-01-01T12:00:00", "timezone": "America/New_York", "profileId": "PROFILE_ID", "platforms": ["twitter", "linkedin"] }'

Profiles

LATE uses a profile-based architecture to organize your social media accounts. Each profile can have one connected account per platform, allowing you to manage multiple brands, clients, or personal accounts separately.

GET /v1/profiles

GET/v1/profiles

Get all profiles for your account.

Response

{
  "profiles": [
    {
      "_id": "profile_id",
      "name": "Personal Brand",
      "description": "My personal accounts", 
      "color": "#ffeda0",
      "isDefault": true,
      "createdAt": "2024-01-01T00:00:00Z"
    }
  ]
}

POST /v1/profiles

POST/v1/profiles

Create a new profile. Subject to plan limits.

⚠️ Plan Limits: Free (2), Basic (10), Professional (50), Advanced (150), Enterprise (250) profiles

Profile limits are enforced in real-time. Creating a profile when at your limit returns HTTP 403.

Request Body

{
  "name": "Business Account",
  "description": "Company social media",
  "color": "#4ade80"
}

Response Status Codes

  • 201 - Profile created successfully
  • 400 - Invalid request data or profile name already exists
  • 401 - Invalid API key
  • 403 - Profile limit reached for your plan
  • 404 - User not found

PUT /v1/profiles/[profileId]

PUT/v1/profiles/[profileId]

Update an existing profile.

DELETE /v1/profiles/[profileId]

DELETE/v1/profiles/[profileId]

Delete a profile. Cannot delete profiles with connected accounts.

Usage Statistics

Monitor your current usage against plan limits in real-time.

GET /v1/usage-stats

GET/v1/usage-stats

Get current usage statistics for your account.

Response

{
  "planName": "Professional",
  "billingPeriod": "yearly",
  "limits": {
    "uploads": -1,
    "profiles": 50,
    "postsPerDayPerAccount": 8
  },
  "usage": {
    "uploads": 847,
    "profiles": 12,
    "lastReset": "2024-01-01T00:00:00.000Z"
  },
  "canUpload": true,
  "canCreateProfile": true
}

Response Fields

  • limits.uploads - Upload limit (-1 = unlimited)
  • limits.profiles - Profile limit
  • usage.uploads - Current period uploads
  • usage.profiles - Total profiles created
  • canUpload - Whether you can create more posts
  • canCreateProfile - Whether you can create more profiles
# Get your current usage stats
curl -H "Authorization: Bearer YOUR_API_KEY" https://api.getlate.dev/v1/usage-stats

Posts

Schedule and manage social media posts across multiple platforms. Upload limits apply based on your plan.

⚠️ Upload Limits: Free (10/month), Basic (120/month), Professional, Advanced & Enterprise (unlimited)

GET /v1/posts

GET/v1/posts

Retrieve a list of your scheduled and published posts with pagination.

Query Parameters

  • page - Page number (default: 1)
  • limit - Posts per page (default: 10, max: 100)
  • status - Filter by status (draft, scheduled, published, failed)
  • platform - Filter by platform

POST /v1/posts

POST/v1/posts

Create and schedule a new post across multiple social media platforms. Subject to upload limits.

⚠️ Upload Limits: Each successful post creation counts toward your monthly/yearly limit (drafts don't count)

Request Body

{
  "content": "Your post content here",
  "profileId": "profile_id",
  "platforms": ["twitter", "instagram", "linkedin"],
  "scheduledFor": "2024-01-01T12:00:00",
  "timezone": "America/New_York",
  "publishNow": false,
  "isDraft": false,
  "visibility": "public|private|unlisted",
  "mediaItems": [
    {
      "type": "image|video|gif",
      "url": "media_url_from_/v1/media",
      "filename": "optional_filename"
    }
  ]
}

🕐 Timezone Handling: The scheduledFor field should be in YYYY-MM-DDTHH:mm format (without Z suffix). The timezone field specifies the timezone for the scheduled time (e.g., "America/New_York", "Europe/London", "UTC"). If no timezone is provided, UTC is assumed.

Posts are sent using the social accounts connected to the specified profile. Each profile can have one account per platform.

Response Status Codes

  • 201 - Post published successfully to all platforms
  • 207 - Multi-Status: Some platforms succeeded, others failed
  • 400 - Invalid request data
  • 401 - Invalid API key

GET /v1/posts/[postId]

GET/v1/posts/[postId]

Get details of a specific post by ID.

PUT /v1/posts/[postId]

PUT/v1/posts/[postId]

Update a post. Only draft and scheduled posts can be edited.

📝 Editable Post Statuses: draft, scheduled
❌ Non-editable: published, publishing, failed, cancelled

Request Body

Same structure as POST /v1/posts, all fields are optional:

{
  "content": "Updated post content",
  "scheduledFor": "2024-01-01T15:00:00",
  "timezone": "America/New_York",
  "platforms": ["twitter", "linkedin"],
  "isDraft": false,
  "publishNow": false,
  "mediaItems": [...]
}
# Update a scheduled post
curl -X PUT https://api.getlate.dev/v1/posts/POST_ID \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"content":"Updated content"}'

DELETE /v1/posts/[postId]

DELETE/v1/posts/[postId]

Delete a post. Published posts cannot be deleted. All other statuses (draft, scheduled, publishing, failed, cancelled) can be deleted.

⚠️ Deletable Post Statuses: draft, scheduled, publishing, failed, cancelled
❌ Non-deletable: published (posts that have been successfully published cannot be deleted)

# Delete a scheduled or failed post
curl -X DELETE -H "Authorization: Bearer YOUR_API_KEY" https://api.getlate.dev/v1/posts/POST_ID

POST /v1/posts/[postId]/retry

POST/v1/posts/[postId]/retry

Retry publishing a failed post. Only failed posts can be retried.

POST /v1/media

POST/v1/media

Upload media files (images/videos) for use in posts.

Request

Content-Type: multipart/form-data

Social Accounts

GET /v1/accounts

GET/v1/accounts

Get connected social media accounts, optionally filtered by profile.

Query Parameters

  • profileId - Filter accounts by profile ID (optional)

Response

{
  "accounts": [
    {
      "_id": "account_id",
      "profileId": "profile_id",
      "platform": "instagram",
      "username": "your_username",
      "displayName": "Your Display Name",
      "profilePicture": "https://...",
      "isActive": true,
      "tokenExpiresAt": "2024-12-31T23:59:59Z",
      "permissions": ["posts:write", "posts:read"]
    }
  ]
}
# Get accounts for a specific profile
curl -H "Authorization: Bearer YOUR_API_KEY" "https://api.getlate.dev/v1/accounts?profileId=PROFILE_ID"

GET /v1/connect/[platform]

GET/v1/connect/[platform]

Initiate OAuth connection for a platform to a specific profile.

Query Parameters

  • profileId - Profile ID to connect the account to (required)
  • redirect_url - Custom URL to redirect to after OAuth completion (optional)

Custom Redirects

By default, users are redirected to the dashboard after connecting an account. Use redirect_url to redirect to your own application instead.

Success Parameters
  • connected - Platform name (e.g., "twitter")
  • profileId - Profile ID the account was connected to
  • username - Connected account username
Error Parameters
  • error - Error type (e.g., "connection_failed")
  • platform - Platform name
# Basic connection (redirects to dashboard)
curl -H "Authorization: Bearer YOUR_API_KEY" "https://api.getlate.dev/v1/connect/twitter?profileId=PROFILE_ID"
# Custom redirect (redirects to your app)
curl -H "Authorization: Bearer YOUR_API_KEY" "https://api.getlate.dev/v1/connect/twitter?profileId=PROFILE_ID&redirect_url=https://myapp.com/oauth-success"
# After success, user gets redirected to:
# https://myapp.com/oauth-success?connected=twitter&profileId=PROFILE_ID&username=johndoe

DELETE /v1/accounts/[accountId]

DELETE/v1/accounts/[accountId]

Disconnect a social media account from its profile.

# Disconnect an account
curl -X DELETE -H "Authorization: Bearer YOUR_API_KEY" https://api.getlate.dev/v1/accounts/ACCOUNT_ID

Facebook Page Management

Facebook connections require special handling because users can manage multiple pages. LATE provides dedicated endpoints for page selection and management.

Facebook Connection Flow

Unlike other platforms, connecting Facebook requires selecting which page to post to. Users are redirected to a page selection interface after OAuth authorization.

GET /v1/connect/facebook/select-page

GET/v1/connect/facebook/select-page

Get available Facebook pages for selection during connection process.

Query Parameters

  • profileId - Profile ID to connect the page to (required)
  • tempToken - Temporary OAuth token from Facebook (required)

Response

{
  "pages": [
    {
      "id": "page_id_123",
      "name": "My Business Page",
      "access_token": "page_access_token_...",
      "category": "Business",
      "tasks": ["MANAGE", "CREATE_CONTENT"]
    }
  ]
}

POST /v1/connect/facebook/select-page

POST/v1/connect/facebook/select-page

Connect a specific Facebook page to a profile.

Request Body

{
  "profileId": "profile_id_123",
  "pageId": "page_id_456",
  "tempToken": "facebook_temp_token...",
  "userProfile": {
    "id": "user_facebook_id",
    "name": "User Name",
    "profilePicture": "https://..."
  }
}

Response

{
  "message": "Facebook page connected successfully",
  "account": {
    "platform": "facebook",
    "username": "My Business Page",
    "displayName": "My Business Page",
    "isActive": true,
    "selectedPageName": "My Business Page"
  }
}

PUT /v1/accounts/[accountId]/facebook-page

PUT/v1/accounts/[accountId]/facebook-page

Update which Facebook page an existing account should post to.

Request Body

{
  "selectedPageId": "new_page_id_789"
}
# Update Facebook page for an account
curl -X PUT -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"selectedPageId": "new_page_id"}' \ https://api.getlate.dev/v1/accounts/ACCOUNT_ID/facebook-page

Important Notes

  • Users must be admin of Facebook pages to connect them
  • Page access tokens are automatically managed
  • Posts are published to the selected page, not personal profile
  • Page selection can be changed anytime via the dashboard or API

Supported Platforms

Instagram Content Types

Posts

Regular Instagram posts that appear in your profile feed. Supports images and videos with captions.

{
  "platform": "instagram",
  "contentType": "post",
  "media": ["image_url_1", "image_url_2"],
  "caption": "Your post caption here"
}

Stories

Instagram Stories that are visible for 24 hours. Supports images and videos with optional stickers and text overlays.

{
  "platform": "instagram",
  "contentType": "story",
  "media": ["image_url_1"],
  "caption": "Optional story caption"
}

Important Notes

  • Stories are visible for 24 hours only
  • Stories don't support captions in the same way as posts
  • Stories support stickers and text overlays through the Instagram API
  • Both posts and stories support images and videos

YouTube Content Types

Regular Videos

Standard YouTube videos that appear in your channel and search results. No duration limits.

{
  "platform": "youtube",
  "media": ["video_url"],
  "title": "Your video title",
  "description": "Your video description"
}

YouTube Shorts

Short-form videos automatically detected by YouTube based on duration (≤ 3 minutes). Appear in the Shorts feed.

{
  "platform": "youtube",
  "media": ["vertical_video_url"],
  "title": "Your short video title",
  "description": "Your description #Shorts"
}

YouTube Shorts Detection

  • Videos ≤ 3 minutes → Automatically detected as YouTube Short
  • Videos > 3 minutes → Regular YouTube video
  • Vertical videos (9:16 aspect ratio) work best for Shorts
  • No manual selection needed - YouTube handles detection automatically
  • Shorts appear in the dedicated Shorts feed for better discovery
TikTok
active
Instagram
active
Facebook
active
YouTube
active
LinkedIn
active
Twitter/X
active
Threads
active

Rate Limits

API requests are rate limited based on your plan to ensure fair usage:

  • Free: 60 requests per minute
  • Basic: 120 requests per minute
  • Professional: 600 requests per minute
  • Advanced: 1200 requests per minute

Plan-Based Limits

Rate limits are separate from usage limits. Even with unlimited uploads, you're still subject to rate limits to prevent API abuse.

Need Help?

Have questions or need support? We're here to help!