Patch an owned agent configuration
const url = 'https://api.harperharbor.com/open/v1/role/example';const options = { method: 'PATCH', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"roleName":"example","roleDesc":"example","roleReadme":"example","roleTag":["example"],"userName":"example","roleDetailDesc":"example","idempotencyKey":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PATCH \ --url https://api.harperharbor.com/open/v1/role/example \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "roleName": "example", "roleDesc": "example", "roleReadme": "example", "roleTag": [ "example" ], "userName": "example", "roleDetailDesc": "example", "idempotencyKey": "example" }'Requires role.write and ownership. Updates only supplied fields of an owned configuration, including from another application tenant and while unlisted. Community review is not required. Validation, immutable hosted snapshot restrictions and ownership checks remain enforced. Use the document endpoint for structured content patches.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Role id. Only the path parameter is honoured.
Request Bodyrequired
Section titled “Request Bodyrequired”All keys optional; at least one must be present.
object
New name (blank ignored).
Short intro; limit 500 chars (2500 for English cards). Blank ignored.
Detail introduction in Markdown for the card’s public page; never sent to the model during chat. Limit 20000 chars (40000 for English cards); over the limit returns role_readme_too_long. Blank ignored (clear it with POST /role/{roleId}/document).
Replacement tag list (empty array ignored).
Player name used by the card (blank ignored).
Full replacement of the private definition; must be non-blank; limit 10000 chars (50000 for English cards).
Accepted; not used for deduplication.
Examplegenerated
{ "roleName": "example", "roleDesc": "example", "roleReadme": "example", "roleTag": [ "example" ], "userName": "example", "roleDetailDesc": "example", "idempotencyKey": "example"}Responses
Section titled “Responses”Updated role summary (result of the last applied block).
Summary returned by every role write.
object
Role id.
Current visibility. HarperHarbor defaults to unlisted (usable by ID without community listing).
Moderation status.
Always owner on these routes.
Present when a deep patch was applied to a single field.
object
Number of operations applied.
Rune count before.
Rune count after.
Hex SHA-256 of the text before.
Hex SHA-256 of the text after.
Per-field patch summaries keyed by field name; present when fieldPatches were used.
object
object
Number of operations applied.
Rune count before.
Rune count after.
Hex SHA-256 of the text before.
Hex SHA-256 of the text after.
Character counts before/after for the edited field (e.g. roleDetailDesc, roleWelcome).
object
object
Character (rune) count before the write.
Character (rune) count after the write.
Suggested next MCP tool names; informational.
Example
{ "roleVisibility": "private", "reviewStatus": "not_submitted", "accountPermission": "owner"}invalid JSON body, nothing to update (body {"error": "..."}).
object
Error code (snake_case) or, for legacy handlers, a free-text/localized message.
Human-readable sentence. Present only on middleware errors and /me, /me/wallet.
Whether retrying may succeed. Present only on middleware errors, /me, /me/wallet and service/share routes.
Only on a first-turn context_capacity_exceeded: the smallest context tier that fits the whole card with room to talk. Save it as context in player settings and resend. Absent when no tier fits.
The token budget of required_context_tier for the selected model, for display.
Only on a first-turn context_capacity_exceeded: whether saving trimConstantLore=true lets the card play at the current tier. Absent on mid-conversation capacity errors.
Only on insufficient_credits: the credits this turn needs before it can start. Absent when the refusal came without an estimate.
Only on insufficient_credits: the credits the wallet could set aside for it.
Examplegenerated
{ "error": "example", "message": "example", "retryable": true, "required_context_tier": 1, "required_context_tokens": 1, "constant_lore_trim_fits": true, "credits_needed": 1, "credits_available": 1}unauthorized.
object
Error code (snake_case) or, for legacy handlers, a free-text/localized message.
Human-readable sentence. Present only on middleware errors and /me, /me/wallet.
Whether retrying may succeed. Present only on middleware errors, /me, /me/wallet and service/share routes.
Only on a first-turn context_capacity_exceeded: the smallest context tier that fits the whole card with room to talk. Save it as context in player settings and resend. Absent when no tier fits.
The token budget of required_context_tier for the selected model, for display.
Only on a first-turn context_capacity_exceeded: whether saving trimConstantLore=true lets the card play at the current tier. Absent on mid-conversation capacity errors.
Only on insufficient_credits: the credits this turn needs before it can start. Absent when the refusal came without an estimate.
Only on insufficient_credits: the credits the wallet could set aside for it.
Examplegenerated
{ "error": "example", "message": "example", "retryable": true, "required_context_tier": 1, "required_context_tokens": 1, "constant_lore_trim_fits": true, "credits_needed": 1, "credits_available": 1}permission_denied — not the author.
object
Error code (snake_case) or, for legacy handlers, a free-text/localized message.
Human-readable sentence. Present only on middleware errors and /me, /me/wallet.
Whether retrying may succeed. Present only on middleware errors, /me, /me/wallet and service/share routes.
Only on a first-turn context_capacity_exceeded: the smallest context tier that fits the whole card with room to talk. Save it as context in player settings and resend. Absent when no tier fits.
The token budget of required_context_tier for the selected model, for display.
Only on a first-turn context_capacity_exceeded: whether saving trimConstantLore=true lets the card play at the current tier. Absent on mid-conversation capacity errors.
Only on insufficient_credits: the credits this turn needs before it can start. Absent when the refusal came without an estimate.
Only on insufficient_credits: the credits the wallet could set aside for it.
Examplegenerated
{ "error": "example", "message": "example", "retryable": true, "required_context_tier": 1, "required_context_tokens": 1, "constant_lore_trim_fits": true, "credits_needed": 1, "credits_available": 1}record not found, public_role_requires_clone, role_desc_too_long, role_detail_too_long, empty_field_patch, or another unclassified error; {"error": "<code>", "retryable": true}.
object
Error code (snake_case) or, for legacy handlers, a free-text/localized message.
Human-readable sentence. Present only on middleware errors and /me, /me/wallet.
Whether retrying may succeed. Present only on middleware errors, /me, /me/wallet and service/share routes.
Only on a first-turn context_capacity_exceeded: the smallest context tier that fits the whole card with room to talk. Save it as context in player settings and resend. Absent when no tier fits.
The token budget of required_context_tier for the selected model, for display.
Only on a first-turn context_capacity_exceeded: whether saving trimConstantLore=true lets the card play at the current tier. Absent on mid-conversation capacity errors.
Only on insufficient_credits: the credits this turn needs before it can start. Absent when the refusal came without an estimate.
Only on insufficient_credits: the credits the wallet could set aside for it.
Examplegenerated
{ "error": "example", "message": "example", "retryable": true, "required_context_tier": 1, "required_context_tokens": 1, "constant_lore_trim_fits": true, "credits_needed": 1, "credits_available": 1}