curl --request PATCH \
--url https://{host}/v1/sellers/{sellerId}/watches/{id}/relationships/images \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/vnd.api+json' \
--data '
{
"data": [
{
"type": "uploads",
"id": "5512"
},
{
"type": "uploads",
"id": "5514"
},
{
"type": "uploads",
"id": "5513"
}
]
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/vnd.api+json'},
body: JSON.stringify({
data: [
{type: 'uploads', id: '5512'},
{type: 'uploads', id: '5514'},
{type: 'uploads', id: '5513'}
]
})
};
fetch('https://{host}/v1/sellers/{sellerId}/watches/{id}/relationships/images', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{host}/v1/sellers/{sellerId}/watches/{id}/relationships/images",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'data' => [
[
'type' => 'uploads',
'id' => '5512'
],
[
'type' => 'uploads',
'id' => '5514'
],
[
'type' => 'uploads',
'id' => '5513'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/vnd.api+json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}import requests
url = "https://{host}/v1/sellers/{sellerId}/watches/{id}/relationships/images"
payload = { "data": [
{
"type": "uploads",
"id": "5512"
},
{
"type": "uploads",
"id": "5514"
},
{
"type": "uploads",
"id": "5513"
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text){
"data": [
{
"type": "uploads",
"id": "5512"
},
{
"type": "uploads",
"id": "5514"
}
],
"links": {
"self": "https://api.wristler.eu/v1/sellers/42/watches/91827/relationships/images",
"related": "https://api.wristler.eu/v1/sellers/42/watches/91827/images"
}
}{
"errors": [
{
"status": "404",
"code": "watch_reserved",
"title": "Not Found",
"detail": "<string>",
"meta": {},
"source": {
"pointer": "/data/attributes/reference",
"parameter": "<string>"
}
}
],
"jsonapi": {
"version": "1.0"
}
}{
"errors": [
{
"status": "404",
"code": "watch_reserved",
"title": "Not Found",
"detail": "<string>",
"meta": {},
"source": {
"pointer": "/data/attributes/reference",
"parameter": "<string>"
}
}
],
"jsonapi": {
"version": "1.0"
}
}{
"errors": [
{
"status": "404",
"code": "watch_reserved",
"title": "Not Found",
"detail": "<string>",
"meta": {},
"source": {
"pointer": "/data/attributes/reference",
"parameter": "<string>"
}
}
],
"jsonapi": {
"version": "1.0"
}
}{
"errors": [
{
"status": "404",
"code": "watch_reserved",
"title": "Not Found",
"detail": "<string>",
"meta": {},
"source": {
"pointer": "/data/attributes/reference",
"parameter": "<string>"
}
}
],
"jsonapi": {
"version": "1.0"
}
}Reorder gallery
Scope: watches:write
Send the images in the order you want them. Leave one out and it is removed — and deleted, not orphaned: a file that belongs to nothing is one we keep paying to store and nobody can reach.
Adding is not done here. New images arrive on the listing, as imageSources (which
we fetch) or imageHandles (from POST /v1/uploads). An upload that is not on one
of this business’s own listings — another business’s photograph, a message’s
attachment — is refused with 422, pointer /data/{index}; upload the file instead.
A listing a Connect feed maintains is refused with 409 feed_managed: its gallery is
the feed’s.
curl --request PATCH \
--url https://{host}/v1/sellers/{sellerId}/watches/{id}/relationships/images \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/vnd.api+json' \
--data '
{
"data": [
{
"type": "uploads",
"id": "5512"
},
{
"type": "uploads",
"id": "5514"
},
{
"type": "uploads",
"id": "5513"
}
]
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/vnd.api+json'},
body: JSON.stringify({
data: [
{type: 'uploads', id: '5512'},
{type: 'uploads', id: '5514'},
{type: 'uploads', id: '5513'}
]
})
};
fetch('https://{host}/v1/sellers/{sellerId}/watches/{id}/relationships/images', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{host}/v1/sellers/{sellerId}/watches/{id}/relationships/images",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'data' => [
[
'type' => 'uploads',
'id' => '5512'
],
[
'type' => 'uploads',
'id' => '5514'
],
[
'type' => 'uploads',
'id' => '5513'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/vnd.api+json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}import requests
url = "https://{host}/v1/sellers/{sellerId}/watches/{id}/relationships/images"
payload = { "data": [
{
"type": "uploads",
"id": "5512"
},
{
"type": "uploads",
"id": "5514"
},
{
"type": "uploads",
"id": "5513"
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text){
"data": [
{
"type": "uploads",
"id": "5512"
},
{
"type": "uploads",
"id": "5514"
}
],
"links": {
"self": "https://api.wristler.eu/v1/sellers/42/watches/91827/relationships/images",
"related": "https://api.wristler.eu/v1/sellers/42/watches/91827/images"
}
}{
"errors": [
{
"status": "404",
"code": "watch_reserved",
"title": "Not Found",
"detail": "<string>",
"meta": {},
"source": {
"pointer": "/data/attributes/reference",
"parameter": "<string>"
}
}
],
"jsonapi": {
"version": "1.0"
}
}{
"errors": [
{
"status": "404",
"code": "watch_reserved",
"title": "Not Found",
"detail": "<string>",
"meta": {},
"source": {
"pointer": "/data/attributes/reference",
"parameter": "<string>"
}
}
],
"jsonapi": {
"version": "1.0"
}
}{
"errors": [
{
"status": "404",
"code": "watch_reserved",
"title": "Not Found",
"detail": "<string>",
"meta": {},
"source": {
"pointer": "/data/attributes/reference",
"parameter": "<string>"
}
}
],
"jsonapi": {
"version": "1.0"
}
}{
"errors": [
{
"status": "404",
"code": "watch_reserved",
"title": "Not Found",
"detail": "<string>",
"meta": {},
"source": {
"pointer": "/data/attributes/reference",
"parameter": "<string>"
}
}
],
"jsonapi": {
"version": "1.0"
}
}Authorizations
Headers
Optional. A UUID per logical operation, not per attempt: a retry carrying the same key gets the first attempt's answer back, headers and all, rather than performing the write twice. Honoured for 24 hours.
A refusal is an answer. A 422 is remembered like any other, so sending a
corrected body under the same key answers 422 idempotency_key_reuse rather
than accepting the correction — the point of a key is that one key means one
decision. Use a new key for a new attempt at the request, and keep the old one
only for retrying the same bytes after a timeout.
A 5xx is the exception: nothing was decided, so the key is released and the
same one may be retried.
| Refusal | Status | code |
|---|---|---|
| The same key with a different body | 422 | idempotency_key_reuse |
| The first request with this key is still running | 409 | idempotency_in_progress |
| The key's record vanished between two requests: retry with a new key | 409 | idempotency_conflict |
| A key longer than 191 characters | 400 | idempotency_key_invalid |
A replayed answer carries Idempotent-Replay: true.
191