Marketplaces and jobs
Read the health of your marketplace connections and find out why a push failed, and follow the asynchronous jobs that endpoints hand back.
GET /api/marketplaces
Your active marketplace connections and the health of each. Needs MarketplacesRead.
This is the endpoint to call when a push did not do what you expected. It tells you whether the connection is working, and if not, what the marketplace said.
{
"Marketplaces": [
{
"MarketplaceId": "6a73...",
"Platform": "Amazon",
"Country": "UnitedKingdom",
"HealthStatus": "UnAuthorized",
"HealthStatusMessage": "The marketplace revoked our authorisation.",
"IsHealthy": false,
"RequiresReauthorization": true,
"LastPull": { "Status": "MarketplaceProductPullCompleted", "TotalSkus": 120, "CurrentSku": 120 }
}
]
}
RequiresReauthorization is the one failure retrying will never clear. Somebody has to reconnect the marketplace in the app. Every other unhealthy state is worth waiting out; this one needs a person. Treat the two differently or your integration will retry forever against a connection that is never coming back on its own.
Only active connections are listed. A connection the merchant has paused is omitted — a paused marketplace is not one to push to.
A connection that has never reported a state comes back with a null HealthStatus. That means "nothing known yet", not "broken".
GET /api/jobs/{id}
The state of one asynchronous job. Needs InventoryRead.
Anything that reaches a marketplace happens on our worker pipeline, so endpoints that trigger one hand you a job id instead of blocking. This is how you follow it.
{
"JobId": "6a73...",
"Type": "EbayInventorySubmit",
"Status": "InProcess",
"IsComplete": false,
"IsSuccessful": false,
"StartedAt": "2026-08-05T10:00:00Z",
"ProgressDone": 120,
"ProgressTotal": 400,
"RecoveryCount": 0
}
- Poll
IsComplete; decide onIsSuccessful. They are separate on purpose — a failed job is complete. Treating "finished" as "worked" is the mistake this shape exists to prevent. Statusis one ofNotStarted,Published(queued),InProcess,Completed,Failed,Cancelled,Skipped. ASkippedjob ran and found nothing to do: it is complete and successful, andSkipReasonsays why. A scheduled import that was held because its file looked wrong (empty, far fewer rows, a mapped column missing, or every quantity 0), or that only previewed what it would change, endsSkippedtoo, with the reason inSkipReason.MarketplaceIdis the connection the job works for, as inGET /api/marketplaces. It is null for a job that belongs to the whole account.ProgressDoneandProgressTotalare null for jobs that do not count rows — absent means "does not report progress", not "zero done".RecoveryCountabove zero means the job was picked up again after a worker restarted. Not a failure, but worth knowing when one is slow.
Poll at a sensible interval — the rate limit applies here too. The failure reason is not returned; open the job in the app to read it.
POST /api/jobs/List
The account’s background jobs, the most recently changed first. Needs InventoryRead.
Use it to find a job you did not start yourself — an import, a scheduled marketplace pull, a publish — and then follow it with GET /api/jobs/{id}. Each job carries the same fields as that endpoint, plus UpdatedAt, the time the list is ordered by.
{
"Statuses": ["NotStarted", "Published", "InProcess", "Failed"],
"MarketplaceId": "6a73...",
"Since": "2026-10-01T00:00:00Z",
"Limit": 20,
"Offset": 0
}
- Every filter is optional.
Statusestakes the names above;NotStartedandPublishedare waiting,InProcessis running. A name that is not a status is a validation error. - Bounded: omit
Limitand you get at most 20; more than 50 is rejected rather than cut. Page withOffsetagainstTotalCount. - As for one job, the raw failure reason is not returned. Open the job in the app to read it.