How to return only the fields you need
Every response of the Sally API can be reduced to the fields you actually need with ?fields=. That keeps answers small and shields your integration from fields that are added later.
This page shows the parameter in a request, the rules it follows, what happens with a typo and where leaving out one field saves the most. Every example works as it stands once SALLY_TOKEN and DIRECTORY_ID are set, see the Quickstart.
Quick navigation
1. Select fields
fields is a query parameter with a comma-separated list of field names:
| Parameter | Type | Default | Description |
|---|---|---|---|
fields | string | all fields | Comma-separated first-level field names, for example recordingId,name,createdOn. |
This request lists recordings with three fields each:
- cURL
- JavaScript
- Python
curl "https://api.sally.io/v1.0/directories/$DIRECTORY_ID/recordings?fields=recordingId,name,createdOn" \
-H "Authorization: Bearer $SALLY_TOKEN"
const url = new URL(`https://api.sally.io/v1.0/directories/${directoryId}/recordings`);
url.searchParams.set('fields', ['recordingId', 'name', 'createdOn'].join(','));
const response = await fetch(url, {
headers: {Authorization: `Bearer ${process.env.SALLY_TOKEN}`},
});
const {items} = await response.json();
import os
import requests
response = requests.get(
f"https://api.sally.io/v1.0/directories/{directory_id}/recordings",
params={"fields": ",".join(["recordingId", "name", "createdOn"])},
headers={"Authorization": f"Bearer {os.environ['SALLY_TOKEN']}"},
)
items = response.json()["items"]
Each entry now carries only the named fields, the envelope stays complete:
{
"page": 1,
"pageSize": 25,
"total": 137,
"hasMore": true,
"items": [
{
"recordingId": "53e2e041-4b34-41c7-a285-634d80b3675d",
"name": "Weekly team meeting",
"createdOn": "2026-09-24T09:30:00Z"
}
]
}
The same entry with and without the parameter:
Without fields | With fields=recordingId,name,createdOn |
|---|---|
recordingId, name, durationInSeconds, isManualUpload, isTranscriptionSucceeded, isTranscriptionCompleted, transcriptionCompletionReason, languageCode, createdOn, tags | recordingId, name, createdOn |
| Fields added later appear automatically. | Fields added later do not appear. |
2. The rules
- Leave it out and you get every field, including fields added in the future. Naming your fields protects you from that.
- First-level names only. A nested list such as
attendees,tags,segmentsorsectionItemscomes whole or not at all.attendees.nameis not supported. - On a paged response the selection applies to the entries in
items. The envelope from Pagination & search (page,pageSize,total,hasMore) is always returned. - An unknown name is rejected with 400 instead of being ignored. A typo therefore fails loudly instead of quietly returning half an answer.
- Almost every endpoint accepts it. Only endpoints without a JSON body in the answer, such as deletes and file downloads, and the health check have no
fieldsparameter.
fields value | Result |
|---|---|
| (left out) | Every field, including future ones. |
recordingId,name | Exactly these two fields per entry. |
tags | The whole tags list with all its sub-fields. |
tags.name | Not supported, nested names cannot be selected. |
recordingId,nmae | 400, nmae is not a field. |
3. Unknown names are rejected
A misspelled or unsupported name answers 400 with the uniform error body:
{
"statusCode": 400,
"message": "<human-readable description of the problem>"
}
The wording of message is meant for people and can vary. The names each endpoint accepts are listed in the reference under its fields parameter, so check there when a selection fails.
4. Where it pays off
A transcript consists almost entirely of segments, a summary with details almost entirely of sectionItems. Leave one of them out and the response gets much smaller.
| Endpoint | Large field | Smaller with |
|---|---|---|
| Transcript of a recording | segments | fields=recordingId,speakers |
| Single summary | sectionItems | fields=recordingSummaryId,languageCode,summary |
| Appointment list | attendees, description | fields=appointmentId,subject,startTime |
This request fetches only the speakers of a transcript, for example to map speakers to your users before you load the text:
- cURL
- JavaScript
- Python
curl "https://api.sally.io/v1.0/directories/$DIRECTORY_ID/recordings/$RECORDING_ID/transcription?fields=recordingId,speakers" \
-H "Authorization: Bearer $SALLY_TOKEN"
const url = new URL(
`https://api.sally.io/v1.0/directories/${directoryId}/recordings/${recordingId}/transcription`,
);
url.searchParams.set('fields', 'recordingId,speakers');
const response = await fetch(url, {
headers: {Authorization: `Bearer ${process.env.SALLY_TOKEN}`},
});
const {speakers} = await response.json();
import os
import requests
response = requests.get(
f"https://api.sally.io/v1.0/directories/{directory_id}/recordings/{recording_id}/transcription",
params={"fields": "recordingId,speakers"},
headers={"Authorization": f"Bearer {os.environ['SALLY_TOKEN']}"},
)
speakers = response.json()["speakers"]
{
"recordingId": "53e2e041-4b34-41c7-a285-634d80b3675d",
"speakers": [
{
"speakerId": "b16c2c6f-d9f5-4709-a27e-41a319410893",
"speakerNumber": 1,
"name": "Anna Berger",
"emailAddress": "anna.berger@example.com"
}
]
}
The endpoints from this table in the reference, where you can try each selection with your own token: