Copied to clipboard!

Complete REST API endpoint documentation for Vibe CMS, including request/response formats, authentication requirements, and practical examples.


Overview

Vibe CMS provides two main APIs:

  1. Public API - Read-only access to published content (requires API key)
  2. Admin API - Full CRUD operations on collections, content, files, and locales (requires JWT authentication)

Base URLs:

  • Production: https://api.vibecms.com
  • Staging: https://staging-api.vibecms.com

Authentication

Public API

Header:

X-API-Key: your-api-key

Example:

curl -H "X-API-Key: vibe_pk_abc123" https://api.vibecms.com/api/public/content

Admin API

Header:

Authorization: Bearer your-jwt-token

Example:

curl -H "Authorization: Bearer eyJhbGc..." https://api.vibecms.com/api/admin/collections

Collections API

List Collections

Endpoint:

GET /api/admin/collections

Parameters:

Parameter Type Required Description
project_id string Yes Project identifier
limit number No Maximum items (default: 50)
offset number No Pagination offset (default: 0)

Response:

{
  "data": [
    {
      "id": "uuid",
      "slug": "blog-posts",
      "name": "Blog Posts",
      "description": "Article content",
      "is_singleton": false,
      "item_count": 42,
      "created_at": "2025-01-01T00:00:00Z",
      "updated_at": "2025-01-01T00:00:00Z"
    }
  ],
  "count": 1,
  "limit": 50,
  "offset": 0
}

Example:

curl -H "Authorization: Bearer TOKEN" \
  "https://api.vibecms.com/api/admin/collections?project_id=proj-123"

Get Collection

Endpoint:

GET /api/admin/collections/{collection_slug}

Parameters:

Parameter Type Required Description
project_id string (query) Yes Project identifier

Response:

{
  "data": {
    "id": "uuid",
    "slug": "blog-posts",
    "name": "Blog Posts",
    "description": "Article content",
    "is_singleton": false,
    "fields": [
      {
        "id": "field-uuid",
        "name": "title",
        "field_type": "text",
        "interface_type": "input",
        "is_required": true,
        "sort_order": 1
      }
    ]
  }
}

Create Collection

Endpoint:

POST /api/admin/collections

Request Body:

{
  "project_id": "proj-123",
  "slug": "blog-posts",
  "name": "Blog Posts",
  "description": "Article content",
  "is_singleton": false
}

Response: 201 Created

{
  "data": {
    "id": "uuid",
    "slug": "blog-posts",
    "name": "Blog Posts",
    "description": "Article content",
    "is_singleton": false
  }
}

Example:

curl -X POST -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "proj-123",
    "slug": "blog-posts",
    "name": "Blog Posts"
  }' \
  https://api.vibecms.com/api/admin/collections

Update Collection

Endpoint:

PATCH /api/admin/collections/{collection_slug}

Request Body:

{
  "project_id": "proj-123",
  "name": "Blog Articles",
  "description": "Updated description"
}

Response: 200 OK


Delete Collection

Endpoint:

DELETE /api/admin/collections/{collection_slug}

Parameters:

Parameter Type Required Description
project_id string (query) Yes Project identifier

Response: 204 No Content


Content Items API

List Content Items

Endpoint:

GET /api/admin/content/{collection_slug}

Parameters:

