client.attest()

The headline call. Runs a payload through the orchestrator's nine stages and returns a sealed receipt containing the manifest hash.

Signature

client.attest(
    payload: str | bytes,
    program_id: str,
    route_id: str,
    registry_record_hash: str,
) -> AttestationReceipt
ArgumentTypeHTTP wire formatNotes
payloadstr or bytespayload_text (string) or payload (string)Strings sent as payload_text; bytes sent as payload (UTF-8 if possible, base64 otherwise). The wire format is always a string.
program_idstrprogram_id64-char lowercase hex
route_idstrroute_idNon-empty
registry_record_hashstrregistry_record_hash64-char lowercase hex

Payload encoding

The HTTP request body sends payload as a JSON string, not as bytes. The SDK's handling:

  • String input: Sent as payload_text in the JSON request. The orchestrator canonicalizes it with the prefix payload.v1 before hashing.
  • Bytes input (UTF-8 decodable): Decoded to string, then sent as payload_text (same as string case).
  • Bytes input (non-UTF-8): Encoded as base64, then sent as payload field (string, not bytes). The orchestrator canonicalizes it with the prefix payload.b64.v1 before hashing.

This means the bytes that get hashed depend on your input type. To ensure determinism across language implementations, always pass strings if your content is text.

Return value

AttestationReceipt. See AttestationReceipt for full field reference. Most callers just want receipt.manifest_hash.

Raises

ExceptionWhen
ValidationErrorClient-side validation failed (bad hex, empty route, wrong type)
StageErrorA specific pipeline stage rejected the run; check .stage
APIErrorAPI returned a non-2xx response that wasn't a stage error
ConnectionErrorCouldn't reach the API

All four inherit from VerdifaxError for single-except handling.

Example

from verdifax import VerdifaxClient

with VerdifaxClient() as client:
    receipt = client.attest(
        payload="hello verdifax",
        program_id="a" * 64,
        route_id="route-test",
        registry_record_hash="b" * 64,
    )
    print(receipt.manifest_hash)

Determinism

Identical inputs produce identical receipts. The SDK enforces this by canonicalizing the request body, payload_text always wins over payload when the input is a UTF-8 string.

Module-level shortcut

For one-shot scripts, verdifax.attest(...) is a convenience that constructs a client from env vars, runs the call, and closes the client:

import verdifax
receipt = verdifax.attest(
    payload="hi", program_id="a"*64, route_id="r", registry_record_hash="b"*64,
)

For high-throughput use, instantiate VerdifaxClient yourself and reuse.

Continue