Skip to main content

Recordings

A recording exists once per recorded meeting. These endpoints list recordings, return their transcript and summaries, create new recordings from uploads or URLs and set their tags.

Every endpoint below shows its parameters and response fields in the middle and a request sample with an example response on the right.

Base URL https://api.sally.ioVersion v1.0 current, not frozen yetHow versioning works

Lists recordings of a directory (paginated, optionally filtered by date)​

GET/v1.0/directories/{directoryId}/recordings

Pagination via ?page + ?pageSize (max. 100). Optional ?createdAfter / ?createdBefore are UTC ISO-8601 (YYYY-MM-DDTHH:MM:SSZ, see „Dates & times" above). Sorted by creation date descending.

Field overview from the specification

Response fields:

  • page / pageSize / total / hasMore: pagination envelope (current page, page size, total count, whether more pages follow).
  • items (array): the recordings on this page. Each item has:
    • recordingId (string): id of the recording.
    • name (string | null): display name of the recording.
    • durationInSeconds (number | null): duration in seconds.
    • isManualUpload (boolean): true if manually uploaded (no meeting bot).
    • isTranscriptionSucceeded (boolean): true when a usable transcript exists. A run that finished without producing one (no spoken audio, empty file, language not detected) leaves this false.
    • isTranscriptionCompleted (boolean): true once the transcription run has finished, whether or not it produced a transcript. Tells "still running" apart from "finished without a result".
    • transcriptionCompletionReason (string enum): why the run ended. One of succeeded, noSpokenAudio, fileEmpty, languageNotDetected, error, quotaExceeded, unknown. The underlying error text is deliberately not exposed.
    • languageCode (string | null): language code of the recording (IETF language tag, e.g. de-DE, en-US).
    • createdOn (string): creation timestamp (ISO-8601).
    • tags (array): effective tags (own + inherited from linked appointments and their recurring series master). Each tag has:
      • tagId (string): id of the tag.
      • name (string): tag display name.
      • colorCode (string | null): a colour key from the Sally tag palette (a colour name like blue/red/green, not a raw hex value; full list in the schema); null if unset.

Path parameters

  • directoryIdstringrequired

    Id of the directory (the Sally company account) the resource belongs to. The directories a token can address are listed by GET /v1.0/me/directories/memberships.

Query parameters

  • pagenumberoptional

    Page number, 1-based. Defaults to 1.

  • pageSizenumberoptional

    Items per page. Defaults to 25, capped at 100.

  • createdAfterstringoptional

    Only recordings created at/after this UTC ISO-8601 timestamp (YYYY-MM-DDTHH:MM:SSZ).

  • createdBeforestringoptional

    Only recordings created at/before this UTC ISO-8601 timestamp (YYYY-MM-DDTHH:MM:SSZ).

  • fieldsstringoptional

    Comma-separated list of the fields to return. Leave it out and you get every field — including fields added in the future, which is your call to make: name your fields if you want to be shielded from that.

    Only first-level fields can be named. A nested list such as attendees, tags or sectionItems is returned whole or not at all; attendees.name is not supported.

    On a paged response the selection applies to the entries in items; page, pageSize, total and hasMore are always returned. An unknown name is rejected with 400 rather than ignored.

    Selectable here: createdOn, durationInSeconds, isManualUpload, isTranscriptionCompleted, isTranscriptionSucceeded, languageCode, name, recordingId, tags, transcriptionCompletionReason.

    Example: createdOn,durationInSeconds

Response: each entry in items

  • recordingIdstringrequired

    Id of the recording.

  • namestringrequirednullable

    Display name of the recording.

  • durationInSecondsnumberrequirednullable

    Duration in seconds.

  • isManualUploadbooleanrequired

    True if manually uploaded (no meeting bot).

  • isTranscriptionSucceededbooleanrequired

    True when a usable transcript exists. This is NOT the same as the run having finished: a recording without spoken audio finishes too, and then this stays false.

  • isTranscriptionCompletedbooleanrequired

    True once the transcription run has finished, whether or not it produced a transcript. Use this to tell "still running" apart from "finished without a result"; whether there is something to read is isTranscriptionSucceeded.

  • transcriptionCompletionReasonstringrequired

    Why the transcription run ended. unknown while it has not finished. The underlying error text is deliberately not exposed.

    Allowed values: succeedednoSpokenAudiofileEmptylanguageNotDetectederrorquotaExceededunknown
  • languageCodestringrequirednullable

    Language code of the recording (IETF language tag, e.g. de-DE, en-US).

  • createdOnstringrequired

    Creation timestamp (ISO-8601).

  • tagsobject[]required

    Effective tags (own + inherited from linked appointments and their recurring series master).

    3 child fields
    • tagIdstringrequired

      Id of the tag.

    • namestringrequired

      Tag display name.

    • colorCodestringrequirednullable

      Colour of the tag as a key from Sally's fixed tag palette — a colour NAME, not a raw hex value. One of: indigo, purple, fuchsia, pink, rose, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, slate, gray, zinc, stone, neutral. The client maps the key to the actual (light/dark) colour; null or an unknown key renders in the neutral default colour. Null if unset.

Every page also carries page, pageSize, total, hasMore.

Status codes

  • 200Success
  • 400

    Invalid request (validation error).

  • 401

    Missing or invalid bearer token.

  • 404

    Resource not found or not accessible.

  • 429

    Rate limit exceeded (per token/IP). Transcription uploads may also return code FUP_LIMIT_EXCEEDED or TOO_MANY_CONCURRENT_TRANSCRIPTIONS.

  • 500

    Internal server error.

Returns a single recording​

GET/v1.0/directories/{directoryId}/recordings/{recordingId}
Field overview from the specification

Response fields:

  • recordingId (string): id of the recording.
  • name (string | null): display name of the recording.
  • durationInSeconds (number | null): duration in seconds.
  • isManualUpload (boolean): true if manually uploaded (no meeting bot).
  • isTranscriptionSucceeded (boolean): true when a usable transcript exists. A run that finished without producing one (no spoken audio, empty file, language not detected) leaves this false.
  • isTranscriptionCompleted (boolean): true once the transcription run has finished, whether or not it produced a transcript. Tells "still running" apart from "finished without a result".
  • transcriptionCompletionReason (string enum): why the run ended. One of succeeded, noSpokenAudio, fileEmpty, languageNotDetected, error, quotaExceeded, unknown. The underlying error text is deliberately not exposed.
  • languageCode (string | null): language code of the recording (IETF language tag, e.g. de-DE, en-US).
  • createdOn (string): creation timestamp (ISO-8601).
  • tags (array): effective tags (own + inherited from linked appointments and their recurring series master). Each tag has:
    • tagId (string): id of the tag.
    • name (string): tag display name.
    • colorCode (string | null): a colour key from the Sally tag palette (a colour name like blue/red/green, not a raw hex value; full list in the schema); null if unset.

Path parameters

  • directoryIdstringrequired

    Id of the directory (the Sally company account) the resource belongs to. The directories a token can address are listed by GET /v1.0/me/directories/memberships.

  • recordingIdstringrequired

    Id of the recording.

Query parameters

  • fieldsstringoptional

    Comma-separated list of the fields to return. Leave it out and you get every field — including fields added in the future, which is your call to make: name your fields if you want to be shielded from that.

    Only first-level fields can be named. A nested list such as attendees, tags or sectionItems is returned whole or not at all; attendees.name is not supported.

    On a paged response the selection applies to the entries in items; page, pageSize, total and hasMore are always returned. An unknown name is rejected with 400 rather than ignored.

    Selectable here: createdOn, durationInSeconds, isManualUpload, isTranscriptionCompleted, isTranscriptionSucceeded, languageCode, name, recordingId, tags, transcriptionCompletionReason.

    Example: createdOn,durationInSeconds

Response

  • recordingIdstringrequired

    Id of the recording.

  • namestringrequirednullable

    Display name of the recording.

  • durationInSecondsnumberrequirednullable

    Duration in seconds.

  • isManualUploadbooleanrequired

    True if manually uploaded (no meeting bot).

  • isTranscriptionSucceededbooleanrequired

    True when a usable transcript exists. This is NOT the same as the run having finished: a recording without spoken audio finishes too, and then this stays false.

  • isTranscriptionCompletedbooleanrequired

    True once the transcription run has finished, whether or not it produced a transcript. Use this to tell "still running" apart from "finished without a result"; whether there is something to read is isTranscriptionSucceeded.

  • transcriptionCompletionReasonstringrequired

    Why the transcription run ended. unknown while it has not finished. The underlying error text is deliberately not exposed.

    Allowed values: succeedednoSpokenAudiofileEmptylanguageNotDetectederrorquotaExceededunknown
  • languageCodestringrequirednullable

    Language code of the recording (IETF language tag, e.g. de-DE, en-US).

  • createdOnstringrequired

    Creation timestamp (ISO-8601).

  • tagsobject[]required

    Effective tags (own + inherited from linked appointments and their recurring series master).

    3 child fields
    • tagIdstringrequired

      Id of the tag.

    • namestringrequired

      Tag display name.

    • colorCodestringrequirednullable

      Colour of the tag as a key from Sally's fixed tag palette — a colour NAME, not a raw hex value. One of: indigo, purple, fuchsia, pink, rose, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, slate, gray, zinc, stone, neutral. The client maps the key to the actual (light/dark) colour; null or an unknown key renders in the neutral default colour. Null if unset.

Status codes

  • 200Success
  • 400

    Invalid request (validation error).

  • 401

    Missing or invalid bearer token.

  • 404

    Resource not found or not accessible.

  • 429

    Rate limit exceeded (per token/IP). Transcription uploads may also return code FUP_LIMIT_EXCEEDED or TOO_MANY_CONCURRENT_TRANSCRIPTIONS.

  • 500

    Internal server error.

Returns the transcript of a recording (time-coded segments + speakers)​

GET/v1.0/directories/{directoryId}/recordings/{recordingId}/transcription
Field overview from the specification

Response fields:

  • recordingId (string): associated recording id.
  • speakers (array): speakers of the transcript. Each item has:
    • speakerId (string): id of the transcript speaker (referenced by each segment).
    • speakerNumber (number): speaker number.
    • name (string | null): name of the speaker.
    • emailAddress (string | null): email of the speaker.
  • segments (array): time-coded segments. Each item has:
    • speakerId (string): speaker id of the segment (resolves to the speakers list above).
    • startTime (number): start time in seconds.
    • endTime (number): end time in seconds.
    • text (string | null): transcribed text of the segment.

Path parameters

  • directoryIdstringrequired

    Id of the directory (the Sally company account) the resource belongs to. The directories a token can address are listed by GET /v1.0/me/directories/memberships.

  • recordingIdstringrequired

    Id of the recording.

Query parameters

  • fieldsstringoptional

    Comma-separated list of the fields to return. Leave it out and you get every field — including fields added in the future, which is your call to make: name your fields if you want to be shielded from that.

    Only first-level fields can be named. A nested list such as attendees, tags or sectionItems is returned whole or not at all; attendees.name is not supported.

    On a paged response the selection applies to the entries in items; page, pageSize, total and hasMore are always returned. An unknown name is rejected with 400 rather than ignored.

    Selectable here: recordingId, segments, speakers.

    Example: recordingId,segments

Response

  • recordingIdstringrequired

    Associated recording id.

  • speakersobject[]required

    Speakers of the transcript.

    4 child fields
    • speakerIdstringrequired

      Id of the transcript speaker.

    • speakerNumbernumberrequired

      Speaker number.

    • namestringrequirednullable

      Name of the speaker.

    • emailAddressstringrequirednullable

      Email of the speaker.

  • segmentsobject[]required

    Time-coded segments.

    4 child fields
    • speakerIdstringrequired

      Speaker id of the segment.

    • startTimenumberrequired

      Start time in seconds.

    • endTimenumberrequired

      End time in seconds.

    • textstringrequirednullable

      Transcribed text of the segment.

Status codes

  • 200Success
  • 400

    Invalid request (validation error).

  • 401

    Missing or invalid bearer token.

  • 404

    Resource not found or not accessible.

  • 429

    Rate limit exceeded (per token/IP). Transcription uploads may also return code FUP_LIMIT_EXCEEDED or TOO_MANY_CONCURRENT_TRANSCRIPTIONS.

  • 500

    Internal server error.

Returns the summaries of a recording​

GET/v1.0/directories/{directoryId}/recordings/{recordingId}/summaries

With ?includeDetails=true, each summary additionally embeds its section items (the structured per-section results of the meeting template). Without the parameter, only the summary texts. To fetch a single summary by id, use GET .../summaries/{recordingSummaryId}.

Field overview from the specification

Each item has:

  • recordingSummaryId (string): id of the recording summary.
  • recordingId (string): associated recording id.
  • appointmentId (string | null): associated appointment id (if present).
  • languageCode (string | null): language code of the summary (IETF language tag, e.g. de-DE, en-US).
  • summary (string | null): summary text.
  • isSummarizationCompleted (boolean): true once the summarization run has finished, whether or not it produced anything.
  • isSummarizationSucceeded (boolean): true when there is something to read: summary text or at least one section item. A run over a recording without a transcript finishes too, and then this stays false.
  • summarizationCompletionReason (string enum): why the run ended. One of succeeded, noTranscript, emptyResult, error, unknown. noTranscript is an expected outcome, not a failure. The underlying error text is deliberately not exposed.
  • createdOn (string): creation timestamp (ISO-8601).
  • sectionItems (array | null): the generated section items of the summary (structured per-section results of the meeting template). Null unless loaded (only with ?includeDetails=true). Each section item has:
    • sectionItemId (string): id of the section item.
    • meetingTemplateSectionId (string | null): id of the meeting template section this item was generated from (resolve via GET /v1.0/directories/{directoryId}/meetingtemplates/{meetingTemplateId}); null for derived items (e.g. task items).
    • title (string): title of the template section item.
    • sectionType (string enum): section type of the item. One of summary, tasks, topics, decisions, customList, freeText, unknown.
    • outputFormat (string enum): output format of the item content. One of html, markdown, unknown.
    • sortOrder (number): order within the summary.
    • content (string | null): free-text/Markdown content of the item.
    • subject (string | null): task subject (for task-like section items).
    • description (string | null): task description.
    • responsibleUserName (string | null): responsible person (name).
    • responsibleUserEmail (string | null): responsible person (email).
    • dueDate (string | null): due date (ISO-8601).

Path parameters

  • directoryIdstringrequired

    Id of the directory (the Sally company account) the resource belongs to. The directories a token can address are listed by GET /v1.0/me/directories/memberships.

  • recordingIdstringrequired

    Id of the recording.

Query parameters

  • includeDetailsbooleanoptional

    When true, every summary additionally carries its sectionItems. When omitted or false, sectionItems is null and only the summary text is returned.

  • fieldsstringoptional

    Comma-separated list of the fields to return. Leave it out and you get every field — including fields added in the future, which is your call to make: name your fields if you want to be shielded from that.

    Only first-level fields can be named. A nested list such as attendees, tags or sectionItems is returned whole or not at all; attendees.name is not supported.

    On a paged response the selection applies to the entries in items; page, pageSize, total and hasMore are always returned. An unknown name is rejected with 400 rather than ignored.

    Selectable here: appointmentId, createdOn, isSummarizationCompleted, isSummarizationSucceeded, languageCode, recordingId, recordingSummaryId, sectionItems, summarizationCompletionReason, summary.

    Example: appointmentId,createdOn

Response

  • recordingSummaryIdstringrequired

    Id of the recording summary.

  • recordingIdstringrequired

    Associated recording id.

  • appointmentIdstringrequirednullable

    Associated appointment id (if present).

  • languageCodestringrequirednullable

    Language code of the summary (IETF language tag, e.g. de-DE, en-US).

  • summarystringrequirednullable

    Summary text.

  • isSummarizationCompletedbooleanrequired

    True once the summarization run has finished, whether or not it produced anything.

  • isSummarizationSucceededbooleanrequired

    True when there is something to read: summary text or at least one section item. A run over a recording without a transcript finishes too, and then this stays false.

  • summarizationCompletionReasonstringrequired

    Why the summarization run ended. noTranscript means there was nothing to summarize, which is an expected outcome and not a failure. unknown while it has not finished. The underlying error text is deliberately not exposed.

    Allowed values: succeedednoTranscriptemptyResulterrorunknown
  • createdOnstringrequired

    Creation timestamp (ISO-8601).

  • sectionItemsobject[]requirednullable

    The generated section items of the summary (the structured, per-section results of the meeting template). Null when not loaded (the recordings list endpoint only fills this with ?includeDetails=true); the single-summary endpoint always includes it.

    12 child fields
    • sectionItemIdstringrequired

      Id of the section item.

    • meetingTemplateSectionIdstringrequirednullable

      Id of the meeting template section this item was generated from. Resolve it via GET /v1.0/directories/{directoryId}/meetingtemplates/{meetingTemplateId} (matches a section’s meetingTemplateSectionId). Null for derived items without a template section (e.g. task items).

    • titlestringrequired

      Title of the template section item.

    • sectionTypestringrequired

      Section type of the item.

      Allowed values: summarytaskstopicsdecisionscustomListfreeTextunknown
    • outputFormatstringrequired

      Output format of the item content.

      Allowed values: htmlmarkdownunknown
    • sortOrdernumberrequired

      Order within the summary.

    • contentstringrequirednullable

      Free-text/Markdown content of the item.

    • subjectstringrequirednullable

      Task subject (for task-like section items).

    • descriptionstringrequirednullable

      Task description.

    • responsibleUserNamestringrequirednullable

      Responsible person (name).

    • responsibleUserEmailstringrequirednullable

      Responsible person (email).

    • dueDatestringrequirednullable

      Due date (ISO-8601).

Status codes

  • 200Success
  • 400

    Invalid request (validation error).

  • 401

    Missing or invalid bearer token.

  • 404

    Resource not found or not accessible.

  • 429

    Rate limit exceeded (per token/IP). Transcription uploads may also return code FUP_LIMIT_EXCEEDED or TOO_MANY_CONCURRENT_TRANSCRIPTIONS.

  • 500

    Internal server error.

Starts a recording upload (step 1/2) — returns a SAS PUT URL​

POST/v1.0/directories/{directoryId}/recordings/uploads

The client then uploads the file bytes via PUT directly to the returned uploadUrl (with the requiredHeaders) and afterwards calls POST .../uploads/{uploadId}/finalize. The transcription quota (fair usage policy) is already checked here — if the quota is exhausted, 429 with code FUP_LIMIT_EXCEEDED is returned.

Field overview from the specification

Body fields:

  • fileName (string, required): original file name (incl. extension, for MIME/extension derivation).
  • mimeType (string, required): MIME type of the file (whitelist: video mp4/mkv/avi/mov/webm, audio mp3/wav/flac/ogg/amr/m4a/opus/aac).
  • sizeBytes (number, required): file size in bytes (> 0, max. 5 GB).

Path parameters

  • directoryIdstringrequired

    Id of the directory (the Sally company account) the resource belongs to. The directories a token can address are listed by GET /v1.0/me/directories/memberships.

Query parameters

  • fieldsstringoptional

    Comma-separated list of the fields to return. Leave it out and you get every field — including fields added in the future, which is your call to make: name your fields if you want to be shielded from that.

    Only first-level fields can be named. A nested list such as attendees, tags or sectionItems is returned whole or not at all; attendees.name is not supported.

    On a paged response the selection applies to the entries in items; page, pageSize, total and hasMore are always returned. An unknown name is rejected with 400 rather than ignored.

    Selectable here: maxBytes, requiredHeaders, storageMode, uploadId, uploadUrl.

    Example: maxBytes,requiredHeaders

Request body application/json

  • fileNamestringrequired

    Original file name (incl. extension, for MIME/extension derivation).

  • mimeTypestringrequired

    MIME type of the file (whitelist: video mp4/mkv/avi/mov/webm, audio mp3/wav/flac/ogg/amr/m4a/opus/aac).

    Example: audio/mpeg
  • sizeBytesnumberrequired

    File size in bytes (> 0, max. 5 GB).

Response

  • uploadIdstringrequired

    Upload token — passed along in the finalize step.

  • uploadUrlstringrequired

    Absolute Azure SAS URL. The client uploads the file bytes via PUT directly to it (no API roundtrip).

  • storageModestringrequired

    Storage mode.

    Example: azure-blob
  • requiredHeadersobjectrequired

    Headers that must be sent with the PUT.

    Example: {"x-ms-blob-type":"BlockBlob"}
  • maxBytesnumberrequired

    Maximum allowed upload size in bytes.

Status codes

  • 200Success
  • 400

    Invalid request (validation error).

  • 401

    Missing or invalid bearer token.

  • 403

    Forbidden (insufficient permissions).

  • 404

    Resource not found or not accessible.

  • 429

    Rate limit exceeded (per token/IP). Transcription uploads may also return code FUP_LIMIT_EXCEEDED or TOO_MANY_CONCURRENT_TRANSCRIPTIONS.

  • 500

    Internal server error.

Completes a recording upload (step 2/2) — creates the recording​

POST/v1.0/directories/{directoryId}/recordings/uploads/{uploadId}/finalize

Call after a successful PUT of the file bytes. Verifies the blob, creates the recording row and triggers the transcription pipeline. Returns the recordingId. If too many transcriptions of the directory are running concurrently, 429 with code TOO_MANY_CONCURRENT_TRANSCRIPTIONS is returned.

Field overview from the specification

Body fields (all optional):

  • languageCode (string, optional): language code of the audio (IETF language tag, e.g. de-DE, en-US). Omit or null to auto-detect.
  • speakerCount (number, optional): number of speakers (for diarization).
  • appointmentId (string, optional): optionally linked appointment (GUID).

Path parameters

  • directoryIdstringrequired

    Id of the directory (the Sally company account) the resource belongs to. The directories a token can address are listed by GET /v1.0/me/directories/memberships.

  • uploadIdstringrequired

    Id of the upload.

Query parameters

  • fieldsstringoptional

    Comma-separated list of the fields to return. Leave it out and you get every field — including fields added in the future, which is your call to make: name your fields if you want to be shielded from that.

    Only first-level fields can be named. A nested list such as attendees, tags or sectionItems is returned whole or not at all; attendees.name is not supported.

    On a paged response the selection applies to the entries in items; page, pageSize, total and hasMore are always returned. An unknown name is rejected with 400 rather than ignored.

    Selectable here: recordingId.

    Example: recordingId

Request body application/json

  • languageCodestringoptionalnullable

    Language code of the audio (IETF language tag, e.g. de-DE, en-US). Omit or null to auto-detect.

  • speakerCountnumberoptionalnullable

    Number of speakers (for diarization).

  • appointmentIdstringoptionalnullable

    Optionally linked appointment (GUID).

Response

  • recordingIdstringrequired

    Id of the created recording (transcription has been triggered).

Status codes

  • 200Success
  • 400

    Invalid request (validation error).

  • 401

    Missing or invalid bearer token.

  • 403

    Forbidden (insufficient permissions).

  • 404

    Resource not found or not accessible.

  • 429

    Rate limit exceeded (per token/IP). Transcription uploads may also return code FUP_LIMIT_EXCEEDED or TOO_MANY_CONCURRENT_TRANSCRIPTIONS.

  • 500

    Internal server error.

Creates a recording from a file URL (no upload needed)​

POST/v1.0/directories/{directoryId}/recordings/from-url

Sally fetches the file from the URL server-side, stores it and triggers the transcription and summarization pipeline, exactly like a finished upload. Use this instead of the two-step upload when the file is already reachable over https. The call returns once the file has been fetched and the recording exists; transcription then runs in the background, so poll GET .../recordings/{recordingId} or use a webhook for the result.

Field overview from the specification

What the URL must satisfy (each of these is enforced, and a violation returns 400):

  • https only. No http, no other scheme.
  • No credentials in the URL. A user:pass@host form is rejected.
  • Public targets only. The host is resolved and rejected if it points into a private or reserved network (loopback, private ranges, link-local including cloud metadata, CGNAT, multicast). The verified address is then pinned for the connection, so a DNS answer that changes between check and fetch cannot redirect us inside.
  • No redirects. Pass the final address; a redirect is rejected rather than followed.
  • A supported media type, either by Content-Type or by the file extension: mp4, mkv, avi, mov, webm, mp3, wav, flac, ogg, amr, m4a, opus, aac.
  • Size limit as returned by the upload endpoint (maxBytes). Both the declared Content-Length and the actual bytes are checked.

The same licence, trial and fair-usage rules apply as for an upload. If too many transcriptions of the directory are running concurrently, 429 with code TOO_MANY_CONCURRENT_TRANSCRIPTIONS is returned and nothing is fetched.

Body fields:

  • url (string): the https URL of the file.
  • name (string, optional): name of the recording. The URL is never used as the name, because presigned links carry credentials in their query string.
  • languageCode (string, optional): IETF language tag of the audio, e.g. de-DE. Omit to auto-detect.
  • speakerCount (number, optional): number of speakers, for diarization.

Path parameters

  • directoryIdstringrequired

    Id of the directory (the Sally company account) the resource belongs to. The directories a token can address are listed by GET /v1.0/me/directories/memberships.

Query parameters

  • fieldsstringoptional

    Comma-separated list of the fields to return. Leave it out and you get every field — including fields added in the future, which is your call to make: name your fields if you want to be shielded from that.

    Only first-level fields can be named. A nested list such as attendees, tags or sectionItems is returned whole or not at all; attendees.name is not supported.

    On a paged response the selection applies to the entries in items; page, pageSize, total and hasMore are always returned. An unknown name is rejected with 400 rather than ignored.

    Selectable here: recordingId.

    Example: recordingId

Request body application/json

  • urlstringrequired

    Publicly reachable https URL of the audio or video file. Must point to the file itself, not to a landing page or a redirect. Presigned links (S3, Azure Blob, Google Cloud Storage) work as long as they are valid at the time of the call.

  • namestringoptionalnullable

    Name of the recording. Defaults to a generated name if omitted; the URL is never used as the name, since presigned links carry credentials in their query string.

  • languageCodestringoptionalnullable

    Language code of the audio (IETF language tag, e.g. de-DE, en-US). Omit or null to auto-detect.

  • speakerCountnumberoptionalnullable

    Number of speakers (for diarization).

Response

  • recordingIdstringrequired

    Id of the created recording (transcription has been triggered).

Status codes

  • 200Success
  • 400

    Invalid request (validation error).

  • 401

    Missing or invalid bearer token.

  • 403

    Forbidden (insufficient permissions).

  • 404

    Resource not found or not accessible.

  • 429

    Rate limit exceeded (per token/IP). Transcription uploads may also return code FUP_LIMIT_EXCEEDED or TOO_MANY_CONCURRENT_TRANSCRIPTIONS.

  • 500

    Internal server error.

Replaces the direct tags of a recording (assign/unassign)​

PUT/v1.0/directories/{directoryId}/recordings/{recordingId}/tags

Replace-set of the recording’s DIRECT tags; tags inherited from linked appointments/series stay dynamic. Max. 20 direct tags per recording.

Field overview from the specification

Body fields:

  • tagIds (array of strings): existing tag ids to assign; the given set replaces the current one. Assigning only takes tag ids, so create the tag first via POST /v1.0/directories/{directoryId}/tags and assign it here.

Path parameters

  • directoryIdstringrequired

    Id of the directory (the Sally company account) the resource belongs to. The directories a token can address are listed by GET /v1.0/me/directories/memberships.

  • recordingIdstringrequired

    Id of the recording.

Query parameters

  • fieldsstringoptional

    Comma-separated list of the fields to return. Leave it out and you get every field — including fields added in the future, which is your call to make: name your fields if you want to be shielded from that.

    Only first-level fields can be named. A nested list such as attendees, tags or sectionItems is returned whole or not at all; attendees.name is not supported.

    On a paged response the selection applies to the entries in items; page, pageSize, total and hasMore are always returned. An unknown name is rejected with 400 rather than ignored.

    Selectable here: colorCode, name, tagId.

    Example: colorCode,name

Request body application/json

  • tagIdsstring[]optional

    Existing tag ids to assign; the given set replaces the current one.

Response

  • tagIdstringrequired

    Id of the tag.

  • namestringrequired

    Tag display name.

  • colorCodestringrequirednullable

    Colour of the tag as a key from Sally's fixed tag palette — a colour NAME, not a raw hex value. One of: indigo, purple, fuchsia, pink, rose, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, slate, gray, zinc, stone, neutral. The client maps the key to the actual (light/dark) colour; null or an unknown key renders in the neutral default colour. Null if unset.

Status codes

  • 200Success
  • 400

    Invalid request (validation error).

  • 401

    Missing or invalid bearer token.

  • 403

    Forbidden (insufficient permissions).

  • 404

    Resource not found or not accessible.

  • 429

    Rate limit exceeded (per token/IP). Transcription uploads may also return code FUP_LIMIT_EXCEEDED or TOO_MANY_CONCURRENT_TRANSCRIPTIONS.

  • 500

    Internal server error.