Listings

Resolve conflict

Pick the side that wins, local or marketplace.

POST
/v1/listings/{listingId}/conflicts/{conflictId}/resolve

Picks the side that wins in an open conflict. It only changes the local desired: resolving never publishes. No Job is created and nothing goes to the marketplace. To send it, publish afterwards.

curl -X POST "$BACKEND_URL/v1/listings/<listingId>/conflicts/<conflictId>/resolve" \
  -H "Authorization: Bearer mk_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"resolution":"manual","value":{"priceInCents":479900}}'

The response is the conflict, with status: "resolved".

The four resolutions

resolutionWhat it does to desiredAfterwards
keep_localNothing: your value stays.The group stays pending_publication.
accept_externalEach conflicting path takes the value the marketplace has.The group goes back to in_sync. Nothing to publish.
inheritRemoves your override of each path. The field inherits again (in content, from Variant and Product).It becomes dirty: publish for the marketplace to follow.
manualEach path takes what you send in value.It becomes dirty: publish.

dirty applies to the Listing (group offer) or to the MarketplaceProduct (group content).

value is required with manual and not accepted with the others. Its keys are exactly the paths of the conflict (priceInCents, or attributes.<key> in content).

In all of them, the outside change now counts as seen: the diff stops treating it as new.

Watch out

  • inherit on the price gives 400: the price has nothing to inherit from. The result must stay valid for the group.
  • Resolving content changes the MarketplaceProduct, and applies to all of its offers.
  • Events: listing.conflict_resolved. When desired changes, listing.updated (offer) or marketplace_product.updated (content) also arrives.
  • Resolving again gives 409 CONFLICT with details.reason: "conflict_not_open". A conflict of another offer or another account gives 404.

Authorization

api_key
headerAuthorizationBearer <token>

API key (mk_...)

Path Parameters

listingId*string

The listing the conflict is on.

Match^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
Formatuuid
conflictId*string

The conflict to resolve.

Match^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
Formatuuid

Header Parameters

Idempotency-Key?string

Optional. A unique value (for example a UUID), 1 to 255 characters, that makes the request safe to retry: repeating it with the same body within 24h returns the original response with Idempotency-Replayed: true instead of running the operation again. Scoped to your account. Reusing it with a different body returns 409.

Length1 <= length <= 255

Request Body

application/json
  1. body

How to resolve a conflict. It changes only the local desired data: it never publishes and never creates a Job.

resolution*string

How to resolve it. keep_local: your value stays, and the offer waits to be published. accept_external: the marketplace value of each conflicting path becomes your local value. inherit: your override of each conflicting path goes away and the field inherits again. manual: you send the value in value. None of them publishes.

Value in"keep_local""accept_external""inherit""manual"
value?

The new local value of each conflicting path, by path. Required, and not empty, with manual; refused with any other resolution.

Response Body

The conflict, now resolved.

application/json
  1. response

A group that changed on the marketplace while it had local changes not yet published. Your local value is kept until you resolve it.

id*string

Identifier of the conflict.

Match^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
Formatuuid
listingId*string

The listing the conflict is on.

Match^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
Formatuuid
group*string

The group that changed on both sides. content belongs to the marketplace product this offer sells; offer belongs to the listing itself.

Value in"content""offer"
paths*array<string>

Paths inside the group where your value and the marketplace value differ: the top-level keys of the value and, in content, attributes.<key>.

desired*unknown

Snapshot of your value of the group when the conflict was detected. It does not follow later local edits.

observed*unknown

Snapshot of the marketplace value of the group. While the conflict is open it follows new external changes on the same group.

status*string

open: waiting for a resolution. resolved: closed by POST …/resolve.

Value in"open""resolved"
resolution*|

How it was resolved: keep_local, accept_external, inherit or manual. null while it is open.

Value in"keep_local""accept_external""inherit""manual"null
resolvedValue*|

The values written to the local desired, by path, for accept_external and manual. null for keep_local and inherit, which write none, and while it is open.

source*string

What detected it. inbound: a marketplace notification. reconciliation: the periodic reconciliation. refresh: a read you asked for. local_edit: your own change to a group the marketplace had already changed.

Value in"inbound""reconciliation""refresh""local_edit"
detectedAt*string

When the conflict was detected, in ISO-8601 (UTC).

Match^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
Formatdate-time
resolvedAt*|

When it was resolved, in ISO-8601 (UTC). null while it is open.

Match^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
Formatdate-time
curl -X POST "https://example.com/v1/listings/0e2ce906-a6ab-4101-9461-4168c8b6b902/conflicts/9d2f4b6a-1c3e-4a58-b7d9-e0f1a2b3c4d5/resolve" \  -H "Content-Type: application/json" \  -d '{    "resolution": "manual",    "value": {      "priceInCents": 479900    }  }'
{  "id": "9d2f4b6a-1c3e-4a58-b7d9-e0f1a2b3c4d5",  "listingId": "0e2ce906-a6ab-4101-9461-4168c8b6b902",  "group": "offer",  "paths": [    "priceInCents"  ],  "desired": {    "priceInCents": 489900,    "currency": "BRL"  },  "observed": {    "priceInCents": 459900,    "currency": "BRL"  },  "status": "open",  "resolution": null,  "resolvedValue": null,  "source": "inbound",  "detectedAt": "2026-10-19T12:00:00.000Z",  "resolvedAt": null}