Support API endpoints
These endpoints are the API side of the dashboard's Support page: list your support requests (tickets), read a conversation, open a new request, reply, and upload or download attachments. cloider support uses them, so scripts and AI agents can open a request with the logs that go with it.
All paths are relative to https://cloider.com/api. See Support for response times and what to include in a request.
At a glance
| Method | Path | Access |
|---|---|---|
| GET | /support | Read |
| GET | /support/tickets/:hashed_id | Read |
| POST | /support/tickets | Write |
| POST | /support/tickets/:hashed_id/reply | Write |
| POST | /support/attachments-uploaded | Write |
| GET | /support/attachments/:hashed_id | Read |
Support request ids and attachment ids are short upper case codes, such as K7Q2M.
The request object
{
"hashed_id": "K7Q2M",
"subject": "Database connection timeouts from the api app",
"description": "Since 09:00 UTC the api app gets connection timeouts to orders-db about once a minute.",
"ticket_type": "QuestionOrIssue",
"ticket_status": "WaitingForReply",
"business_impact": "PartiallyBlocked",
"service": "Database",
"attachments": [
{"hashed_id": "P3X8D", "filename": "api-logs.txt", "uploaded": true}
],
"user": {"first_name": "Jane", "last_name": "Doe", "picture": ""},
"agent": {"first_name": "Sam", "last_name": "Lee", "picture": ""},
"created_at": "2026-10-20T09:42:17.118204Z",
"updated_at": "2026-10-20T11:05:52.660931Z"
}
| Field | Type | Description |
|---|---|---|
hashed_id | string | The request's id |
subject, description | string | What the request is about |
ticket_type | string | QuestionOrIssue, FeatureRequest, DocumentationIssue, Feedback, Billing or NotListed |
ticket_status | string | Open, Pending, InProgress, OnHold, WaitingForReply, Resolved, Cancelled, Closed or Reopened |
business_impact | string | Question, Issue, PartiallyBlocked or CompletelyBlocked |
service | string | The product it is about: App, Kubernetes, Database, Bucket, Registry, Volume, LoadBalancer, Domain or Other. Older requests can show a database engine instead, such as PostgreSQL |
attachments | object list | Files attached to the request itself, each with its hashed_id, filename and whether it was uploaded |
user | object | Who opened it: first_name, last_name, picture |
agent | object or null | The support agent handling it, or null |
created_at, updated_at | string | When it was opened and last changed |
List support requests
GET /support
Returns the account's support requests, oldest first. The list is a summary: user and agent aren't filled in and attachments is empty. Get a single request for the full conversation.
Access: any token.
curl https://cloider.com/api/support \
-H "Authorization: Bearer $CLOIDER_TOKEN"
[
{
"hashed_id": "K7Q2M",
"subject": "Database connection timeouts from the api app",
"description": "Since 09:00 UTC the api app gets connection timeouts to orders-db about once a minute.",
"ticket_type": "QuestionOrIssue",
"ticket_status": "WaitingForReply",
"business_impact": "PartiallyBlocked",
"service": "Database",
"attachments": [],
"user": {"first_name": "", "last_name": "", "picture": ""},
"agent": null,
"created_at": "2026-10-20T09:42:17.118204Z",
"updated_at": "2026-10-20T11:05:52.660931Z"
}
]
Get a request and its replies
GET /support/tickets/:hashed_id
Returns one request with every reply, newest reply first.
Access: any token.
curl https://cloider.com/api/support/tickets/K7Q2M \
-H "Authorization: Bearer $CLOIDER_TOKEN"
{
"ticket": {
"hashed_id": "K7Q2M",
"subject": "Database connection timeouts from the api app",
"ticket_status": "WaitingForReply",
"attachments": [{"hashed_id": "P3X8D", "filename": "api-logs.txt", "uploaded": true}],
"user": {"first_name": "Jane", "last_name": "Doe", "picture": ""},
"agent": {"first_name": "Sam", "last_name": "Lee", "picture": ""},
"created_at": "2026-10-20T09:42:17.118204Z",
"updated_at": "2026-10-20T11:05:52.660931Z"
},
"replies": [
{
"reply_text": "Thanks, we see the connection limit being reached. Could you share the pool size your app uses?",
"attachments": [],
"user": {"first_name": "Sam", "last_name": "Lee", "picture": ""},
"created_at": "2026-10-20T11:05:52.660931Z",
"updated_at": "2026-10-20T11:05:52.660931Z"
}
]
}
The ticket has all the fields of the request object; some are left out above for brevity. A request that doesn't exist or belongs to another account answers 404 with Support request not found!.
Open a support request
Opening a request with attachments takes three steps: create the request, which returns a presigned upload URL for each attachment, upload the files to those URLs, then tell the API which uploads succeeded. Without attachments, step 1 is all there is.
Step 1: create the request
POST /support/tickets
Access: Read & Write token.
| Field | Type | Required | Description |
|---|---|---|---|
subject | string | Yes | At least 4 characters |
description | string | Yes | At least 20 characters. Include ids, times and error messages |
ticket_type | string | Yes | One of the ticket types |
business_impact | string | Yes | Question, Issue, PartiallyBlocked or CompletelyBlocked |
service | string | Yes | One of the services |
attachments | object list | No | Up to 5 files, each {"name", "type", "size"}: the file name, its MIME type and its size in bytes, up to 10 MB each |
Allowed attachment types are text/plain, application/pdf, application/zip, application/msword and any image/... type. Zip other files first.
curl -X POST https://cloider.com/api/support/tickets \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"subject\": \"Database connection timeouts from the api app\",
\"description\": \"Since 09:00 UTC the api app gets connection timeouts to orders-db about once a minute.\",
\"ticket_type\": \"QuestionOrIssue\",
\"business_impact\": \"PartiallyBlocked\",
\"service\": \"Database\",
\"attachments\": [{\"name\": \"api-logs.txt\", \"type\": \"text/plain\", \"size\": $(wc -c < api-logs.txt)}]
}"
{
"request_id": "K7Q2M",
"presigned_urls": [
{"id": "P3X8D", "url": "https://s3.eu-central-2.cloider.com/...api-logs?X-Amz-Signature=..."}
]
}
presigned_urls has one entry per attachment, in the order you listed them, and is absent when there are none. The request is created and the support team is notified at this point, whether or not attachments follow.
Step 2: upload the files
PUT each file to its URL with the Content-Type and size you declared. Don't send your API token to the storage URL.
curl -X PUT "$ATTACHMENT_URL" \
-H "Content-Type: text/plain" \
--data-binary @api-logs.txt
Step 3: confirm the uploads
POST /support/attachments-uploaded
Marks the attachments that uploaded successfully, so support can open them.
Access: Read & Write token.
| Field | Type | Required | Description |
|---|---|---|---|
resource_type | string | Yes | request for attachments of a new request, reply for those of a reply |
hashed_id | string | Yes | The request_id from step 1, or the reply's hashed_id |
uploaded_list | string list | Yes | The ids of the attachments whose upload succeeded |
curl -X POST https://cloider.com/api/support/attachments-uploaded \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"resource_type": "request", "hashed_id": "K7Q2M", "uploaded_list": ["P3X8D"]}'
It answers 200 when every attachment is confirmed. When some are missing from the list, it answers 400 with (1) attachments did not upload successfully!. An unknown request or reply answers 404 with request not found! or reply not found!.
Errors of step 1
| Status | Field | Message |
|---|---|---|
400 | subject | Subject is required!, Subject must not be shorter than 4 characters! |
400 | description | Description is required!, Description must not be shorter than 20 characters! |
400 | ticket_type | Invalid type! |
400 | business_impact | Invalid value! |
400 | service | Invalid service! |
400 | attachments | Only maximum of 5 files are allowed per submission, zip the files if you need more!, File (dump.sql) exceeded the allowed size of 10MB!, File (dump.sql) type is not allowed, you can zip it before uploading! |
400 | _ | Operation failed, Couldn't submit the request! |
400 | _ | Request submitted but attachments did not upload successfully!, with data holding the request_id: the request exists, only the attachments failed |
403 | _ | This API token is read only! |
Reply to a request
POST /support/tickets/:hashed_id/reply
Adds a reply to a request, optionally with attachments. Attachments follow the same three steps as for a new request, with resource_type reply and the reply's hashed_id in step 3.
Access: Read & Write token.
| Field | Type | Required | Description |
|---|---|---|---|
reply_text | string | Yes | The reply |
attachments | object list | No | Up to 5 files, as for a new request |
curl -X POST https://cloider.com/api/support/tickets/K7Q2M/reply \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"reply_text": "We use a pool of 50 connections per instance and run 3 instances."}'
{"hashed_id": "R9N4T", "created_at": "2026-10-20T11:31:04.290117Z"}
With attachments, the response also has presigned_urls. Errors: 400 Reply text is required! (on reply_text), the attachment errors above, Reply submitted but attachments did not upload successfully!, and 404 Not Found (plain text) for a request that isn't the account's.
Download an attachment
GET /support/attachments/:hashed_id
Redirects (302) to a short lived presigned URL for the file. Follow the redirect to get the bytes.
Access: any token.
curl -L -o api-logs.txt https://cloider.com/api/support/attachments/P3X8D \
-H "Authorization: Bearer $CLOIDER_TOKEN"
To get the URL instead of the file, don't follow the redirect and read the Location header:
curl -s -o /dev/null -w "%{redirect_url}\n" https://cloider.com/api/support/attachments/P3X8D \
-H "Authorization: Bearer $CLOIDER_TOKEN"
An attachment of another account's request answers 404 Not Found (plain text).
Related
- Support in the dashboard
- cloider support commands