Signed Receipts
The canonical trust artifact returned by a node after it certifies a CER.
What is a Signed Receipt?
A signed receipt is the attestation proof returned by a NexArt node after it certifies a CER bundle. It is the canonical trust artifact in the NexArt protocol.
The receipt binds three things together:
- The CER's
certificateHash - The node's identity
- A timestamp
The Ed25519 signature proves the node witnessed the record at that point in time. The node does not store or own the execution data.
Canonical Location
In a certified CER bundle, attestation data lives under meta.attestation:
- meta.attestation.receipt - the canonical payload that was signed
- meta.attestation.signature - raw Ed25519 signature
- meta.attestation.kid - the signing key identifier
The API response from POST /v1/cer/ai/certify duplicates the receipt and signature at the top level for convenience, but the CER bundle is the canonical source.
Trust Hierarchy
Not all CERs have the same level of attestation. Signed receipts represent the strongest trust level:
- Signed receipt - full node attestation. The entire CER bundle is witnessed and signed. This is the canonical trust model and the default when you use
POST /v1/cer/ai/certify. - Hash-only timestamp - only the
certificateHashis signed. The node attests the hash exists at a point in time but does not witness the full snapshot. Used when full attestation is not possible. - Legacy - older records that may lack attestation data entirely. Verification coverage is limited.
For most integrations, signed receipts are what you want. They are the default output of the certify endpoint.
Receipt Structure
The receipt object is the canonical payload that gets signed. Verification is always performed against this payload.
// Inside the CER bundle at meta.attestation:
{
"receipt": {
"certificateHash": "sha256:9e8d7c6b5a4f...",
"timestamp": "2026-03-06T12:00:00.000Z",
"nodeId": "nexart-node-primary",
"kid": "key_01HXYZ..."
},
"signature": "<raw Ed25519 signature bytes>",
"kid": "key_01HXYZ..."
}Field Reference
- receipt - the canonical payload signed by the node.
- certificateHash - SHA-256 hash of the CER bundle being attested.
- timestamp - attestation time generated by the node (ISO 8601).
- nodeId - identifies which node produced the receipt.
- kid - the signing key identifier. Matches a key published at the node's well-known endpoint.
- signature - raw Ed25519 signature over the canonical receipt payload.
The API response also includes signatureB64Url (base64url encoding) for transport convenience.
Verification URLs
When you certify a record via the API, the response includes a verificationUrl. This URL points to the public verifier where anyone can independently check the record:
// By execution ID
https://verify.nexart.io/e/exec_abc123
// By certificate hash
https://verify.nexart.io/c/sha256%3A7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069The verification URL is safe to share. The public verifier shows only a redacted, public-safe representation of the record.
Key Discovery
Nodes publish their public keys at a well-known endpoint. The kid in the receipt tells you which key to use for verification.
GET node.nexart.io/.well-known/nexart-node.json
{
"nodeId": "nexart-node-primary",
"activeKid": "key_01HXYZ...",
"keys": [
{
"kid": "key_01HXYZ...",
"algorithm": "Ed25519",
"publicKey": "MCowBQYDK2VwAyEA..."
}
]
}Canonical Signing Payload
The signed payload is exactly the receipt object. The node signs the canonical JSON representation of this payload using Ed25519. The resulting signature is stored at meta.attestation.signature.
Verification must be performed against this exact payload. The canonical payload consists of the following fields only:
certificateHashtimestampnodeIdkid
Canonical JSON serialization must be deterministic: the payload is encoded as UTF-8 with stable lexicographic key ordering. This ensures that independent verifiers produce identical byte sequences and therefore identical verification results. No additional fields may be included in the signing payload.
Receipt Immutability
A signed receipt is immutable. If any field in the receipt payload is modified after signing, the Ed25519 signature becomes invalid and the attestation cannot be verified.
The receipt binds together:
- The CER's
certificateHash - The node identity (
nodeId) - The attestation timestamp
- The signing key identifier (
kid)
If the underlying CER changes, a new CER bundle and a new signed receipt must be generated. There is no mechanism to re-sign or amend an existing receipt.
This immutability is a protocol guarantee. Any mutation to a signed receipt renders the attestation unverifiable.
Verification Rules
A valid signed receipt must satisfy all of the following conditions:
- The receipt's
certificateHashmatches thecertificateHashof the CER bundle being verified. - The Ed25519 signature is valid for the canonical receipt payload.
- The receipt's
kidresolves to a public key published by the node at/.well-known/nexart-node.json. - The
nodeIdin the node metadata document matches thenodeIdin the receipt, confirming that the signing key was published by the declared node.
If any condition fails, the receipt is invalid and the attestation cannot be trusted. These rules apply uniformly to all compliant verification implementations.
Verifying a Receipt
- Retrieve the node's public keys from
node.nexart.io/.well-known/nexart-node.json - Select the key matching the receipt's
kid - Verify the Ed25519 signature over the canonical receipt payload
- Confirm the receipt's
certificateHashmatches the CER bundle
This process requires no API access to NexArt. You only need the CER bundle and the node's published public key.
You can also verify through the public verifier at verify.nexart.io.
Protocol Version Binding
Receipts are bound to the CER protocol version used by the bundle they attest. The receipt proves that the node witnessed the record according to the protocol rules applicable at that time.
Verification tools must interpret the receipt according to the CER Protocol rules applicable to the attested bundle. A receipt signed under an earlier protocol version remains valid when verified against the rules of that version.
Future protocol revisions may extend receipt structures while preserving backward verification compatibility. Historical receipts must remain independently verifiable under their original protocol semantics.
Scope
The current NexArt trust model is centered on a canonical attestation node. The receipt protocol is designed so that independent node implementations can verify and interoperate against the same receipt structure in the future, but this page describes the current canonical trust model only.