Skip to main content

Create Ticket

Creates a new ticket from a service catalog offer. The endpoint accepts the dynamic field values defined by the chosen offer and persists a new ticket record bound to a team and ticket template. On success the API returns the newly created ticket, including its server-assigned UUID, human-readable display ID (e.g. CTC-0054), and current etag.


Endpoint

Method: POST URL: {{base_url}}/api/v2/ticketing/ticket/create/{teamId}/{itemTypeId}


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 create-ticket handler enforces both the OAuth scope tickets:write and realm role membership. Tokens that carry the scope but lack a write-permitted role (for example, a service-account token without ticket_agent, ticket_user, or tenant_admin) will be rejected with 401 USER_PERMISSION_FAILURE.


Headers

HeaderDescriptionRequired
AuthorizationBearer token (JWT) for authenticationYes
acceptSpecifies acceptable response formats (application/json)Yes
content-typeRequest body media type (application/json)Yes
x-tenantidUUID identifying the tenant/organizationYes
realmnameThe authentication realm nameYes
issupportrequestBoolean flag indicating if this is a support-related requestNo

Path Parameters

ParameterTypeDescriptionRequired
teamIdstringThe team slug that owns the ticket. Example: jamesYes
itemTypeIdstringThe id of the ticket type. Returned by GET /api/v2/ticketing/ticket-type for each ticket type. Example: 16910Yes

Query Parameters

ParameterTypeDescriptionRequired
typestringCatalog type. Accepted values: template, agent, userYes
modulestringThe module context. Example: ticketingYes

Request Body Schema

{
"source": "string",
"summary": "string",
"ticketBody": {
"offerId": "string",
"<field-uuid>": "<value>"
},
"attachments": {},
"ticketRelation": null
}
FieldTypeDescriptionRequired
sourcestringOrigin of the ticket. Should be apiYes
summarystringShort human-readable summary stored at the top level of the ticket record (also surfaces in list views)Yes
ticketBodyobjectMap of field-UUID → value, plus the special key offerId. Field UUIDs come from the ticket type's fields[].id values returned by GET /api/v2/ticketing/ticket-typeYes
ticketBody.offerIdstringThe id of the service catalog offer used to create this ticket. Returned by GET /api/v2/ticketing/tenant/sc/offersYes
attachmentsobjectMap of attachment metadata. Send {} when there are no attachmentsYes
ticketRelationobject | nullReference to a parent or related ticket. Send null when the new ticket has no relationYes

Field discovery: Use GET /api/v2/ticketing/ticket-type to retrieve all ticket types. Each entry's fields[].id is the UUID to send as a key in ticketBody, and fields[].defaultValue is the default value for that field. Use GET /api/v2/ticketing/tenant/sc/offers to discover the offerId to send in ticketBody.offerId.


Example cURL

curl --request POST \
--url '{{base_url}}/api/v2/ticketing/ticket/create/james/16910?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 '{
"source": "api",
"summary": "Hardware request - new laptop",
"ticketBody": {
"offerId": "23629",
"ab13e5d1-9b9d-4c3e-8fc4-e86912c8cb53": "Need a replacement laptop",
"7f111983-1013-41be-a056-989fff018bb5": "<p>Current laptop battery no longer holds charge.</p>",
"711ea9e6-1b73-4070-9eb2-941803f7f5d4": "<2week"
},
"attachments": {},
"ticketRelation": null
}'

Success Response Example

Status Code: 200 OK

