How to create Custom (Structured) Content in Arc XP
You can create a structured content schema in two ways: in Data Manager, under Content Types, or programmatically through the Arc XP Draft API. Both produce the same schema.
This guide covers the API, which is what you want for anything repeatable: provisioning the same schema across sandbox, staging, and production, or scripting schema setup as part of a deployment pipeline. If you are defining a schema once, by hand, Data Manager is the shorter path, and it shows your organization’s schema and indexed-field usage against its limits as you build. Creating and editing schemas there requires the admin permission.
See Structured (Custom) Content in Arc XP to learn more about Structured Content.
This guide walks through a complete schema creation request using POST /draft/v1/schema-type, with a working events schema as the example.
Before you start
You need:
- A valid Arc XP API token with write access to the Draft API
- Your organization’s Arc XP API base URL (i.e.,
https://api.myorg.arcpublishing.com) - A clear picture of your schema structure: field names, types, and which fields need search indexing
That last point is the most important one to get right before sending your first request.
Plan your schema
Two decisions are hard to reverse: field types and search indexing. Both need to be right when you create the schema.
Field types are permanent. A field defined as short-text cannot become date-time. If you get this wrong, you’d need to start with a new schema.
Search indexing is configured with the search_settings object on a field. It has two independent dimensions, and both are set through the Draft API:
retrievalmakes the field queryable via the Arc XP Content API (reader-facing query/filter).editorialmakes the field searchable/filterable inside editorial tools (Data Center / Data Manager).
Each dimension is optional, and each takes exactly one index kind. A field with no search_settings is stored but not indexed for search.
Decide both for every field upfront. Think through which fields editors or developers will want to filter or search on, not just which ones need to be stored.
A schema can have up to 200 fields. The other limit that matters is how many fields you make searchable (indexed): that capacity is a pool shared across all schemas in your org, not a per-schema allowance.
Make the request
Endpoint
POST /draft/v1/schema-typeAuthentication uses a Bearer token in the Authorization header.
Request body
A schema requires name, display_name, and fields. The name is the unique machine-readable identifier: 3–30 characters, kebab-case (^[a-z0-9]+(-[a-z0-9]+)*$, e.g. calendar-event or staff-profile). It cannot be changed after creation. display_name is required (1–50 characters); description is optional (up to 500 characters).
A schema must have between 1 and 200 fields, and field keys must be unique within the schema. Each field requires key, type, and display_name — key is 3–30 characters, kebab- or snake-case (e.g. event_date), and display_name is 1–50 characters. Everything else is optional but worth including.
Field types:
| Type | Use for |
|---|---|
short-text | Titles, labels, short strings |
long-text | Descriptions, body copy |
date-time | Dates and timestamps (ISO 8601) |
geo-point | Location coordinates (lat/lng) |
Additional field types are supported, including boolean, integer, decimal, date, enum, rich-text, array (including multi-select, an array of enum), object, and reference. See field types for the full list, and validation rules to constrain field values. The valid search index kinds depend on the field type (see below).
Search indexing (search_settings):
Search indexing is set with the search_settings object. It has two optional keys — editorial and retrieval — each an array containing exactly one index kind:
"search_settings": { "editorial": ["keyword"], "retrieval": ["keyword"]}The valid index kinds depend on the field type and on the dimension (editorial vs retrieval):
| Field type | editorial kinds | retrieval kinds |
|---|---|---|
short-text | keyword, semantic | keyword |
long-text | semantic | — |
date-time | range | range |
geo-point | geo | geo |
(For the other field types: boolean, enum, and multi-select support keyword; integer, decimal, and date support range.)
The available index kinds are:
keyword— exact-match filtering and facetingsemantic— embedding/semantic searchrange— numeric and date range queriesgeo— geo-distance queries
Which kinds you can use on a field depends on its type and on whether you’re indexing it for editorial or retrieval (see the table above).
cURL example
This creates an events schema with four fields: a required title indexed for keyword search (both editorial and retrieval), an optional description, a required date, and an optional location.
curl -X POST "https://api.{YOUR_ORG}.arcpublishing.com/draft/v1/schema-type" \ -H "Authorization: Bearer {YOUR_API_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "name": "calendar-event", "display_name": "Calendar Event", "description": "Schema for event listings such as concerts, conferences, and local happenings.", "fields": [ { "key": "title", "display_name": "Event Title", "description": "Name of the event", "type": "short-text", "is_required": true, "search_settings": { "editorial": ["keyword"], "retrieval": ["keyword"] } }, { "key": "description", "display_name": "Description", "description": "Full event description visible to readers", "type": "long-text", "is_required": false }, { "key": "event_date", "display_name": "Event Date", "description": "Start date and time of the event", "type": "date-time", "is_required": true }, { "key": "venue_location", "display_name": "Venue Location", "description": "Coordinates of the event venue", "type": "geo-point", "is_required": false } ] }'Replace {YOUR_ORG} with your organization identifier and {YOUR_API_TOKEN} with a valid token.
Understand the response
A successful request returns 200 OK with the full schema object:
{ "name": "calendar-event", "display_name": "Calendar Event", "description": "Schema for event listings such as concerts, conferences, and local happenings.", "schema_version": 1, "created_at": "2026-06-26T12:00:00.000Z", "updated_at": "2026-06-26T12:00:00.000Z", "fields": [ { "key": "title", "display_name": "Event Title", "description": "Name of the event", "type": "short-text", "is_required": true, "search_settings": { "editorial": ["keyword"], "retrieval": ["keyword"] } }, { "key": "description", "display_name": "Description", "description": "Full event description visible to readers", "type": "long-text", "is_required": false }, { "key": "event_date", "display_name": "Event Date", "description": "Start date and time of the event", "type": "date-time", "is_required": true }, { "key": "venue_location", "display_name": "Venue Location", "description": "Coordinates of the event venue", "type": "geo-point", "is_required": false } ]}schema_version starts at 1 and increments with each PATCH that changes the schema. created_at and updated_at are system-managed and read-only.
Common errors
400: Invalid request Returned for all validation failures, including:
- A required property is missing (
name,display_name,fields, or a field’skey/type/display_name) - A field type is not recognized
- The request contains an unrecognized property (the API rejects unknown fields), or a field’s
validationuses a rule that is not supported for its type - An index kind is not valid for the field’s type, or more than one index kind is supplied for
editorialorretrieval - The schema has zero fields or more than 200, or two fields share the same
key - A schema with that
namealready exists — schema names are unique per organization (message:duplicate schema name '<name>' already exists); a name that belonged to a deleted schema returnsSchema has been deleted. - An org limit is exceeded (maximum number of schema types, or the org-wide indexed-field capacity, e.g.
already reached or exceeded 25 indexed fields across all schemas)
Check the error_message in the response for specifics.
403: Forbidden Structured Content is not enabled for your organization. Contact Arc XP support to enable it.
Verify the schema was created
Fetch the schema by name to confirm it looks right:
curl "https://api.{YOUR_ORG}.arcpublishing.com/draft/v1/schema-type/calendar-event" \ -H "Authorization: Bearer {YOUR_API_TOKEN}"To list all schemas in your org:
curl "https://api.{YOUR_ORG}.arcpublishing.com/draft/v1/schema-type" \ -H "Authorization: Bearer {YOUR_API_TOKEN}"