API Documentation

Everything you need to extract Instagram comments at scale.

Base URL: https://api.social-flex.com

Getting Started

1. Create an Account

Sign up for a free account at Social Flex. You'll get 5,000 free credits (one-time) with no credit card required.

2. Get Your API Key

Navigate to your API Keys dashboard and generate a key. Your key will look like sf_live_aBcDeFgHiJkLmNoPqRsT. Keep it secure — treat it like a password.

3. Make Your First Request

The API uses an async job pattern: submit a post URL, get a job ID, poll for status, then fetch results.

JavaScript / Node.js
// Extract comments from an Instagram post
const response = await fetch('https://api.social-flex.com/scrape', {
  method: 'POST',
  headers: {
    'X-API-Key': 'sf_live_YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    post_url: 'https://www.instagram.com/p/ABC123DEF456/'
  })
});

const job = await response.json();
// { "id": "uuid", "status": "pending", ... }

// Poll for results
const result = await fetch(`https://api.social-flex.com/jobs/${job.id}`, {
  headers: { 'X-API-Key': 'sf_live_YOUR_API_KEY' }
});

const data = await result.json();
if (data.status === 'completed') {
  // Fetch scraped data
  const scraped = await fetch(`https://api.social-flex.com/jobs/${job.id}/result`, {
    headers: { 'X-API-Key': 'sf_live_YOUR_API_KEY' }
  });
  console.log(await scraped.json());
}

Authentication

All API requests require an API key in the X-API-Key header:

X-API-Key: sf_live_YOUR_API_KEY

You can also use JWT bearer tokens for session-based authentication (e.g., from the dashboard):

Authorization: Bearer YOUR_JWT_TOKEN

Security Best Practices

  • Never commit API keys to version control
  • Use environment variables to store keys
  • Rotate keys periodically from the API Keys dashboard
  • Use separate keys for development and production
  • Revoke compromised keys immediately

API Endpoints

POST/scrape

Submit a public Instagram post for comment extraction. Accepts both regular posts (/p/) and reels (/reel/). Returns a job object you can poll for status. Each comment extracted costs 1 credit. Optionally set include_replies to also extract replies (1 credit per reply).

Request Body

{
  "post_url": "https://www.instagram.com/p/ABC123DEF456/",
  "include_replies": false
}
ParameterTypeRequiredDescription
post_urlstringYesFull Instagram post or reel URL
include_repliesbooleanNoWhen true, also extracts replies to comments from edge_threaded_comments. Each reply costs 1 additional credit. Default: false

Response (201 Created)

{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "pending",
  "post_url": "https://www.instagram.com/p/ABC123DEF456/",
  "include_replies": false,
  "created_at": 1699999999.0,
  "started_at": null,
  "completed_at": null,
  "has_result": false,
  "error_message": null
}

Job Statuses

StatusMeaning
pendingJob queued, waiting to be processed
in_progressCurrently extracting comments
completedDone — fetch results via /jobs/{id}/result
failedError occurred — check error_message field

Code Examples

// Extract comments from an Instagram post
const response = await fetch('https://api.social-flex.com/scrape', {
  method: 'POST',
  headers: {
    'X-API-Key': 'sf_live_YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    post_url: 'https://www.instagram.com/p/ABC123DEF456/'
  })
});

const job = await response.json();
// { "id": "uuid", "status": "pending", ... }

// Poll for results
const result = await fetch(`https://api.social-flex.com/jobs/${job.id}`, {
  headers: { 'X-API-Key': 'sf_live_YOUR_API_KEY' }
});

const data = await result.json();
if (data.status === 'completed') {
  // Fetch scraped data
  const scraped = await fetch(`https://api.social-flex.com/jobs/${job.id}/result`, {
    headers: { 'X-API-Key': 'sf_live_YOUR_API_KEY' }
  });
  console.log(await scraped.json());
}
GET/jobs/{job_id}

Check the status of a scraping job. Poll this endpoint until status is completed or failed.

Example
curl https://api.social-flex.com/jobs/123e4567-e89b-12d3-a456-426614174000 \
  -H "X-API-Key: sf_live_YOUR_API_KEY"
GET/jobs/{job_id}/result

Get the extracted data from a completed job. Returns the post metadata and all comments with usernames, text, timestamps, likes, and reply counts. When include_replies was set to true, each comment also includes a reply_comments array.

