Skip to main content
The bulk operations system lets you move large volumes of product data in and out of Synq without writing per-record API loops. A bulk job is a named, asynchronous task — identified by a job_type string — that accepts a JSON payload describing the work to be done (e.g., a list of products to import or a set of updates to apply). Jobs are created synchronously but processed asynchronously; poll the list endpoint to track their status. The export endpoint queues an asynchronous catalog export to Cloud Storage. The validation endpoint surfaces unresolved data quality issues flagged by the system against your products.
All requests require the standard headers: Authorization: Bearer <token>, X-Tenant-ID, and X-Org-ID.

Bulk jobs

Bulk import workflow

1

Prepare your payload

Structure your product data as a JSON array. Each item should contain at minimum a title. Include sku, description, category, and brand fields for better catalog quality scores.
{
  "job_type": "BULK_IMPORT",
  "payload": [
    {
      "title": "Merino Wool Crew Neck Sweater",
      "description": "100% Grade-A merino wool.",
      "category": "Knitwear",
      "brand": "NordicThread"
    },
    {
      "title": "Classic Oxford Button-Down",
      "description": "Egyptian cotton, slim fit.",
      "category": "Shirts",
      "brand": "HarbourLine"
    }
  ]
}
2

Create the bulk job

POST your payload to the bulk jobs endpoint. The API validates that payload is valid JSON, creates the job with status PENDING, and returns the job record immediately.
curl -X POST https://api.synq.com/api/v1/pim/bulk-jobs \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "X-Org-ID: $ORG_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "job_type": "BULK_IMPORT",
    "payload": [
      { "title": "Merino Wool Crew Neck Sweater", "category": "Knitwear" },
      { "title": "Classic Oxford Button-Down", "category": "Shirts" }
    ]
  }'
3

Store the job ID

From the response, save the id field. You need it to poll for status.
{
  "id": "c1d2e3f4-0001-5a6b-7c8d-9e0f1a2b3c4d",
  "job_type": "BULK_IMPORT",
  "status": "PENDING",
  "total_items": null,
  "processed_items": null,
  "created_at": "2024-11-15T14:00:00Z"
}
4

Poll for completion

List bulk jobs filtered by type=BULK_IMPORT and check the status and processed_items fields. Poll at a reasonable interval (every 5–30 seconds depending on job size).
curl "https://api.synq.com/api/v1/pim/bulk-jobs?type=BULK_IMPORT" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "X-Org-ID: $ORG_ID"
5

Handle completion or failure

When status reaches COMPLETED, all items have been processed. If status is FAILED, check validation issues at GET /api/v1/pim/validation to identify which records caused errors.

Create a bulk job

POST /api/v1/pim/bulk-jobs
Request body
job_type
string
required
The type of operation to perform. Supported values: BULK_IMPORT, BULK_UPDATE, BULK_DELETE.
payload
array | object
required
A valid JSON structure describing the work. For imports and updates, pass an array of product objects. For deletions, pass an array of product IDs. The value must be valid JSON.
curl -X POST https://api.synq.com/api/v1/pim/bulk-jobs \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "X-Org-ID: $ORG_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "job_type": "BULK_IMPORT",
    "payload": [
      { "title": "Merino Wool Sweater", "category": "Knitwear" },
      { "title": "Linen Shirt", "category": "Shirts" }
    ]
  }'
Response 200 OK
{
  "id": "c1d2e3f4-0001-5a6b-7c8d-9e0f1a2b3c4d",
  "org_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tenant_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
  "job_type": "BULK_IMPORT",
  "status": "PENDING",
  "payload_json": "[{\"title\":\"Merino Wool Sweater\",...}]",
  "total_items": null,
  "processed_items": null,
  "created_by": "d1e2f3a4-b5c6-7890-abcd-ef1234567890",
  "created_at": "2024-11-15T14:00:00Z",
  "updated_at": "2024-11-15T14:00:00Z"
}
status
string
Initial status is always PENDING. Transitions to PROCESSING, then COMPLETED or FAILED.
payload_json
string
The submitted payload stored as a JSON string. This is the raw content you sent in the payload field of the request.
total_items
integer | null
Total number of records in the job. Populated once the job starts processing.
processed_items
integer | null
Number of records successfully processed so far. Use alongside total_items to calculate progress percentage.

List bulk jobs

