Errors

The ITSM API uses conventional HTTP status codes to indicate the success or failure of a request. Every error response follows a consistent JSON structure that includes a machine-readable error code, a human-readable message, and a unique request ID for troubleshooting.


Error response format

All error responses from the ITSM API share a consistent structure. The top-level success field is always false for errors, and the error object contains everything you need to understand and handle the failure.

  • Name
    success
    Type
    boolean
    Description

    Always false for error responses.

  • Name
    error.code
    Type
    string
    Description

    A machine-readable error code such as VALIDATION_ERROR or NOT_FOUND. Use this for programmatic error handling.

  • Name
    error.message
    Type
    string
    Description

    A human-readable description of what went wrong.

  • Name
    error.details
    Type
    object
    Description

    Additional context about the error. For validation errors, this includes field-level details. May be null for some error types.

  • Name
    error.requestId
    Type
    string
    Description

    A unique identifier for this request, prefixed with req_. Include this when contacting support.

  • Name
    error.timestamp
    Type
    string
    Description

    ISO 8601 timestamp of when the error occurred.

  • Name
    error.path
    Type
    string
    Description

    The API endpoint path that generated the error.

Error response structure

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Ticket title is required",
    "details": {
      "field": "title",
      "constraint": "isNotEmpty"
    },
    "requestId": "req_abc123",
    "timestamp": "2026-02-24T10:00:00Z",
    "path": "/v1/tickets"
  }
}

Success status codes

These status codes indicate that the request was processed successfully.

  • Name
    200 OK
    Description

    The request succeeded. Returned for successful GET, PUT, and PATCH requests. The response body contains the requested or updated resource.

  • Name
    201 Created
    Description

    A new resource was created successfully. Returned for successful POST requests. The response body contains the newly created resource.

  • Name
    204 No Content
    Description

    The request succeeded but there is no content to return. Returned for successful DELETE requests. The response body is empty.


Client error status codes

These status codes indicate a problem with the request. Check the error code and message fields for details on what to fix.

400 Bad Request

The request body or query parameters contain invalid data. The details object provides field-level information about what failed validation.

  • Name
    VALIDATION_ERROR
    Description

    One or more fields failed validation. The details object contains the specific field name and the constraint that was violated (e.g., isNotEmpty, isEmail, maxLength).

400 Validation error

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Ticket title is required",
    "details": {
      "field": "title",
      "constraint": "isNotEmpty"
    },
    "requestId": "req_v4l1d8t10n",
    "timestamp": "2026-02-24T10:00:00Z",
    "path": "/v1/tickets"
  }
}

401 Unauthorized

The request lacks valid authentication credentials. This can happen when the token is missing, expired, or malformed.

  • Name
    AUTHENTICATION_ERROR
    Description

    No authentication credentials were provided, or the credentials are invalid. Ensure you are sending the Authorization: Bearer header.

  • Name
    TOKEN_EXPIRED
    Description

    The access token has expired. Use your refresh token to obtain a new access token via POST /v1/auth/refresh.

  • Name
    TOKEN_INVALID
    Description

    The token is malformed or was signed with an unrecognized key. Re-authenticate to obtain a fresh token.

401 Token expired

{
  "success": false,
  "error": {
    "code": "TOKEN_EXPIRED",
    "message": "Access token has expired",
    "details": null,
    "requestId": "req_t0k3n3xp",
    "timestamp": "2026-02-24T10:15:00Z",
    "path": "/v1/tickets"
  }
}

403 Forbidden

The authenticated user does not have permission to perform the requested action. Unlike 401, the credentials are valid but the user's role or account state prevents access.

  • Name
    AUTHORIZATION_ERROR
    Description

    The user does not have the required role or permission for this operation. Check the user's assigned role and the endpoint's required permissions.

  • Name
    ACCOUNT_LOCKED
    Description

    The user's account has been locked, typically due to repeated failed login attempts or an administrator action. Contact your organization's ITSM administrator.

403 Authorization error

{
  "success": false,
  "error": {
    "code": "AUTHORIZATION_ERROR",
    "message": "Insufficient permissions to delete tickets",
    "details": {
      "requiredRole": "admin",
      "currentRole": "agent"
    },
    "requestId": "req_4uth0r1z",
    "timestamp": "2026-02-24T10:20:00Z",
    "path": "/v1/tickets/tkt_9f8a7b6c5d4e3f2a"
  }
}

404 Not Found

