Get member correspondence history
GET /api/members/{memberId}/correspondence
Success: 200 OK
- Products: Operator (
FOH), Consumer (CONSUMER) (any one of these products, not all) - Features: Online Bookings (
ONLINEBOOK), Online Joining (ONLINEJOIN), Front of House Generic Access (FOHGENERIC) (any one of these features, not all)
Overview
Lists the correspondence trail held against a member — reception and office messages, notes staff have left, letters and mail merges sent, calls, tasks, appointments and emails. It is a single mixed feed; type tells you which kind each entry is.
Known defect — read before you build on this. Every date in the response is converted to local time. In environments where that conversion fails, any request that would return at least one entry fails with 500, while a member with no correspondence returns 200 and an empty array. If you see 500 on members with history and 200 on members without, this is what you are hitting; it is a platform fault, not something you can work around in the request. Verify the endpoint against a member who has correspondence before you rely on it.
There is no paging, despite what the response size suggests. limit caps the entries and there is no offset or continuation token, so you can take the first n or take everything.
Sort order depends on which parameters you send: filter by type and entries come back newest first by raisedDate; omit type and no ordering is applied at all, so do not rely on the sequence. Sort client-side if order matters.
Linked members are allowed here: a primary member's token can read the correspondence of a member linked to them.
Endpoint
GET {base_url}/api/members/{memberId}/correspondence
{base_url} is the environment URL issued to your integration. See Authenticating with Gladstone APIs.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
memberId | integer (int32) | Yes | The member whose correspondence you want. Must be greater than 0; 0 and -999 are rejected with 400. A well-formed member id that does not exist is not an error — you get 200 and an empty array, so this endpoint cannot be used to check whether a member exists. With a member-scoped token this may be the token's own member or a member linked to them. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer (int32) | No | Caps the number of entries returned. Defaults to 0, which means no cap. There is no offset parameter to go with it, so this cannot page through history — it only truncates. A negative value is not validated and fails with 500, so do not use one. |
type | string | No | Restricts the feed to one kind of correspondence, given by name, not number: None, ReceptionMessage, Note, OfficeMessage, Document, MailMerge, Call, Task, Appointment or Email. Matched case-insensitively, so note works. Numeric values are also accepted — 1 is parsed as Note — but anything that is neither a valid name nor a defined number is rejected with an empty 400. Omit it to get every type. Note that supplying it also changes the ordering: filtered results come back newest first, unfiltered results are unordered. |
Sample request
curl -X GET '{base_url}/api/members/{memberId}/correspondence' \
-H 'Authorization: Bearer {accessToken}' \
-H 'X-Use-SSO: true'Response fields
| Field | Type | Description |
|---|---|---|
[].id | integer (int32) | The correspondence record's own id. Use it to address the record on the update endpoint. Note that the update endpoint does not check the record belongs to the member in its route, so keep ids paired with the member you read them for. |
[].type | integer (int32) | What kind of correspondence this is, as a number even though the type filter takes a name: -1 none, 0 reception message, 1 note, 2 office message, 3 document, 4 mail merge, 5 call, 6 task, 7 appointment, 8 email. Map it back to a name yourself; the response does not carry one. |
[].subject | string | The one-line heading staff gave the item. null when none was entered. |
[].details | string | The body of the correspondence — the note text, the message, or the description of the task. null when nothing was written. |
[].conclusion | string | What the item was closed with — the outcome staff recorded when they finished with it. null while the item is still open, which is the usual state for anything outstanding. |
[].priority | integer (int32) | How urgent the item was marked. |
[].raisedByUserId | string | The staff user id that created the item. null when it was created without a user in context. Not a member id. |
[].handlerUserId | string | The staff user id the item is assigned to — who has to deal with it, as opposed to who raised it. null when nobody has been assigned. |
[].raisedDate | string (date-time) | When the item was created. This is the field that filtered results are sorted on, newest first. null on entries where it was never set, which will sort unpredictably. |
[].activateDate | string (date-time) | When the item becomes live — used for correspondence raised in advance so it does not appear in staff queues until its date. null when it was live immediately. |
[].lastActionDate | string (date-time) | When someone last worked on the item. null when nothing has happened since it was raised. |
[].nextActionDate | string (date-time) | When the item is next due to be dealt with. Unlike the other dates this one is never null, so expect a value on every entry — including entries where nothing is genuinely due, where it may hold a default rather than a meaningful date. |
[].reminderDate | string (date-time) | When staff are to be reminded about the item. null when no reminder was set. |
[].terminateDate | string (date-time) | When the item was closed off. null while it is still open — the most reliable way to tell open items from finished ones. |
[].fileName | string | The name of the file attached to the item, for document and mail-merge correspondence. null for types that carry no file. This is a name only: the endpoint does not return the file itself or a URL to it. |
[].archivingMemberId | integer (int32) |
Sample response
[
{
"id": 12345,
"type": 1,
"subject": "string",
"details": "string",
"conclusion": "string",
"priority": 1,
"raisedByUserId": "string",
"handlerUserId": "string",
"raisedDate": "2026-08-14T19:00:00Z",
"activateDate": "2026-08-14T19:00:00Z",
"lastActionDate": "2026-08-14T19:00:00Z",
"nextActionDate": "2026-08-14T19:00:00Z",
"reminderDate": "2026-08-14T19:00:00Z",
"terminateDate": "2026-08-14T19:00:00Z",
"fileName": "string",
"archivingMemberId": 12345
}
]Errors
| Status | Meaning | When |
|---|---|---|
400 | Bad request | type is neither a valid correspondence type name nor a defined type number. The response body is empty — you are not told what was wrong with it. |
400 | Bad request | memberId is 0 or negative. The body is {memberId} is an invalid member ID. |
403 | Forbidden | The token belongs to a member who is neither memberId nor linked to them. The body is The given member ID of {memberId} does not belong to the logged in member nor any linked members. |
500 | Internal server error | The date time-zone conversion fails while the entries are being read. See the warning in the Overview: this affects every request that would return at least one entry in an affected environment, and is not caused by anything in your request. |
500 | Internal server error | limit is negative, which is not validated. |