Instagram Profile Download
Export a full public Instagram profile as a ZIP file with media, captions, post metadata, manifest.json, and posts.csv. Authenticated runs are recommended in async mode. Pricing depends on account eligibility and profile size. See the Instagram profile downloader in your dashboard for your starting price.
/v1/instagram/profile-downloadSend Authorization: Bearer YOUR_API_KEY. Get an API key →
Parameters
Send these fields in a flat JSON body. Add _run to choose execution options.
profilestringRequiredInstagram username, @handle, or profile URL to export as a ZIP file. Minimum length: 1. Maximum length: 2000.
limitintegerOptionalOptional maximum number of posts to include. Omit this field to export the full public profile. Preferred name; maxPosts remains supported. Minimum: 1. Maximum: 100000.
Advanced & compatibility inputs 1
maxPostsintegerOptionalOptional maximum number of posts to include. Omit this field to export the full public profile. You can also use limit. Minimum: 1. Maximum: 100000.
Response
Every response describes a run. Read result once run_status is succeeded.
run_id- The run to track. Keep it when contacting support.
run_status- Queued, running, waiting for sign-in, succeeded, or failed. Check this even after an HTTP 200.
status_url- Poll this URL while the run is pending. Keep the same run instead of starting another request.
result- The endpoint’s returned data. The example is illustrative; actual fields may be empty or unavailable.
error- On failure, inspect its code, message, retryable and action fields.
View the complete output schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "The result begins with an export ID. A completed run returns artifact details, download expiry and collection statistics. partial_success means some media could not be downloaded; inspect failed_media.",
"anyOf": [
{
"type": "object",
"properties": {
"success": {
"type": "boolean",
"const": true
},
"export_id": {
"type": "string",
"description": "Export identifier. Poll the run until it succeeds before downloading."
},
"status": {
"type": "string",
"enum": [
"completed",
"partial_success",
"pending"
]
},
"file_name": {
"type": "string"
},
"download_url": {
"type": "string",
"description": "Short-lived signed download URL. It can be a pending:// placeholder before the artifact is ready."
},
"download_url_expires_at": {
"type": [
"string",
"null"
]
},
"expires_at": {
"type": [
"string",
"null"
]
},
"error_code": {
"type": [
"string",
"null"
]
},
"error_message": {
"type": [
"string",
"null"
]
},
"max_posts": {
"type": [
"number",
"null"
]
},
"truncated": {
"type": "boolean"
},
"profile": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"null"
]
},
"username": {
"type": "string"
},
"full_name": {
"type": [
"string",
"null"
]
},
"is_private": {
"type": "boolean"
},
"total_posts": {
"type": "number"
},
"profile_pic_url": {
"type": [
"string",
"null"
]
},
"authenticated": {
"type": "boolean"
}
},
"required": [
"id",
"username",
"full_name",
"is_private",
"total_posts",
"profile_pic_url",
"authenticated"
],
"additionalProperties": false
},
"result_summary": {
"type": "object",
"properties": {
"postsDiscovered": {
"type": "number"
},
"mediaDiscovered": {
"type": "number"
},
"estimatedBytes": {
"type": "number"
},
"downloadedFiles": {
"type": "number"
},
"failedFiles": {
"type": "number"
},
"skippedFiles": {
"type": "number"
},
"truncated": {
"type": "boolean"
},
"postsDownloaded": {
"type": "number"
}
},
"required": [
"postsDiscovered",
"mediaDiscovered",
"estimatedBytes",
"downloadedFiles",
"failedFiles",
"skippedFiles",
"truncated",
"postsDownloaded"
],
"additionalProperties": false
},
"failed_media": {
"type": "array",
"items": {
"type": "object",
"properties": {
"post_id": {
"type": [
"string",
"null"
]
},
"post_code": {
"type": [
"string",
"null"
]
},
"post_url": {
"type": [
"string",
"null"
]
},
"post_index": {
"type": [
"number",
"null"
]
},
"media_index": {
"type": [
"number",
"null"
]
},
"media_id": {
"type": [
"string",
"null"
]
},
"file_name": {
"type": [
"string",
"null"
]
},
"failure_reason": {
"type": "string"
}
},
"required": [
"post_id",
"post_code",
"post_url",
"post_index",
"media_index",
"media_id",
"file_name",
"failure_reason"
],
"additionalProperties": false
}
}
},
"required": [
"success",
"export_id",
"status",
"file_name",
"download_url",
"download_url_expires_at",
"expires_at",
"error_code",
"error_message",
"max_posts",
"truncated",
"profile",
"result_summary",
"failed_media"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"export_id": {
"type": "string"
}
},
"required": [
"export_id"
],
"additionalProperties": false
}
]
}View a polled run response
{
"run_id": "00000000-0000-4000-8000-000000000001",
"task_key": "instagram-profile-download",
"task_name": "Instagram Profile Download",
"run_status": "succeeded",
"status_url": "/v1/runs/00000000-0000-4000-8000-000000000001",
"result": {
"success": true,
"export_id": "id-1",
"status": "completed",
"file_name": "Stylish Shoreditch Loft with Balcony",
"download_url": "https://example.com/item-1",
"download_url_expires_at": "https://example.com/item-1",
"expires_at": "sample",
"error_code": "sample",
"error_message": "sample",
"max_posts": 1.5,
"truncated": true,
"profile": {
"id": "id-1",
"username": "Stylish Shoreditch Loft with Balcony",
"full_name": "Stylish Shoreditch Loft with Balcony",
"is_private": true,
"total_posts": 180,
"profile_pic_url": "https://example.com/item-1",
"authenticated": true
},
"result_summary": {
"postsDiscovered": 1.5,
"mediaDiscovered": 1.5,
"estimatedBytes": 1.5,
"downloadedFiles": 1.5,
"failedFiles": 1.5,
"skippedFiles": 1.5,
"truncated": true,
"postsDownloaded": 1.5
},
"failed_media": [
{
"post_id": "id-1",
"post_code": "sample",
"post_url": "https://example.com/item-1",
"post_index": 1.5,
"media_index": 1.5,
"media_id": "id-1",
"file_name": "Stylish Shoreditch Loft with Balcony",
"failure_reason": "sample"
}
]
},
"error": null
}Errors & retries
400Fix the fields listed inerrorsbefore retrying.428Connect the requested website account using the returned sign-in link.429Wait for the duration inRetry-After.5xxRetry transient failures with backoff. Keep the request ID.
A failed run has its own error inside the response. Retry it only when error.retryable is true.
More examples
Async request with polling
RUN=$(curl -s -X POST "https://api-ingress-worker-staging.browsable-staging.workers.dev/v1/instagram/profile-download" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"profile":"natgeo"}')
RUN_ID=$(echo "$RUN" | jq -er '.run_id // empty') || { echo "$RUN" >&2; exit 1; }
POLL_DELAY=3
while true; do
RESULT=$(curl -s -H "Authorization: Bearer YOUR_API_KEY" "https://api-ingress-worker-staging.browsable-staging.workers.dev/v1/runs/$RUN_ID")
STATUS=$(echo "$RESULT" | jq -r '.run_status')
if [[ "$STATUS" =~ ^(succeeded|failed|errored|cancelled|canceled|expired)$ ]]; then
echo "$RESULT"
break
fi
sleep "$(awk "BEGIN { print $POLL_DELAY * (0.9 + ($RANDOM % 21) / 100) }")"
POLL_DELAY=$((POLL_DELAY < 30 ? POLL_DELAY * 2 : 30))
[ "$POLL_DELAY" -gt 30 ] && POLL_DELAY=30
doneWait-for-results request
curl -X POST "https://api-ingress-worker-staging.browsable-staging.workers.dev/v1/instagram/profile-download" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"profile":"natgeo","_run":{"async":false}}'Canonical & compatibility routes
You can also send the same JSON body to /v1/tasks/instagram-profile-download/runs.