The requested resource does not exist or is not accessible to the authenticated user.

  • Name
    NOT_FOUND
    Description

    No resource was found matching the provided identifier. Verify the ID is correct and that the resource belongs to your organization.

404 Not found

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Ticket not found",
    "details": {
      "resource": "ticket",
      "id": "tkt_nonexistent123"
    },
    "requestId": "req_n0tf0und",
    "timestamp": "2026-02-24T10:25:00Z",
    "path": "/v1/tickets/tkt_nonexistent123"
  }
}

409 Conflict

The request conflicts with the current state of a resource. This typically occurs when a business logic constraint is violated, such as attempting to close a ticket that is already closed or creating a duplicate resource.

  • Name
    CONFLICT
    Description

    The operation cannot be completed due to a conflict with the current resource state. The details object describes the specific conflict.

409 Conflict

{
  "success": false,
  "error": {
    "code": "CONFLICT",
    "message": "Ticket is already resolved",
    "details": {
      "resource": "ticket",
      "id": "tkt_9f8a7b6c5d4e3f2a",
      "currentStatus": "resolved"
    },
    "requestId": "req_c0nfl1ct",
    "timestamp": "2026-02-24T10:30:00Z",
    "path": "/v1/tickets/tkt_9f8a7b6c5d4e3f2a/close"
  }
}

429 Too Many Requests

You have exceeded the API rate limit. The ITSM API enforces per-organization rate limits using a Redis-backed token bucket. Check the Retry-After response header to determine how long to wait before retrying.

  • Name
    RATE_LIMIT_EXCEEDED
    Description

    Too many requests in a given time window. Back off and retry after the duration indicated in the Retry-After header.

429 Rate limit exceeded

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Retry after 30 seconds.",
    "details": {
      "limit": 1000,
      "window": "60s",
      "retryAfter": 30
    },
    "requestId": "req_r4t3l1m1t",
    "timestamp": "2026-02-24T10:35:00Z",
    "path": "/v1/tickets"
  }
}

Server error status codes

These status codes indicate an issue on the ITSM platform side. If you encounter these persistently, contact support with the requestId.

500 Internal Server Error

An unexpected error occurred while processing the request. These are not your fault and the ITSM engineering team is automatically alerted.

  • Name
    INTERNAL_ERROR
    Description

    An unexpected internal error occurred. Retry the request after a brief delay. If the problem persists, contact support with the requestId.

500 Internal error

{
  "success": false,
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "An unexpected error occurred",
    "details": null,
    "requestId": "req_1nt3rn4l",
    "timestamp": "2026-02-24T10:40:00Z",
    "path": "/v1/tickets"
  }
}

503 Service Unavailable

A downstream service that the API depends on is temporarily unavailable. This can occur when the AI triage engine, the background job queue, or another infrastructure component is experiencing issues.

  • Name
    SERVICE_UNAVAILABLE
    Description

    A required service (AI engine, job queue, database, etc.) is temporarily unavailable. Retry with exponential backoff. The details object may indicate which service is affected.

503 Service unavailable

{
  "success": false,
  "error": {
    "code": "SERVICE_UNAVAILABLE",
    "message": "AI triage service is temporarily unavailable",
    "details": {
      "service": "ai-triage",
      "retryAfter": 60
    },
    "requestId": "req_s3rv1c3",
    "timestamp": "2026-02-24T10:45:00Z",
    "path": "/v1/tickets"
  }
}

Handling errors in your application

We recommend building a centralized error handler that inspects the error.code field and takes appropriate action. Here is a reference implementation that handles the most common error scenarios, including automatic token refresh and retry with backoff for rate limits and transient failures.

async function itsmRequest(url, options = {}) {
  const response = await fetch(url, {
    ...options,
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
      ...options.headers,
    },
  })

  if (response.ok) return response.json()

  const { error } = await response.json()

  switch (error.code) {
    case 'TOKEN_EXPIRED':
      await refreshAccessToken()
      return itsmRequest(url, options) // retry once

    case 'RATE_LIMIT_EXCEEDED':
      const delay = error.details?.retryAfter ?? 30
      await new Promise((r) => setTimeout(r, delay * 1000))
      return itsmRequest(url, options)

    case 'VALIDATION_ERROR':
      console.error(`Field "${error.details.field}": ${error.message}`)
      throw error

    default:
      console.error(`[${error.code}] ${error.message} (${error.requestId})`)
      throw error
  }
}

Was this page helpful?