CertifiedData.io

Developers · Prediction Integrity

Certify a prediction

Submit a canonicalized prediction payload to the existing CertifiedData issuance endpoint. Receive a signed certificate that any party can verify independently.

This page documents the production certificate issuance flow with the prediction payload convention. No new endpoint is required — the same canonicalization, hashing, and Ed25519 signing pipeline that powers every other CertifiedData certificate handles predictions.

1. Build the prediction payload

The payload is what gets canonicalized, hashed, and signed. Use the prediction_receipt.v1 schema.

{
  "artifact_type": "prediction",
  "artifact_schema": "prediction_receipt.v1",
  "source": "your-platform-id",
  "prediction_id": "pred_01j9k2m...",
  "model_version": "v3.2",
  "predicted_at": "2026-05-14T12:03:24Z",
  "context_summary": "<short description of what was predicted>"
}
  • artifact_type — must be "prediction" for individual receipts.
  • predicted_at — ISO-8601 timestamp recorded when the prediction was generated, not when it was certified.
  • source — a stable identifier for the platform issuing the prediction.
  • model_version — optional but recommended; binds the prediction to the model artifact certificate when present.

2. Canonicalize and hash

The payload must be canonicalized using RFC 8785 JSON Canonicalization Scheme (JCS) before hashing. This produces deterministic bytes regardless of key ordering or whitespace.

// Node.js example using the same canonicalize package CertifiedData uses
import canonicalize from "canonicalize";
import crypto from "node:crypto";

const payload = { artifact_type: "prediction", /* ... */ };
const canonical = canonicalize(payload);              // RFC 8785 JCS
const hash = crypto.createHash("sha256")
  .update(canonical, "utf-8")
  .digest("hex");
// hash is what gets signed by CertifiedData on the server

The server recomputes the canonical bytes from the submitted content, so it is fine to submit pretty-printed JSON. The canonicalization step on your end is only required if you want to verify the hash locally before submission.

3. Issue the certificate

Submit the canonicalized payload as the content field. The server computes the SHA-256 fingerprint, builds the certificate envelope, signs it with Ed25519, and returns the certificate ID.

POST /api/notary/create
Authorization: Bearer <your_session_token>
Content-Type: application/json

{
  "content": "<canonicalized prediction payload as a string>",
  "type": "text",
  "filename": "prediction-pred_01j9k2m.json"
}

Response

{
  "certificate_id": "cert_01j9k2m...",
  "certificate_type": "GENESIS",
  "schema_version": "cert.v1",
  "signature_alg": "Ed25519",
  "signing_key_id": "key_2026_q2",
  "signature": "MEYCIQDx...",
  "issued_at": "2026-05-14T12:03:25Z",
  "verify_url": "https://certifieddata.io/verify/cert_01j9k2m..."
}

Store the certificate_id alongside the prediction in your own system. Anyone with the certificate ID and the original prediction payload can verify the binding.

4. Verify independently

Verification does not require auth. Any party can fetch the signed certificate and validate it using the public signing key.

# Fetch the signed certificate manifest
curl https://certifieddata.io/api/cert/cert_01j9k2m.../manifest

# Verify in one step (server-side recompute and signature check)
curl https://certifieddata.io/api/verify/cert_01j9k2m...

# Verify by hash only
curl -X POST https://certifieddata.io/api/verify/hash \
  -H "Content-Type: application/json" \
  -d '{"hash": "sha256:a3f9b2e1..."}'

The public signing key is published at /.well-known/signing-keys.json. Verifiers can perform the entire validation offline using the published key.

5. Certify a daily prediction manifest

At the end of each period, gather the canonical hashes of every prediction issued and submit the manifest as a separate certificate. Use the prediction_manifest.v1 schema.

{
  "artifact_type": "prediction_manifest",
  "artifact_schema": "prediction_manifest.v1",
  "source": "your-platform-id",
  "period_start": "2026-05-14T00:00:00Z",
  "period_end": "2026-05-14T23:59:59Z",
  "prediction_hashes": ["sha256:abc...", "sha256:def..."],
  "manifest_hash": "sha256:xyz..."
}

Submit the canonicalized manifest payload through the same POST /api/notary/create endpoint. The resulting certificate is the canonical record of the complete prediction set for that period.

See daily prediction manifest for the rationale and selective-disclosure model.

Error handling

Status / codeWhen it happens
401 auth_requiredSession token missing or invalid. Sign in or rotate the token.
400 content_requiredRequest body is missing the required content field.
413 content_too_largePayload exceeds 5,000,000 character limit. Split or compress.
402 notary_paywallFree quota (3 certifications) is exhausted. Add credits at /api/stripe/notary-credits-checkout or upgrade.
429 rate_limitedStrict per-IP rate limit hit. Back off and retry.

Machine-readable summary

{
  "concept": "Certify prediction API",
  "concept_type": "developer-reference",
  "canonical_url": "https://certifieddata.io/developers/certify-prediction-api",
  "parent_concept": "Prediction Integrity",
  "related_concepts": [
    "Certified predictions",
    "Daily prediction manifest",
    "AI artifact verification"
  ],
  "issuance_endpoint": "POST /api/notary/create",
  "issuance_auth": "Bearer session token; rate-limited by strictApiRateLimiter",
  "verification_endpoints": [
    "GET /api/verify/:certId",
    "GET /api/cert/:certId/manifest",
    "POST /api/verify/hash"
  ],
  "canonicalization": "RFC 8785 JSON Canonicalization Scheme (JCS)",
  "signing_algorithm": "Ed25519",
  "hash_algorithm": "SHA-256",
  "public_key_url": "https://certifieddata.io/.well-known/signing-keys.json",
  "payload_schemas": [
    "prediction_receipt.v1",
    "prediction_manifest.v1"
  ],
  "quota": "3 free notarizations per user; paid credits via POST /api/stripe/notary-credits-checkout",
  "max_payload_chars": 5000000
}
Certify a Prediction — API Reference | CertifiedData | CertifiedData