Imports
Imports let you load large volumes of products into your catalog from CSV, Excel, JSON, or XML files. Jobs are processed asynchronously — poll the status endpoint or use a webhook to know when they complete.
All import endpoints are under the /api/v1/imports prefix. Automated recurring configs use the separate router /api/v1/import-configs.
Job lifecycle
pending → analyzing → awaiting_mapping → ready → processing → completed
→ failed
→ cancelled
| Status | Description |
|---|---|
pending | Queued, not yet started |
analyzing | File is being parsed and headers detected |
awaiting_mapping | File analyzed, column mapping required before proceeding |
ready | Mapping saved (or auto-detected), ready to process |
processing | Currently importing rows |
completed | Finished successfully |
failed | Aborted due to a critical error |
cancelled | Cancelled by the user |
Upload a file
Starts a new import job by uploading a file via multipart/form-data. The file is analyzed immediately; the job reaches awaiting_mapping (if column mapping is required) or ready (if a template is provided).
Body parameters (multipart/form-data)
- Name
file- Type
- file
- Description
The import file. Accepted formats:
.csv,.xlsx,.json,.xml.
- Name
supplier_code- Type
- string
- Description
Supplier code to associate with all imported products.
- Name
supplier_id- Type
- string
- Description
UUID of the supplier record (alternative to
supplier_code).
- Name
template_id- Type
- string
- Description
UUID of a saved mapping template to apply automatically.
- Name
import_type- Type
- string
- Description
Import type identifier (default:
"manual").
- Name
auto_process- Type
- boolean
- Description
If
trueand a template is provided, start processing immediately after analysis (default:false).
- Name
skip_header_rows- Type
- integer
- Description
Number of leading rows to skip before the header row (default:
0).
The file field is the only required parameter. supplier_code or supplier_id is strongly recommended so that imported products are linked to a known supplier.
Request
curl -X POST https://api.pixeepim.com/api/v1/imports/upload \
-H "Authorization: Bearer {api_key}" \
-F "file=@catalog.csv" \
-F "supplier_code=SUPPLIER_A" \
-F "auto_process=false"
Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "analyzing",
"file_name": "catalog.csv",
"file_type": "csv",
"supplier_code": "SUPPLIER_A",
"created_at": "2026-03-15T09:00:00Z"
}
Upload from URL
Starts an import job by fetching a file from a public URL. Useful for one-off downloads without configuring a full FTP/SFTP automation.
Body parameters (JSON)
- Name
url- Type
- string
- Description
Public URL of the file to import (HTTP or HTTPS).
- Name
supplier_id- Type
- string
- Description
UUID of the supplier to link imported products to.
- Name
template_id- Type
- string
- Description
UUID of a saved mapping template to apply automatically.
- Name
skip_header_rows- Type
- integer
- Description
Number of leading rows to skip (default:
0).
Request
curl -X POST https://api.pixeepim.com/api/v1/imports/upload-from-url \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"url": "https://supplier.com/exports/products.csv",
"supplier_id": "b1e9c3d2-1111-4abc-8def-000000000001"
}'
Response
{
"id": "550e8400-e29b-41d4-a716-446655440010",
"status": "analyzing",
"file_name": "products.csv",
"file_type": "csv",
"created_at": "2026-03-15T10:00:00Z"
}
Import via FTP / SFTP / email
Trigger a one-off import by fetching a file from a remote FTP, SFTP, or email (IMAP) source. These endpoints create a job immediately and return its ID.
FTP — POST /imports/import/ftp
- Name
host- Type
- string
- Description
FTP server hostname or IP.
- Name
port- Type
- integer
- Description
FTP port (default:
21).
- Name
username- Type
- string
- Description
FTP username.
- Name
password- Type
- string
- Description
FTP password.
- Name
directory_path- Type
- string
- Description
Remote directory to scan.
- Name
file_pattern- Type
- string
- Description
Glob pattern to filter files (e.g.
products_*.csv).
- Name
supplier_code- Type
- string
- Description
Supplier code to associate with imported products.
SFTP — POST /imports/import/sftp
- Name
host- Type
- string
- Description
SFTP server hostname.
- Name
port- Type
- integer
- Description
SFTP port (default:
22).
- Name
username- Type
- string
- Description
SFTP username.
- Name
key_file_path- Type
- string
- Description
Path to the private key file on the server.
- Name
directory_path- Type
- string
- Description
Remote directory to scan.
- Name
supplier_code- Type
- string
- Description
Supplier code to associate with imported products.
Email (IMAP) — POST /imports/import/email
- Name
imap_host- Type
- string
- Description
IMAP server hostname.
- Name
email- Type
- string
- Description
Email address to connect with.
- Name
password- Type
- string
- Description
Email account password or app password.
- Name
folder- Type
- string
- Description
IMAP folder to scan (default:
INBOX).
- Name
sender_filter- Type
- string
- Description
Only process emails from this sender address.
- Name
supplier_code- Type
- string
- Description
Supplier code to associate with imported products.
FTP request
curl -X POST https://api.pixeepim.com/api/v1/imports/import/ftp \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"host": "ftp.supplier.com",
"port": 21,
"username": "ftpuser",
"password": "s3cr3t",
"directory_path": "/exports",
"file_pattern": "products_*.csv",
"supplier_code": "SUPPLIER_A"
}'
SFTP request
curl -X POST https://api.pixeepim.com/api/v1/imports/import/sftp \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"host": "sftp.supplier.com",
"username": "sftpuser",
"key_file_path": "/keys/supplier_rsa",
"directory_path": "/exports",
"supplier_code": "SUPPLIER_A"
}'
Response
{
"id": "550e8400-e29b-41d4-a716-446655440020",
"status": "pending",
"supplier_code": "SUPPLIER_A",
"created_at": "2026-03-15T11:00:00Z"
}
List jobs
Returns a paginated list of import jobs, ordered by creation date (most recent first).
Query parameters
- Name
status- Type
- string
- Description
Filter by job status (e.g.
completed,failed,processing).
- Name
supplier_code- Type
- string
- Description
Filter by supplier code.
- Name
page- Type
- integer
- Description
Page number (default:
1).
- Name
per_page- Type
- integer
- Description
Items per page, max 100 (default:
20).
Request
curl "https://api.pixeepim.com/api/v1/imports/?status=failed&page=1&per_page=20" \
-H "Authorization: Bearer {api_key}"
Response
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"file_name": "catalog.csv",
"supplier_code": "SUPPLIER_A",
"total_rows": 1250,
"failed_rows": 1250,
"created_at": "2026-03-15T09:00:00Z"
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 20,
"total_pages": 1,
"has_next": false,
"has_previous": false
}
}
Get a job
Returns the full detail of a single import job, including progress counters and any top-level error summary.
Path parameters
- Name
import_id- Type
- string
- Description
The import job UUID.
Request
curl https://api.pixeepim.com/api/v1/imports/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer {api_key}"
Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"file_name": "catalog.csv",
"file_type": "csv",
"file_size": 1024000,
"supplier_code": "SUPPLIER_A",
"import_type": "manual",
"total_rows": 1250,
"successful_rows": 1245,
"failed_rows": 5,
"products_created": 980,
"products_updated": 265,
"last_error": null,
"started_at": "2026-03-15T09:00:00Z",
"completed_at": "2026-03-15T09:02:34Z",
"created_at": "2026-03-15T08:59:55Z"
}
Job errors
Returns per-row errors for a completed or failed job. Use this to identify which rows failed and why.
Path parameters
- Name
import_id- Type
- string
- Description
The import job UUID.
Query parameters
- Name
page- Type
- integer
- Description
Page number (default:
1).
- Name
per_page- Type
- integer
- Description
Items per page, max 200 (default:
50).
- Name
error_type- Type
- string
- Description
Filter by error type (e.g.
ean_invalid,missing_required_field).
- Name
severity- Type
- string
- Description
Filter by severity:
errororwarning.
- Name
search- Type
- string
- Description
Full-text search within error messages.
A full CSV report of all errors is also available at GET /imports/{import_id}/report.
Request
curl "https://api.pixeepim.com/api/v1/imports/550e8400-e29b-41d4-a716-446655440000/errors?severity=error&per_page=50" \
-H "Authorization: Bearer {api_key}"
Response
{
"items": [
{
"row_number": 42,
"severity": "error",
"error_type": "ean_invalid",
"field": "ean",
"message": "EAN checksum invalid (expected 13 digits)",
"raw_value": "123ABC7890",
"created_at": "2026-03-15T09:01:30Z"
}
],
"meta": {
"total": 5,
"page": 1,
"per_page": 50,
"total_pages": 1,
"has_next": false,
"has_previous": false
}
}
Dry-run (preview)
Runs the import pipeline without persisting any data. Returns a preview of rows that would be created or updated, along with detected validation errors.
The job must be in pending, ready, or awaiting_mapping status before calling this endpoint.
Path parameters
- Name
import_id- Type
- string
- Description
The import job UUID.
A dry-run does not advance the job status. Call POST /imports/{import_id}/start-processing to actually run the import.
Request
curl -X POST https://api.pixeepim.com/api/v1/imports/550e8400-e29b-41d4-a716-446655440000/dry-run \
-H "Authorization: Bearer {api_key}"
Response
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"total_rows": 1250,
"preview_rows": [
{
"row_number": 1,
"action": "create",
"ean": "3760000000001",
"title": "Sample Product",
"price": 29.99
},
{
"row_number": 2,
"action": "update",
"ean": "3760000000002",
"title": "Existing Product"
}
],
"validation_errors": [
{
"row_number": 42,
"field": "ean",
"message": "EAN checksum invalid"
}
],
"products_to_create": 980,
"products_to_update": 265,
"rows_with_errors": 5
}
Save column mapping
Saves the column mapping for a job in awaiting_mapping status. After this call the job moves to ready and can be processed.
Path parameters
- Name
import_id- Type
- string
- Description
The import job UUID.
Body parameters (JSON)
- Name
column_mapping- Type
- object
- Description
Map of file column names to product field names (e.g.
{"EAN Code": "ean", "Titre": "title"}).
- Name
validation_rules- Type
- object
- Description
Optional per-field validation overrides.
- Name
import_options- Type
- object
- Description
Optional processing options (e.g.
{"overwrite_existing": true}).
Request
curl -X POST https://api.pixeepim.com/api/v1/imports/550e8400-e29b-41d4-a716-446655440000/save-mapping \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"column_mapping": {
"EAN Code": "ean",
"Titre produit": "title",
"Prix HT": "price",
"Marque": "brand_name"
},
"import_options": {
"overwrite_existing": true
}
}'
Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "ready",
"column_mapping": {
"EAN Code": "ean",
"Titre produit": "title",
"Prix HT": "price",
"Marque": "brand_name"
}
}
Start processing
Triggers the actual import processing for a job in ready status. The job transitions to processing and rows are persisted to the catalog asynchronously.
Path parameters
- Name
import_id- Type
- string
- Description
The import job UUID.
Request
curl -X POST https://api.pixeepim.com/api/v1/imports/550e8400-e29b-41d4-a716-446655440000/start-processing \
-H "Authorization: Bearer {api_key}"
Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"started_at": "2026-03-15T09:01:00Z"
}
Cancel a job
Cancels an import job. Only jobs in pending or processing status can be cancelled. Rows already committed before cancellation are not rolled back.
Path parameters
- Name
import_id- Type
- string
- Description
The import job UUID.
Request
curl -X POST https://api.pixeepim.com/api/v1/imports/550e8400-e29b-41d4-a716-446655440000/cancel \
-H "Authorization: Bearer {api_key}"
Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "cancelled"
}
Retry a job
Re-queues a job that ended in failed or cancelled status. The job returns to pending and re-runs from scratch using the same file and mapping.
Path parameters
- Name
import_id- Type
- string
- Description
The import job UUID.
Request
curl -X POST https://api.pixeepim.com/api/v1/imports/550e8400-e29b-41d4-a716-446655440000/retry \
-H "Authorization: Bearer {api_key}"
Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending"
}
Archive / unarchive
Archive a completed job to hide it from the default list view, or unarchive it to restore visibility. Archived jobs are not deleted.
| Endpoint | Effect |
|---|---|
POST /imports/{import_id}/archive | Archive the job |
POST /imports/{import_id}/unarchive | Restore to active list |
Path parameters
- Name
import_id- Type
- string
- Description
The import job UUID.
Archive request
curl -X POST https://api.pixeepim.com/api/v1/imports/550e8400-e29b-41d4-a716-446655440000/archive \
-H "Authorization: Bearer {api_key}"
Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"is_archived": true
}
Delete a job
Permanently deletes an import job and its associated error records. This action is irreversible.
Path parameters
- Name
import_id- Type
- string
- Description
The import job UUID.
Request
curl -X DELETE https://api.pixeepim.com/api/v1/imports/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer {api_key}"
Response
{
"deleted": true,
"id": "550e8400-e29b-41d4-a716-446655440000"
}
Recent jobs & stats
Two convenience endpoints for dashboards:
| Endpoint | Description |
|---|---|
GET /imports/recent | Last N jobs (default: 10, query param limit) |
GET /imports/stats | Aggregated statistics (total jobs, success rate, rows processed) |
These endpoints return results from the current user's tenant scope.
Recent jobs
curl "https://api.pixeepim.com/api/v1/imports/recent?limit=5" \
-H "Authorization: Bearer {api_key}"
Stats
curl https://api.pixeepim.com/api/v1/imports/stats \
-H "Authorization: Bearer {api_key}"
Stats response
{
"total_jobs": 142,
"completed_jobs": 138,
"failed_jobs": 4,
"total_rows_processed": 1842500,
"total_products_created": 980000,
"total_products_updated": 250000,
"success_rate": 97.2
}
EANs pending resolution
Lists EAN codes encountered during imports that could not be matched to an existing product or supplier record. These are queued for manual resolution or can be bulk-ignored.
Query parameters
- Name
page- Type
- integer
- Description
Page number (default:
1).
- Name
per_page- Type
- integer
- Description
Items per page (default:
20).
- Name
supplier_code- Type
- string
- Description
Filter by originating supplier.
- Name
search- Type
- string
- Description
Search by EAN value or description.
| Endpoint | Description |
|---|---|
GET /imports/ean-pending | List unresolved EANs |
DELETE /imports/ean-pending/{resolution_id} | Ignore a single entry |
POST /imports/ean-pending/bulk-delete | Ignore multiple entries |
Request
curl "https://api.pixeepim.com/api/v1/imports/ean-pending?supplier_code=SUPPLIER_A&per_page=20" \
-H "Authorization: Bearer {api_key}"
Response
{
"items": [
{
"id": "aabb1234-0000-0000-0000-000000000001",
"ean": "3760000000099",
"supplier_code": "SUPPLIER_A",
"description": "Widget Pro 3000",
"first_seen_at": "2026-03-10T08:00:00Z"
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 20,
"total_pages": 1,
"has_next": false,
"has_previous": false
}
}
Bulk ignore
curl -X POST https://api.pixeepim.com/api/v1/imports/ean-pending/bulk-delete \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"ids": [
"aabb1234-0000-0000-0000-000000000001",
"aabb1234-0000-0000-0000-000000000002"
]
}'
Automated imports
Automated import configurations are managed under a separate router: /api/v1/import-configs/. Each config defines a source (FTP, SFTP, email, HTTP URL), a cron schedule, a supplier, and a column mapping. The Celery Beat task check-scheduled-imports runs every 5 minutes and triggers jobs for configs whose next_run_at has passed.
These endpoints use the prefix /api/v1/import-configs/, not /api/v1/imports/automations.
| Endpoint | Description |
|---|---|
GET /import-configs/configs | List all automated configs |
POST /import-configs/configs | Create a new automated config |
Body parameters — create config (JSON)
- Name
name- Type
- string
- Description
Descriptive name for the automation.
- Name
supplier_code- Type
- string
- Description
Supplier code to associate with imported products.
- Name
schedule- Type
- string
- Description
Cron expression (e.g.
0 2 * * *for daily at 2 AM UTC).
- Name
file_source- Type
- object
- Description
Source configuration object. Must include
type(ftp,sftp,email, orhttp) and the relevant connection fields.
- Name
mapping- Type
- object
- Description
Column mapping: file column → product field (e.g.
{"EAN": "ean", "Titre": "title"}).
- Name
is_active- Type
- boolean
- Description
Activate the schedule immediately (default:
true).
List configs
curl https://api.pixeepim.com/api/v1/import-configs/configs \
-H "Authorization: Bearer {api_key}"
Create config
curl -X POST https://api.pixeepim.com/api/v1/import-configs/configs \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"name": "Daily Supplier A SFTP Import",
"supplier_code": "SUPPLIER_A",
"schedule": "0 2 * * *",
"file_source": {
"type": "sftp",
"host": "sftp.supplier.com",
"username": "sftpuser",
"key_file_path": "/keys/supplier_rsa",
"directory_path": "/exports",
"file_pattern": "products_*.csv"
},
"mapping": {
"EAN": "ean",
"Titre": "title",
"Prix HT": "price",
"Marque": "brand_name"
},
"is_active": true
}'
Response
{
"id": "550e8400-e29b-41d4-a716-446655440099",
"name": "Daily Supplier A SFTP Import",
"supplier_code": "SUPPLIER_A",
"schedule": "0 2 * * *",
"is_active": true,
"next_run_at": "2026-03-16T02:00:00Z",
"created_at": "2026-03-15T09:00:00Z"
}