Appearance
SOM fit check
Does your story model fit SOM 1.0? You can find out before you write any code. In the portal, open SOM fit check (under Test), paste one of your stories as your system exports it, and press Check fit. It is in every workspace, vendor and publisher, and works on a phone too.
Synthetic content only
Paste a made-up or anonymised story, never unpublished or personal material. Nothing you paste is stored or logged: the check runs once, answers, and is gone. The limit is 240,000 bytes, the same as the gateway's.
What it does with your JSON Available now
The fit check first works out what you pasted:
| You paste | The fit check |
|---|---|
A SOM message: an envelope with a payload | Checks it exactly as the gateway checks a publish, by the gateway's own dry run against your workspace's story state and its story-ownership setting, and stops before anything is stored or sent. You get the same verdict as the Playground |
A bare story.context payload, without an envelope | Wraps it in an envelope and runs the same dry run. The fields are named as your payload's own |
| A story in your own shape (anything else) | Suggests how your fields map onto story.context, lists what's missing and what wouldn't pass, and builds a starter message |
If you paste an array, the first story in it is checked.
A SOM message: every failure in plain words Available now
Each rule the gateway reports comes with:
- the field, as a readable path such as
payload.assets[0].status. For a missing or unknown field, the field itself, not only its parent; - the problem, in one sentence: "
correlation_idis required by SOM 1.0 and is missing"; - what the rule means and how to fix it, from the same catalogue as the rule pages in these docs.
Rules marked tolerated are accepted anyway: see Verdicts.
Your own shape: the mapping helper Available now
For a story in your own shape, the fit check compares your field names and value types with the story.context fields of the SOM 1.0 schema the bus validates against. It uses a fixed table of names, not AI, so the same story always gets the same answer. Some of the names it knows:
story.context field | Your field may be called |
|---|---|
story_id | id, uuid, guid, article_id, content_id, document_id |
slug | slug, slugline, catchline, keyword, working_title, name |
headline | headline, title, hed, heading, display_title |
story_type | status, state, story_status, workflow_status |
sequence_number | version, revision, rev, sequence, seq |
updated_at | updated, modified, last_modified, date_modified, changed |
story_owner | owner, assignee, editor, author, byline, reporter |
priority.level | priority, urgency, importance |
lifecycle.phase | phase, stage, workflow_stage, editorial_status |
story_meaning.summary | summary, description, abstract, dek, standfirst, teaser |
tags | tags, keywords, categories, topics, section, desk |
content_refs | url, canonical_url, link, permalink |
It looks inside wrapper objects such as data, attributes, article or fields, and reads author.name as the author, not as a headline.
You get four lists:
- Mapped: your field, the
story.contextfield it maps to, and whether the value is usable as it is (ok), usable once converted (converted, with what the conversion does, such as a number sent as a string, a date read as UTC or yourpublishedstatus read asACTIVE), or needs fixing in your system (fix at source). - Required, but missing: the fields SOM 1.0 requires that none of yours map to, why SOM needs each, and the starter value used for it.
- Would not pass as they are: values the gateway would refuse, such as a date with no recognisable format or a status with no SOM equivalent.
- Not mapped: your other fields. Where SOM carries something elsewhere, it says where: the story's text and media travel by reference, never on the bus (
content_refs,assets[]anddelivery.media_available), and publication time belongs to a telling.
Check each suggestion: a name can match and still mean something else in your system.
The starter message Available now
The fit check builds a whole story.context message from the mapping, with starter values for what's missing (a placeholder story_id, a slug from your headline, story_type PLANNED, sequence_number1), and runs it through the gateway's dry run. Open in the Playground loads it into the Playground's editor, ready to validate; Copy JSON copies it. Replace the placeholders and your-system-id with your own values before you build on it.
story.context is a whole snapshot every time, never a delta, and sequence_number grows by one with each snapshot of a story: see Snapshots.