Example Response (with include_replies=true)
{
  "post": {
    "shortcode": "ABC123DEF456",
    "username": "example_user",
    "caption": "Post caption text...",
    "likes": 1250,
    "comments_count": 89,
    "creation_date": "2026-03-10T14:30:00Z",
    "cover_image_url": "https://..."
  },
  "comments": [
    {
      "username": "commenter1",
      "text": "Great post!",
      "likes": 5,
      "reply_count": 2,
      "timestamp": "2026-03-10T15:00:00Z",
      "profile_pic_url": "https://...",
      "reply_comments": [
        {
          "username": "replier1",
          "text": "Totally agree!",
          "likes": 1,
          "timestamp": "2026-03-10T15:05:00Z",
          "profile_pic_url": "https://..."
        }
      ]
    },
    ...
  ],
  "total_comments": 89,
  "credits_charged": 91
}
// Note: reply_comments array is only present when include_replies=true.
// credits_charged = comments + replies (each costs 1 credit).
GET/jobs/{job_id}/result.csv

Download a completed job's comments as a CSV file. One row per comment, plus one row per reply (with is_reply=true and the parent comment's username). UTF-8 with BOM so it opens cleanly in Excel.

cURL
curl -OJ https://api.social-flex.com/jobs/JOB_ID/result.csv \
  -H "X-API-Key: YOUR_API_KEY"
GET/jobs/{job_id}/progress

Live progress snapshot for an in-flight job: current phase,comments_collected,estimated_total, andpercent_complete. A Server-Sent Events stream of the same data is available at/jobs/{job_id}/progress/stream?token=YOUR_API_KEY(EventSource can't set headers, so the key goes in the query string).

WEBHOOKJob completion notifications

Get a POST callback when a job finishes. Set a default webhook URL in Settings, or pass webhook_url per job in the POST /scrape body. Requests carry X-SocialFlex-Event(job.completed /job.failed) and, when a signing secret is configured, an HMAC-SHA256 signature inX-SocialFlex-Signature. Failed deliveries are retried with exponential backoff.

Payload
{
  "job_id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "completed",
  "post_url": "https://www.instagram.com/p/ABC123/",
  "credits_charged": 842,
  "has_result": true,
  "timestamp": 1699999999.0
}
Verify the signature (Python)
import hmac, hashlib

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, header)
GET/jobs

List all your scraping jobs. Supports optional query parameters for filtering.

ParameterTypeDescription
statusstringFilter by status: pending, in_progress, completed, failed
limitintegerMax results to return (default: 50)
POST/jobs/{job_id}/retry

Retry a failed job. Creates a new processing attempt using the same post URL. Only works on jobs with failed status.

DELETE/jobs/{job_id}

Delete a job and its associated data. This action is irreversible. Credits already charged are not refunded.

Rate Limiting

Rate limits are per-user and vary by plan. Every API response includes these headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1642175460

Limits by Plan

PlanRequests / MinuteCredits
Free105,000 (one-time)
Starter2010,000/month
Professional6050,000/month
Growth120250,000/month

Handling Rate Limits

When you exceed your rate limit, the API returns 429 Too Many Requests. Check the X-RateLimit-Reset header for the Unix timestamp when your limit resets. Implement exponential backoff for best results.

Error Handling

Errors return standard HTTP status codes with a JSON body containing a detail field:

{
  "detail": "Rate limit exceeded. Try again in 45 seconds."
}

HTTP Status Codes

CodeDescription
201Created — Scraping job submitted successfully (POST /scrape)
200OK — Request completed successfully (GET endpoints)
400Bad Request — Invalid or missing post_url parameter
401Unauthorized — Missing or invalid API key
402Payment Required — Insufficient credits to process this job
404Not Found — Job ID does not exist or belongs to another user
429Too Many Requests — Rate limit exceeded for your plan
500Internal Server Error — Something went wrong on our end

Support & Resources

Need Help?

Our support team is here to help. Response times vary by plan.

Contact Support →

Blog & Tutorials

Guides, best practices, and the latest updates.

Visit Blog →

API Playground

Test endpoints directly from your dashboard.

Open Playground →

Pricing

Transparent, credit-based pricing that scales with you.

View Pricing →

Ready to start building?

Get your API key and extract Instagram comments in minutes.

Get Your Free API Key →