Verify a Sume TTS transcript_receipt SHA-256 yourself in Python

Recompute submitted_transcript_sha256 from your script with NFC and LF canonicalization and compare it to the transcript_receipt on a finished Sume TTS job.

5 min readSume
All posts

A Sume TTS job generated from an accepted script carries a server-owned transcript_receipt in its result. One field, submitted_transcript_sha256, is the SHA-256 of the exact transcript the job read. You can recompute it from your own copy of the script and confirm the audio was made from the words you approved.

The receipt has six fields: job_id, script_revision_id, sentence_ids, canonicalization_version (always nfc-lf-sentence-v1), submitted_transcript_sha256 and input_integrity (always source_bound). A receipt you supply yourself is not accepted as proof; Sume's own verify-spine check is the authoritative one.

The recipe

Canonicalize each block to NFC with LF line endings, cut it at ., !, ?, take the sentences named in sentence_ids, join them, add a newline wherever the selection crosses into another block, strip surrounding whitespace, and hash the UTF-8 bytes. For a selection inside one block that is simply the joined sentence text, trimmed.

import hashlib, unicodedata

def canon(t):
    t = unicodedata.normalize("NFC", t)
    return t.replace("\r\n", "\n").replace("\r", "\n")

block = canon("Hello there. This is the approved line. Extra.")
chosen = ["Hello there.", " This is the approved line."]
assert "".join(chosen) in block
transcript = "".join(chosen).strip()
print(hashlib.sha256(transcript.encode("utf-8")).hexdigest())

Reading the result

Compare the printed digest with result.transcript_receipt.submitted_transcript_sha256 from GET on the job. Equal digests mean the job read exactly those characters. A difference means a sentence was edited, the selection was different, or the line endings or Unicode form you hashed were not canonical. Fetch the job as described in Jobs and results.

For a whole-script check across many jobs, call POST /v1/tts-1.0/source/verify-spine; it also proves coverage, with no gap or overlap, which a single hash cannot.

Cost of a check

Hashing is local and free, and verify-spine is free and read-only. Only generating audio is billed, at $0.0475 per 1,000 characters.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume