Organizing Assets with Custom Metadata Schemas
Designing, creating, and using asset schemas to add structured, searchable metadata to assets -- field types, naming conventions, preset templates, search integration, and best practices.
Every asset in FileSpin has core metadata -- file name, size, content type, dimensions. But real-world asset management needs more. You need to track which campaign a photo belongs to, who approved it, what product SKU it represents, or when the usage rights expire.
Asset schemas let you define structured metadata fields for your assets, with validation, search indexing, and UI rendering -- all powered by JSON Schema standard.
What is an asset schema?
An asset schema is a JSON Schema definition that describes the custom metadata fields you want to attach to assets. Think of it as a form definition: it specifies the fields, their types, validation rules, and how they should be displayed and searched.
Schema = field definitions + validation rules + search configuration + UI hints
When you assign a schema to an asset and provide data, FileSpin:
- Validates the data against the schema before saving
- Indexes searchable fields for fast retrieval
- Renders form fields in dashboard using the UI hints
Real-World Use Cases
Asset schemas solve critical metadata challenges across industries:
- eCommerce — Track SKU, product name, category, seasonal tags, usage rights, and approval status for every product image. Schemas enable fast search-to-shelf workflows and enforcement of channel-specific metadata before syndication to Amazon, Shopify, and marketplace partners.
- Events & Conferences — Capture speaker name, session ID, sponsor affiliation, and usage rights for event photography. Face recognition pairs with metadata for automatic speaker identification, and schemas enable filtered sponsor asset delivery through branded share pages.
- Attractions & Experiences — Tag photos with guest ID, ride, location, and timestamp. Schemas power unified guest galleries ("find all my photos") and drive preview-to-purchase revenue workflows.
- Real Estate — Organize property images by listing ID, room type, and status. Schemas enable automatic portal-specific format generation and off-market watermark protection.
Getting started with preset schemas
FileSpin provides industry-specific preset schemas so you don't have to start from scratch. These cover the most common metadata patterns for different use cases.
List available presets