{
"success": true,
"message": "ticket created successfully",
"status": 200,
"objectId": "CTC-0054",
"ticket": {
"id": "51b101e4-e689-4b86-a0bb-d3fc8188e3b1",
"tenant_id": "820188ff-2036-4924-b80f-d11610735d86",
"object_id": "CTC-0054",
"etag": "f9d8ad0b-6e4f-45a8-bc14-a11362dc61bd",
"summary": "Hardware request - new laptop",
"data": {
"ab13e5d1-9b9d-4c3e-8fc4-e86912c8cb53": "Need a replacement laptop",
"7f111983-1013-41be-a056-989fff018bb5": "<p>Current laptop battery no longer holds charge.</p>",
"711ea9e6-1b73-4070-9eb2-941803f7f5d4": "<2week",
"offerId": "23629",
"ccWatchers": [],
"toWatchers": [],
"submittedBy": "user@example.com",
"lastUpdatedBy": {
"lastName": "Doe",
"username": "user@example.com",
"firstName": "Jane"
}
},
"lookup_props": {
"teamId": "james",
"itemTypeId": "16910"
},
"moved_to": null,
"deleted_seq": -1,
"version": 2,
"status_type": "Open",
"status_category": "To-do Category",
"created_at": "2025-07-10T12:34:56.737Z",
"updated_at": "2025-07-10T12:34:56.737Z",
"id_serial": 1458684,
"metrics": [],
"slas": []
}
}
FieldTypeDescription
objectIdstringDisplay ID assigned to the new ticket. Use this in the URL path of subsequent GET and PATCH requests
ticket.idstring (UUID)Internal record ID
ticket.etagstring (UUID)Concurrency token. Required for the next update of this ticket
ticket.status_typestringInitial status (e.g. Open)
ticket.dataobjectEcho of all field values stored on the ticket, including system-populated fields

Error Responses

Status CodeError codeDescription
400 Bad RequestINPUT_VALIDATION_FAILUREOne or more fields failed validation. The validationResult.reason map names the offending field UUIDs and the validation message
401 UnauthorizedUSER_PERMISSION_FAILUREThe caller authenticated successfully, but is not permitted to create tickets. Service-account tokens without write-permitted realm roles fall into this case
403 Forbidden(none)The token's roles cannot use the requested team or item type
404 Not Found(HTML)teamId or itemTypeId does not exist for this tenant
500 Internal Server Error(none)Unexpected server-side error during processing

Example — Input Validation Failure:

{
"error": true,
"code": "INPUT_VALIDATION_FAILURE",
"message": "There occured an error during ticket data validation",
"status": 400,
"validationResult": {
"result": false,
"reason": {
"93aabbc9-fd45-407d-8569-b140bf9cc6a7": ["Field Number is required"],
"5b53c791-e047-40e8-9e88-bae13f153cc3": ["You have entered an invalid date value for Updated At, expects a proper date string"]
}
}
}

Example — Permission Failure:

{
"error": true,
"code": "USER_PERMISSION_FAILURE",
"message": "You do not have the required permissions to create ticket",
"status": 401
}

Notes

  1. Field UUIDs come from the ticket type. Before calling create, fetch ticket types via GET /api/v2/ticketing/ticket-type and read fields[].id for each field UUID (these are the keys you send in ticketBody) and fields[].defaultValue for the default.

  2. offerId and itemTypeId must agree. ticketBody.offerId is mandatory and is sent as a string. Discover it via GET /api/v2/ticketing/tenant/sc/offers. The item_type of that offer must match the itemTypeId in the URL path — a mismatch results in validation failure.

  3. Date fields. Send ISO-8601 strings (2025-07-10T12:34:56.789Z). Empty strings are rejected as invalid dates even when the offer template defaults the field to "".

  4. source value. Use api for programmatic creation. The value is stored verbatim and surfaces in audit and metric views.

  5. attachments and ticketRelation. Both are required keys. Send {} and null respectively when not used — omitting them returns 400.

  6. Display ID format. The returned objectId follows the tenant-configured prefix (e.g. REQ-####, CTC-####, PMT-####). It is the identifier used in all subsequent ticket APIs.

  7. Etag on creation. The response includes the initial etag. Cache it: the next PATCH /update call will require it.

  8. Multi-tenancy. The x-tenantid header and the tenant_id claim inside the JWT must agree. Mismatches return 404 Tenant not found.