API · Conventions
Metadata
Flat string-to-string map. 50 keys, 40 char keys, 500 char values. matter_ prefix reserved.
Last updated
TL;DR. Every resource carries a metadata field — flat map<string, string>. Up
to 50 keys per resource, 40 chars per key, 500 chars per value. The matter_ prefix
is reserved for platform-written fields. Never store secrets in metadata.
Every resource in the Matter API carries a metadata field — a flat map<string, string>
for storing arbitrary customer-owned data.
Limits
- Up to 50 keys per resource.
- Keys: up to 40 characters, charset
[A-Za-z0-9_\-.]. - Values: up to 500 characters.
- Keys prefixed
matter_are reserved for platform use and will be rejected with400.
Typical patterns
Link Matter resources to your own customer identifiers:
{
"metadata": {
"customer_id": "cus_7Hpx9WxY",
"portfolio_tag": "y-combinator-w26",
"owner_team": "compliance-bot-v2",
"internal_notes": "Dissolution requested via support ticket #1234"
}
}Queryability
Metadata is filterable on list endpoints and in the search DSL.
Exact-match filtering on list endpoints:
GET /v1/entities?metadata[fund]=fund-iii&metadata[environment]=productionMultiple pairs AND together. Prefer sparse keys — every filtered key incurs an index cost. A handful of long-lived keys (customer ID, portfolio tag, owner team) is the sweet spot.
Boolean composition in search:
POST /v1/entities/search
{ "query": "metadata['fund']:'fund-iii' AND (status:'active' OR status:'registered')" }See /api/tooling/search for the full DSL.
Metadata indexing is best-effort — new values are queryable within ~1 minute. For
strong read-after-write semantics on metadata, use the retrieve endpoint and check
metadata.key directly.
Mutation
Any mutation that accepts metadata in the request body replaces the entire map. To
merge, read first and post the merged map:
const entity = await matter.entities.retrieve("ent_...");
await matter.entities.update("ent_...", {
metadata: { ...entity.metadata, portfolio_tag: "y-combinator-s26" }
});Deletion
Pass an empty value to remove a single key:
{ "metadata": { "portfolio_tag": "" } }Pass an empty object to clear all metadata:
{ "metadata": {} }Audit
Metadata changes are captured in AuditEntry.before / after like any other field. If you
use metadata to carry business-critical routing (e.g., owner_team), a malicious change is
fully traceable to an actor in the audit log.