Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/VisualGraphxLLC/API-HUB/llms.txt

Use this file to discover all available pages before exploring further.

Triggering an import kicks off a background job that runs the supplier’s adapter — discovering product references, hydrating each product’s full data, normalizing it into the hub’s canonical schema, and upserting everything into PostgreSQL. The endpoint accepts the request immediately and returns a sync_job_id to poll for progress.

Trigger an import

curl -X POST https://your-hub.example.com/api/suppliers/sanmar/import \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "first_n",
    "limit": 50
  }'
supplier_id
string (UUID)
required
UUID of the supplier. Slugs are not accepted on this endpoint — use the UUID.
Request body
mode
string
default:"first_n"
required
Discovery mode. Controls which products the adapter fetches:
ModeBehavior
first_nFetch the first limit products from the supplier’s catalog. Use for testing.
deltaFetch only products changed since the last last_delta_sync or last_full_sync timestamp. Falls back to 2000-01-01 if no prior sync exists.
full_sellableFetch the complete sellable catalog. May take hours for large suppliers. Used by the weekly cron.
explicit_listFetch specific products by supplier SKU. Requires explicit_list to be provided.
closeoutsFetch products marked as closeout by the supplier. Used by the monthly cron.
limit
integer
default:"20"
Maximum number of products to fetch. Only used by first_n mode. Accepted range: 1–10000.
explicit_list
string[]
List of supplier SKUs to import. Required when mode is explicit_list.
Response — 202 Accepted
sync_job_id
string (UUID)
ID of the created sync job. Use this to poll GET /api/sync-jobs/{id} for status.
supplier_id
string (UUID)
Echoes the supplier UUID from the path.
mode
string
Discovery mode that was accepted.
accepted_at
string (ISO 8601)
UTC timestamp when the job was accepted. The actual import starts asynchronously.
{
  "sync_job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "supplier_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "mode": "first_n",
  "accepted_at": "2026-05-07T14:30:00.123456+00:00"
}
Error responses
StatusDetail
404 Not FoundSupplier not found
409 Conflict"supplier 'SanMar' has no adapter_class set; configure one before importing"adapter_class is null
409 Conflict"import already running for supplier 'SanMar' mode 'first_n' (job ...)" — a pending or running job already exists for this supplier + mode combination
422 Unprocessable Entitymode=explicit_list with no explicit_list provided
Only one import per supplier + mode combination can run at a time. Starting a delta import while full_sellable is running is allowed — they are different modes. Starting two delta imports for the same supplier will return 409.

List sync jobs for a supplier

Returns recent sync jobs for a specific supplier, ordered by started_at descending.
curl "https://your-hub.example.com/api/suppliers/sanmar/sync-jobs?limit=20"
supplier_id
string (UUID)
required
UUID of the supplier.
limit
integer
default:"50"
Maximum number of jobs to return.
Response — 200 OK — array of SyncJobRead
[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "supplier_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "supplier_name": "SanMar",
    "job_type": "import:first_n",
    "status": "success",
    "started_at": "2026-05-07T14:30:00Z",
    "completed_at": "2026-05-07T14:35:42Z",
    "total_products": 50,
    "success_count": 49,
    "failed_count": 1,
    "records_processed": 50,
    "error_log": null,
    "errors": null,
    "discovery_mode": "first_n"
  }
]
id
string (UUID)
Unique job identifier.
job_type
string
Format: import:{mode} — e.g., import:first_n, import:delta, import:full_sellable.
status
string
Job lifecycle status: pending, running, success, partial_success, or failed.
total_products
integer
Total products discovered by the adapter’s discover() call.
success_count
integer
Products successfully normalized and upserted.
failed_count
integer
Products that errored during hydration or normalization.
records_processed
integer
Running count updated during the import. Equal to success_count + failed_count when complete.
errors
array | null
JSONB array of per-product error details. Populated when individual products fail.
discovery_mode
string | null
The discovery mode string echoed from the import request.

Polling pattern

After triggering an import, poll the global sync-job endpoint until the status reaches a terminal state:
# 1. Trigger import
RESPONSE=$(curl -s -X POST https://your-hub.example.com/api/suppliers/sanmar/import \
  -H "Content-Type: application/json" \
  -d '{"mode": "delta"}')

JOB_ID=$(echo $RESPONSE | jq -r '.sync_job_id')

# 2. Poll until terminal
while true; do
  STATUS=$(curl -s https://your-hub.example.com/api/sync-jobs/$JOB_ID | jq -r '.status')
  echo "Status: $STATUS"
  case $STATUS in
    success|partial_success|failed) break ;;
    *) sleep 10 ;;
  esac
done
Terminal statuses are success, partial_success, and failed. The n8n cron workflows use this same pattern internally.

Build docs developers (and LLMs) love