Parameter Type Required Description
project_id string (query) Yes Project identifier
limit number No Maximum items (default: 50)
offset number No Pagination offset (default: 0)
status string No Filter by status: draft, published, archived
locale string No Filter by locale (default: project's default locale)

Response:

{
  "data": [
    {
      "id": "item-uuid",
      "collection_slug": "blog-posts",
      "status": "published",
      "description": "First blog post",
      "locales": ["en-US", "de-DE"],
      "created_at": "2025-01-01T00:00:00Z",
      "updated_at": "2025-01-01T00:00:00Z"
    }
  ],
  "count": 1,
  "limit": 50,
  "offset": 0
}

Get Content Item

Endpoint:

GET /api/admin/content/{collection_slug}/{item_id}

Parameters:

Parameter Type Required Description
project_id string (query) Yes Project identifier
locale string No Specific locale (default: all locales)

Response:

{
  "data": {
    "id": "item-uuid",
    "collection_slug": "blog-posts",
    "status": "published",
    "description": "First blog post",
    "translations": [
      {
        "locale": "en-US",
        "data": {
          "title": "Hello World",
          "content": "# Welcome\n\nThis is my first post.",
          "slug": "hello-world"
        },
        "updated_at": "2025-01-01T00:00:00Z"
      },
      {
        "locale": "de-DE",
        "data": {
          "title": "Hallo Welt",
          "content": "# Willkommen\n\nDas ist mein erster Beitrag.",
          "slug": "hallo-welt"
        },
        "updated_at": "2025-01-01T00:00:00Z"
      }
    ]
  }
}

Create Content Item

Endpoint:

POST /api/admin/content/{collection_slug}

Request Body:

{
  "project_id": "proj-123",
  "status": "draft",
  "description": "New blog post"
}

Response: 201 Created

{
  "data": {
    "id": "item-uuid",
    "collection_slug": "blog-posts",
    "status": "draft",
    "description": "New blog post",
    "created_at": "2025-01-01T00:00:00Z"
  }
}

Update Content Translation

Endpoint:

PUT /api/admin/content/{collection_slug}/{item_id}/{locale}

Request Body:

{
  "project_id": "proj-123",
  "data": {
    "title": "Hello World",
    "content": "# Welcome\n\nThis is my first post.",
    "slug": "hello-world"
  },
  "status": "published"
}

Response: 200 OK

{
  "success": true,
  "message": "Translation updated successfully"
}

Delete Content Item

Endpoint:

DELETE /api/admin/content/{collection_slug}/{item_id}

Parameters:

Parameter Type Required Description
project_id string (query) Yes Project identifier
locale string No Delete specific locale only

Response: 204 No Content


Files API

List Files

Endpoint:

GET /api/admin/files

Parameters:

Parameter Type Required Description
project_id string (query) Yes Project identifier
folder_path string No Filter by folder (e.g., '/images')
mime_type string No Filter by MIME type (e.g., 'image/')
limit number No Maximum items (default: 50)
offset number No Pagination offset (default: 0)

Response:

{
  "data": [
    {
      "id": "file-uuid",
      "filename": "hero.jpg",
      "mime_type": "image/jpeg",
      "file_size": 1024000,
      "folder_path": "/images",
      "title": "Hero Image",
      "alt_text": "Modern office",
      "url": "https://cdn.vibecms.com/projects/proj-123/files/file-uuid",
      "created_at": "2025-01-01T00:00:00Z"
    }
  ],
  "count": 1,
  "limit": 50,
  "offset": 0
}

Get File

Endpoint:

GET /api/admin/files/{file_id}

Parameters:

Parameter Type Required Description
project_id string (query) Yes Project identifier

Response:

{
  "data": {
    "id": "file-uuid",
    "filename": "hero.jpg",
    "mime_type": "image/jpeg",
    "file_size": 1024000,
    "width": 1920,
    "height": 1080,
    "folder_path": "/images",
    "title": "Hero Image",
    "alt_text": "Modern office workspace",
    "caption": "Hero image for homepage",
    "description": "High-res hero image",
    "focus_keyword": "office workspace",
    "url": "https://cdn.vibecms.com/projects/proj-123/files/file-uuid"
  }
}

Upload File

Endpoint:

POST /api/admin/files/upload

Request (multipart/form-data):

Content-Type: multipart/form-data

- project_id: proj-123
- file: [binary file data]
- folder_path: /images
- title: Hero Image
- alt_text: Modern office

Response: 201 Created

{
  "data": {
    "id": "file-uuid",
    "filename": "hero.jpg",
    "mime_type": "image/jpeg",
    "file_size": 1024000,
    "url": "https://cdn.vibecms.com/projects/proj-123/files/file-uuid"
  }
}

Update File Metadata

Endpoint:

PATCH /api/admin/files/{file_id}

Request Body:

{
  "project_id": "proj-123",
  "title": "Updated Title",
  "alt_text": "Updated alt text",
  "caption": "Updated caption",
  "focus_keyword": "new keyword",
  "folder_path": "/images/featured"
}

Response: 200 OK


Delete File

Endpoint:

DELETE /api/admin/files/{file_id}

Parameters:

Parameter Type Required Description
project_id string (query) Yes Project identifier

Response: 204 No Content


Locales API

List Locales

Endpoint:

GET /api/admin/locales

Parameters:

Parameter Type Required Description
project_id string (query) Yes Project identifier

Response:

{
  "data": [
    {
      "locale_code": "en-US",
      "display_name": "English (US)",
      "is_default": true,
      "is_active": true
    },
    {
      "locale_code": "de-DE",
      "display_name": "German (Germany)",
      "is_default": false,
      "is_active": true
    }
  ],
  "count": 2
}

Create Locale

Endpoint:

POST /api/admin/locales

Request Body:

{
  "project_id": "proj-123",
  "locale_code": "fr-FR",
  "display_name": "French (France)",
  "is_active": true,
  "is_default": false
}

Response: 201 Created


Update Locale

Endpoint:

PATCH /api/admin/locales/{locale_code}

Request Body:

{
  "project_id": "proj-123",
  "display_name": "French (France)",
  "is_active": true,
  "is_default": false
}

Response: 200 OK


Delete Locale

Endpoint:

DELETE /api/admin/locales/{locale_code}

Parameters:

Parameter Type Required Description
project_id string (query) Yes Project identifier

Response: 204 No Content


Public API

Get Published Content

Endpoint:

GET /api/public/content/{collection_slug}

Parameters:

Parameter Type Required Description
api_key string (header) Yes API Key
locale string No Locale code (default: project's default)
limit number No Maximum items (default: 50)
offset number No Pagination offset (default: 0)

Response:

{
  "data": [
    {
      "id": "item-uuid",
      "slug": "hello-world",
      "title": "Hello World",
      "content": "# Welcome\n\nThis is my first post.",
      "published_at": "2025-01-01T00:00:00Z"
    }
  ],
  "count": 1,
  "limit": 50,
  "offset": 0
}

Get Published Item by Slug

Endpoint:

GET /api/public/content/{collection_slug}/{slug}

Parameters:

Parameter Type Required Description
api_key string (header) Yes API Key
locale string No Locale code (default: project's default)

Response:

{
  "data": {
    "id": "item-uuid",
    "slug": "hello-world",
    "title": "Hello World",
    "content": "# Welcome\n\nThis is my first post.",
    "published_at": "2025-01-01T00:00:00Z"
  }
}

Error Responses

All endpoints return consistent error responses:

Format:

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": {}
  }
}

Common Error Codes:

  • VALIDATION_ERROR (400) - Invalid parameters
  • UNAUTHORIZED (401) - Missing or invalid authentication
  • FORBIDDEN (403) - Insufficient permissions
  • NOT_FOUND (404) - Resource not found
  • CONFLICT (409) - Duplicate or conflicting data
  • UNPROCESSABLE_ENTITY (422) - Semantically invalid data
  • TOO_MANY_REQUESTS (429) - Rate limit exceeded
  • INTERNAL_SERVER_ERROR (500) - Server error

Pagination

All list endpoints support pagination:

curl -H "Authorization: Bearer TOKEN" \
  "https://api.vibecms.com/api/admin/content/blog-posts?project_id=proj-123&limit=20&offset=40"

Response metadata:

{
  "data": [...],
  "count": 100,
  "limit": 20,
  "offset": 40,
  "total": 100,
  "has_more": true
}

Rate Limits

API rate limits per project:

  • Public API: 1000 requests/hour
  • Admin API: 100 requests/minute

Headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640000000

Webhooks (Advanced)

Vibe CMS supports webhooks for content events:

Available Events:

  • content.created
  • content.updated
  • content.published
  • content.unpublished
  • content.deleted
  • file.uploaded
  • file.deleted

Webhook Payload:

{
  "event": "content.published",
  "project_id": "proj-123",
  "timestamp": "2025-01-01T00:00:00Z",
  "data": {
    "id": "item-uuid",
    "collection_slug": "blog-posts",
    "status": "published"
  }
}

See Also