Skip to content

Integration Sync API

The Integration Sync API connects a MicroPIM account to a storefront (for example a Shopify shop) and pushes product data from MicroPIM to it. It is used by storefront connectors that need to create and manage an integration, monitor its health, and push batches of products.

This API is distinct from the core Product API, which is used for reading and writing product data directly against MicroPIM. If you only need to manage products in MicroPIM itself, use the core Product API instead.

MicroPIM syncs product data only — products, variants, SKUs, prices, stock/inventory levels, categories, brands, images, attributes, and SEO fields. MicroPIM does not sync orders or customers, and no endpoint on this page returns or accepts order or customer data.

Core Product APIIntegration Sync API
Auth headerX-API-KEYAuthorization: Bearer <api_token>
Envelope{"status": 1, "data": ..., "error": null}{"status": "success", "message": "...", "data": {...}, "code": "..."}
PurposeRead/write product data directlyConnect a storefront, monitor sync health, push product batches
Reference/reference/rest-api/This page

Most endpoints require a bearer token sent via the Authorization header:

Terminal window
curl -H "Authorization: Bearer a1b2c3d4..." https://app.micropim.net/api/status

The token (api_token) is issued by POST /api/connect and returned as data.api_token. It is an opaque string, not a JWT.

Tokens carry a scope, which maps to a role required by each endpoint:

ScopeRole
readROLE_API_READ
writeROLE_API_WRITE
adminROLE_API_ADMIN

A few endpoints (POST /api/connect, GET /api/status/{integrationId}, GET /api/system/status) are public and require no token.

Requests with a missing or invalid token return 401 Unauthorized.

Most endpoints return an enveloped JSON body:

{
"status": "success",
"message": "Human-readable message",
"data": { },
"code": null
}
  • status is one of "success", "error", or "partial" (used only by products/push when some items in a batch fail).
  • On success, code is typically absent or null.
  • On error, code is a machine-readable string (see Error codes) and data is typically absent.

Two endpoints are an exception and return a raw, non-enveloped JSON object — there is no status/data wrapper:

  • GET /api/status/{integrationId} returns a flat object with fields directly at the top level.
  • GET /api/system/status returns {"status": "operational", "timestamp": "...", "stats": {...}} (here status is a plain health string, not the envelope’s success/error/partial status).

Keep this inconsistency in mind when parsing responses — check which endpoint you called before assuming the envelope shape.

Timestamps also differ in format by endpoint:

  • Y-m-d H:i:s (e.g. "2026-07-16 10:30:00") — used by connect, status, integration/update, disconnect, products/mappings, products/mapping.
  • ISO-8601 (c) (e.g. "2026-07-16T10:30:00+00:00") — used by status/{integrationId} and system/status.

Rate limiting is enforced at authentication time and keyed by client IP. When the limit is exceeded, the request fails authentication with 401 Unauthorized and this enveloped body:

{
"status": "error",
"message": "Rate limit exceeded. Please try again later.",
"code": "AUTHENTICATION_FAILED"
}

The rate-limit-exceeded response (and other authentication failures) carries the current bucket state in response headers:

X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1752657600

Note that these headers are attached to the 401 authentication-failure response — they are not returned on successful requests. Rate limiting is surfaced as an authentication failure with code AUTHENTICATION_FAILED, not a dedicated rate-limit code or a 429 status.

POST /api/products/push accepts at most 50 products per request. Sending more returns BATCH_SIZE_EXCEEDED.

CodeHTTPMeaningWhere
AUTHENTICATION_FAILED401Missing/invalid token, or the IP rate limit was exceededany authenticated endpoint
INVALID_JSON400Request body is not valid JSONconnect, integration/update, products/push
MISSING_FIELD400A required field is missingconnect
SHOP_NOT_FOUND404The shop must already exist (app installed) before connectingconnect
INTEGRATION_EXISTS409An integration already exists for this shopconnect
VALIDATION_FAILED400 (connect) / 503 (integration/update)Field validation failed, or credentials could not be validated against MicroPIMconnect, integration/update
INVALID_CREDENTIALS401MicroPIM credentials are invalidconnect, integration/update
CONNECTION_FAILED503Could not reach MicroPIM to validate credentialsconnect
NO_UPDATES400No updatable fields were providedintegration/update
NO_PRODUCTS400No product data was providedproducts/push
BATCH_SIZE_EXCEEDED400More than 50 products were submittedproducts/push
MAPPING_NOT_FOUND404No product mapping exists for the given MicroPIM product idproducts/mapping/{id}
INTERNAL_ERROR500Unexpected server errorall endpoints
StatusMeaning
200Success
207Partial success (some items in a batch failed)
400Bad request (validation, malformed JSON, batch too large)
401Missing/invalid token, invalid credentials, or rate limit exceeded
404Resource not found
409Conflict (integration already exists)
500Internal server error
503Could not validate credentials against MicroPIM

