Headlessly
Concepts

Schema System

Understanding the Headless.ly type system — Nouns, Verbs, Actions, and Events.

Meta-Type Foundation

At its core, Headless.ly uses a semantic type system built on four foundational types:

Noun

Entity type definitions. Every entity in the system is a Noun.

import { Noun } from 'digital-objects'

export const Contact = Noun('Contact', {
  name: 'string!',
  email: 'string?#',
  stage: 'Lead | Qualified | Customer | Churned | Partner',
  organization: '-> Organization.contacts',
  deals: '<- Deal.contact[]',
  qualify: 'Qualified',
})

Verb

Action predicates that describe what can be done.

Verb: {
  verb: 'create',
  activity: 'Creating',
  event: 'Created',
  inverse: 'delete',
  category: 'CRUD',
}

Action

Semantic operations combining Subject + Verb + Object (GraphDL notation):

Action: {
  name: 'Create Contact',
  subject: 'User',
  verb: 'create',
  object: 'Contact',
  enabled: true,
}

Event

Past-tense outcomes that record what happened:

Event: {
  type: 'ContactCreated',
  action: 'create-contact',
  actor: 'user_fX9bL5nRd',
  target: 'contact_jH6gT3mVa',
  timestamp: '2026-01-15T12:00:00Z',
}

Schema Categories

The full schema spans these domains:

CategoryEntitiesDescription
IdentityUser, ApiKeyAuthentication and API access
CRMOrganization, Contact, Lead, Deal, Activity, PipelineCustomer relationship management
BillingCustomer, Product, Plan, Price, Subscription, Invoice, PaymentBilling and subscriptions
ProjectsProject, Issue, CommentProject and issue tracking
ContentContent, Asset, SiteContent management
SupportTicketCustomer support
AnalyticsEvent, Metric, Funnel, GoalObservability and metrics
MarketingCampaign, Segment, FormMarketing automation
ExperimentationExperiment, FeatureFlagA/B testing and feature flags
PlatformWorkflow, Integration, AgentPlatform infrastructure
CommunicationMessageMessaging

Field Notation

PatternMeaningExample
'string!'Required stringname: 'string!'
'string?'Optional stringphone: 'string?'
'string?#'Optional, indexedemail: 'string?#'
'-> Type.field'Belongs-to relationshiporganization: '-> Organization.contacts'
'<- Type.field[]'Has-many relationshipdeals: '<- Deal.contact[]'
'A | B | C'Enum (pipe-separated)stage: 'Lead | Qualified | Customer'
'PascalCase'Custom verbqualify: 'Qualified'
nullOpt out of CRUD verbupdate: null (makes immutable)

On this page