Update Ticket
Updates one or more fields on an existing ticket. The endpoint requires the ticket's current etag to enforce optimistic concurrency: if the ticket has been modified since the caller last read it, the update is rejected without modification. On success the API returns the new etag to use for any subsequent updates.
Endpoint
Method: PATCH
URL: {{base_url}}/api/v2/ticketing/ticket/{objectId}/update
Authentication
This endpoint uses Bearer Token authentication via a JWT (JSON Web Token). The token must be included in the Authorization header and contains user identity, realm access roles, and team membership information.
The update-ticket handler enforces both the OAuth scope tickets:write and realm role membership. Tokens that carry the scope but lack a write-permitted role will be rejected with 401 USER_PERMISSION_FAILURE.
Headers
| Header | Description | Required |
|---|---|---|
Authorization | Bearer token (JWT) for authentication | Yes |
accept | Specifies acceptable response formats (application/json) | Yes |
content-type | Request body media type (application/json) | Yes |
x-tenantid | UUID identifying the tenant/organization | Yes |
realmname | The authentication realm name | Yes |
issupportrequest | Boolean flag indicating if this is a support-related request | No |
Path Parameters
| Parameter | Type | Description | Required |
|---|---|---|---|
objectId | string | The display ID of the ticket to update (e.g. REQ-0509, CTC-0054, PMT-0047). Returned as objectId from create and as object_id from GET/list responses | Yes |
Query Parameters
| Parameter | Type | Description | Required |
|---|---|---|---|
type | string | Catalog type. Accepted values: template, agent, user | Yes |
module | string | The module context. Example: ticketing | Yes |
Request Body Schema
{
"etag": "string",
"ticketUpdate": {
"<field-uuid>": "<new value>"
}
}
| Field | Type | Description | Required |
|---|---|---|---|
etag | string (UUID) | The ticket's current etag, fetched from the latest GET /api/v2/ticketing/ticket/{objectId} or returned by the previous create/update response | Yes |
ticketUpdate | object | Map of field UUID → new value. Field UUIDs come from the ticket type's fields[].id values returned by GET /api/v2/ticketing/ticket-type. Only the keys present here are updated; omitted keys are left unchanged | Yes |
Partial updates only. This endpoint applies a shallow merge over the ticket's
dataobject. To clear a field, send the appropriate empty value for its type ("",null, or[]).
Example cURL
curl --request PATCH \
--url '{{base_url}}/api/v2/ticketing/ticket/REQ-0509/update?type=template&module=ticketing' \
--header 'accept: application/json' \
--header 'authorization: Bearer {{access_token}}' \
--header 'content-type: application/json' \
--header 'x-tenantid: {{tenant_id}}' \
--header 'realmname: {{realm_name}}' \
--header 'issupportrequest: false' \
--data '{
"etag": "b5f8c028-924c-4e2c-af9e-eed4aa584e99",
"ticketUpdate": {
"459cf0c6-ae1c-4ba2-8116-3b8b38207528": "<p>Updated description text.</p>"
}
}'
Success Response Example
Status Code: 200 OK
{
"success": true,
"message": "ticket updated successfully",
"status": 200,
"etag": "78dade55-9d93-4d7f-bbe0-2ee549581f38"
}
| Field | Type | Description |
|---|---|---|
success | boolean | true on successful update |
message | string | Human-readable status message |
status | integer | HTTP status code |
etag | string (UUID) | The ticket's new etag. Use this value for any subsequent updates |
To verify the change, follow up with
GET /api/v2/ticketing/ticket/{objectId}. The returnedetagwill match the value above anddata.<field-uuid>will reflect the new value.
Error Responses
| Status Code | Error code | Description |
|---|---|---|
400 Bad Request | ETAG_MISMATCH | The ticket has been modified since the caller fetched it. Re-fetch the ticket to obtain the current etag and resubmit |
400 Bad Request | INPUT_VALIDATION_FAILURE | One or more field values failed validation. The validationResult.reason map names the offending field UUIDs and validation messages |
401 Unauthorized | USER_PERMISSION_FAILURE | The caller authenticated successfully but is not permitted to update this ticket |
404 Not Found | (JSON) | objectId does not exist for this tenant |
500 Internal Server Error | (none) | Unexpected server-side error during processing |
Example — Etag Mismatch:
{
"error": true,
"code": "ETAG_MISMATCH",
"message": "Ticket might have been updated. Please check changes and resubmit",
"status": 400
}
Example — Permission Failure:
{
"error": true,
"code": "USER_PERMISSION_FAILURE",
"message": "You do not have the permission to update the ticket",
"status": 401
}
Example — Ticket Not Found:
{
"error": true,
"message": "Ticket not found (REQ-9999)"
}
Notes
-
Etag is required. The endpoint will not accept an update without
etag. Fetching the ticket viaGET /api/v2/ticketing/ticket/{objectId}returns the current value at the top level. -
Etag changes on every write. A successful
PATCHreturns a newetag. Subsequent updates must use the returned value, not the one originally read. -
Field UUIDs. The keys inside
ticketUpdateare the same field UUIDs used at create time. Discover them viaGET /api/v2/ticketing/ticket-type(fields[].id), or by reading the existing ticket'sdataobject. -
Partial update semantics. Only the keys you send are written. To clear a value, send the empty form for that field type (
""for text,nullfor nullable references,[]for arrays). -
Path uses display ID, not UUID. Use the
object_id(e.g.REQ-0509), not the internalidUUID, in the URL. AGETagainst the internal UUID returns404 Ticket not found. -
Audit trail. Updates are recorded in the ticket's
lastUpdatedBy. Service-account writes appear under the SA subject (e.g.sa-tenant-…). -
Multi-tenancy. The
x-tenantidheader and thetenant_idclaim inside the JWT must agree. Mismatches return404 Tenant not found. -
Concurrent updates. When multiple clients update the same ticket, the server serializes them via etag. The losing caller receives
400 ETAG_MISMATCHand must rebase its change on the latest read.