Available presets:
| Preset | Fields | Best for |
|---|---|---|
| Marketing | 19 | Campaign tracking, brand assets, channel distribution |
| E-Commerce & Retail | 23 | Product catalogs, SKU tracking, seasonal collections |
| Events & Conferences | 21 | Session/speaker tracking, sponsor assets |
| Attractions & Experiences | 19 | Venue management, guest photos |
| Hospitality & Travel | 20 | Hotel/venue assets, seasonal campaigns |
| Fashion & Apparel | 21 | Collections, style tracking, lookbooks |
Using presets
Presets are available for immediate use. To apply a preset to your assets, reference the preset ID when creating a schema or assigning metadata. For example, use ecommerce to tag assets with product-specific fields like SKU, category, and season.
Each preset includes a set of common fields (title, description, tags, status, project, etc.) plus industry-specific fields. You can customize them after creation by building a custom schema based on the preset structure.
Designing a custom schema
If presets don't fit your needs, you can design a schema from scratch. Here's the anatomy of a schema definition:
Schema structure
{
"name": {"en": "Product Assets"},
"status": "ACTIVE",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"product_name": {
"type": "string",
"maxLength": 200,
"filespin_properties": {
"title": {"en": "Product Name"},
"hint": {"en": "The product this asset is associated with"},
"placeholder": {"en": "e.g. Summer Hat Collection"},
"searchable": true,
"keyword_searchable": true,
"ui": {"order": 1}
}
},
"sku": {
"type": "string",
"maxLength": 50,
"filespin_properties": {
"title": {"en": "SKU"},
"searchable": false,
"keyword_searchable": false,
"ui": {"order": 2}
}
}
}
}
}
Supported field types
String fields:
"title": {
"type": "string",
"maxLength": 500
}
String with format (email):
"contact_email": {
"type": "string",
"format": "email",
"maxLength": 254
}
Date fields:
"expiration_date": {
"type": "string",
"format": "date"
}
Date values must be in YYYY-MM-DD format.
Enum fields (predefined options):
"status": {
"type": "string",
"enum": ["draft", "in_review", "approved", "published", "archived"]
}
Array fields (multiple values):
"tags": {
"type": "array",
"items": {"type": "string", "maxLength": 100}
}
Number fields:
"price": {
"type": "number"
}
Boolean fields:
"approved": {
"type": "boolean"
}
FileSpin properties
Every field should include filespin_properties to control how it behaves in search and the UI:
"filespin_properties": {
"title": {"en": "Display Label"},
"hint": {"en": "Help text shown below the field"},
"placeholder": {"en": "Placeholder text inside the input"},
"searchable": true,
"keyword_searchable": true,
"ui": {
"order": 1,
"readonly": false,
"disabled": false,
"hidden": false,
"multiline": false
}
}
| Property | Effect |
|---|---|
searchable | Field is included in full-text search |
keyword_searchable | Field contributes to the keyword search field |
ui.order | Display order in forms (lower numbers first) |
ui.multiline | Render as a text area instead of single-line input |
ui.hidden | Don't show in the form |
Creating a schema
Use the Create Asset Schema API:
curl -X POST "https://app.filespin.io/api/v1/assetschemas" \
-H "X-FileSpin-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": {"en": "Product Assets"},
"status": "ACTIVE",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"product_name_txt": {
"type": "string",
"maxLength": 200,
"filespin_properties": {
"title": {"en": "Product Name"},
"searchable": true,
"keyword_searchable": true,
"ui": {"order": 1}
}
},
"sku": {
"type": "string",
"maxLength": 50,
"filespin_properties": {
"title": {"en": "SKU"},
"searchable": false,
"ui": {"order": 2}
}
},
"category": {
"type": "string",
"enum": ["clothing", "accessories", "footwear", "electronics"],
"filespin_properties": {
"title": {"en": "Category"},
"searchable": false,
"ui": {"order": 3}
}
},
"tags": {
"type": "array",
"items": {"type": "string", "maxLength": 100},
"filespin_properties": {
"title": {"en": "Tags"},
"searchable": true,
"keyword_searchable": true,
"ui": {"order": 4}
}
}
}
}
}'
Response:
{
"id": 3
}
Creating schemas requires the SCHEMA_ADMIN permission. Typically, only ADMIN users have this.
Assigning a schema to an asset
At upload time
Include data_schema_id and custom_metadata in the upload request:
curl -X POST "https://app.filespin.io/api/v1/assets/new/content/original/upload" \
-H "X-FileSpin-Api-Key: YOUR_API_KEY" \
-F "file=@summer-hat.jpg" \
-F 'custom_metadata={"product_name": "Summer Straw Hat", "sku": "HAT-STR-001", "category": "accessories", "tags": ["summer", "straw", "beach"], data_schema_id=3}'
After upload (update metadata)
curl -X POST "https://app.filespin.io/api/v1/assets/ASSET_ID/data/update" \
-H "X-FileSpin-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data_schema_id": 3,
"data": {
"product_name": "Summer Straw Hat",
"sku": "HAT-STR-001",
"category": "accessories",
"tags": ["summer", "straw", "beach"]
},
"mode": "REPLACE"
}'
FileSpin validates the data against the schema before saving. If validation fails, a HTTP 400 response will be returned with useful error message.
Using schemas with the File Picker widget
When using the File Picker widget, assign a schema via the reserved __data_schema_id key:
var payload = {
"ASSET_ID": {
"product_namet": "Summer Straw Hat",
"sku": "HAT-STR-001",
"__data_schema_id": 3
}
};
The __data_schema_id key is not stored as data -- it only tells FileSpin which schema to associate.
Searching by schema fields
Once assets have schema data, you can search using schema_criteria:
curl -X POST "https://app.filespin.io/api/v1/assets/search" \
-H "X-FileSpin-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"schema_criteria": {
"data_schema_id": 3,
"fields": {
"category": "accessories",
"tags": "summer"
}
}
}'
You can combine schema criteria with keyword search and other filters:
curl -X POST "https://app.filespin.io/api/v1/assets/search" \
-H "X-FileSpin-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"keyword": "hat",
"content_type": "image*",
"schema_criteria": {
"data_schema_id": 3,
"fields": {
"category": "accessories"
}
}
}'
See the Search Patterns guide for more advanced search techniques.
Updating a schema
Use the Update Asset Schema API to modify schemas. You can change some things, but with restrictions to protect existing data:
What you CAN change
- Add new fields -- Existing assets won't have values for these fields, which is fine
- Increase
maxLengthfor text fields -- Makes the field accept longer values
What you CANNOT change
- Field types -- Can't change a string to a number
- Search properties (
searchable,keyword_searchable) -- Would require re-indexing - Remove fields -- Would orphan existing data
- Rename fields -- Same as remove + add, breaks existing data
- Decrease
minLength-- Would invalidate previously valid data
Since you can't change field types or search properties, plan your schema carefully before creating it. If you need incompatible changes, create a new schema and migrate assets gradually. After migration, you can deactivate the old schema by setting status: "INACTIVE".
Deleting a schema
Use the Delete Asset Schema API. Schemas can be deleted directly. To deactivate a schema instead (soft-delete), set its status to INACTIVE:
# Delete the schema
curl -X DELETE "https://app.filespin.io/api/v1/assetschemas/3" \
-H "X-FileSpin-Api-Key: YOUR_API_KEY"
Alternatively, to keep the schema but prevent new assets from using it, set it to INACTIVE:
curl -X PUT "https://app.filespin.io/api/v1/assetschemas/3" \
-H "X-FileSpin-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": 3, "status": "INACTIVE", "name": {"en": "Product Assets"}, "schema": {"$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": {}}}'
Best practices
-
Use presets as a starting point. Even if they don't match your use case exactly, they demonstrate good schema design patterns and save time.
-
Keep total metadata under 3,000 characters. This is the storage limit per asset for custom data. Avoid storing lengthy content -- keep metadata concise and descriptive.
-
Keep individual text fields under 1,000 characters. This is the per-field limit for string values.
-
Start with common fields. Fields like title, description, tags, and status are useful in almost every schema. The presets all share 11 common fields for this reason.
-
Use enums for controlled vocabularies. If a field has a fixed set of valid values (status, category, region), use
enumto enforce consistency. -
Configure search properties deliberately. Making every field
searchableandkeyword_searchableadds indexing overhead. Only enable what you actually need to query.