Instagram API

The Instagram API that actually ships

The Instagram API requires weeks of Meta app review, complex OAuth flows, 60-day token rotation, and 3 API calls just to post a carousel. Aether wraps all of that into one endpoint — so you post photos, carousels, and Reels in the same call, with one API key.

Post to Instagram in under 15 minutes

One call for photos, carousels, and scheduled posts. Aether handles media containers, format validation, and retry logic.

Node.js / TypeScript
import Aether from "aether";

const aether = new Aether({ apiKey: process.env.AETHER_API_KEY });

// Single photo post
const photo = await aether.posts.create({
  text: "Shipping something new today 🚀 #buildinpublic",
  profileIds: ["ig_abc123"],
  mediaUrls: ["https://your-cdn.com/photo.jpg"],
});

// Carousel post (up to 10 images)
const carousel = await aether.posts.create({
  text: "A thread of behind-the-scenes shots 📷",
  profileIds: ["ig_abc123"],
  mediaUrls: [
    "https://your-cdn.com/slide-1.jpg",
    "https://your-cdn.com/slide-2.jpg",
    "https://your-cdn.com/slide-3.jpg",
  ],
});

// Scheduled post
const scheduled = await aether.posts.create({
  text: "See you tomorrow morning ☀️",
  profileIds: ["ig_abc123"],
  mediaUrls: ["https://your-cdn.com/morning.jpg"],
  scheduledFor: "2026-06-15T09:00:00Z",
});

Free tier · 3 accounts · no credit card

Get your free API key

The same call in Python and cURL

Python
import os
import aether

client = aether.Aether(api_key=os.environ["AETHER_API_KEY"])

# Single photo post
post = client.posts.create(
    text="Shipping something new today 🚀 #buildinpublic",
    profile_ids=["ig_abc123"],
    media_urls=["https://your-cdn.com/photo.jpg"],
)

# Scheduled carousel
carousel = client.posts.create(
    text="A thread of behind-the-scenes shots 📷",
    profile_ids=["ig_abc123"],
    media_urls=["https://your-cdn.com/slide-1.jpg", "https://your-cdn.com/slide-2.jpg"],
    scheduled_for="2026-06-15T09:00:00Z",
)
cURL
curl -X POST https://api.aetherhq.dev/v1/posts \
  -H "Authorization: Bearer $AETHER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Shipping something new today 🚀 #buildinpublic",
    "profileIds": ["ig_abc123"],
    "mediaUrls": ["https://your-cdn.com/photo.jpg"],
    "scheduledFor": "2026-06-15T09:00:00Z"
  }'

The actual API response

Aether returns a normalized post object immediately. Once published, the publishResults array includes the platform-native Instagram post ID and publish timestamp.

JSON
{
  "success": true,
  "data": {
    "id": "post_2k4mn8x",
    "status": "scheduled",
    "text": "Shipping something new today 🚀 #buildinpublic",
    "profileIds": ["ig_abc123"],
    "mediaUrls": ["https://cdn.aetherhq.dev/org_9p2qrs/photo.jpg"],
    "mediaKeys": ["org_9p2qrs/photo.jpg"],
    "scheduledFor": "2026-06-15T09:00:00.000Z",
    "publishResults": [],
    "publishedAt": null,
    "failedAt": null,
    "createdAt": "2026-06-08T14:23:11.000Z"
  }
}

Instagram OAuth — without the headache

Getting instagram_content_publish directly means: register a Meta developer app, record a screen-share video of the OAuth flow, submit for review, wait weeks for approval, then build token refresh infrastructure for the 60-day expiry.

Aether's Connect Link removes all of that. Call one endpoint, get a URL, send it to your user. They click, Instagram authenticates them, and their account appears in your dashboard.

TypeScript
// Generate a Connect Link for your user to authenticate Instagram
const link = await aether.connectLinks.create({
  platform: "instagram",
  redirectUrl: "https://yourapp.com/settings/social",
});

// Send link.url to your user — they click, authenticate on Instagram,
// and the account appears in your dashboard automatically.
// No Meta app setup needed on your end.
console.log(link.url);     // "https://connect.aetherhq.dev/link/cl_xk9p2m..."
console.log(link.expiresAt); // "2026-06-15T14:23:11.000Z"

Everything the Instagram API gives you

No app review required

Aether's Connect Link handles Instagram OAuth on your behalf. Your users connect in one click — no Meta developer portal work on your side.

Photos & carousels

Single images, multi-image carousels (up to 10), and Stories. Aether handles the multi-step container API — you send one request.

Reels & video

Upload videos directly or pass a URL. Aether handles format validation, container creation, and processing wait — then publishes automatically.

Scheduling

Pass scheduledFor in your request. Aether queues the post and publishes at the right time. Supports timezone strings for account-local scheduling.

Comments & DMs

Read and reply to Instagram comments and DMs programmatically. All threads in one unified inbox API surface across platforms.

