Support reports
Send bugs, suggestions and questions from your application to the IntelligenceBox support queue. Include screenshots, documents and logs so support receives the context in a single ticket, labelled with the source application.
Auth service address
UseAUTH_URL, the authentication service URL for your installation. This endpoint stores tickets in the cloud support service; the box address and the key received when launching an embedded app cannot be used for this request.Submit a report#
AUTH_URL/api/v1/ticketsJWT / cloud API keyCreates an open ticket for the authenticated user. It appears in the existing support queue, filterable by sourceApp.
curl --request POST "$AUTH_URL/api/v1/tickets" \
--header "Authorization: Bearer $REPORTS_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"sourceApp": "customer-portal",
"type": "BUG",
"title": "Exported PDF does not open",
"description": "Exporting from the documents page produces an unreadable PDF.",
"context": { "externalId": "PORT-123", "appVersion": "2.4.0" }
}'Authentication#
Send Authorization: Bearer <credential> with a cloud JWT signed by the auth service or an active, unexpired cloud API key. The user must exist and must not be banned. This endpoint does not accept the x-api-key header, better-auth session tokens or box-local JWTs.
Create a cloud key with the user’s JWT through POST /api/auth/api-key. The example expires after 30 days. Store the returned key in your application’s backend and use it as REPORTS_API_KEY.
curl --request POST "$AUTH_URL/api/auth/api-key" \
--header "Authorization: Bearer $USER_JWT" \
--header 'Content-Type: application/json' \
--data '{"name":"customer-portal-reports","expiresIn":2592000}'Keys with permissions: null retain full access. A restricted key must include {"tickets":["create"]}. Local box keys and embedded-app boxe_ keys are not cloud keys.
Who the ticket belongs to
The user, email and company come from the credentials and database. A shared key submits tickets as its owner; individual attribution requires each user’s credentials. Existing visibility rules for reporters, companies, partners and staff still apply.Request body#
Send JSON with Content-Type: application/json. No tRPC or SuperJSON envelope is needed. Unknown fields are rejected: the caller cannot set the user, company, status, priority or support notes.
sourceAppstringrequired- Application name, 1–60 characters. Starts with an ASCII letter or digit; spaces, dots, underscores and hyphens are also allowed. Converted to lowercase, with spaces and underscores becoming hyphens: Portale Web → portale-web. This is a declared source, not a verified identity.
titlestringrequired- Title, 3–200 characters after trimming leading and trailing whitespace.
descriptionstringrequired- Description, 1–10,000 characters after trimming leading and trailing whitespace.
type"BUG" | "SUGGESTION" | "QUESTION"- BUG for a problem, SUGGESTION for a proposal, QUESTION for a question.Default:
BUG. brandstring- Brand associated with the report, up to 100 characters.
screenshotstring- Data URL starting with data:image/, up to 4,000,000 characters. Do not send a remote URL.
attachmentstring- One document as a data URL starting with data:, up to 8,000,000 characters.
attachmentNamestring- Document name, up to 255 characters. Directory components are removed; the fallback is allegato. Ignored when attachment is absent.
attachmentMimestring- Document MIME type, up to 255 characters. Ignored when attachment is absent.
uiLogsobject[]- Up to 500 entries per array. Each entry contains ts (max 40 characters), level (16), message (4,000) and optionally src (120).
serverLogsobject[]- Up to 500 entries per array. Each entry contains ts (max 40 characters), level (16), message (4,000) and optionally src (120).
contextobject- JSON metadata such as app version, page, reproduction steps or an ID in your system.
Size and usage limits#
The complete HTTP body must not exceed 20,000,000 bytes, even without Content-Length. Individual field limits also apply. Configured key quotas and rate limits are enforced; quota usage and the ticket insert share a transaction. Invalid payloads and failed saves do not consume quota.
Call from your backend
This is a server-to-server integration. Keep API keys in your backend: the auth service’s CORS policy does not enable arbitrary web origins.Response#
A successful request returns 201 Created and Cache-Control: no-store. Store ticket.id in your system. Reading tickets and conversations remain available in the support dashboard and through the auth.tickets.* APIs.
{
"ticket": {
"id": "cmexampleticket",
"createdAt": "2026-09-07T10:00:00.000Z",
"status": "OPEN",
"sourceApp": "customer-portal"
}
}Repeated submissions
Every successful POST creates a new ticket.context.externalId is metadata and does not deduplicate requests. After a timeout, verify the outcome before submitting again.Errors#
Errors return error.code and error.message. Validation errors also include error.issues with each field path and message. Internal database details are never returned.
{
"error": {
"code": "INVALID_JSON",
"message": "Il corpo della richiesta non è JSON valido"
}
}400INVALID_JSON / VALIDATION_ERROR — missing body, malformed JSON or invalid fields.401UNAUTHORIZED — missing, expired or invalid credentials, disabled key or unavailable account.403FORBIDDEN — the key does not grant tickets.create.413PAYLOAD_TOO_LARGE — body exceeds 20,000,000 bytes.415UNSUPPORTED_MEDIA_TYPE — use Content-Type: application/json.429RATE_LIMITED / QUOTA_EXCEEDED — rate limit or quota reached. RETRY_REQUEST — key changed or used concurrently: no ticket was created; retry with a short backoff if the key is still valid.500INTERNAL_ERROR — the report could not be saved.