LateLate API
Migrations

Migrate from Ayrshare

Step-by-step guide to migrate from Ayrshare to Late API


This guide walks you through migrating from Ayrshare to Late. Choose the path that fits your situation:

PathBest forEffort
Drop-in SDKAlready using the Ayrshare social-media-api npm package~5 minutes
Full API migrationUsing raw HTTP calls or a custom client1–2 hours

Drop-in SDK Replacement

If you're using the Ayrshare social-media-api npm package, the fastest way to migrate is our drop-in replacement SDK. All method signatures are identical — just swap the package and API key.

Install

npm uninstall social-media-api
npm install @getlatedev/social-media-api

Update your import

- import SocialMediaAPI from 'social-media-api';
+ import SocialMediaAPI from '@getlatedev/social-media-api';

const social = new SocialMediaAPI('your_late_api_key');

That's it. All existing calls (post, history, upload, createProfile, etc.) work without changes.

Supported methods

All core Ayrshare SDK methods are fully supported:

CategoryMethods
Postspost, delete, getPost, retryPost, updatePost
Historyhistory
Useruser
ProfilescreateProfile, deleteProfile, updateProfile, getProfiles
Mediaupload, media, mediaUploadUrl, verifyMediaExists
AnalyticsanalyticsPost, analyticsSocial
CommentspostComment, getComments, deleteComments, replyComment
WebhooksregisterWebhook, unregisterWebhook, listWebhooks
SchedulingsetAutoSchedule, deleteAutoSchedule, listAutoSchedule
Reviewsreviews, review, replyReview, deleteReplyReview

Not yet available: AI generation (generatePost, generateRewrite, etc.), RSS feeds, URL shortening, and a few media/analytics utilities return 501 for now. See the full compatibility list for details.

Multi-profile support

If you use Ayrshare Profile Keys, the SDK supports the same pattern:

social.setProfileKey('your_profile_key');

// All subsequent requests are scoped to this profile
const history = await social.history({ lastRecords: 10 });

Find your profile keys via social.getProfiles().


Full API Migration

If you're making raw HTTP calls or want to use Late's native API directly, follow the steps below.

Quick Reference

The main differences at a glance:

WhatAyrshareLate
Base URLapi.ayrshare.com/apigetlate.dev/api/v1
Content fieldpostcontent
Platforms["twitter", "facebook"][{platform, accountId}]
MediamediaUrls: ["url"]mediaItems: [{type, url}]
SchedulescheduleDatescheduledFor
Publish nowOmit scheduleDatepublishNow: true
Multi-userProfile-Key headerProfiles as resources

Before You Start

What you'll need:

  • Your Ayrshare API key and Profile Keys
  • A Late account (sign up here)
  • A Late API key from your dashboard

How Late organizes accounts

Late uses a two-level structure:

Profile: "Acme Corp"
├── Twitter (@acmecorp)
├── LinkedIn (Acme Corp Page)
└── Facebook (Acme Corp)

Profile: "Side Project"
├── Twitter (@sideproject)
└── Instagram (@sideproject)

Profiles group social accounts together (like brands or clients). Each Account is a connected social media account with its own accountId.


Step 1: Set Up Late Profiles

For each Ayrshare Profile Key, create a corresponding Late profile:

curl -X POST https://getlate.dev/api/v1/profiles \
  -H "Authorization: Bearer YOUR_LATE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Brand"}'

Save the returned _id — you'll need it to connect accounts.


Step 2: Connect Social Accounts

Initiate OAuth for each platform you had connected in Ayrshare:

curl -X GET "https://getlate.dev/api/v1/connect/{platform}?profileId=PROFILE_ID&redirect_url=https://yourapp.com/callback" \
  -H "Authorization: Bearer YOUR_LATE_API_KEY"

Supported platforms: twitter instagram facebook linkedin tiktok youtube pinterest reddit bluesky threads googlebusiness telegram snapchat

Platform name change: Ayrshare uses gmb for Google My Business. Late uses googlebusiness (no underscore).

The response includes an authUrl — redirect your user there to complete authorization.


Step 3: Get Your Account IDs

After connecting, fetch the account IDs:

curl -X GET "https://getlate.dev/api/v1/accounts?profileId=PROFILE_ID" \
  -H "Authorization: Bearer YOUR_LATE_API_KEY"
{
  "accounts": [
    {
      "_id": "abc123",
      "platform": "twitter",
      "username": "@yourhandle",
      "displayName": "Your Name"
    }
  ]
}

Store this mapping in your database — you'll need the _id values when creating posts.


Step 4: Update Your Post Calls

Here's how the API calls change:

Ayrshare:

curl -X POST https://api.ayrshare.com/api/post \
  -H "Authorization: Bearer API_KEY" \
  -H "Profile-Key: PROFILE_KEY" \
  -d '{
    "post": "Hello world!",
    "platforms": ["twitter", "linkedin"]
  }'

