REST API Documentation
Total CMS provides a RESTful API for accessing content and schemas. This documentation covers all available endpoints with examples and response formats.
API Overview
Section titled “API Overview”- Base URL: Your site’s API root (e.g.,
https://yoursite.com/api) - Content Type:
application/json - Authentication: API keys (Pro edition) or session-based
Authentication
Section titled “Authentication”Total CMS supports two authentication methods for API access: API Keys (recommended for external applications, Pro edition required) and Session Authentication (for same-origin admin panel requests).
📖 For comprehensive API key documentation, see API Keys Guide
API Key Authentication (Pro Edition)
Section titled “API Key Authentication (Pro Edition)”API keys provide secure, token-based authentication ideal for headless CMS implementations, mobile apps, and third-party integrations.
Using the X-API-Key header (recommended):
curl -H "X-API-Key: tcms_1234567890abcdef1234567890abcdef" \ -H "Content-Type: application/json" \ https://yoursite.com/api/collections/blogUsing query parameter:
curl "https://yoursite.com/api/collections/blog?api_key=tcms_1234567890abcdef1234567890abcdef"Key Features:
- Scope-based permissions - Control HTTP methods (GET, POST, PUT, DELETE, PATCH)
- Path restrictions - Limit access to specific collections or endpoints
- Usage tracking - Monitor last used timestamps
- Easy revocation - Delete keys to immediately revoke access
Creating API Keys:
Navigate to Utilities → API Keys in the admin interface, or visit /admin/utils/api-keys.
For detailed information on scopes, permissions, and best practices, see the API Keys documentation.
Session Authentication
Section titled “Session Authentication”For admin panel and same-origin requests using cookies:
// Include CSRF token for session-based requestsfetch('/api/collections/blog', { headers: { 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content, 'Content-Type': 'application/json' }});When to use session authentication:
- Admin panel JavaScript
- Same-origin web applications
- Browser-based tools running on the same domain
When to use API keys:
- Mobile applications
- Third-party integrations
- Headless CMS implementations
- Automated scripts and workflows
Collections API
Section titled “Collections API”Get All Collections
Section titled “Get All Collections”GET /api/collectionsResponse:
{ "collections": [ { "name": "blog", "title": "Blog Posts", "count": 25, "schema": "/schemas/blog" }, { "name": "products", "title": "Products", "count": 150, "schema": "/schemas/products" } ]}Get Collection Objects
Section titled “Get Collection Objects”GET /api/collections/{collection}Query Parameters:
limit- Number of results (default: 50, max: 100)offset- Starting position (default: 0)sort- Sort field (default: created)order- Sort direction:ascordesc(default: desc)filter- Filter by field valuessearch- Full-text search
Examples:
# Get all blog postscurl https://yoursite.com/api/collections/blog
# Get published posts onlycurl "https://yoursite.com/api/collections/blog?filter[status]=published"
# Get latest 10 postscurl "https://yoursite.com/api/collections/blog?limit=10&sort=date&order=desc"
# Search postscurl "https://yoursite.com/api/collections/blog?search=tutorial"
# Paginationcurl "https://yoursite.com/api/collections/blog?limit=20&offset=40"Response:
{ "collection": "blog", "total": 25, "count": 10, "limit": 10, "offset": 0, "objects": [ { "id": "my-first-post", "title": "My First Post", "content": "Post content here...", "author": "john-doe", "status": "published", "date": "2024-01-15", "created": "2024-01-15T09:00:00Z", "modified": "2024-01-16T10:30:00Z" } ]}Get Single Object
Section titled “Get Single Object”GET /api/collections/{collection}/{id}Example:
curl https://yoursite.com/api/collections/blog/my-first-postResponse:
{ "id": "my-first-post", "title": "My First Post", "content": "Post content here...", "author": "john-doe", "status": "published", "date": "2024-01-15", "tags": ["tutorial", "beginner"], "image": { "url": "/media/images/post-image.jpg", "alt": "Post featured image", "width": 1200, "height": 630 }, "created": "2024-01-15T09:00:00Z", "modified": "2024-01-16T10:30:00Z"}Create Object
Section titled “Create Object”POST /api/collections/{collection}Request Body:
{ "title": "New Blog Post", "content": "This is the content of my new blog post.", "author": "jane-doe", "status": "draft", "tags": ["announcement", "news"]}Response (201 Created):
{ "id": "new-blog-post", "title": "New Blog Post", "content": "This is the content of my new blog post.", "author": "jane-doe", "status": "draft", "tags": ["announcement", "news"], "created": "2024-01-20T14:30:00Z", "modified": "2024-01-20T14:30:00Z"}Update Object
Section titled “Update Object”PUT /api/collections/{collection}/{id}Request Body:
{ "title": "Updated Blog Post Title", "status": "published"}Response (200 OK):
{ "id": "new-blog-post", "title": "Updated Blog Post Title", "content": "This is the content of my new blog post.", "author": "jane-doe", "status": "published", "tags": ["announcement", "news"], "created": "2024-01-20T14:30:00Z", "modified": "2024-01-20T15:45:00Z"}Partial Update
Section titled “Partial Update”PATCH /api/collections/{collection}/{id}Updates only specified fields:
{ "status": "published"}Delete Object
Section titled “Delete Object”DELETE /api/collections/{collection}/{id}Response (204 No Content)
Clone Object
Section titled “Clone Object”POST /api/collections/{collection}/{id}/cloneCreates a copy of an existing object. Optionally clone to a different ID or collection.
Request Body (optional):
{ "id": "new-object-id", "collection": "other-collection"}If no body is provided, the clone uses the same ID and collection as the source.
Response (200 OK):
{ "id": "new-object-id", "title": "My First Post", "content": "Post content here...", "created": "2024-01-20T14:30:00Z", "modified": "2024-01-20T14:30:00Z"}Check Collection Exists
Section titled “Check Collection Exists”HEAD /api/collections/{collection}Returns 200 OK if the collection exists, 404 Not Found if it does not. No response body.
Check Object Exists
Section titled “Check Object Exists”HEAD /api/collections/{collection}/{id}Returns 200 OK if the object exists, 404 Not Found if it does not. No response body.
Get Collection Schema
Section titled “Get Collection Schema”GET /api/collections/{collection}/schemaReturns the schema definition for a specific collection.
Query Parameters:
raw- Set totrueto return the raw (non-flattened) schema. Default returns the flattened schema.
Response (200 OK):
{ "name": "blog", "title": "Blog Posts", "properties": { "title": { "type": "string", "required": true, "maxLength": 255 } }}Query API
Section titled “Query API”The query endpoint provides paginated access to collection objects with filtering, sorting, and multiple output formats.
Query Objects
Section titled “Query Objects”GET /api/collections/{collection}/queryQuery Parameters:
limit- Items per pageoffset- Pagination offsetsort- Property name to sort bysearch- Full-text search terminclude- Comma-separated property names to include in resultsexclude- Comma-separated property names to exclude from resultsformat- Output format:json(default),csv,html
Example:
# Paginated query with sortingcurl "https://yoursite.com/api/collections/blog/query?limit=10&offset=0&sort=date"
# Search with field filteringcurl "https://yoursite.com/api/collections/blog/query?search=tutorial&include=title,date,status"
# Export as CSVcurl "https://yoursite.com/api/collections/blog/query?format=csv&include=title,date"Response (JSON, default):
{ "data": [ { "id": "my-post", "title": "My Post", "date": "2024-01-15" } ], "pagination": { "total": 25, "count": 10, "per_page": 10, "current_page": 1, "total_pages": 3 }}Get Collection Index
Section titled “Get Collection Index”GET /api/collections/{collection}/indexReturns the full collection index. Supports filtering and sorting.
Query Parameters:
include- Comma-separated property names to includeexclude- Comma-separated property names to excludesort- Property name to sort by
Rebuild Collection Index
Section titled “Rebuild Collection Index”PUT /api/collections/{collection}/indexRebuilds the collection index from scratch. No request body required. Returns the rebuilt index.
Property Operations
Section titled “Property Operations”Update, patch, or delete individual properties on an object without sending the entire object.
Update Property
Section titled “Update Property”PUT /api/collections/{collection}/{id}/{property}Replaces the entire property value (PUT semantics).
Request Body: The new value for the property.
"New title value"Response (200 OK): The updated object.
Patch Property
Section titled “Patch Property”PATCH /api/collections/{collection}/{id}/{property}Merges into the existing property value (PATCH semantics). Useful for updating individual fields within a complex property.
Request Body: Fields to merge.
{ "alt": "Updated alt text"}Response (200 OK): The updated object.
Delete Property
Section titled “Delete Property”DELETE /api/collections/{collection}/{id}/{property}Removes the property from the object entirely.
Response (200 OK): The updated object with the property removed.
Increment Property
Section titled “Increment Property”POST /api/collections/{collection}/{id}/{property}/incrementPOST /api/collections/{collection}/{id}/{property}/increment/{amount}Increments a numeric property value. Defaults to incrementing by 1.
Examples:
# Increment view count by 1curl -X POST https://yoursite.com/api/collections/blog/my-post/views/increment
# Increment by 5curl -X POST https://yoursite.com/api/collections/blog/my-post/views/increment/5Response (200 OK): The updated property value.
Response (400 Bad Request): If the property is not numeric.
Decrement Property
Section titled “Decrement Property”POST /api/collections/{collection}/{id}/{property}/decrementPOST /api/collections/{collection}/{id}/{property}/decrement/{amount}Decrements a numeric property value. Defaults to decrementing by 1.
Property Metadata
Section titled “Property Metadata”Update metadata associated with individual files or items within a property (e.g., alt text on an image, captions on gallery items).
Update Property Metadata
Section titled “Update Property Metadata”PUT /api/collections/{collection}/{id}/{property}/{name}Replaces the metadata for a specific item within a property.
Query Parameters:
path- Subfolder path for depot files
Request Body: The metadata to set.
{ "alt": "Photo of sunset", "caption": "Taken in Hawaii"}Patch Property Metadata
Section titled “Patch Property Metadata”PATCH /api/collections/{collection}/{id}/{property}/{name}Merges into existing metadata for a specific item within a property.
Query Parameters:
path- Subfolder path for depot files
Request Body: Fields to merge into existing metadata.
Deck Items API
Section titled “Deck Items API”CRUD operations for items within a deck (repeatable sections) property. Deck is a Pro edition feature.
Create Deck Item
Section titled “Create Deck Item”POST /api/collections/{collection}/{id}/{property}/deckRequest Body:
{ "id": "item-1", "title": "Slide 1", "image": "/media/slide1.jpg", "caption": "Welcome slide"}The id field is optional if the schema supports auto-generation.
Response (201 Created): The updated parent object including the new deck item.
Get Deck Item
Section titled “Get Deck Item”GET /api/collections/{collection}/{id}/{property}/deck/{itemId}Response (200 OK):
{ "id": "item-1", "title": "Slide 1", "image": "/media/slide1.jpg", "caption": "Welcome slide"}Response (404 Not Found): If the deck item does not exist.
Update Deck Item
Section titled “Update Deck Item”PUT /api/collections/{collection}/{id}/{property}/deck/{itemId}Replaces the deck item entirely.
Request Body:
{ "title": "Updated Slide 1", "image": "/media/slide1-new.jpg", "caption": "Updated caption"}Response (200 OK): The updated parent object.
Delete Deck Item
Section titled “Delete Deck Item”DELETE /api/collections/{collection}/{id}/{property}/deck/{itemId}Response (200 OK): The updated parent object with the deck item removed.
Reports API
Section titled “Reports API”Export collection data as CSV or JSON with field selection.
Get Report Fields
Section titled “Get Report Fields”GET /report/collections/{collection}/fieldsReturns the list of fields available for export.
Query Parameters:
format-jsonorhtml(default)
Response (JSON):
[ { "name": "title", "label": "Title", "type": "string" }, { "name": "status", "label": "Status", "type": "string" }]Export CSV Report
Section titled “Export CSV Report”GET /report/collections/{collection}/csvQuery Parameters:
fields(required) - Comma-separated field names to export. Use dot notation for deck fields:name,items.value,items.statusinclude- Filter objects by property valuesexclude- Exclude objects by property values
Example:
curl "https://yoursite.com/report/collections/blog/csv?fields=title,date,status"Response: CSV file download with Content-Disposition: attachment.
Deck fields expand into multiple rows per object — one row per deck item, with scalar fields repeated on each row.
Export JSON Report
Section titled “Export JSON Report”GET /report/collections/{collection}/jsonQuery Parameters:
fields(required) - Comma-separated field names to export. Supports dot notation for deck fields.include- Filter objects by property valuesexclude- Exclude objects by property values
Example:
curl "https://yoursite.com/report/collections/blog/json?fields=title,date,status"Response: JSON file download. Deck fields remain nested (not expanded like CSV).
[ { "title": "My Post", "date": "2024-01-15", "status": "published" }]If any objects are skipped due to data errors, the response wraps the data:
{ "data": [...], "errors": ["object-id-1", "object-id-2"]}Schemas API
Section titled “Schemas API”Get All Schemas
Section titled “Get All Schemas”GET /api/schemasResponse:
{ "schemas": [ { "name": "blog", "title": "Blog Posts", "description": "Blog post collection", "url": "/schemas/blog" } ]}Get Schema Definition
Section titled “Get Schema Definition”GET /api/schemas/{collection}Response:
{ "name": "blog", "title": "Blog Posts", "description": "Blog post collection", "properties": { "title": { "type": "string", "required": true, "maxLength": 255 }, "content": { "type": "string", "format": "html" }, "author": { "type": "string", "reference": "users" }, "status": { "type": "string", "enum": ["draft", "published", "archived"], "default": "draft" }, "tags": { "type": "array", "items": { "type": "string" } }, "date": { "type": "string", "format": "date" } }}Property Files API
Section titled “Property Files API”Save, move, delete, and manage files attached to a property on an object. These are the endpoints the admin UI uses behind every image, file, gallery, and depot field — and the ones to call from your own integrations.
Files are stored under tcms-data/{collection}/{id}/{property}/[{path}/]{filename} and served back over the public imageworks / download / stream endpoints documented in File Downloads & Streaming.
Save a File to a Property
Section titled “Save a File to a Property”Upload a file to an image, file, gallery, or depot property. The same endpoint handles three input modes:
- Direct upload —
multipart/form-datawith the file under the property name (or, for nested fields, under the child field name — see the nested example below). - Chunked upload — Dropzone-compatible chunking via
dzchunkindex/dztotalchunkcount(orchunkindex/totalchunkcount) in the form body. Intermediate chunks return{ "status": "chunk received" }; the final chunk assembles and saves. - URL upload — Instead of a file, POST a JSON body with the property name set to a URL. The server downloads the URL (subject to
maxDownloadSizeintcms.php) and saves the result as if it had been uploaded directly.
POST /api/collections/{collection}/{id}/{property}POST /api/collections/{collection}/{id}/{property}/{path}Behavior:
- HEIC images are auto-converted to JPEG before saving.
- The response is the updated object (same shape as
GET /api/collections/{collection}/{id}) so clients see the new file in context. - Nested-path uploads target card children, deck-item children, or depot subfolders. The form-field name in the request body must match the last segment of
{path}(e.g., uploading to…/mycard/imageputs the file under the form keyimage, notmycard).
Direct upload example:
curl -X POST https://yoursite.com/api/collections/blog/my-post/cover \ -H "Authorization: Bearer tcms_1234567890abcdef1234567890abcdef" \ -F "cover=@./hero.jpg"URL upload example:
curl -X POST https://yoursite.com/api/collections/blog/my-post/cover \ -H "Authorization: Bearer tcms_..." \ -H "Content-Type: application/json" \ -d '{"cover": "https://example.com/external-hero.jpg"}'Nested upload example (image inside a card field):
curl -X POST https://yoursite.com/api/collections/blog/my-post/hero-card/image \ -H "Authorization: Bearer tcms_..." \ -F "image=@./photo.jpg"Response (full object with updated file metadata):
{ "data": { "id": "my-post", "cover": { "name": "hero.jpg", "size": 245760, "alt": "", "focalpoint": { "x": 50, "y": 50 } } }, "meta": { ... }}Common errors:
{ "error": "No file found in request for property: cover" }{ "error": "File exceeds upload_max_filesize in php.ini" }Delete a File
Section titled “Delete a File”Remove a single file from a gallery or depot, or delete the file held by an image/file field.
DELETE /api/collections/{collection}/{id}/{property}/{path}{path} is the file’s name relative to the property — photo.jpg for a top-level file, 2026/photo.jpg for a depot subfolder, or the child field key for a nested property delete (e.g., mycard/image).
Example:
curl -X DELETE https://yoursite.com/api/collections/blog/my-post/gallery/old-photo.jpg \ -H "Authorization: Bearer tcms_..."Response is the updated object after the delete.
Move a File
Section titled “Move a File”Move a file from one depot subfolder to another. Used by the depot field’s drag-and-drop UI; the request body’s destination is the new subfolder path.
PUT /api/collections/{collection}/{id}/{property}/{name}/moveQuery parameters:
- path — Current subfolder containing the file. Omit if the file is at the root of the property.
Request body:
- destination — Target subfolder path.
Example:
curl -X PUT "https://yoursite.com/api/collections/blog/my-post/files/report.pdf/move?path=2025" \ -H "Authorization: Bearer tcms_..." \ -H "Content-Type: application/json" \ -d '{"destination": "2026/january"}'Response:
{ "moved": true }Create a Folder
Section titled “Create a Folder”Create a subfolder inside a depot property.
POST /api/collections/{collection}/{id}/{property}/folderRequest body:
- path — Folder path to create. Forward slashes create nested folders in one call.
curl -X POST https://yoursite.com/api/collections/blog/my-post/files/folder \ -H "Authorization: Bearer tcms_..." \ -H "Content-Type: application/json" \ -d '{"path": "2026/q1"}'Response is the updated object showing the new folder structure.
Rename a Folder
Section titled “Rename a Folder”PUT /api/collections/{collection}/{id}/{property}/folder/renameQuery parameters:
- path — Current folder path to rename.
Request body:
- name — New folder name (just the last segment, not a full path).
curl -X PUT "https://yoursite.com/api/collections/blog/my-post/files/folder/rename?path=2025/q4" \ -H "Authorization: Bearer tcms_..." \ -H "Content-Type: application/json" \ -d '{"name": "archived-q4"}'Clear a Property’s Image Cache
Section titled “Clear a Property’s Image Cache”Force-regenerate every cached image derivative (ImageWorks output) for a property. Useful after changing image presets or watermark settings.
DELETE /api/collections/{collection}/{id}/{property}/cacheResponse:
{ "deleted": 12 }deleted is the number of cached files that were removed.
Clear Cache for One File
Section titled “Clear Cache for One File”Clear the cache for a single gallery item, or the cache that lives under a card / deck child property.
DELETE /api/collections/{collection}/{id}/{property}/{path}/cacheThe action picks the right cache to clear based on filesystem state: a gallery file name clears just that file’s image derivatives; a child-property key clears the nested property’s cache directory.
Tiptap / Styled-Text Embedded Uploads
Section titled “Tiptap / Styled-Text Embedded Uploads”The styled-text (Tiptap) editor uses a separate, internal /api/upload/* namespace for inline image and file embeds inserted from the rich-text toolbar:
POST /api/upload/{collection}/{id}/{property}[/{path}]GET /api/upload/{collection}/{id}/{property}GET /api/upload/{collection}/{id}/{property}/{path}DELETE /api/upload/{collection}/{id}/{property}/{path}These behave similarly to the property-file endpoints above but return a single link URL (image/audio/video/file get routed to imageworks / stream / download respectively) rather than the full object. They’re public-facing in the sense that the URLs need to remain stable for content embedded in saved HTML, but they’re not the recommended integration surface — prefer the /api/collections/{collection}/{id}/{property} endpoints above for any first-party file upload work.
File Downloads & Streaming
Section titled “File Downloads & Streaming”Download File (Forces Download)
Section titled “Download File (Forces Download)”Download a file from a specific collection with Content-Disposition: attachment.
GET /download/{collection}/{id}/{property}POST /download/{collection}/{id}/{property}Path Parameters:
collection- Collection name (e.g., ‘files’, ‘documents’)id- Object IDproperty- Property name containing the file
Query Parameters:
pwd- Encrypted password for protected files
Examples:
# Basic file downloadcurl -O https://yoursite.com/download/files/manual/file
# Download with custom collection/propertycurl -O https://yoursite.com/download/documents/guide/pdf
# Password-protected file (password must be encrypted)curl -O "https://yoursite.com/download/private/secret/file?pwd=ENCRYPTED_PASSWORD"Download Depot File
Section titled “Download Depot File”Download a specific file from a depot (multi-file) property.
GET /download/{collection}/{id}/{property}/{filename}POST /download/{collection}/{id}/{property}/{filename}Path Parameters:
collection- Collection nameid- Object IDproperty- Depot property namefilename- Specific file to download
Query Parameters:
path- Subfolder path within depotpwd- Encrypted password for protected files
Examples:
# Download specific depot filecurl -O https://yoursite.com/download/depot/assets/files/document.pdf
# Download from subfoldercurl -O "https://yoursite.com/download/depot/assets/files/image.jpg?path=photos/vacation"
# Password-protected depot filecurl -O "https://yoursite.com/download/depot/private/files/secret.zip?pwd=ENCRYPTED_PASSWORD"Stream File (Plays in Browser)
Section titled “Stream File (Plays in Browser)”Stream a file with Content-Disposition: inline and HTTP range request support. Ideal for video/audio files.
GET /stream/{collection}/{id}/{property}Path Parameters:
collection- Collection nameid- Object IDproperty- Property name containing the file
Query Parameters:
pwd- Encrypted password for protected files
Headers:
Range- HTTP range request (e.g., “bytes=0-1023”)
Response Headers:
Accept-Ranges: bytesContent-Range- For partial content responses (206)Content-Length- File or range size
Examples:
# Stream video filecurl https://yoursite.com/stream/videos/movie/video
# Range request for video seekingcurl -H "Range: bytes=0-1023" https://yoursite.com/stream/videos/movie/video
# Password-protected streamingcurl "https://yoursite.com/stream/private/secret/video?pwd=ENCRYPTED_PASSWORD"Stream Depot File
Section titled “Stream Depot File”Stream a specific file from a depot property.
GET /stream/{collection}/{id}/{property}/{filename}Path Parameters:
collection- Collection nameid- Object IDproperty- Depot property namefilename- Specific file to stream
Query Parameters:
path- Subfolder path within depotpwd- Encrypted password for protected files
Examples:
# Stream depot videocurl https://yoursite.com/stream/media/playlist/videos/movie.mp4
# Stream with subfolder pathcurl "https://yoursite.com/stream/media/playlist/videos/song.mp3?path=albums/rock"HTML5 Media Integration
Section titled “HTML5 Media Integration”Video Streaming:
<video controls> <source src="/stream/videos/movie/video" type="video/mp4"></video>Audio Streaming:
<audio controls> <source src="/stream/audio/song/file" type="audio/mpeg"></audio>Download vs Stream Comparison
Section titled “Download vs Stream Comparison”| Feature | Download | Stream |
|---|---|---|
| Content-Disposition | attachment | inline |
| Browser Behavior | Forces download dialog | Plays/displays in browser |
| Range Requests | No | Yes (HTTP 206) |
| Video/Audio Support | Basic | Full seeking/scrubbing |
| Safari Compatibility | Standard | Enhanced for media |
| Use Cases | Documents, archives | Video, audio, PDFs |
Password Protection
Section titled “Password Protection”Both download and stream endpoints support password protection:
- Frontend: Use Twig functions that auto-encrypt passwords
- API: Passwords must be encrypted using the Cipher class
- URLs: Encrypted passwords are URL-encoded in query parameters
Twig Examples:
{# Auto-encrypts plain password #}{{ cms.download('id', {pwd: 'plaintext'}) }}{{ cms.stream('id', {pwd: 'plaintext'}) }}
{# Already encrypted passwords work too #}{{ cms.download('id', {pwd: encrypted_pwd}) }}Image Processing (ImageWorks)
Section titled “Image Processing (ImageWorks)”Basic Image Manipulation
Section titled “Basic Image Manipulation”GET /imageworks/{collection}/{id}/{property}.{format}Parameters:
w- Width in pixelsh- Height in pixelsfit- Resize mode:crop,contain,cover,fill,inside,outsideformat- Output format:jpg,png,webp,avifquality- JPEG quality (1-100)blur- Blur amount (1-100)brightness- Brightness (-100 to 100)contrast- Contrast (-100 to 100)gamma- Gamma correction (0.1 to 3.0)sharpen- Sharpen amount (1-100)grayscale- Convert to grayscale (true/false)sepia- Apply sepia effect (true/false)
Examples:
# Resize to 800x600curl "https://yoursite.com/imageworks/gallery/hero/image.jpg?w=800&h=600"
# Crop to square thumbnailcurl "https://yoursite.com/imageworks/products/laptop/image.jpg?w=300&h=300&fit=crop"
# Convert to WebP with qualitycurl "https://yoursite.com/imageworks/blog/featured/image.webp?quality=80"
# Apply filterscurl "https://yoursite.com/imageworks/portfolio/photo/image.jpg?grayscale=true&contrast=20"
# Responsive image with blurcurl "https://yoursite.com/imageworks/hero/banner/image.jpg?w=1200&blur=5"Gallery Images
Section titled “Gallery Images”GET /imageworks/{collection}/{id}/{property}/{name}.{format}Fetch a specific image from a gallery property.
Dynamic Gallery Images
Section titled “Dynamic Gallery Images”GET /imageworks/{collection}/{id}/{property}/{action}Actions:
first- Get the first imagelast- Get the last imagerandom- Get a random imagefeatured- Get the featured image
Error Handling
Section titled “Error Handling”Error Response Format
Section titled “Error Response Format”{ "error": { "code": 400, "message": "Validation failed", "details": { "title": ["Title is required"], "email": ["Invalid email format"] } }}HTTP Status Codes
Section titled “HTTP Status Codes”200 OK- Successful request201 Created- Resource created successfully204 No Content- Successful request with no response body400 Bad Request- Invalid request data401 Unauthorized- Authentication required403 Forbidden- Insufficient permissions404 Not Found- Resource not found422 Unprocessable Entity- Validation errors429 Too Many Requests- Rate limit exceeded500 Internal Server Error- Server error
Rate Limiting
Section titled “Rate Limiting”Headers:
X-RateLimit-Limit- Request limit per windowX-RateLimit-Remaining- Remaining requestsX-RateLimit-Reset- Time when limit resets
Example Response Headers:
X-RateLimit-Limit: 60X-RateLimit-Remaining: 45X-RateLimit-Reset: 1705751400Pagination
Section titled “Pagination”For endpoints that return multiple items:
Headers:
X-Total-Count- Total number of itemsLink- Pagination links (next, prev, first, last)
Example:
X-Total-Count: 150Link: </collections/blog?offset=20&limit=20>; rel="next", </collections/blog?offset=0&limit=20>; rel="first", </collections/blog?offset=140&limit=20>; rel="last"CORS Support
Section titled “CORS Support”The API supports Cross-Origin Resource Sharing (CORS) for browser-based requests:
// Example browser requestfetch('https://yoursite.com/api/collections/blog', { method: 'GET', headers: { 'X-API-Key': 'tcms_your_api_key_here', 'Content-Type': 'application/json' }});