Errors

One format, with a stable code for your code to handle.

Every error has this body:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request.",
    "details": [
      {
        "origin": "string",
        "code": "too_small",
        "minimum": 1,
        "inclusive": true,
        "path": ["name"],
        "message": "Too small: expected string to have >=1 characters"
      }
    ]
  }
}

details comes in two shapes. On a body, query or :id VALIDATION_ERROR, it is the list of validation problems, one per field. In the cases of the table below, it is an object that says what clashed. Other errors have no details. The text of each message may change: use code and details.

CaseHTTPdetails
Seller-Id header missing or malformed400{ "header": "Seller-Id" }
marketplace not available in this environment400{ "field": "allowedMarketplaces", "unavailable": ["amazon"] }
redirectUrl that is not https400{ "field": "redirectUrl" }
webhook URL refused400{ "field": "url" }
Idempotency-Key longer than 255 characters400{ "header": "Idempotency-Key" }
marketplace options refused (another marketplace namespace, or a URL, header or credential inside)400{ "field": "marketplaceOptions" }, or "oneTimeMarketplaceOptions" when publishing
invalid binding: a Variant that does not exist or belongs to another seller, bindingIds that are not the listing's, or eligibleBindingIds from another listing400{ "field": "bindings" }, { "field": "bindingIds" }, or { "field": "eligibleBindingIds" }
conflict resolution refused: value outside the conflict paths, or a result that is invalid for the group400{ "field": "value" } or { "field": "resolution", "issues": [...] }
repeated externalId409{ "field": "externalId" }
seller with active connections409{ "reason": "active_connections" }
link session that is not pending409{ "status": "completed" } (the current status)
Connection that is not active (for example, revoked)409{ "reason": "connection_inactive" }
publishing with outbound sync off, or a listing with no Variant binding409{ "reason": "outbound_disabled" } or { "reason": "listing_unlinked" }
publishing content: already published (create), never published (update) or without a variation409{ "reason": "marketplace_product_published" }, "marketplace_product_unpublished" or "marketplace_product_without_variants"
archiving a Product or Variant that a listing binding still uses409{ "reason": "product_in_use" } or { "reason": "variant_in_use" }
kit BOM with a cycle409{ "reason": "component_cycle" }
archiving a Product or Variant that is a component of an active kit409{ "reason": "product_in_kit" } or { "reason": "variant_in_kit" }
BOM or listing binding with an archived Variant, or one active in an archived Product409{ "reason": "variant_archived" } or { "reason": "product_archived" }
inventory movement on a Variant that MarketAPI does not manage409{ "reason": "inventory_authority" }
inventory movement in an archived warehouse409{ "reason": "warehouse_archived", "warehouseId": "…" }
movement that would leave the warehouse without enough stock (for a transfer, the source)409{ "reason": "inventory_underflow", "warehouseId": "…" }
archiving the seller's default warehouse, or a warehouse with balance409{ "reason": "warehouse_in_use", "uses": ["default", "stock"] }
quantity publication with no eligible target409{ "reason": "inventory_target_empty" }
resolving a listing conflict that was already resolved409{ "reason": "conflict_not_open" }
Connection without the operation's scope403{ "marketplace": "mercadolivre", "capability": "listings.publish" }
operation the marketplace does not offer422{ "marketplace": "mercadolivre", "capability": "listings.publish" }
HTTPcodeWhen
400VALIDATION_ERRORinvalid body, query (page, pageSize, filters), :id that is not a UUID, or Idempotency-Key; Seller-Id header missing or malformed; marketplace not available; redirectUrl that is not https; webhook URL refused; marketplace options refused; invalid binding; request the marketplace itself refused (discovery routes)
401UNAUTHORIZEDmissing, invalid or revoked API key
402PAYMENT_REQUIREDthe account has no subscription in good standing; activate or reactivate it in Billing, in the dashboard
403FORBIDDENdashboard session with no account created yet; any /v1 route. Does not happen with an API key
403CAPABILITY_NOT_GRANTEDthe marketplace offers the operation, but the Connection lacks a required scope; the seller authorizes again. In a job, also when the marketplace itself refuses the app the permission for the operation: enable the permission in the app and authorize again
404NOT_FOUNDunknown route, or a valid id that does not exist (or belongs to another account) — including the seller in the path or in Seller-Id, and an internal job. On the discovery routes, also a category, product type or catalog product the marketplace does not know
409CONFLICTexternalId already in use, Idempotency-Key reused with a different body, seller with active connections, link session that is not pending, inactive Connection, listing state, Product or Variant in use, BOM cycle, inventory MarketAPI does not manage, not enough stock in a warehouse, archived or in-use warehouse, archived Variant or kit component, listing conflict already resolved. Any POST can return the reused Idempotency-Key
422CAPABILITY_UNSUPPORTEDthe Connection's marketplace does not offer the operation. See Connection capabilities
429RATE_LIMITEDAPI key limit exceeded; see Retry-After
500INTERNAL_ERRORour fault; already logged
503MARKETPLACE_UNAVAILABLEthe marketplace did not answer a call of ours, refused the app or limited the requests; try again. details.reason tells a wait from an outage
503STORAGE_UNAVAILABLEfile storage is not configured in this environment (asset routes)

