curl --request PATCH \
--url https://api.aurous-labs.com/v1/characters/{id} \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--data '
{
"name": "Aurora the Bold",
"attributes": {
"gender": "female",
"age": 28,
"ethnicity": "east-asian",
"hair_color": "black",
"hair_style": "shoulder-length straight",
"eye_color": "brown",
"body_type": "athletic",
"additional_details": "small scar above right eyebrow; warm smile"
},
"nudity": "clothed"
}
'import requests
url = "https://api.aurous-labs.com/v1/characters/{id}"
payload = {
"name": "Aurora the Bold",
"attributes": {
"gender": "female",
"age": 28,
"ethnicity": "east-asian",
"hair_color": "black",
"hair_style": "shoulder-length straight",
"eye_color": "brown",
"body_type": "athletic",
"additional_details": "small scar above right eyebrow; warm smile"
},
"nudity": "clothed"
}
headers = {
"X-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'X-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Aurora the Bold',
attributes: {
gender: 'female',
age: 28,
ethnicity: 'east-asian',
hair_color: 'black',
hair_style: 'shoulder-length straight',
eye_color: 'brown',
body_type: 'athletic',
additional_details: 'small scar above right eyebrow; warm smile'
},
nudity: 'clothed'
})
};
fetch('https://api.aurous-labs.com/v1/characters/{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://api.aurous-labs.com/v1/characters/{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' => 'Aurora the Bold',
'attributes' => [
'gender' => 'female',
'age' => 28,
'ethnicity' => 'east-asian',
'hair_color' => 'black',
'hair_style' => 'shoulder-length straight',
'eye_color' => 'brown',
'body_type' => 'athletic',
'additional_details' => 'small scar above right eyebrow; warm smile'
],
'nudity' => 'clothed'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>"
],
]);
$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://api.aurous-labs.com/v1/characters/{id}"
payload := strings.NewReader("{\n \"name\": \"Aurora the Bold\",\n \"attributes\": {\n \"gender\": \"female\",\n \"age\": 28,\n \"ethnicity\": \"east-asian\",\n \"hair_color\": \"black\",\n \"hair_style\": \"shoulder-length straight\",\n \"eye_color\": \"brown\",\n \"body_type\": \"athletic\",\n \"additional_details\": \"small scar above right eyebrow; warm smile\"\n },\n \"nudity\": \"clothed\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("X-Api-Key", "<api-key>")
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://api.aurous-labs.com/v1/characters/{id}")
.header("X-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Aurora the Bold\",\n \"attributes\": {\n \"gender\": \"female\",\n \"age\": 28,\n \"ethnicity\": \"east-asian\",\n \"hair_color\": \"black\",\n \"hair_style\": \"shoulder-length straight\",\n \"eye_color\": \"brown\",\n \"body_type\": \"athletic\",\n \"additional_details\": \"small scar above right eyebrow; warm smile\"\n },\n \"nudity\": \"clothed\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.aurous-labs.com/v1/characters/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Aurora the Bold\",\n \"attributes\": {\n \"gender\": \"female\",\n \"age\": 28,\n \"ethnicity\": \"east-asian\",\n \"hair_color\": \"black\",\n \"hair_style\": \"shoulder-length straight\",\n \"eye_color\": \"brown\",\n \"body_type\": \"athletic\",\n \"additional_details\": \"small scar above right eyebrow; warm smile\"\n },\n \"nudity\": \"clothed\"\n}"
response = http.request(request)
puts response.read_body{
"id": "char_01HXMQ7Z3K8Y2NABCDEFGHJKMR",
"object": "character",
"name": "Aurora the Adventurer",
"status": "ready",
"nudity": "clothed",
"refs": [
{
"pose": "front",
"view": "full_front",
"source": "generated",
"url": "https://storage-host.example/storage/v1/object/sign/characters/full_front.jpg?token=eyJhbGciOi..."
}
],
"views": [
{
"view": "full_front",
"status": "generated",
"url": null,
"nudity": "clothed",
"reason": null,
"detected_view": null,
"made_from": [
"head_front",
"full_front"
]
}
],
"build": {
"missing_views": [
"full_front",
"full_right"
],
"cost_credits": 123,
"per_view_credits": 123
},
"created_at": "2026-05-08T10:00:00Z",
"updated_at": "2026-05-08T10:00:00Z",
"client_reference_id": "bot_8472",
"attributes": {
"gender": "female",
"age": 28,
"ethnicity": "east-asian",
"hair_color": "black",
"hair_style": "shoulder-length straight",
"eye_color": "brown",
"body_type": "athletic",
"additional_details": "small scar above right eyebrow; warm smile"
},
"error_message": null,
"aurous_version": "2026-08-26"
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}Update a character
Edit a character’s name and attributes. Refs are immutable.
curl --request PATCH \
--url https://api.aurous-labs.com/v1/characters/{id} \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--data '
{
"name": "Aurora the Bold",
"attributes": {
"gender": "female",
"age": 28,
"ethnicity": "east-asian",
"hair_color": "black",
"hair_style": "shoulder-length straight",
"eye_color": "brown",
"body_type": "athletic",
"additional_details": "small scar above right eyebrow; warm smile"
},
"nudity": "clothed"
}
'import requests
url = "https://api.aurous-labs.com/v1/characters/{id}"
payload = {
"name": "Aurora the Bold",
"attributes": {
"gender": "female",
"age": 28,
"ethnicity": "east-asian",
"hair_color": "black",
"hair_style": "shoulder-length straight",
"eye_color": "brown",
"body_type": "athletic",
"additional_details": "small scar above right eyebrow; warm smile"
},
"nudity": "clothed"
}
headers = {
"X-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'X-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Aurora the Bold',
attributes: {
gender: 'female',
age: 28,
ethnicity: 'east-asian',
hair_color: 'black',
hair_style: 'shoulder-length straight',
eye_color: 'brown',
body_type: 'athletic',
additional_details: 'small scar above right eyebrow; warm smile'
},
nudity: 'clothed'
})
};
fetch('https://api.aurous-labs.com/v1/characters/{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://api.aurous-labs.com/v1/characters/{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' => 'Aurora the Bold',
'attributes' => [
'gender' => 'female',
'age' => 28,
'ethnicity' => 'east-asian',
'hair_color' => 'black',
'hair_style' => 'shoulder-length straight',
'eye_color' => 'brown',
'body_type' => 'athletic',
'additional_details' => 'small scar above right eyebrow; warm smile'
],
'nudity' => 'clothed'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>"
],
]);
$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://api.aurous-labs.com/v1/characters/{id}"
payload := strings.NewReader("{\n \"name\": \"Aurora the Bold\",\n \"attributes\": {\n \"gender\": \"female\",\n \"age\": 28,\n \"ethnicity\": \"east-asian\",\n \"hair_color\": \"black\",\n \"hair_style\": \"shoulder-length straight\",\n \"eye_color\": \"brown\",\n \"body_type\": \"athletic\",\n \"additional_details\": \"small scar above right eyebrow; warm smile\"\n },\n \"nudity\": \"clothed\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("X-Api-Key", "<api-key>")
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://api.aurous-labs.com/v1/characters/{id}")
.header("X-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Aurora the Bold\",\n \"attributes\": {\n \"gender\": \"female\",\n \"age\": 28,\n \"ethnicity\": \"east-asian\",\n \"hair_color\": \"black\",\n \"hair_style\": \"shoulder-length straight\",\n \"eye_color\": \"brown\",\n \"body_type\": \"athletic\",\n \"additional_details\": \"small scar above right eyebrow; warm smile\"\n },\n \"nudity\": \"clothed\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.aurous-labs.com/v1/characters/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Aurora the Bold\",\n \"attributes\": {\n \"gender\": \"female\",\n \"age\": 28,\n \"ethnicity\": \"east-asian\",\n \"hair_color\": \"black\",\n \"hair_style\": \"shoulder-length straight\",\n \"eye_color\": \"brown\",\n \"body_type\": \"athletic\",\n \"additional_details\": \"small scar above right eyebrow; warm smile\"\n },\n \"nudity\": \"clothed\"\n}"
response = http.request(request)
puts response.read_body{
"id": "char_01HXMQ7Z3K8Y2NABCDEFGHJKMR",
"object": "character",
"name": "Aurora the Adventurer",
"status": "ready",
"nudity": "clothed",
"refs": [
{
"pose": "front",
"view": "full_front",
"source": "generated",
"url": "https://storage-host.example/storage/v1/object/sign/characters/full_front.jpg?token=eyJhbGciOi..."
}
],
"views": [
{
"view": "full_front",
"status": "generated",
"url": null,
"nudity": "clothed",
"reason": null,
"detected_view": null,
"made_from": [
"head_front",
"full_front"
]
}
],
"build": {
"missing_views": [
"full_front",
"full_right"
],
"cost_credits": 123,
"per_view_credits": 123
},
"created_at": "2026-05-08T10:00:00Z",
"updated_at": "2026-05-08T10:00:00Z",
"client_reference_id": "bot_8472",
"attributes": {
"gender": "female",
"age": 28,
"ethnicity": "east-asian",
"hair_color": "black",
"hair_style": "shoulder-length straight",
"eye_color": "brown",
"body_type": "athletic",
"additional_details": "small scar above right eyebrow; warm smile"
},
"error_message": null,
"aurous_version": "2026-08-26"
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}{
"error": {
"type": "invalid_request",
"code": "balance_too_low",
"message": "Team available balance is 1.5 credits, generation requires 2.0.",
"doc_url": "https://docs.aurous-labs.com/errors#balance_too_low",
"request_id": "req_01HXMQ7Z3K8Y2VNABCDEFGHJKM",
"param": "prompt",
"reason": "wrong_view",
"detected_view": "full_left"
}
}PATCH /v1/characters/{id} updates the mutable fields of a character: name, attributes, and nudity while the character is still a draft. Send only the fields you want to change. Omitted fields are preserved.
The reference images themselves (refs[]) are immutable by design. The cover defaults to the head_front view; change it from the dashboard. To change the visual identity, re-render a single view via POST /v1/characters/{id}/refs/{view}/regenerate or rerun the whole synthesis via POST /v1/characters/{id}/resynthesize.
Changing nudity
nudity (nude or clothed) is a property of the whole reference set, so it can only move while nothing has been rendered — that is, while the character’s status is draft. Sending it on any other status returns 400 character_status_invalid with param: nudity — that check runs first, so it is what you see even on a team that could not have taken the value anyway. On a draft, an explicit nudity: "nude" from a team that always renders clothed returns 400 nudity_not_allowed (param: nudity).
curl -X PATCH https://api.aurous-labs.com/v1/characters/char_01HXMQ7Z3K8Y2VNABCDEFGHJKM \
-H "X-Api-Key: $AUROUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"nudity": "clothed"}'
draft the choice is fixed — create a new character to change it. See Views and lifecycle.
When to use
- Renaming a character.
- Updating
attributes.additional_detailsto add notes you want to surface in your UI. - Setting
nudityon a draft before you build it. - Giving a draft with no uploaded photos the
attributesa build needs. Once the draft holds any uploaded photo,attributesno longer satisfy the identity rule — one of the photos must show the face.
Examples
curl -X PATCH https://api.aurous-labs.com/v1/characters/char_01HXMQ7Z3K8Y2VNABCDEFGHJKM \
-H "X-Api-Key: $AUROUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Aurora (final)"}'
const updated = await fetch(
`https://api.aurous-labs.com/v1/characters/${id}`,
{
method: "PATCH",
headers: {
"X-Api-Key": process.env.AUROUS_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({ name: "Aurora (final)" }),
},
).then((r) => r.json());
import os, requests
r = requests.patch(
f"https://api.aurous-labs.com/v1/characters/{character_id}",
headers={"X-Api-Key": os.environ["AUROUS_API_KEY"]},
json={"name": "Aurora (final)"},
).json()
Limits
- Rate limit: bucket
characters_post— 30 requests/min sustained, 60 burst per team.
Errors
| Code | HTTP | When |
|---|---|---|
resource_not_found | 404 | Unknown ID, soft-deleted character, or cross-team. error.param is "character_id". |
invalid_request | 400 | Body validation failure (e.g. name over the length cap). error.param names the offending field. |
character_status_invalid | 400 | nudity was sent on a character that is no longer a draft. error.param is "nudity". |
nudity_not_allowed | 400 | nudity: "nude" on a team that always renders clothed. error.param is "nudity". |
prompt_blocked | 400 | The free text in attributes.additional_details was declined by content policy. error.param is "prompt" — the error always names the field prompt, not attributes.additional_details. |
Common pitfalls
- The platform applies a strict whitelist server-side. Sending fields outside the v1.0 mutable set (
name,attributes, andnudityon a draft) — for examplerefs,id,team_id,status, oraurous_version— returns400 invalid_requestwitherror.paramnaming the first rejected field and a message listing every offending key. This is intentional: a silent-ignore policy would let a buggy client believe a non-existent field had taken effect. If you need a field to be mutable, send a feature request — new mutable fields land in v1.1 schema bumps. - PATCH on a
deletedcharacter returns 404resource_not_found— revive flows are not part of v1.0. attributesis not deep-merged; sendingattributes: { eye_color: "blue" }replaces the whole object. Re-send all fields you want preserved.
Authorizations
Your team API key (starts with al_live_).
Headers
Optional API version pin (YYYY-MM-DD). Omit the header to receive the platform default, currently 2026-08-26.
^\d{4}-\d{2}-\d{2}$"2026-08-26"
Path Parameters
Opaque character ID
"char_01HXMQ7Z3K8Y2NABCDEFGHJKMR"
Body
New display name (1-80 chars). Refs are immutable post-creation; use :id/refs/regenerate or :id/resynthesize to change them.
1 - 80"Aurora the Bold"
Updated character attributes (full replace, not merge).
Show child attributes
Show child attributes
Whether this character's reference set is nude or clothed. Accepted only while status is draft; a change on any other status returns 400 character_status_invalid. On teams that always render clothed an explicit nude returns 400 nudity_not_allowed.
nude, clothed "clothed"
Response
Updated character
Opaque character ID.
"char_01HXMQ7Z3K8Y2NABCDEFGHJKMR"
Discriminator
character "character"
Display name.
"Aurora the Adventurer"
Lifecycle state. draft: references are being assembled; nothing has been charged and the character cannot be used for generation. New lifecycle states may be added in future — treat any status other than ready as "not yet usable". synthesizing: references are being built. ready: usable on POST /v1/images — both create flows advance here on their own. reviewing: reached only after POST /:id/resynthesize or POST /:id/build; call POST /:id/save to return to ready. failed: the build failed; error_message carries the reason and POST /:id/build (builder characters) or POST /:id/resynthesize retries. deleted: soft-deleted (filtered out of the list endpoint).
draft, synthesizing, reviewing, ready, failed, deleted "ready"
What the reference set is rendered as — nude unless you chose clothed, or — when you omitted nudity — your team's default is clothed. An explicit value always wins. Fixed once the references are built.
nude, clothed "clothed"
Reference images, one per view the character has. A character built today has eight; an older one can have fewer than eight (typically six, some of the oldest four). Do not assume a count — read views[], the canonical read model for new integrations, or build.missing_views. refs[] lists only the references that exist.
Show child attributes
Show child attributes
One entry per named view, in canonical order — every reference that maps to a named view, keyed by view, plus what is missing or was rejected. A reference from before named views existed (refs[].view is other) appears only in refs[].
Show child attributes
Show child attributes
What a build would render and cost right now. Always present.
Show child attributes
Show child attributes
Creation timestamp (ISO 8601).
"2026-05-08T10:00:00Z"
Last-update timestamp (ISO 8601).
"2026-05-08T10:00:00Z"
Caller-supplied reference echoed back (the value sent on create). Null if unset.
"bot_8472"
Character attributes. Null when unset.
Show child attributes
Show child attributes
Machine-readable failure code from the most recent synthesize/resynthesize attempt. One of synthesis_failed, synthesis_timeout, provider_unavailable — a closed set to switch on, not customer-facing prose. Null when the most recent attempt succeeded (or none has run yet). Set on failed, but NOT failed-exclusive: a failed resynthesize restores the character to its prior working status (reviewing) rather than overwriting a good generation, so a reviewing row can carry a non-null code here — check this field for failure, not status. Cleared on the next resynthesize attempt and on success.
null
API contract version applied at the time this row was minted (D25 — frozen for replay across future version bumps).
"2026-08-26"