POST /api/connect

Public — no token required.

Creates a new integration linking a shop to a MicroPIM account. Credentials are validated live against MicroPIM before the integration is created.

Body parameters (all required):

ParameterTypeDescription
shop_domainstringDomain of the shop to connect
micropim_base_urlstringBase URL of the MicroPIM instance
micropim_api_keystringMicroPIM API key
micropim_api_secretstringMicroPIM API secret

Example request:

Terminal window
curl -X POST https://app.micropim.net/api/connect \
-H "Content-Type: application/json" \
-d '{
"shop_domain": "example-shop.myshopify.com",
"micropim_base_url": "https://demo.micropim.net",
"micropim_api_key": "mp_key_123",
"micropim_api_secret": "mp_secret_456"
}'

Example response:

{
"status": "success",
"message": "Integration created successfully",
"data": {
"integration_id": 42,
"shop_domain": "example-shop.myshopify.com",
"api_token": "a1b2c3d4...",
"created_at": "2026-07-16 10:30:00"
}
}

Error codes: INVALID_JSON(400), MISSING_FIELD(400), SHOP_NOT_FOUND(404), INTEGRATION_EXISTS(409), VALIDATION_FAILED(400), INVALID_CREDENTIALS(401), CONNECTION_FAILED(503), INTERNAL_ERROR(500)

Notes:

  • The shop must already exist (the app must be installed) or you’ll get SHOP_NOT_FOUND.
  • Credentials are live-validated against MicroPIM before the integration is created.
  • Save data.api_token — it’s required for all authenticated endpoints below.
PUT /api/integration/update

Requires token with ROLE_API_ADMIN.

Updates one or more MicroPIM connection fields on an existing integration. Credentials are revalidated against MicroPIM when changed.

Body parameters (optional, at least one required):

ParameterTypeDescription
micropim_base_urlstringNew MicroPIM base URL
micropim_api_keystringNew MicroPIM API key
micropim_api_secretstringNew MicroPIM API secret

Example request:

Terminal window
curl -X PUT https://app.micropim.net/api/integration/update \
-H "Authorization: Bearer a1b2c3d4..." \
-H "Content-Type: application/json" \
-d '{"micropim_api_key": "mp_key_789"}'

Example response:

{
"status": "success",
"message": "Integration updated successfully",
"data": {
"integration_id": 42,
"updated_at": "2026-07-16 10:45:00"
}
}

Error codes: INVALID_JSON(400), NO_UPDATES(400), INVALID_CREDENTIALS(401), VALIDATION_FAILED(503), INTERNAL_ERROR(500)

Notes:

  • Requires an admin-scope (ROLE_API_ADMIN) token.
  • At least one field must be provided or you’ll get NO_UPDATES.
  • Only the changed connection fields need to be sent.
POST /api/disconnect

Requires token with ROLE_API_ADMIN. No request body.

Deactivates the integration and revokes all of its API tokens.

Example request:

Terminal window
curl -X POST https://app.micropim.net/api/disconnect \
-H "Authorization: Bearer a1b2c3d4..."

Example response:

{
"status": "success",
"message": "Integration disconnected successfully",
"data": {
"integration_id": 42,
"status": "inactive",
"disconnected_at": "2026-07-16 11:00:00"
}
}

Error codes: INTERNAL_ERROR(500)

Notes:

  • After calling this, the token you used is revoked and can no longer authenticate.
  • To reconnect, call POST /api/connect again to obtain a new token.

GET /api/status

Requires a token with any authenticated role.

Returns a detailed health snapshot for the caller’s own integration, including recent sync activity, connectivity checks, and a health score.

Example request:

Terminal window
curl https://app.micropim.net/api/status \
-H "Authorization: Bearer a1b2c3d4..."

Example response:

