nexart.iodocs

    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:

    1. 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.
    2. Hash-only timestamp - only the certificateHash is 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.
    3. 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.

    Attestation Data (meta.attestation)
    // 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:

    Verification URL Formats
    // By execution ID
    https://verify.nexart.io/e/exec_abc123
    
    // By certificate hash
    https://verify.nexart.io/c/sha256%3A7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069

    The 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.

    Node Key Discovery
    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:

    • certificateHash
    • timestamp
    • nodeId
    • kid

    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:

    1. The receipt's certificateHash matches the certificateHash of the CER bundle being verified.
    2. The Ed25519 signature is valid for the canonical receipt payload.
    3. The receipt's kid resolves to a public key published by the node at /.well-known/nexart-node.json.
    4. The nodeId in the node metadata document matches the nodeId in 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

    1. Retrieve the node's public keys from node.nexart.io/.well-known/nexart-node.json
    2. Select the key matching the receipt's kid
    3. Verify the Ed25519 signature over the canonical receipt payload
    4. Confirm the receipt's certificateHash matches 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.