MeshKit

Records

Store structured app records with the same encrypted envelope model.

Use mesh.records for JSON-serializable app state that should use the same encrypted envelope, CID, and proof model as files.

Records are best for preferences, private metadata, drafts, profile fragments, workflow state, and other structured values your app wants to version or retrieve by CID.

import { meshkit } from "@meshkit/meshkit";

type Preferences = {
  theme: "light" | "dark";
  retries: number;
};

const mesh = await meshkit();

const saved = await mesh.records.put<Preferences>("user-preferences", {
  theme: "dark",
  retries: 2,
});

const preferences = await mesh.records.get<Preferences>(saved.cid);

console.log(saved.cid, preferences.theme);

Files Versus Records

Use files when...Use records when...
The payload is a document, image, export, upload, or binary valueThe payload is JSON-like application state
You care about filenames and content typesYou care about record names and TypeScript shapes
The value may be streamed or downloadedThe value should be parsed back into an object

Both APIs encrypt before storage and return a CID. The difference is how your application thinks about the payload.

How Records Work

records.put<T> JSON-encodes the value, encrypts the encoded bytes, stores the envelope, and returns a MeshFile. records.get<T> reads by CID, decrypts, and parses the JSON back into T.

The generic type parameter is for TypeScript ergonomics. MeshKit does not validate a runtime schema for you. Validate user-provided data before storing it and after reading it if the shape matters.

API

await mesh.records.put<T>(name, value, options);
await mesh.records.get<T>(cid);
ParameterTypeRequiredDescription
records.put<T>(name, value, options)string, T, PutOptionsYes for name and valueStores JSON as an encrypted MeshKit object
records.get<T>(cid)stringYesDecrypts and parses the record
options.recipientsstring[]NoWraps the data key for additional identities
options.metadataRecord<string, unknown>NoAuthenticated metadata for app routing, not secrets

What To Persist

  • Record CID
  • Logical record name
  • App schema or version
  • Owner, workspace, or tenant ID
  • Proof summary if audit matters

Common Mistakes

  • Treating the TypeScript generic as runtime validation.
  • Storing secrets in metadata instead of inside the encrypted record value.
  • Overwriting an application pointer without keeping the previous CID when users need history.
  • Assuming a record name is globally unique. The CID is the stable retrieval handle.

Failure Modes

SymptomLikely causeAction
JSON parse failsThe CID points to non-record content or incompatible schemaConfirm the CID and migrate or validate schema
key_unwrap_failedCurrent identity is not authorized for that envelopeOpen with the right identity or share the record
Record cannot be found laterApp did not persist the returned CIDStore CIDs in your application database
Works locally but not in productionProvider bytes exist but MeshKit metadata is missingValidate the metadata service and provider config

Production Notes

  • Treat record schemas as application contracts. MeshKit stores encrypted bytes; it does not manage schema migrations.
  • Keep only routing-safe values in metadata.
  • Persist current and previous CIDs when users need rollback, history, or audit.
  • Use sharing or capabilities when another identity needs access.

Next Steps

On this page