Examples

409 CONFLICT has several causes (listed in the table above). Tell them apart by details; the reused Idempotency-Key is the only one without it.

Repeated externalId, with details.field:

{
  "error": {
    "code": "CONFLICT",
    "message": "A seller with this externalId already exists.",
    "details": { "field": "externalId" }
  }
}

Seller with active connections, on DELETE /v1/sellers/<id>:

{
  "error": {
    "code": "CONFLICT",
    "message": "Seller with active connections cannot be removed. Disconnect them first.",
    "details": { "reason": "active_connections" }
  }
}

Link session that is no longer pending, on DELETE /v1/link-sessions/<id>:

{
  "error": {
    "code": "CONFLICT",
    "message": "Only a pending link session can be revoked.",
    "details": { "status": "completed" }
  }
}

400 for a missing Seller-Id, on GET /v1/connections:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Seller-Id header is required.",
    "details": { "header": "Seller-Id" }
  }
}

Idempotency-Key reused with a different body, no details (see Idempotency and limits):

{
  "error": {
    "code": "CONFLICT",
    "message": "Idempotency-Key already used with a different body."
  }
}

422 CAPABILITY_UNSUPPORTED, when publishing a listing on a Connection whose marketplace does not publish. 403 CAPABILITY_NOT_GRANTED has the same details. In an inventory batch the error is not in the response: that Connection's item fails in the job, with the code in its message.

{
  "error": {
    "code": "CAPABILITY_UNSUPPORTED",
    "message": "Marketplace mercadolivre does not support listings.publish.",
    "details": {
      "marketplace": "mercadolivre",
      "capability": "listings.publish"
    }
  }
}

402 PAYMENT_REQUIRED (no subscription in good standing; it does not count toward the rate limit):

{
  "error": {
    "code": "PAYMENT_REQUIRED",
    "message": "Subscription required. Add a payment method in the dashboard."
  }
}

429 RATE_LIMITED comes with the Retry-After header (seconds):

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Try again after the time given in Retry-After."
  }
}

500 INTERNAL_ERROR:

{
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "Internal error."
  }
}

503 MARKETPLACE_UNAVAILABLE, on the Connection discovery and catalog routes, which read the marketplace right away. details.reason tells a wait from an outage:

details.reasonWhat happenedWhat to do
missingthe marketplace did not answer, or refused the apptry again later
marketplace_rate_limitedthe marketplace is limiting the requests of the appwait a little and try again
connection_refreshingthe Connection credential is being renewedtry again in a moment
{
  "error": {
    "code": "MARKETPLACE_UNAVAILABLE",
    "message": "The marketplace is limiting requests. Try again.",
    "details": { "reason": "marketplace_rate_limited" }
  }
}

If the marketplace ended the seller's access in the middle of the call, the answer is not 503: it is 409 CONFLICT with { "reason": "connection_inactive" }, the same as any route of a Connection that is not active. Ask the seller to connect again.

Handle errors by code, not by message: the message may change, the code won't. The message is in English and is meant for logs and debugging.

Each endpoint page shows the errors it can return, with an example body for each status. For example: Create a seller.

On this page