Tickets API
Interactive Swagger UI — click Authorize to try requests with your access key, or with an OAuth client ID/secret (see Getting API Credentials for how to generate either).
See Recent Changes for what's changed in the last 6 months.
Overview
The Tickets API provides access to eSentire's Service Desk: query, create, and update cases, add comments and attachments, and look up customer contacts and locations.
Base URL: https://api.esentire.com/tickets
Case types: Alert and CSIRT cases are created by eSentire, not by customers; General Request, Technical Support, Ticketing API Test and similar case types can be created via POST /cases. "Not customer-creatable" only means you can't originate one of these cases — you can still acknowledge, comment on, and resolve an existing Alert/CSIRT case via PATCH /v2/cases/{ticket_id} the same as any other case type. Use GET /case_type_configs or GET /all_case_type_configs to look up the current valid case_type/case_subtype/service combinations rather than hardcoding them — they're configured per environment and change over time.
v1 vs v2: GET /v2/cases, GET /v2/cases/{ticket_id}, GET /v2/cases/{ticket_id}/comments, GET /v2/cases/{ticket_id}/emails and PATCH /v2/cases/{ticket_id} are the current way to list/read/update cases, comments and emails. Older GET /cases, GET /cases/{ticket_id}, GET /cases/{ticket_id}/comments, GET /cases/{ticket_id}/emails and PATCH /cases/{ticket_id} endpoints still work for existing integrations but are deprecated and will be removed in a future release — use the v2 endpoints for anything new.
Every field returned by these endpoints is described in the Swagger UI's schema definitions (Ticket, TicketV2, Comment, Email, Contact, Location, etc.) — this page focuses on what each endpoint does and behavior that isn't obvious from the request/response shape alone. Each section below links straight to that endpoint's entry in the Swagger UI.
Authentication
Requests need an Authorization header carrying either an Atlas API access key or an OAuth-issued bearer token (see Getting API Credentials):
curl -H 'Authorization: <token>' 'https://api.esentire.com/tickets/v2/cases'
read-data scope covers all GET endpoints below; write-data covers creating/updating cases and managing attachments.
Partner on-behalf-of access
If your organization is a partner managing one or more tenant customers, pass an optional tenant_code query parameter to act on behalf of a tenant you are the direct parent of. Omit it to act on your own organization, exactly as before.
- With
tenant_codeset, the request is scoped entirely to the named tenant — case lists, case details, contacts, locations, and writes all apply to the tenant, not to your own organization. tenant_codeequal to your own organization's code is treated the same as omitting it.- Returns
403if the named organization is not a direct child of yours. Returns404if the named organization doesn't exist at all, and403(separately) if it exists but isn't active. - Not supported on the deprecated v1 endpoints (
GET /cases,GET /cases/{ticket_id},GET /cases/{ticket_id}/comments,GET /cases/{ticket_id}/emails,PATCH /cases/{ticket_id}) — use the v2 endpoints for on-behalf-of access. - Authorized contact from either organization: for
acknowledged_byonPATCH /v2/cases/{ticket_id}, and forusernameon the attachment upload/delete endpoints, you can supply a contact authorized under either your own organization or the tenant's, not just the tenant's. This lets your own staff act on a tenant's ticket using their own identity, without needing to be added as a contact on every tenant they support. (This does not apply tocontactonPOST /cases, which is always validated against the tenant's own contacts.)
# List a tenant's cases, acting on behalf of tenant ACME
curl -G -H 'Authorization: <token>' \
--data-urlencode 'tenant_code=ACME' \
'https://api.esentire.com/tickets/v2/cases'
# Acknowledge a tenant's Alert case, using a contact authorized under
# your own (partner) organization rather than the tenant's
curl -X PATCH -H 'Authorization: <token>' -H 'Content-Type: application/json' \
-d '{
"username": "jane.doe@example.com",
"acknowledged": true,
"acknowledged_by": "jane.doe@example.com"
}' \
'https://api.esentire.com/tickets/v2/cases/CS2263047?tenant_code=ACME'
# Attach a file to a tenant's ticket, using a contact authorized under
# your own (partner) organization rather than the tenant's
curl -X PUT -H 'Authorization: <token>' -H 'Content-Type: text/plain' \
--data-binary @report.txt \
'https://api.esentire.com/tickets/cases/CS2263047/attachments/report.txt/jane.doe%40example.com?tenant_code=ACME'
Endpoints
Cases
List cases — GET /v2/cases
Returns a paginated list of cases, with finding_details attached for Alert-type cases. Supports fields, filters, sorts, and limit/offset (or page/per_page) query parameters. Supersedes the deprecated v1 GET /cases.
When filters is omitted or empty, an implicit updated_date >= (now - 1 day) filter is applied instead — pass an explicit filter if you need a wider window.
curl -G -H 'Authorization: <token>' \
--data-urlencode 'filters=[{"field":"created_date","op":">=","value":"2026-01-01"}]' \
'https://api.esentire.com/tickets/v2/cases'
Get case details — GET /v2/cases/{ticket_id}
Returns a single case, with finding_details instead of v1's threat_details. Supersedes the deprecated v1 GET /cases/{ticket_id}.
Create a case — POST /cases
Creates a new case, and optionally an initial comment. contact and location, if supplied, must match an existing entry from GET /customer/contacts / GET /customer/locations or the request returns 400.
curl -X POST -H 'Authorization: <token>' -H 'Content-Type: application/json' \
-d '{
"case_type": "Technical Support",
"customer_urgency": "MEDIUM",
"short_description": "Need help configuring a sensor",
"description": "Detailed description of the issue.",
"username": "jane.doe@example.com"
}' \
'https://api.esentire.com/tickets/cases'
Update a case — PATCH /v2/cases/{ticket_id}
Updates customer-defined fields, adds a comment, resolves a case, or acknowledges an Alert-type case, returning finding_details instead of v1's threat_details. Supersedes the deprecated v1 PATCH /cases/{ticket_id}. acknowledged_by, if supplied, must be an existing authorized contact or the request returns 400. resolved is the only valid target state and requires an accompanying comment. Closed and Cancelled cases can't be updated further, but Resolved cases can — a PATCH to a Resolved case (e.g. to add a comment) leaves it Resolved; omitting state does not re-open it.
curl -X PATCH -H 'Authorization: <token>' -H 'Content-Type: application/json' \
-d '{
"username": "jane.doe@example.com",
"state": "resolved",
"comments": "Issue has been resolved."
}' \
'https://api.esentire.com/tickets/v2/cases/CS2263047'
Comments & emails (v2)
List comments — GET /v2/cases/{ticket_id}/comments
Returns customer-visible comments for a case — internal work notes are never exposed through this API. Supersedes the deprecated v1 GET /cases/{ticket_id}/comments.
List emails — GET /v2/cases/{ticket_id}/emails
Returns the emails associated with a case, sourced from the Atlas notification-service. Supersedes the deprecated v1 GET /cases/{ticket_id}/emails.
Attachments
Attachments are handled by a separate backend (the eSentire Atlas platform) from the rest of the Tickets API. Every write below requires username to be an existing authorized contact (see GET /customer/contacts) with an email on file — otherwise the request returns 400.
List attachments — GET /cases/{ticket_id}/attachments
Add an attachment — POST /cases/{ticket_id}/attachments
File content ≤ 5MB can be included directly in the request body (base64-encoded if binary). For files > 5MB and ≤ 5GB, omit content instead — the response includes upload fields for uploading the file directly to secure cloud storage.
Upload an attachment (binary) — PUT /cases/{ticket_id}/attachments/{file_name}/{username}
An alternative to POST .../attachments for files ≤ 5MB, sent as a raw request body instead of JSON. file_name and username must be URL-encoded path segments.
Download an attachment — GET /cases/{ticket_id}/attachments/{file_uid}
For files ≤ 5MB, set the Accept header to the file's actual stored content type (or application/octet-stream) to get the raw bytes back, or to application/json for a JSON-wrapped response. For files > 5MB, Accept must be application/json — the response includes a temporary download URL instead of the file content. An Accept header that doesn't match the stored content type returns 400.
Delete an attachment — DELETE /cases/{ticket_id}/attachments/{file_uid}
Case type configuration
Case type configs by type — GET /case_type_configs
Returns the valid case_subtype/service combinations for one creatable case_type (required query parameter) — use this ahead of POST /cases rather than hardcoding subtype/service values, since they're configured per environment.
All case type configs — GET /all_case_type_configs
Returns every customer-visible case type config, including types (e.g. Alert, CSIRT) that customers can't create via this API, each flagged with can_create. can_create: false only means POST /cases can't originate that type — existing cases of that type can still be updated via PATCH /v2/cases/{ticket_id}.
Customer lookups
List contacts — GET /customer/contacts
Returns the customer's authorized contacts. Use this to resolve valid contact, acknowledged_by, and attachment username values before referencing them in other calls.
List locations — GET /customer/locations
Health & metadata
API info — GET /info
Returns the deployed API's name, title and version.
Connectivity check — GET /test
A lightweight connectivity check with an empty response body.
Neither endpoint needs anything beyond a valid token.
Related APIs
- Findings API - Security findings
- MVS API - Vulnerability management
- Base API Reference - General API concepts