Exports
Exports let you download your catalog (or a filtered subset) in multiple formats, or push products to a remote platform such as FTP, SFTP, S3, MinIO, or Google Drive.
There are two independent job systems under /api/v1/exports. Format exports (/exports/csv/..., /exports/excel/..., /exports/json/..., /exports/zip/...) run as a Celery task identified by task_id, tracked with GET /exports/progress/{task_id} and downloaded with GET /exports/download/{task_id}. Platform exports (/exports/platforms/{platform_id}/export) create a row in a separate jobs table, tracked and listed under /exports/jobs. They do not share IDs.
Export to CSV, Excel, JSON, or ZIP
Starts a background export of products or suppliers in the given format. Each combination is its own endpoint:
| Endpoint | Content |
|---|---|
POST /exports/csv/products | Products, CSV |
POST /exports/csv/suppliers | Suppliers, CSV |
POST /exports/excel/products | Products, Excel (.xlsx, multi-sheet) |
POST /exports/excel/suppliers | Suppliers, Excel |
POST /exports/json/products | Products, JSON |
POST /exports/json/suppliers | Suppliers, JSON |
POST /exports/zip/products | Products, ZIP of CSV chunks (for very large catalogs) |
Body parameters
- Name
filters- Type
- object
- Description
Optional filters, e.g.
{"is_active": true, "supplier_id": "uuid"}.
- Name
include_fields- Type
- array
- Description
- List of fields to include. Exports all fields if omitted.
- Name
exclude_fields- Type
- array
- Description
- Fields to exclude from the output.
- Name
language- Type
- string
- Description
ISO 639-1 code of an enabled language (2 lowercase letters). Text fields (title, description…) are resolved in that language; if omitted, the pivot language is used and logged. This is a boutique export: a missing variant silently falls back to the pivot rather than leaving the cell empty.
- Name
utf8_bom- Type
- boolean
- Description
- CSV only. Prepend a UTF-8 BOM for Excel compatibility (default:
true).
- Name
include_sheets- Type
- array
- Description
- Excel only. Sheets to include:
products,suppliers,categories(default:["products"]).
- Name
formatting- Type
- boolean
- Description
- Excel only. Apply header formatting and column auto-width (default:
true).
- Name
include_relations- Type
- boolean
- Description
- JSON only. Include nested relationships (default:
false).
- Name
pretty- Type
- boolean
- Description
- JSON only. Pretty-print the output (default:
true).
- Name
json_lines- Type
- boolean
- Description
- JSON only. Output NDJSON, one object per line (default:
false).
- Name
max_rows_per_file- Type
- integer
- Description
- ZIP only. Maximum rows per CSV file inside the archive (default:
30000).
This request does not return a downloadable file directly, nor a platform job. It returns a task_id — see track and download a format export.
Request
curl -X POST https://api.pixeepim.com/api/v1/exports/csv/products \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"filters": {"is_active": true},
"include_fields": ["ean", "name", "price", "cost_price"],
"language": "en"
}'
Response
{
"task_id": "3f9c9a1e-8b2d-4a55-9e11-2b6a7c0f9d10",
"status": "pending",
"message": "CSV export started",
"check_progress_url": "/exports/progress/3f9c9a1e-8b2d-4a55-9e11-2b6a7c0f9d10"
}
Track and download a format export
Poll progress, then download the file once the task succeeds.
Path parameters
- Name
task_id- Type
- string
- Description
- The Celery task ID returned by a format export request.
Progress response fields
- Name
state- Type
- string
- Description
PENDING,PROGRESS,SUCCESS, orFAILURE.
- Name
current- Type
- integer
- Description
- Records processed so far.
- Name
total- Type
- integer
- Description
- Total records to process.
- Name
percent- Type
- number
- Description
- Progress percentage.
- Name
message- Type
- string
- Description
- Status message.
- Name
result- Type
- object
- Description
- Final result once
stateisSUCCESS.
GET /exports/download/{task_id} only succeeds once state is SUCCESS; otherwise it returns 400. It streams the file with the matching content type (text/csv, .xlsx, application/json, or application/zip).
Progress
curl https://api.pixeepim.com/api/v1/exports/progress/3f9c9a1e-8b2d-4a55-9e11-2b6a7c0f9d10 \
-H "Authorization: Bearer {api_key}"
Progress response
{ "state": "SUCCESS", "current": 5000, "total": 5000, "percent": 100, "message": "Export complete", "result": { "file": "/data/exports/products_2026-09-15.csv" } }
Download
curl https://api.pixeepim.com/api/v1/exports/download/3f9c9a1e-8b2d-4a55-9e11-2b6a7c0f9d10 \
-H "Authorization: Bearer {api_key}" \
-o products.csv
Stream products (CSV / JSON)
Synchronous streaming export — no task, no polling. Suited to smaller, on-demand pulls (e.g. a scheduled script).
| Endpoint | Content |
|---|---|
GET /exports/stream/csv/products | CSV stream |
GET /exports/stream/json/products | JSON stream (or NDJSON with json_lines=true) |
Query parameters
- Name
limit- Type
- integer
- Description
- Max records to stream.
- Name
offset- Type
- integer
- Description
- Records to skip.
- Name
filters- Type
- string
- Description
- Filters, JSON-encoded.
- Name
include_fields- Type
- string
- Description
- Comma-separated fields to include.
- Name
exclude_fields- Type
- string
- Description
- Comma-separated fields to exclude.
- Name
language- Type
- string
- Description
- ISO 639-1 code; omitted = pivot language (same policy as above).
- Name
include_relations- Type
- boolean
- Description
- JSON stream only. Include nested relationships.
- Name
json_lines- Type
- boolean
- Description
- JSON stream only. Output NDJSON (default:
false).
Request
curl "https://api.pixeepim.com/api/v1/exports/stream/csv/products?limit=500&language=fr" \
-H "Authorization: Bearer {api_key}" -o products.csv
Export platforms
A platform is a registered remote destination that completed exports can be pushed to.
platform_type is one of gdrive, minio, ftp, sftp, s3 — there is no separate marketplace type (Google Shopping, Amazon…) in this API; those integrations live under their own routers, not /exports.
| Endpoint | Description |
|---|---|
GET /exports/platforms | List platforms (platform_type, is_active, search, skip, limit) |
POST /exports/platforms | Create a platform |
GET /exports/platforms/{platform_id} | Get one platform |
PUT /exports/platforms/{platform_id} | Update a platform |
DELETE /exports/platforms/{platform_id} | Delete a platform |
POST /exports/platforms/{platform_id}/toggle | Enable/disable (body: {"is_active": true}) |
POST /exports/platforms/{platform_id}/test | Test the connection of an existing platform |
POST /exports/platforms/test | Test unsaved {platform_type, config}, e.g. from a setup wizard, before creating the platform |
Body parameters — create (JSON)
- Name
name- Type
- string
- Description
- Descriptive name for the platform.
- Name
platform_type- Type
- string
- Description
gdrive,minio,ftp,sftp, ors3.
- Name
config- Type
- object
- Description
- Platform-specific credentials and settings (host/bucket/folder, keys…).
- Name
field_mappings- Type
- object
- Description
- Custom field mappings applied when exporting a product to this platform.
- Name
is_active- Type
- boolean
- Description
- Enable the platform (default:
false).
- Name
rate_limit_per_second- Type
- integer
- Description
- Outbound rate limit (default:
2).
- Name
retry_on_error- Type
- boolean
- Description
- Retry failed exports automatically (default:
true).
- Name
max_retries- Type
- integer
- Description
- Max retry attempts (default:
3).
Create
curl -X POST https://api.pixeepim.com/api/v1/exports/platforms \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"name": "Google Drive – Exports",
"platform_type": "gdrive",
"config": { "credentials": "...", "folder_id": "1abc123xyz" },
"is_active": true
}'
Response
{
"id": "550e8400-e29b-41d4-a716-446655440010",
"name": "Google Drive – Exports",
"platform_type": "gdrive",
"is_active": true,
"total_exports": 0,
"success_rate": null,
"created_at": "2026-09-15T09:00:00Z"
}
Test unsaved config
curl -X POST https://api.pixeepim.com/api/v1/exports/platforms/test \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{"platform_type": "sftp", "config": {"host": "sftp.example.com", "username": "user", "password": "***"}}'
Test response
{ "success": true, "error_message": null }
Export a product to a platform
Push one or more products to a registered platform, or preview the transformation without sending anything.
| Endpoint | Description |
|---|---|
POST /exports/platforms/{platform_id}/export | Export a single product |
POST /exports/platforms/{platform_id}/bulk-export | Export multiple products (creates one platform export job, see below) |
POST /exports/platforms/{platform_id}/preview | Preview the transformed payload for a product, without exporting it |
Body parameters
- Name
product_id- Type
- string
- Description
- Product UUID (single export / preview).
- Name
product_ids- Type
- array
- Description
- Array of product UUIDs (bulk export).
- Name
job_metadata- Type
- object
- Description
- Optional metadata attached to the resulting job (bulk export).
Bulk export
curl -X POST https://api.pixeepim.com/api/v1/exports/platforms/550e8400-e29b-41d4-a716-446655440010/bulk-export \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{"product_ids": ["7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e"]}'
Response
{
"id": "9a9a9a9a-0000-0000-0000-000000000001",
"platform_id": "550e8400-e29b-41d4-a716-446655440010",
"job_type": "bulk",
"status": "pending",
"total_items": 2,
"success_items": 0,
"failed_items": 0,
"created_at": "2026-09-15T09:00:00Z"
}
Preview
curl -X POST https://api.pixeepim.com/api/v1/exports/platforms/550e8400-e29b-41d4-a716-446655440010/preview \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{"product_id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d"}'
Platform export jobs
Jobs created by exporting to a platform.
| Endpoint | Description |
|---|---|
GET /exports/jobs | List jobs (platform_id, status, skip, limit) |
GET /exports/jobs/stats | Counts by status (pending, running, completed, failed, cancelled) and overall success_rate |
GET /exports/jobs/{job_id} | Get one job |
DELETE /exports/jobs/{job_id} | Delete a job record |
POST /exports/jobs/{job_id}/retry | Re-queue a failed job |
GET /exports/jobs/{job_id}/items | Per-product results of a bulk job (skip, limit) |
List jobs
curl "https://api.pixeepim.com/api/v1/exports/jobs?platform_id=550e8400-e29b-41d4-a716-446655440010&status=failed" \
-H "Authorization: Bearer {api_key}"
Job response
{
"id": "9a9a9a9a-0000-0000-0000-000000000001",
"platform_id": "550e8400-e29b-41d4-a716-446655440010",
"platform_name": "Google Drive – Exports",
"platform_type": "gdrive",
"job_type": "bulk",
"status": "failed",
"total_items": 2,
"success_items": 1,
"failed_items": 1,
"error_details": { "7a8b9c0d-...": "Timeout uploading file" },
"started_at": "2026-09-15T09:00:05Z",
"completed_at": "2026-09-15T09:00:40Z",
"created_at": "2026-09-15T09:00:00Z"
}
Job items
[
{
"id": "aaaaaaaa-0000-0000-0000-000000000001",
"job_id": "9a9a9a9a-0000-0000-0000-000000000001",
"product_id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d",
"product_name": "Widget Pro",
"status": "success",
"external_id": "gdrive-file-abc123",
"retry_count": 0
}
]
Export schedules
Recurring exports pushed automatically to a registered platform.
| Endpoint | Description |
|---|---|
GET /exports/schedules | List schedules (platform_id, schedule_type, is_active, page, per_page) |
POST /exports/schedules | Create a schedule |
GET /exports/schedules/{schedule_id} | Get one schedule |
PUT /exports/schedules/{schedule_id} | Update a schedule, including changing its destination (platform_id) |
DELETE /exports/schedules/{schedule_id} | Delete a schedule |
POST /exports/schedules/{schedule_id}/toggle?enabled=true | Enable/disable |
Body parameters — create (JSON)
- Name
platform_id- Type
- string
- Description
- UUID of the destination export platform.
- Name
schedule_name- Type
- string
- Description
- Descriptive name.
- Name
schedule_type- Type
- string
- Description
cron_expressionorinterval_minutes(default:cron_expression).
- Name
cron_expression- Type
- string
- Description
- Cron expression, e.g.
0 9 * * 1for Mondays at 9 AM. Required whenschedule_typeiscron_expression.
- Name
interval_minutes- Type
- integer
- Description
- Interval in minutes. Required when
schedule_typeisinterval_minutes.
- Name
timezone- Type
- string
- Description
- IANA timezone (default:
Europe/Paris).
- Name
is_active- Type
- boolean
- Description
- Enable immediately (default:
true).
- Name
export_config- Type
- object
- Description
- Filters, format, and other export options applied on each run.
- Name
max_retries- Type
- integer
- Description
- Retry attempts on failure (default:
3).
- Name
retry_delay_seconds- Type
- integer
- Description
- Delay between retries, in seconds (default:
300).
- Name
notification_emails- Type
- array
- Description
- Addresses notified about this schedule's runs.
- Name
notify_on_success- Type
- boolean
- Description
- Email on success (default:
false).
- Name
notify_on_failure- Type
- boolean
- Description
- Email on failure (default:
true).
There is also a lighter, standalone POST /exports/schedule (singular) that hands a cron expression straight to Celery Beat and returns {"task_id", "status": "scheduled"}. It is not persisted as a row you can list, update, or toggle later — prefer POST /exports/schedules (plural) above for anything you'll need to manage afterward.
Create schedule
curl -X POST https://api.pixeepim.com/api/v1/exports/schedules \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"platform_id": "550e8400-e29b-41d4-a716-446655440010",
"schedule_name": "Weekly products export",
"cron_expression": "0 9 * * 1",
"timezone": "Europe/Paris",
"notify_on_failure": true,
"notification_emails": ["ops@example.com"]
}'
Response
{
"id": "550e8400-e29b-41d4-a716-446655440020",
"platform_id": "550e8400-e29b-41d4-a716-446655440010",
"platform_name": "Google Drive – Exports",
"schedule_name": "Weekly products export",
"cron_expression": "0 9 * * 1",
"timezone": "Europe/Paris",
"is_active": true,
"run_count": 0,
"created_at": "2026-09-15T09:00:00Z"
}
Legacy one-off schedule
curl -X POST https://api.pixeepim.com/api/v1/exports/schedule \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{"export_type": "products", "schedule": "0 2 * * *", "format": "csv"}'
Generic export jobs (legacy)
An older, generic job model kept for backward compatibility, independent of both systems above.
| Endpoint | Description |
|---|---|
POST /exports/create | Create a generic export job (export_type: products, suppliers, imports, orders, or customers; format default csv) |
GET /exports/{export_id} | Get one generic export job |
DELETE /exports/{export_id} | Delete it |
GET /exports | List generic export jobs (status, export_type, limit, offset) — reads the same jobs table as the platform export jobs, so a job created by POST /exports/create and the entries listed here don't always line up one-to-one |
GET /exports/products | Real product export: returns matching rows inline for small result sets, or a Celery task_id (poll via progress/download) once the estimated count exceeds 1,000 |
POST /exports/products and POST /exports/suppliers (as opposed to GET /exports/products above, and to POST /exports/csv|excel|json|zip/products) are legacy placeholders kept only for backward compatibility — they accept a free-form JSON body and do not perform a real export. Use POST /exports/csv/products (or excel/json/zip) instead.
Create
curl -X POST https://api.pixeepim.com/api/v1/exports/create \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{"export_type": "products", "format": "csv", "filters": {"is_active": true}}'
Response
{
"id": "bbbbbbbb-0000-0000-0000-000000000001",
"export_type": "products",
"format": "csv",
"status": "pending",
"created_at": "2026-09-15T09:00:00Z",
"file_url": null,
"total_records": null
}
Real product export
curl "https://api.pixeepim.com/api/v1/exports/products?format=csv&supplier_code=SUPPLIER_A&limit=500" \
-H "Authorization: Bearer {api_key}"