import requests
url = "https://app.strandai.com/api/v1/samples/{id}"
payload = {
"name": "<string>",
"fields": {},
"mpp": 50
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)curl --request PATCH \
--url https://app.strandai.com/api/v1/samples/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"fields": {},
"mpp": 50
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '<string>', fields: {}, mpp: 50})
};
fetch('https://app.strandai.com/api/v1/samples/{id}', 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://app.strandai.com/api/v1/samples/{id}",
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([
'name' => '<string>',
'fields' => [
],
'mpp' => 50
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.strandai.com/api/v1/samples/{id}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"fields\": {},\n \"mpp\": 50\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://app.strandai.com/api/v1/samples/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"fields\": {},\n \"mpp\": 50\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.strandai.com/api/v1/samples/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"fields\": {},\n \"mpp\": 50\n}"
response = http.request(request)
puts response.read_body{
"ownership": "mine",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"appUrl": "<string>",
"name": "<string>",
"filename": "<string>",
"status": "<string>",
"fileSize": "<string>",
"widthPx": 123,
"heightPx": 123,
"mpp": 123,
"fields": {},
"createdAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z",
"expiresAtSource": "org_default",
"expiresInDays": 123,
"willExpire": true,
"trashedAt": "2023-11-07T05:31:56Z",
"jobs": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "<string>",
"progress": 123,
"reservedCredits": 123,
"markers": [
"<string>"
],
"createdAt": "2023-11-07T05:31:56Z",
"startedAt": "2023-11-07T05:31:56Z",
"completedAt": "2023-11-07T05:31:56Z",
"errorMessage": "<string>",
"resultsAvailable": true
}
],
"jobCount": 1,
"segmentation": {
"status": "not_started",
"retryable": true,
"creditCost": 0,
"job": {},
"layer": {}
}
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}Update a sample
Atomically update any combination of an owned sample’s display name, unified field values, and isotropic microns-per-pixel value. Public share ids are not patchable. OAuth callers need both samples:read and samples:write because the response includes full owned detail and job history. When countable mpp is supplied, an idempotent recount is enqueued even if the stored value is unchanged; after an enqueue-failure 500, retry the identical patch to heal the recount.
import requests
url = "https://app.strandai.com/api/v1/samples/{id}"
payload = {
"name": "<string>",
"fields": {},
"mpp": 50
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)curl --request PATCH \
--url https://app.strandai.com/api/v1/samples/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"fields": {},
"mpp": 50
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '<string>', fields: {}, mpp: 50})
};
fetch('https://app.strandai.com/api/v1/samples/{id}', 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://app.strandai.com/api/v1/samples/{id}",
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([
'name' => '<string>',
'fields' => [
],
'mpp' => 50
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.strandai.com/api/v1/samples/{id}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"fields\": {},\n \"mpp\": 50\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://app.strandai.com/api/v1/samples/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"fields\": {},\n \"mpp\": 50\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.strandai.com/api/v1/samples/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"fields\": {},\n \"mpp\": 50\n}"
response = http.request(request)
puts response.read_body{
"ownership": "mine",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"appUrl": "<string>",
"name": "<string>",
"filename": "<string>",
"status": "<string>",
"fileSize": "<string>",
"widthPx": 123,
"heightPx": 123,
"mpp": 123,
"fields": {},
"createdAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z",
"expiresAtSource": "org_default",
"expiresInDays": 123,
"willExpire": true,
"trashedAt": "2023-11-07T05:31:56Z",
"jobs": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "<string>",
"progress": 123,
"reservedCredits": 123,
"markers": [
"<string>"
],
"createdAt": "2023-11-07T05:31:56Z",
"startedAt": "2023-11-07T05:31:56Z",
"completedAt": "2023-11-07T05:31:56Z",
"errorMessage": "<string>",
"resultsAvailable": true
}
],
"jobCount": 1,
"segmentation": {
"status": "not_started",
"retryable": true,
"creditCost": 0,
"job": {},
"layer": {}
}
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}{
"error": "<string>",
"message": "<string>",
"required": 123,
"retryAfterSeconds": 123
}fields is keyed by stable definition key. Each supplied value replaces that
field’s complete value; null clears it. This payload replaces Tags:
{ "fields": { "tags": ["baseline", "trial-42"] } }
fields.public but
is not writable through this endpoint; publication uses its protected flow.
Use GET /sample-fields to discover keys, value types, origin, storage, and
writability. The retired top-level tags property is rejected with HTTP 400.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Body
Trimmed display name. Null or an empty string reverts to filename. NUL characters are rejected.
200^[^\u0000]*$Complete values for the named fields, not deltas. Null clears a field. fields.tags is the complete desired tag set; fields.public is read-only and returns 403.
User-reported microns per pixel. Object axes must be equal; anisotropic input is rejected.
0 < x <= 100Response
Updated owned sample detail
An owned sample's curated read model and its 50 newest inference jobs. jobCount is the uncapped total.
mine Canonical browser URL for this owned sample.
Human-friendly display name, or null if unset (falls back to filename).
Original uploaded filename.
Lifecycle status: uploading, upload_failed, deid_running, deid_failed, preprocessing, ready, or preprocess_failed.
Uploaded file size in bytes (string-encoded 64-bit integer).
Level-0 width in pixels, or null before the dimensions probe completes.
Level-0 height in pixels, or null before the dimensions probe completes.
Effective isotropic microns per pixel (user override → calibrated slide value), or null when the sample has no usable scale yet.
Unified field values keyed by stable definition key. Tags is a string array at tags; Public is a boolean at public. Values are validated against the organization's definitions.
When the sample moves to Trash. Null when it never expires.
org_default = derived from the org policy at upload time. custom = set by an explicit expiration call (a date or a never-expire pin). Null when the sample has no expiration and no org policy applies.
org_default, custom, null Whole days until expiry, clamped at 0 for a sample at/past its date but not yet swept. Null when the sample never expires.
True when the sample has an expiration date set.
When the sample entered Trash, or null if it is still active. Trashed samples are permanently deleted 7 days after this time.
50Show child attributes
Show child attributes
Total inference-job count for the sample before the 50-job cap.
x >= 0Show child attributes
Show child attributes
Was this page helpful?