Retrieve bulk jobs filtered by type, ordered by most recently created first.
GET /api/v1/pim/bulk-jobs
Query parameters
type
string
Filter by job_type. Defaults to BULK_UPDATE if omitted. Pass BULK_IMPORT or BULK_DELETE as needed.
curl "https://api.synq.com/api/v1/pim/bulk-jobs?type=BULK_IMPORT" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "X-Org-ID: $ORG_ID"
Response 200 OK
[
  {
    "id": "c1d2e3f4-0001-5a6b-7c8d-9e0f1a2b3c4d",
    "org_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "tenant_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
    "job_type": "BULK_IMPORT",
    "status": "COMPLETED",
    "total_items": 250,
    "processed_items": 250,
    "created_at": "2024-11-15T14:00:00Z",
    "updated_at": "2024-11-15T14:03:42Z"
  },
  {
    "id": "c1d2e3f4-0002-5a6b-7c8d-9e0f1a2b3c4d",
    "org_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "tenant_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
    "job_type": "BULK_IMPORT",
    "status": "FAILED",
    "total_items": 50,
    "processed_items": 47,
    "created_at": "2024-11-14T09:00:00Z",
    "updated_at": "2024-11-14T09:01:10Z"
  }
]

Export products

Queue an asynchronous export of your entire product catalog. When the export completes, the file is placed in Cloud Storage and you are notified (via webhook or email, depending on your tenant configuration).
POST /api/v1/pim/export
curl -X POST https://api.synq.com/api/v1/pim/export \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "X-Org-ID: $ORG_ID"
Response 202 Accepted
{
  "status": "success",
  "message": "Export job queued. You will be notified when the file is ready in Cloud Storage."
}
The export endpoint returns 202 Accepted immediately — the actual file generation happens asynchronously. Do not poll this endpoint; wait for the delivery notification instead.

Validation issues

Synq continuously evaluates your catalog against data quality rules — missing descriptions, duplicate SKUs, invalid barcodes, low data quality scores — and records each finding as a validation issue. Use this endpoint to retrieve all unresolved issues for your tenant so your team can triage and fix them.
GET /api/v1/pim/validation
curl https://api.synq.com/api/v1/pim/validation \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "X-Org-ID: $ORG_ID"
Response 200 OK
[
  {
    "id": "v1d2e3f4-0001-5a6b-7c8d-9e0f1a2b3c4d",
    "org_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "tenant_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
    "product_id": "018e7c3a-1f2b-7d4e-9a0c-3f5b6e7d8c90",
    "issue_type": "MISSING_DESCRIPTION",
    "severity": "WARNING",
    "message": "Product has no description. Add one to improve SEO and customer experience.",
    "resolved": false,
    "created_at": "2024-11-15T08:00:00Z",
    "updated_at": "2024-11-15T08:00:00Z"
  },
  {
    "id": "v1d2e3f4-0002-5a6b-7c8d-9e0f1a2b3c4d",
    "org_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "tenant_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
    "product_id": "029f8d4b-3c4d-5e6f-a1b2-c3d4e5f6a7b8",
    "issue_type": "DUPLICATE_SKU",
    "severity": "ERROR",
    "message": "SKU 'MWS-RED-S' is used by more than one variant in this tenant.",
    "resolved": false,
    "created_at": "2024-11-15T08:01:00Z",
    "updated_at": "2024-11-15T08:01:00Z"
  }
]
issue_type
string
Machine-readable code identifying the class of issue (e.g., MISSING_DESCRIPTION, DUPLICATE_SKU, INVALID_BARCODE).
severity
string
Either WARNING (catalog quality degradation) or ERROR (blocks publishing or export).
resolved
boolean
The endpoint returns only issues where resolved = false. Once your team fixes the underlying data, the issue is automatically resolved and disappears from this list.
ERROR-severity issues may block products from being included in exports or published to sales channels. Resolve all ERROR issues before triggering an export job.

PIM audit log

Synq records every create, update, and delete operation performed on PIM resources as an immutable audit event. Retrieve the most recent 100 events for your tenant to track who changed what and when.
GET /api/v1/pim/audit
curl https://api.synq.com/api/v1/pim/audit \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "X-Org-ID: $ORG_ID"
Response 200 OK
[
  {
    "id": "e1d2f3a4-0001-5b6c-7d8e-9f0a1b2c3d4e",
    "org_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "tenant_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
    "actor_email": "alice@example.com",
    "action": "product.created",
    "entity_type": "product",
    "entity_id": "018e7c3a-1f2b-7d4e-9a0c-3f5b6e7d8c90",
    "details": {},
    "ip_address": "203.0.113.42",
    "created_at": "2024-11-15T10:00:00Z"
  }
]
actor_email
string
Email address of the user who performed the action.
action
string
Description of the operation performed (e.g., product.created, variant.updated).
entity_type
string
The type of resource that was affected (e.g., product, variant, brand).
entity_id
string
UUID of the specific resource that was affected.