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 serverThe 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 / code | When it happens |
|---|---|
| 401 auth_required | Session token missing or invalid. Sign in or rotate the token. |
| 400 content_required | Request body is missing the required content field. |
| 413 content_too_large | Payload exceeds 5,000,000 character limit. Split or compress. |
| 402 notary_paywall | Free quota (3 certifications) is exhausted. Add credits at /api/stripe/notary-credits-checkout or upgrade. |
| 429 rate_limited | Strict 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
}