Types are schemas. Every item has aDocumentation Index
Fetch the complete documentation index at: https://docs.myme.so/llms.txt
Use this file to discover all available pages before exploring further.
type, and its properties are validated against that type’s schema on write.
Custom types are the default path
core.* is small and narrow on purpose. Most apps register their own types — inheritance from core.* is optional, not expected.
A type earns core-set inclusion only by passing four tests:
- Life-noun. Names something a person would describe as a thing in their life, not infrastructure or app state.
- Stable shape. Canonical fields don’t change with context.
- Cross-app meaning. Multiple unrelated apps want to read each other’s writes in the raw form, without translation.
- Stewardship. The core maintainers are willing and able to own the schema long-term.
claude.memory, chatgpt.memory, cursor.memory. Different shapes are honest.
Namespacing
Five tiers. Reserved roots tell a reader (or parser) the shape at first glance.| Namespace | Purpose |
|---|---|
core.* | Platform-shipped, immutable, narrow. |
system.* | Platform-internal operational types. See System types. |
app.<app-name>.<type> | App-published types. The app. prefix separates app trust from publisher trust. |
user.<type> | Unpublished personal types, space-scoped. |
<publisher>.<type> | Community-published, installable. |
demo.web_gallery, not demo/web-gallery.
The reserved roots — core, system, app, user, marfa — cannot be claimed as publisher handles. Any first segment that isn’t a reserved root is interpreted as a publisher handle.
User types are flat by convention but can extend via inheritance where it earns its place. Sibling is the default; inherit only when every ancestor field is semantically required for your type. See Sibling vs child below and the Namespace concept page for the full grammar.
Why core file subtypes stop where they do
core.file has three subtypes: image, audio, video. There is no core.file.document.
core.file.image carries width and height; image viewers rely on those. core.file.audio and core.file.video carry duration (plus dimensions for video). core.file.document doesn’t earn a subtype — PDFs, Word docs, Markdown, plain text, EPUBs don’t share fields beyond what core.file already carries (blob_ref, mime_type); a generic file viewer reads them all the same way.
For the full rubric behind the boundary, see Authoring types — when a subtype earns its place.
The core catalog
22 types across four families. Required fields only — full schemas in the API reference.Standalone (6)
Standalone (6)
| Type | Purpose | Required |
|---|---|---|
core.note | User-authored text | body |
core.bookmark | Saved external content | — |
core.task | Something to be done | title |
core.event | Something that happens at a time | title |
core.highlight | User engagement with content | text |
core.message | Cross-platform message | body, from |
core.highlight carries its highlighted parent via a references edge, not an embedded reference. core.message is a light cross-platform handle — threading reuses the existing in-thread and parent-of edges; tool-specific richness (reactions, read receipts, channel ids) lives in app namespaces, not core. core.note and the optional bodies on core.bookmark and core.task are markdown.Entity (3)
Entity (3)
| Type | Purpose | Required |
|---|---|---|
core.entity | Things with identity | name |
core.entity.person | People | name (inherited) |
core.entity.place | Locations | name (inherited) |
core.entity.person adds given_name, family_name, pronouns, organization, job title, birthday. core.entity.place adds address components plus latitude / longitude / altitude / timezone.Media (9)
Media (9)
| Type | Purpose | Required |
|---|---|---|
core.media | Content the user engages with | title |
core.media.book | Books | title (inherited) |
core.media.article | Articles | title (inherited) |
core.media.film | Films | title (inherited) |
core.media.song | Songs | title (inherited) |
core.media.album | Albums | title (inherited) |
core.media.podcast | Podcast episodes | title (inherited) |
core.media.series | TV series | title (inherited) |
core.media.tv_episode | TV episodes | title (inherited) |
author, url, publisher, published_at, image_url, language, body, notes) and add their own (isbn, duration, section, track_number, etc.).File (4)
File (4)
| Type | Purpose | Required |
|---|---|---|
core.file | Binary content | blob_ref, mime_type |
core.file.image | Images | blob_ref, mime_type, width, height |
core.file.audio | Audio | blob_ref, mime_type, duration |
core.file.video | Video | blob_ref, mime_type, width, height, duration |
blob_ref is a SHA-256 content hash — see Items for the blob upload flow.core.message is intentionally light — body + from + optional to. Tool-specific richness (reactions, read receipts, channel ids, attachment vocabularies) varies too much per producer; apps and publishers register their own message types in their own namespaces (e.g. slack.message, apple.imessage) when they need it.There is no core.collection — collection-like groupings are custom types plus parent-of edges. See Edges.There is no core.thread — threads are implicit, defined by in-thread edges. See Edges.Custom types
Register a custom type at runtime:core.* and system.*. Core types can’t be modified or deleted via the API.
Sibling vs child
A custom type can be a sibling of a core type (its own shape, optionally declaringcompatible-with: core.<type>) or a child that inherits.
Both are first-class. Visual schema builders default to sibling — AI-assisted authoring tends toward over-inheritance, and a bad inheritance choice is hard to recover from (children cannot redefine ancestor fields). Sibling is recoverable; you can always add inheritance later.
The rubric: inherit only if every ancestor field is semantically required for your type. Otherwise sibling, optionally compatible-with.
compatible-with is a server-checkable declaration: the platform verifies at registration that your type is a structural superset of the named type, optionally under name mappings. It is not a free-text tag — claims that don’t hold are rejected.
Inheritance is single-parent and additive-only. Children may add fields; they cannot redefine or reshape ancestor fields.
Cross-discoverability differs between the two. A child appears in parent-type queries automatically — ?type=core.bookmark returns inheriting subtypes. A sibling with compatible-with does not; consumers must know the type identifier to query for it. Prefer inheritance when cross-readability by generic clients matters; stay sibling when the shape genuinely diverges. See Authoring types — cross-discoverability for the deeper trade-off.
Inheritance
A custom type can inherit from a core type.Reads inherit down
GET /items?type=core.bookmark returns both core.bookmark items and readwise.reader.document items. Each carries its actual type; inclusion is by inheritance. A generic reader querying core.bookmark can rely on every result having the core.bookmark contract — title, body, url mean the same thing across children.
Writes require the exact type
A credential withwrite core.bookmark can’t update a readwise.reader.document — writes require the specific type in scope. This prevents cross-app write-through corruption while preserving the read-side interop benefits.
The inheritance rule
Inherited fields keep their parent-type meaning in every descendant. A child type may not redefine what a parent field means. If a child needs different content, it adds a new property alongside — it doesn’t repurpose the parent’s. Example:core.bookmark.body is the user’s annotation on the bookmark. A Reader-style child type that wants to carry the parsed article text adds parsed_body (or similar) — it doesn’t redefine body to mean the article content.
Attempting to redefine a parent field at registration returns 400 inheritance_violation.
Schema evolution across inheritance
Items carryschema_version. Incrementing a parent type’s schema doesn’t automatically re-validate inheriting-type items. Inheriting types declare which parent versions they’re compatible with and migrate when ready.
Registration
- Runtime registration.
POST /typeswith a JSON schema. Admin only within the space; reserved-root namespaces (core.*,system.*) reject non-platform credentials. Types become available in the space. - Schema evolution. Types carry a version. Registering an updated type computes a structural diff against the prior version; the version bump must match the diff class (additive → minor; field removed or required-tightened → major; descriptive-only → patch). Mismatched bumps are rejected at registration. See Authoring types.
- Global publication. Community types are published under a publisher handle to the Marfa type registry; published types are referenceable by any space that opts in. See Handles and publishers.
Field types
Type field definitions support:string,integer,number,boolean,arrayurl,email,date,datetime(string types with semantic validation)enum(withenum_values)- Nested objects via
fields
required: true on the field definition. Missing required fields return 400 validation_error.
Type-specific time fields
Every item carriestimestamp — the primary user-meaningful time for the item (a photo’s captured-at, a note’s authored-at). Type-specific time properties appear only when a type genuinely carries more than one meaningful time.
core.taskaddsdue_at,completed_at, optionalstarts_at— three distinct moments, none reducible totimestamp.core.eventaddsstarts_atandends_at.core.media.*addspublished_at— the content’s publication date, distinct from when the user engaged with it.
timestamp and the type adds no extra field. A highlight’s “when-highlighted” is timestamp; there is no separate highlighted_at.
Display hints
Types may declare an optionaldisplay_hints block:
Merge policy
Types may declare an optionalmerge_policy block that controls how concurrent edits resolve per field. Long-text fields like body and notes typically keep both copies; scalars and metadata typically take the last writer’s value.
last_writer_wins and keep_both_copies. Field names in merge_policy.fields must exist in the type’s fields map. Inheritance behaves like display_hints and version_policy — a subtype’s policy merges field-by-field over its parent’s, and a subtype that omits the block inherits the parent’s wholesale.
See Conflicts for the resolution flow and the per-core-type defaults.