Skip to main content

Endpoints

POST /api/hub/subscriptions/{subscriptionId}/sync/apply
GET  /api/hub/subscriptions/{subscriptionId}/conflicts
PUT  /api/hub/subscriptions/{subscriptionId}/conflicts/{conflictId}
Manage the sync lifecycle for Hub subscriptions: apply pending publisher updates to your local catalog, list field-level conflicts, and resolve them individually.

Path parameters

ParameterTypeRequiredDescription
subscriptionIdstringYesYour subscription ID (from subscribe response)
conflictIdstringYesConflict ID (from list conflicts response)

Apply pending updates

POST /api/hub/subscriptions/{subscriptionId}/sync/apply Applies pending publisher version updates to your local catalog. For subscriptions with syncStrategy: "auto", this happens automatically. For "manual" subscriptions, call this endpoint when you’re ready to sync.

Request body

{
  "targetVersion": 7
}
FieldTypeRequiredDescription
targetVersionnumberNoSpecific version to sync to. Defaults to latest published version

Response

{
  "applied": true,
  "fromVersion": 5,
  "toVersion": 7,
  "productsUpdated": 34,
  "productsAdded": 12,
  "productsRemoved": 3,
  "conflictsCreated": 5,
  "duration_ms": 2100
}

Apply sync examples

# Apply latest publisher updates
curl -X POST "https://app.alana.shopping/api/hub/subscriptions/sub_4k2n8x/sync/apply" \
  -H "Authorization: Bearer sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'

# Apply a specific version
curl -X POST "https://app.alana.shopping/api/hub/subscriptions/sub_4k2n8x/sync/apply" \
  -H "Authorization: Bearer sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"targetVersion": 7}'

List conflicts

GET /api/hub/subscriptions/{subscriptionId}/conflicts Returns all unresolved conflicts for a subscription — fields where your local edits differ from the publisher’s new value.

Response

{
  "conflicts": [
    {
      "id": "conflict_9a3b",
      "productId": "prod_local_789",
      "field": "description",
      "localValue": "Our hand-curated description of this premium blazer...",
      "remoteValue": "Classic linen blazer in sky blue. Machine washable. Available in S-XL.",
      "publisherVersion": 7,
      "createdAt": "2026-03-17T11:00:00Z",
      "status": "pending"
    },
    {
      "id": "conflict_7c1d",
      "productId": "prod_local_456",
      "field": "price",
      "localValue": 89.99,
      "remoteValue": 94.99,
      "publisherVersion": 7,
      "createdAt": "2026-03-17T11:00:00Z",
      "status": "pending"
    }
  ],
  "total": 2
}

Conflict fields

FieldTypeDescription
idstringConflict ID
productIdstringLocal product ID with the conflict
fieldstringField name where the conflict exists
localValueanyYour current local value
remoteValueanyPublisher’s new value
publisherVersionnumberPublisher version that introduced this change
createdAtstringWhen the conflict was created
statusstring"pending", "resolved_local", "resolved_remote", "resolved_merged"

List conflicts examples

curl "https://app.alana.shopping/api/hub/subscriptions/sub_4k2n8x/conflicts" \
  -H "Authorization: Bearer sk_live_your_api_key_here"

Resolve a conflict

PUT /api/hub/subscriptions/{subscriptionId}/conflicts/{conflictId} Resolves a single field conflict by choosing local, remote, or a custom merged value.

Request body

{
  "resolution": "keep_local"
}
Or with a custom merged value:
{
  "resolution": "merge",
  "mergedData": "Classic sky blue linen blazer — our premium pick. Machine washable. Available in S-XL."
}
FieldTypeRequiredDescription
resolutionstringYes"keep_local", "accept_remote", or "merge"
mergedDataanyNoCustom merged value (required when resolution is "merge")

Response

{
  "conflictId": "conflict_9a3b",
  "status": "resolved_local",
  "resolvedAt": "2026-03-17T11:30:00Z",
  "resolvedBy": "user_abc"
}

Resolve conflict examples

# Keep your local value
curl -X PUT "https://app.alana.shopping/api/hub/subscriptions/sub_4k2n8x/conflicts/conflict_9a3b" \
  -H "Authorization: Bearer sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"resolution": "keep_local"}'

# Accept the publisher's value
curl -X PUT "https://app.alana.shopping/api/hub/subscriptions/sub_4k2n8x/conflicts/conflict_7c1d" \
  -H "Authorization: Bearer sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"resolution": "accept_remote"}'

# Use a custom merged value
curl -X PUT "https://app.alana.shopping/api/hub/subscriptions/sub_4k2n8x/conflicts/conflict_9a3b" \
  -H "Authorization: Bearer sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "resolution": "merge",
    "mergedData": "Classic sky blue linen blazer — our premium pick."
  }'

Conflict workflow


Error responses

HTTP statusCodeDescription
403INSUFFICIENT_PERMISSIONSNot your subscription
404SUBSCRIPTION_NOT_FOUNDSubscription ID not found
404CONFLICT_NOT_FOUNDConflict ID not found or already resolved
409SYNC_ALREADY_RUNNINGA sync is already in progress
422NO_PENDING_UPDATESAlready on the latest version (apply only)
422MERGE_DATA_REQUIREDmergedData is required when resolution is "merge"
Last modified on March 18, 2026