ExportComments API for Python
This is the official Python client for the ExportComments API v3. Export comments and reviews from 40+ social media and review platforms including Instagram, YouTube, TikTok, Facebook, Twitter/X, Reddit, Trustpilot, Amazon, and more.
Installation
pip install exportcomments
Or install from source:
git clone https://github.com/exportcomments/exportcomments-python.git
cd exportcomments-python
pip install -r requirements.txt
python setup.py install
Usage
Initialize the client with your API token (get it at app.exportcomments.com/user/api):
from exportcomments import ExportComments
ex = ExportComments('<YOUR API TOKEN HERE>')
Check API Connectivity
result = ex.ping()
print(result) # {'message': 'pong'}
Create an Export Job
Start an export by submitting a URL. The queue is limited to 5 concurrent requests.
response = ex.jobs.create(
url='https://www.instagram.com/p/1234567',
options={'replies': True, 'limit': 100}
)
guid = response.body['guid']
Check Job Status
response = ex.jobs.check(guid=guid)
status = response.body['status'] # 'queueing', 'progress', 'done', or 'error'
# Or block until the job is finished (polls every 10s, 1h timeout by default)
job = ex.jobs.wait(guid)
Bulk Export (many URLs in one call)
Premium and Business plans can submit a list of URLs at once. The server queues them and runs them at your plan's concurrency; every URL becomes a regular job.
response = ex.jobs.create_batch(
urls=[
'https://www.instagram.com/p/AAAAAAA/',
'https://www.instagram.com/p/BBBBBBB/',
],
options={'replies': True},
)
batch_id = response.body['batchId']
guids = response.body['guids'] # one per accepted URL
rejected = response.body['errors'] # URLs the server did not accept
status = ex.jobs.wait_batch(batch_id) # or ex.jobs.check_batch(batch_id).body
for job in status['exports']:
print(job['url'], job['status'], job['total'])
Limits: Business tokens may hold up to 100 queued URLs and send 5 batch submissions per 10 minutes (Premium: 25 queued, 5 per 30 minutes). Only accepted submissions count toward the window.
Exports with 0 results
When the source returns nothing for a URL (private or login-gated content,
comments disabled, filters too narrow), the job finishes as done with
total: 0. No file is produced in that case — download_url / json_url
are null and result_note explains why. download() and download_json()
raise EmptyExportError instead of failing on a dead link:
from exportcomments.exceptions import EmptyExportError
try:
ex.jobs.download(guid)
except EmptyExportError as e:
print(e.result_note)
For login-gated content, run the export with your own session cookies (Advanced Mode, see Job Options below).
List Jobs
response = ex.jobs.list(page=1, limit=10)
jobs = response.body
Download Export File
Download the Excel/CSV file for a completed job:
# Downloads and saves the file, returns the file path
file_path = ex.jobs.download(guid=guid)
print(f"Saved to: {file_path}")
# Or specify a custom output path
file_path = ex.jobs.download(guid=guid, output_path='my_export.xlsx')
Download Raw JSON Data
Get the exported data as parsed JSON:
data = ex.jobs.download_json(guid=guid)
for comment in data:
print(comment['message'], comment['author_name'])
Job Options
The API supports various options when creating a job:
response = ex.jobs.create(
url='https://www.instagram.com/p/1234567',
options={
'replies': True,
'limit': 500,
'minTimestamp': 1622505600,
'maxTimestamp': 1625097600,
'vpn': 'Norway',
'cookies': {
'sessionid': 'your_session_id'
}
}
)
Backward Compatibility
For backward compatibility, ex.exports still works as an alias for ex.jobs:
response = ex.exports.create(
url='https://www.instagram.com/p/1234567',
options={'replies': True}
)
Handling Errors
from exportcomments.exceptions import ExportCommentsException
try:
response = ex.jobs.create(
url='https://www.instagram.com/p/1234567',
options={'replies': True}
)
except ExportCommentsException as e:
print(e)
| Exception Class | Description |
|---|---|
ExportCommentsException |
Base class for all exceptions. |
RequestParamsError |
Invalid parameter sent. Check the message or response object for details. |
AuthenticationError |
Authentication failed, typically due to an invalid API token. |
ForbiddenError |
Insufficient permissions for the requested action. |
PlanRateLimitError |
Too many requests per minute according to your plan's limits. |
ConcurrencyRateLimitError |
Too many requests per second. |
EmptyExportError |
The job finished with 0 results, so there is no file to download (result_note says why). |
Complete Example
from exportcomments import ExportComments
from exportcomments.exceptions import ExportCommentsException
import time
import sys
ex = ExportComments('<YOUR API TOKEN HERE>')
# Verify connectivity
print(ex.ping())
# Create export
try:
response = ex.jobs.create(
url='https://www.instagram.com/p/1234567',
options={'replies': True, 'limit': 100}
)
except ExportCommentsException as e:
print(e)
sys.exit()
guid = response.body['guid']
# Poll until done
while True:
response = ex.jobs.check(guid=guid)
status = response.body['status']
if status == 'done':
break
elif status == 'error':
print("Error:", response.body.get('error'))
sys.exit()
time.sleep(5)
# Download the file
file_path = ex.jobs.download(guid=guid)
print(f"Downloaded: {file_path}")
# Or get raw JSON data
data = ex.jobs.download_json(guid=guid)
print(f"Got {len(data)} comments")
Changelog
2.2.0
- Bulk exports:
create_batch(),check_batch(),wait_batch()(POST /api/v1/batch-export) wait(guid)polls a job until it is finishedEmptyExportErrorfor jobs that finished with 0 results (no file exists); reads the API'sresult_note- Error messages surface the API's
errortext instead of a generic "Internal server error"
API v3 Changes
Version 2.0.0 supports API v3:
- New method names: Use
ex.jobsinstead ofex.exports(backward compatibility maintained) - Updated parameters:
create()uses anoptionsdict instead of individual parameters - New methods:
ping(),download(),download_json() - Endpoints: Uses
/api/v3/endpoints
For more information, visit ExportComments API Documentation.
Metadata
Release files for exportcomments 2.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| exportcomments-2.2.0.tar.gz | 12.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| exportcomments-2.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 24.0 kB
Release files / exportcomments-2.2.0.tar.gz
| Download URL | exportcomments-2.2.0.tar.gz |
|---|---|
| Size | 12.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
70eaa6faaffe565e8e180387335f5a0ee608b69f570a183b21d3d0ee4f18f77c
|
|
BLAKE2b-256 checksum How to use checksums |
ba9c8462f814de51cbd25f6a346e29112dbedc293ca16ada153f8fe62f6568ac
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / exportcomments-2.2.0-py3-none-any.whl
| Download URL | exportcomments-2.2.0-py3-none-any.whl |
|---|---|
| Size | 11.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
73acf4cf91c40c0b04b125f6f296ec9215692fa0e379f42246d84ced686e8818
|
|
BLAKE2b-256 checksum How to use checksums |
776c66e08372338ce28942c07dc8e50cf07d5aae9c991c59069e487faf89f45a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency log