API reference: messages and notes
Read every message on a ticket, oldest first, and add an internal note the customer never sees.
Last updated
A ticket's thread holds customer emails, replies and internal notes. Attachments come back by name only. Every sample reads the key from CURRENT_API_KEY and calls https://api.current.day/v1.
/v1/tickets/{ticket_id}/messagesNeeds the tickets:read scope. Pages with a cursor.
Reads every message on a ticket, oldest first: customer emails, replies and internal notes, with attachment names only. Pages with a cursor, at most 100 a page. It changes nothing and never returns a file's contents.
Parameters
Path parameters
- ticket_iduuid or integer, 1 or moreRequired
- The ticket's id, or its number (such as 48213).
Query parameters
- limitinteger, 1 to 100Optional
- Rows per page, 1 to 100. 50 when left out.
- cursorcursorOptional
- next_cursor from the previous page.
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
curl -sS --fail-with-body "https://api.current.day/v1/tickets/6f1d2e8b-4c10-4a7e-9a52-0b8f2c5e3c1d/messages?limit=20" \
-H "Authorization: Bearer $CURRENT_API_KEY"
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": [
{
"id": "e7a2c9d1-3b5f-4e80-9c64-2d1f8a7b3e50",
"kind": "customer_message",
"channel": "email",
"author": {
"untrusted_text": "Dana Whitfield",
"source": "customer"
},
"author_is_agent": false,
"at": "2026-10-30T13:52:40.000Z",
"delivery_state": null,
"body": {
"untrusted_text": "Hi, the reception printer is offline again. Can someone take a look?",
"source": "customer"
},
"attachments": [
{
"name": {
"untrusted_text": "printer-screen.jpg",
"source": "customer"
},
"content_type": "image/jpeg",
"size_bytes": 184320
}
]
}
],
"next_cursor": null,
"has_more": false
}/v1/tickets/{ticket_id}/notesNeeds the tickets:write scope.
Adds an internal note (plain text, up to 15,000 characters) to a ticket as this agent; staff see it and the customer never does. Current emails the customer nothing (the ticket's Teams status card still updates, and a linked PSA may send its own notices). Retry with the same request_id and the note is never added twice.
Parameters
Path parameters
- ticket_iduuidRequired
- The ticket's id (read it with GET /v1/tickets/{ticket_id} or GET /v1/tickets). A number is not accepted on a change.
Header parameters
- Idempotency-KeyuuidOptional
- The same uuid as request_id, if you prefer a header. Send one or the other, or both with the same value.
Body parameters
- request_iduuidOptional
- A uuid you mint for this change. Send the same one again to retry safely: Current answers the first answer and never writes twice (kept 24 hours). Required unless the Idempotency-Key header is sent.
- bodytext, up to 15,000 charactersRequired
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 409 | conflictSomeone changed this first. Read it again, then retry. |
| 413 | bad_request (body_too_large)The request body is larger than 64 KB. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
REQUEST_ID=$(uuidgen) # a new id for this change; send the same one again only to retry it
curl -sS --fail-with-body -X POST "https://api.current.day/v1/tickets/6f1d2e8b-4c10-4a7e-9a52-0b8f2c5e3c1d/notes" \
-H "Authorization: Bearer $CURRENT_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{"request_id":"$REQUEST_ID","body":"Cleared the print queue and restarted the spooler."}
EOF
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"message_id": "b3f8e1a6-7d24-4c09-a5e3-9f2c6d1b8a74",
"ticket_id": "6f1d2e8b-4c10-4a7e-9a52-0b8f2c5e3c1d"
}
}