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.
// 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_KEYYou can also use JWT bearer tokens for session-based authentication (e.g., from the dashboard):
Authorization: Bearer YOUR_JWT_TOKENSecurity 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
/scrapeSubmit 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
}| Parameter | Type | Required | Description |
|---|---|---|---|
post_url | string | Yes | Full Instagram post or reel URL |
include_replies | boolean | No | When 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
| Status | Meaning |
|---|---|
pending | Job queued, waiting to be processed |
in_progress | Currently extracting comments |
completed | Done — fetch results via /jobs/{id}/result |
failed | Error 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());
}/jobs/{job_id}Check the status of a scraping job. Poll this endpoint until status is completed or failed.
curl https://api.social-flex.com/jobs/123e4567-e89b-12d3-a456-426614174000 \
-H "X-API-Key: sf_live_YOUR_API_KEY"/jobs/{job_id}/resultGet 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.
{
"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)./jobs/{job_id}/result.csvDownload 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 -OJ https://api.social-flex.com/jobs/JOB_ID/result.csv \
-H "X-API-Key: YOUR_API_KEY"/jobs/{job_id}/progressLive 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).
Job completion notificationsGet 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.
{
"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
}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)/jobsList all your scraping jobs. Supports optional query parameters for filtering.
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: pending, in_progress, completed, failed |
limit | integer | Max results to return (default: 50) |
/jobs/{job_id}/retryRetry a failed job. Creates a new processing attempt using the same post URL. Only works on jobs with failed status.
/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: 1642175460Limits by Plan
| Plan | Requests / Minute | Credits |
|---|---|---|
| Free | 10 | 5,000 (one-time) |
| Starter | 20 | 10,000/month |
| Professional | 60 | 50,000/month |
| Growth | 120 | 250,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
| Code | Description |
|---|---|
201 | Created — Scraping job submitted successfully (POST /scrape) |
200 | OK — Request completed successfully (GET endpoints) |
400 | Bad Request — Invalid or missing post_url parameter |
401 | Unauthorized — Missing or invalid API key |
402 | Payment Required — Insufficient credits to process this job |
404 | Not Found — Job ID does not exist or belongs to another user |
429 | Too Many Requests — Rate limit exceeded for your plan |
500 | Internal Server Error — Something went wrong on our end |
Support & Resources
Ready to start building?
Get your API key and extract Instagram comments in minutes.
Get Your Free API Key →