{
"status": "success",
"data": {
"integration_id": 42,
"shop_domain": "example-shop.myshopify.com",
"micropim_base_url": "https://demo.micropim.net",
"status": "active",
"is_active": true,
"created_at": "2026-07-16 10:30:00",
"last_sync_at": "2026-07-16 12:00:00",
"updated_at": "2026-07-16 11:45:00",
"product_mapping_stats": {
"synced": 120,
"pending": 4,
"error": 1
},
"recent_syncs": [
{
"id": 501,
"operation": "products.push",
"status": "success",
"records_processed": 25,
"records_failed": 0,
"duration": "1.24s",
"started_at": "2026-07-16 12:00:00",
"completed_at": "2026-07-16 12:00:01"
}
],
"micropim_status": {
"status": "connected"
},
"shopify_status": {
"status": "connected",
"shop_name": "Example Shop",
"shop_id": "gid://shopify/Shop/987654321",
"plan": "advanced"
},
"active_tokens": 1,
"queue_stats": {
"pending_messages": 0,
"processing_messages": 0,
"failed_messages": 0,
"note": "Queue stats require message broker integration"
},
"health_score": {
"score": 96,
"status": "excellent",
"factors": ["all_syncs_recent", "no_recent_failures"]
}
}
}

Error codes: INTERNAL_ERROR(500)

Notes:

  • product_mapping_stats groups product mapping counts by sync status; exact keys can vary as new statuses are introduced.
  • micropim_status and shopify_status report {"status": "error", "error": "Unable to connect to MicroPIM"} (or "Unable to connect to Shopify") when the corresponding system can’t be reached.
  • health_score.status is one of "excellent", "good", "fair", or "poor".
GET /api/status/{integrationId}

Public — no token required.

Returns a lightweight, raw (non-enveloped) status object for any integration by ID. Useful for public health checks (e.g. status badges) without exposing a token.

Path parameterTypeDescription
integrationIdintegerThe integration’s numeric ID

Example request:

Terminal window
curl https://app.micropim.net/api/status/42

Example response:

{
"integration_id": 42,
"shop_domain": "example-shop.myshopify.com",
"is_active": true,
"is_connected": true,
"last_error": null,
"created_at": "2026-07-16T10:30:00+00:00",
"last_sync_at": "2026-07-16T12:00:00+00:00",
"sync_stats": {
"last_24h": {
"total_syncs": 8,
"successful_syncs": 8,
"failed_syncs": 0
},
"product_mappings": {
"total": 125,
"synced": 120,
"pending": 4,
"failed": 1
}
},
"queue_stats": {
"pending_messages": 0,
"processing_messages": 0,
"failed_messages": 0,
"note": "Queue stats require message broker integration"
},
"health_score": {
"score": 96,
"status": "excellent",
"factors": ["all_syncs_recent", "no_recent_failures"]
}
}

Error codes: integration not found → {"error": "Integration not found"} (404); check failed → {"error": "Status check failed"} (500)

Notes:

  • This response is not wrapped in the status/data envelope used elsewhere on this page.
  • Timestamps here use ISO-8601 (c), unlike most other endpoints on this page.
GET /api/system/status

Public — no token required.

Reports overall system operational status, independent of any single integration.

Example request:

Terminal window
curl https://app.micropim.net/api/system/status

Example response:

{
"status": "operational",
"timestamp": "2026-07-16T12:05:00+00:00",
"stats": {
"total_integrations": 340,
"active_integrations": 312,
"recent_syncs": {
"total_syncs_24h": 4820,
"successful_syncs_24h": 4790,
"failed_syncs_24h": 30
},
"system_health": {
"database": "healthy",
"php_version": "8.3.9",
"memory_usage": "128MB",
"memory_peak": "192MB"
}
}
}

Error codes: {"status": "error", "timestamp": "...", "error": "System status check failed"} (500)

Notes:

  • This response is not wrapped in the status/data envelope; status here means overall system health, not request success.
  • system_health.database is "healthy" or "unhealthy".

POST /api/products/push

Requires token with ROLE_API_WRITE.

Pushes one or more products from MicroPIM to the connected storefront. Only product data is sent — products, variants, SKUs, prices, stock, images, and categories. Orders and customers are never included, since MicroPIM does not sync them.

Body:

Either a single product object, or a batch:

FieldTypeDescription
idintegerRequired on each product object — the MicroPIM product ID
productsarrayOptional wrapper for pushing a batch; max 50 items

Example request (batch):

Terminal window
curl -X POST https://app.micropim.net/api/products/push \
-H "Authorization: Bearer a1b2c3d4..." \
-H "Content-Type: application/json" \
-d '{
"products": [
{"id": 1001},
{"id": 1002}
]
}'