Late:

curl -X POST https://getlate.dev/api/v1/posts \
  -H "Authorization: Bearer API_KEY" \
  -d '{
    "content": "Hello world!",
    "platforms": [
      {"platform": "twitter", "accountId": "abc123"},
      {"platform": "linkedin", "accountId": "def456"}
    ],
    "publishNow": true
  }'

Ayrshare:

curl -X POST https://api.ayrshare.com/api/post \
  -d '{
    "post": "See you tomorrow!",
    "platforms": ["twitter"],
    "scheduleDate": "2025-01-15T10:00:00Z"
  }'

Late:

curl -X POST https://getlate.dev/api/v1/posts \
  -d '{
    "content": "See you tomorrow!",
    "platforms": [
      {"platform": "twitter", "accountId": "abc123"}
    ],
    "scheduledFor": "2025-01-15T10:00:00Z"
  }'

Omit publishNow for scheduled posts — it defaults to false.

Ayrshare:

curl -X POST https://api.ayrshare.com/api/post \
  -d '{
    "post": "Check this out!",
    "platforms": ["twitter"],
    "mediaUrls": ["https://example.com/image.jpg"]
  }'

Late:

curl -X POST https://getlate.dev/api/v1/posts \
  -d '{
    "content": "Check this out!",
    "platforms": [
      {"platform": "twitter", "accountId": "abc123"}
    ],
    "mediaItems": [
      {"type": "image", "url": "https://example.com/image.jpg"}
    ],
    "publishNow": true
  }'

Key changes summary

AyrshareLate
postcontent
platforms: ["twitter"]platforms: [{platform: "twitter", accountId: "..."}]
mediaUrls: ["url"]mediaItems: [{type: "image", url: "..."}]
scheduleDatescheduledFor
Omit scheduleDate to publishpublishNow: true
Profile-Key headerNot needed (use accountId in platforms)

Step 5: Update Media Uploads

Late uses presigned URLs for uploads (supports files up to 5GB):

Request a presigned URL

curl -X POST https://getlate.dev/api/v1/media/presign \
  -H "Authorization: Bearer API_KEY" \
  -d '{"filename": "photo.jpg", "contentType": "image/jpeg"}'

Response:

{
  "uploadUrl": "https://storage.../presigned-url",
  "publicUrl": "https://media.getlate.dev/temp/photo.jpg"
}

Upload your file

curl -X PUT "https://storage.../presigned-url" \
  -H "Content-Type: image/jpeg" \
  --data-binary "@photo.jpg"

Use the public URL in your post

{
  "mediaItems": [
    {"type": "image", "url": "https://media.getlate.dev/temp/photo.jpg"}
  ]
}

Already have public URLs? Skip the upload — just pass your URLs directly in mediaItems.

Supported types: image/jpeg image/png image/webp image/gif video/mp4 video/quicktime video/webm application/pdf


Step 6: Migrate Scheduled Posts

Don't lose your queued content! Export scheduled posts from Ayrshare and recreate them in Late.

Export from Ayrshare:

curl -X GET https://api.ayrshare.com/api/history \
  -H "Authorization: Bearer AYRSHARE_KEY" \
  -H "Profile-Key: PROFILE_KEY"

Recreate in Late for each post with a future scheduleDate:

curl -X POST https://getlate.dev/api/v1/posts \
  -d '{
    "content": "...",
    "platforms": [{"platform": "twitter", "accountId": "..."}],
    "scheduledFor": "2025-01-20T14:00:00Z"
  }'

Then delete or pause the Ayrshare posts to avoid duplicates.


Cutover Strategy

Don't switch all at once. Use a gradual rollout to catch issues early.

PhaseActions
PrepCreate Late profiles, connect accounts, build integration
PilotTest with internal users for a few days
RolloutEnable for 10% → 50% → 100% of users
CutoffDisable Ayrshare, keep keys for 30 days as fallback

Troubleshooting

ErrorCauseFix
Invalid accountIdUsing Ayrshare profile keyUse Late account _id from /v1/accounts
Platform not supportedWrong platform nameUse googlebusiness not gmb
Media not foundURL inaccessibleEnsure HTTPS and publicly accessible
Post not publishingWrong date formatUse ISO 8601 UTC: 2025-01-15T10:00:00Z

Code Example: Node.js

// Late post function
const createPost = async (content, accounts, media = [], scheduledFor = null) => {
  const response = await fetch('https://getlate.dev/api/v1/posts', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.LATE_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      content,
      platforms: accounts, // [{platform: "twitter", accountId: "..."}]
      mediaItems: media.map(url => ({
        type: url.match(/\.(mp4|mov|webm)$/i) ? 'video' : 'image',
        url
      })),
      ...(scheduledFor ? { scheduledFor } : { publishNow: true })
    }),
  });

  const data = await response.json();
  return data.post._id;
};

Need Help?