Analytics

Impressions, reach, likes, saves, comments — per post and per account. Historical data with custom date ranges and sub-second queries.

Best time to post

Historical engagement analysis per account tells you the optimal days and hours to publish for maximum reach.

MCP / AI agents

Every Instagram endpoint is an MCP tool. Claude, Cursor, and any MCP-compatible agent can post, schedule, and retrieve analytics.

Pull Instagram analytics via API

Impressions, reach, likes, saves, and follower delta — post-level and account-level, over any date range, with sub-second Tinybird queries.

TypeScript
// Post-level analytics
const metrics = await aether.analytics.getPostMetrics("post_2k4mn8x");
// [{ metricType: "impression", value: 2840 }, { metricType: "like", value: 127 }, ...]

// Account analytics for June
const account = await aether.analytics.getAccountMetrics({
  profileId: "ig_abc123",
  from: "2026-06-01",
  to: "2026-06-30",
  granularity: "day",
});

// Best times to post on this Instagram account
const bestTimes = await aether.analytics.getBestPostingTimes({
  platform: "instagram",
});

Why not build directly on the Instagram Graph API?

You can — but you take on everything Meta requires. Here's the realistic comparison.

FeatureAetherInstagram Graph API directly
AuthenticationOne API keyApp Review + complex OAuth 2.0
Rate limitsAutomatic retry & backoffManually managed per endpoint
Media hostingUpload to Aether, we handle the restExternal CDN required
API maintenanceWe absorb all breaking changesYour team's responsibility
Time to first post< 15 minutesDays to weeks
Platform complianceOfficial API, fully compliantOfficial API, fully compliant

Instagram API rate limits

Platform-level limits set by Instagram. Aether queues and retries automatically — your integration does not need backoff logic.

OperationLimitError codeNote
Content publish50 posts / 24 h341Per Instagram account
API calls200 calls / hr / token17Per access token
Media file size100 MB per file352Images + videos
Video (Feed)60 s max · min 3 sMP4 / MOV
Reels90 min max · 50 / dayPer account
Carousel10 items max100Images or videos
Caption2,200 characters100UTF-8, links not clickable
Hashtags30 per post100Instagram limit

Instagram API error codes reference

CodeMeaningHow Aether handles it
190Invalid or expired OAuth tokenAether auto-refreshes — reconnect if it persists
200Missing permission scopeRe-connect via Connect Link; all scopes are requested upfront
341Daily publish limit (50/day) reachedAether queues and retries after the window resets
368Account temporarily blockedContent policy issue — review the post before resubmitting
10App review gate — permission deniedUse Aether — Meta review is Aether's problem, not yours
100Invalid request parameterAether validates the request; check your input
352Media file too largeCompress below 100 MB — Aether will surface this before sending

AI-Native

Let your AI agent post to Instagram

Aether ships an MCP server that exposes every Instagram endpoint as a callable tool. Claude Desktop, Cursor, Windsurf, and any MCP-compatible agent can post, schedule, pull analytics, and manage DMs — with no additional integration code.

Claude Desktop config
# Add to ~/.claude/claude_desktop_config.json
{
  "mcpServers": {
    "aether": {
      "command": "npx",
      "args": ["-y", "aether-mcp"],
      "env": { "AETHER_API_KEY": "sk_live_..." }
    }
  }
}

# Claude can now post to Instagram, pull analytics, and manage DMs:
# "Post our launch photo to Instagram now"
# "Schedule tomorrow's carousel for 9am"
# "What's our Instagram engagement rate this week?"

Frequently asked questions

How do I post to Instagram via API?+

With Aether you call POST /v1/posts with your Instagram profile ID and content. Aether handles all underlying Graph API calls — media containers, carousel assembly, processing waits, and scheduling — so you send one request and get back one normalized response.

Do I need to go through Instagram's app review?+

No. Aether's platform app has already completed Meta's review and holds the instagram_content_publish permission. Your app only needs an Aether API key. No Meta developer portal setup, no screen-share video, no waiting.

What is the Instagram API rate limit?+

Instagram allows 50 published posts per 24 hours per account and 200 API calls per hour per access token. Aether automatically queues and retries requests that hit platform rate limits, surfacing the status in the post's publishResults field.

Can I schedule Instagram posts via the API?+

Yes. Pass scheduledFor as an ISO 8601 datetime string. Aether stores the post as 'scheduled' and publishes it at the correct time. You can also pass a timezone string to schedule in the account's local time zone.

How do I post an Instagram carousel via API?+

With Aether you just pass multiple URLs in mediaUrls — up to 10 items. Aether handles the multi-step Graph API carousel flow (create per-item containers, create carousel container, publish) automatically. No extra code on your end.

Ready to ship your Instagram integration?

Free tier · 3 accounts · full API access · MCP server · no credit card.

Get your free API key →