Example response (all succeeded, HTTP 200):

{
"status": "success",
"message": "Processed 2 products: 2 successful, 0 failed",
"data": {
"sync_log_id": 501,
"total_products": 2,
"successful_count": 2,
"failed_count": 0,
"results": [
{
"status": "success",
"message": "Product created",
"micropim_product_id": 1001,
"shopify_product_id": 555001,
"shopify_handle": "product-1001",
"method": "create"
},
{
"status": "success",
"message": "Product updated",
"micropim_product_id": 1002,
"shopify_product_id": 555002,
"shopify_handle": "product-1002",
"method": "update"
}
]
}
}

Example response (partial failure, HTTP 207):

{
"status": "partial",
"message": "Processed 2 products: 1 successful, 1 failed",
"data": {
"sync_log_id": 502,
"total_products": 2,
"successful_count": 1,
"failed_count": 1,
"results": [
{
"status": "success",
"message": "Product updated",
"micropim_product_id": 1001,
"shopify_product_id": 555001,
"shopify_handle": "product-1001",
"method": "update"
},
{
"status": "error",
"message": "Validation failed",
"micropim_product_id": 1003,
"shopify_product_id": null,
"validation_errors": ["price is required"]
}
]
}
}

Error codes: INVALID_JSON(400), NO_PRODUCTS(400), BATCH_SIZE_EXCEEDED(400), INTERNAL_ERROR(500)

Notes:

  • HTTP is 200 when every product succeeds (status: "success"), and 207 when at least one fails (status: "partial"); the partial response has no top-level code.
  • Only product data is pushed — products, variants, SKUs, prices, stock, images, and categories. Never orders or customers.
  • Requests with more than 50 products return BATCH_SIZE_EXCEEDED.
GET /api/products/mappings

Requires token with ROLE_API_READ.

Lists the mappings between MicroPIM products and their corresponding storefront products, with pagination.

Query parameters:

ParameterTypeDescription
limitintegerItems per page, 1-100 (default: 20)
offsetintegerOffset for pagination (default: 0)
statusstringFilter by sync status: pending, synced, error

Example request:

Terminal window
curl "https://app.micropim.net/api/products/mappings?limit=20&offset=0&status=synced" \
-H "Authorization: Bearer a1b2c3d4..."

Example response:

{
"status": "success",
"data": {
"mappings": [
{
"id": 1,
"micropim_product_id": 1001,
"shopify_product_id": 555001,
"shopify_variant_id": 660001,
"sync_status": "synced",
"sync_error": null,
"last_synced_at": "2026-07-16 12:00:00",
"created_at": "2026-07-16 10:35:00",
"updated_at": "2026-07-16 12:00:00"
}
],
"pagination": {
"total": 125,
"limit": 20,
"offset": 0,
"has_more": true
}
}
}

Error codes: INTERNAL_ERROR(500)

Notes:

  • sync_status values line up with the status query filter: pending, synced, error.
  • Use pagination.has_more with offset/limit to page through results.
GET /api/products/mapping/{microPimProductId}

Requires token with ROLE_API_READ.

Returns the mapping and extra metadata for a single MicroPIM product.

Path parameterTypeDescription
microPimProductIdstringThe MicroPIM product ID

Example request:

Terminal window
curl https://app.micropim.net/api/products/mapping/1001 \
-H "Authorization: Bearer a1b2c3d4..."

Example response:

{
"status": "success",
"data": {
"id": 1,
"micropim_product_id": 1001,
"shopify_product_id": 555001,
"shopify_variant_id": 660001,
"sync_status": "synced",
"sync_error": null,
"last_synced_at": "2026-07-16 12:00:00",
"created_at": "2026-07-16 10:35:00",
"updated_at": "2026-07-16 12:00:00",
"metadata": {
"shopify_handle": "product-1001",
"shopify_title": "Product 1001",
"variant_count": 3,
"image_count": 5,
"last_push_method": "update"
}
}
}

Error codes: MAPPING_NOT_FOUND(404), INTERNAL_ERROR(500)

Notes:

  • metadata fields describe the storefront-side product and are supplementary — the canonical product data still lives in MicroPIM.
  • If no mapping exists yet for the given ID, this returns MAPPING_NOT_FOUND.

Building a custom integration?

Talk to our technical team about authentication, rate limits, or custom endpoints.