API Reference

SonicJS provides a comprehensive REST API for managing content, collections, media, and authentication programmatically. Built on Cloudflare Workers with a three-tiered caching system for optimal performance.


Introduction

Base URL

https://your-domain.com/api

For local development:

http://localhost:8787/api

Interactive API Documentation

SonicJS includes an interactive API explorer powered by Scalar UI. Access it at:

http://localhost:8787/docs

OpenAPI Specification

Get the complete OpenAPI 3.0 specification:

curl -X GET "http://localhost:8787/api/"

Authentication

Most API endpoints require authentication. SonicJS uses JWT (JSON Web Tokens) with HTTP-only cookies for web clients and Bearer tokens for API clients.

Login

Get an access token by authenticating with your credentials.

Login Request

curl -X POST "http://localhost:8787/auth/login" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@sonicjs.com",
    "password": "admin123"
  }'

Login Response

200 Success

{
  "user": {
    "id": "admin-user-id",
    "email": "admin@sonicjs.com",
    "username": "admin",
    "firstName": "Admin",
    "lastName": "User",
    "role": "admin"
  },
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

401 Error

{
  "error": "Invalid email or password"
}

Using the Token

Include the token in the Authorization header for all authenticated requests:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

For browser-based applications, the token is automatically stored as an HTTP-only cookie named auth_token.

Register

Create a new user account.

Register Request

curl -X POST "http://localhost:8787/auth/register" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "newuser@example.com",
    "password": "securepassword123",
    "username": "newuser",
    "firstName": "John",
    "lastName": "Doe"
  }'

Get Current User

Get information about the currently authenticated user.

Get User Request

curl -X GET "http://localhost:8787/auth/me" \
  -H "Authorization: Bearer {token}"

Refresh Token

Refresh your access token before it expires.

curl -X POST "http://localhost:8787/auth/refresh" \
  -H "Authorization: Bearer {token}"

Logout

End your session.

curl -X POST "http://localhost:8787/auth/logout"

Collections

List All Collections

Retrieve all active collections with their schemas.

Authentication: None required Cache: 5 minutes

List Collections

curl -X GET "http://localhost:8787/api/collections"

Collections Response

200 Success

{
  "data": [
    {
      "id": "blog-posts-collection-id",
      "name": "blog-posts",
      "display_name": "Blog Posts",
      "description": "Blog posts collection",
      "schema": {
        "name": "blog-posts",
        "displayName": "Blog Posts",
        "fields": [
          {
            "name": "title",
            "type": "text",
            "label": "Title",
            "required": true
          },
          {
            "name": "content",
            "type": "richtext",
            "label": "Content"
          },
          {
            "name": "featuredImage",
            "type": "media",
            "label": "Featured Image"
          }
        ]
      },
      "is_active": 1,
      "created_at": 1730000000,
      "updated_at": 1730000000
    }
  ],
  "meta": {
    "count": 1,
    "timestamp": "2025-10-06T12:34:56.789Z",
    "cache": {
      "hit": false,
      "source": "database"
    },
    "timing": {
      "total": 45,
      "execution": 12,
      "unit": "ms"
    }
  }
}

Content Management

List All Content

Retrieve all content items with pagination and filtering.

Authentication: None required Cache: 5 minutes

Query Parameters:

  • limit - Maximum items to return (default: 50, max: 100)
  • offset - Number of items to skip for pagination
  • sort - Sort field (prefix with - for descending)
  • filter - Advanced filtering (see Filtering & Querying)

List Content

curl -X GET "http://localhost:8787/api/content?limit=10"

Get Content by Collection

Retrieve content for a specific collection.

Authentication: None required Cache: 5 minutes

Get Collection Content

curl -X GET "http://localhost:8787/api/collections/blog-posts/content?limit=25"

Get Single Content Item

Retrieve a specific content item by ID.

Authentication: None required Cache: 5 minutes

Get Content

curl -X GET "http://localhost:8787/api/content/{id}"

Create Content

Create a new content item.

Authentication: Required Permissions: Editor or Admin role

Create Content

curl -X POST "http://localhost:8787/api/content" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "collectionId": "blog-posts-collection-id",
    "title": "My New Blog Post",
    "slug": "my-new-blog-post",
    "status": "draft",
    "data": {
      "title": "My New Blog Post",
      "content": "<p>This is my blog post content...</p>",
      "excerpt": "A brief description"
    }
  }'

Update Content

Update an existing content item.

Authentication: Required Permissions: Content owner, Editor, or Admin role

Update Content

curl -X PUT "http://localhost:8787/api/content/{id}" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Updated Blog Post Title",
    "status": "published",
    "data": {
      "title": "Updated Blog Post Title",
      "content": "<p>Updated content...</p>"
    }
  }'

Delete Content

Delete a content item.

Authentication: Required Permissions: Content owner, Editor, or Admin role

Delete Content

curl -X DELETE "http://localhost:8787/api/content/{id}" \
  -H "Authorization: Bearer {token}"

Media Management

All media endpoints require authentication.

Upload Single File

Upload a file to Cloudflare R2 storage.

Authentication: Required Content-Type: multipart/form-data Max File Size: 50MB

Supported File Types:

  • Images: JPEG, PNG, GIF, WebP, SVG
  • Documents: PDF, TXT, DOC, DOCX
  • Videos: MP4, WebM, OGG, AVI, MOV
  • Audio: MP3, WAV, OGG, M4A

Upload File

curl -X POST "http://localhost:8787/api/media/upload" \
  -H "Authorization: Bearer {token}" \
  -F "file=@/path/to/image.jpg" \
  -F "folder=blog-images"

Upload Response

200 Success

{
  "success": true,
  "file": {
    "id": "V1StGXR8_Z5jdHi6B",
    "filename": "V1StGXR8_Z5jdHi6B.jpg",
    "originalName": "my-image.jpg",
    "mimeType": "image/jpeg",
    "size": 245678,
    "width": 1920,
    "height": 1080,
    "publicUrl": "https://pub-sonicjs-media-dev.r2.dev/blog-images/V1StGXR8_Z5jdHi6B.jpg",
    "thumbnailUrl": "https://imagedelivery.net/account-id/blog-images/V1StGXR8_Z5jdHi6B.jpg/thumbnail",
    "uploadedAt": "2025-10-06T12:34:56.789Z"
  }
}

400 Error

{
  "error": "File validation failed",
  "details": [
    {
      "code": "too_big",
      "message": "File size exceeds 50MB limit",
      "path": ["size"]
    }
  ]
}

Upload Multiple Files

Upload multiple files in a single request.

Authentication: Required

Upload Multiple Files

curl -X POST "http://localhost:8787/api/media/upload-multiple" \
  -H "Authorization: Bearer {token}" \
  -F "files=@/path/to/image1.jpg" \
  -F "files=@/path/to/image2.png" \
  -F "folder=gallery"

Update File Metadata

Update file metadata (alt text, caption, tags, folder).

Authentication: Required Permissions: Uploader or Admin role

Update File

curl -X PATCH "http://localhost:8787/api/media/{id}" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "alt": "Beautiful sunset over the ocean",
    "caption": "Sunset at Malibu Beach",
    "tags": ["nature", "sunset", "ocean"],
    "folder": "featured-images"
  }'

Delete File

Delete a single file.

Authentication: Required Permissions: Uploader or Admin role

Delete File

curl -X DELETE "http://localhost:8787/api/media/{id}" \
  -H "Authorization: Bearer {token}"

Bulk Delete Files

Delete multiple files in a single request.

Authentication: Required Max Files: 50 per request

Bulk Delete

curl -X POST "http://localhost:8787/api/media/bulk-delete" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "fileIds": ["file-id-1", "file-id-2", "file-id-3"]
  }'

Bulk Move Files

Move multiple files to a different folder.

Authentication: Required Max Files: 50 per request

Bulk Move

curl -X POST "http://localhost:8787/api/media/bulk-move" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "fileIds": ["file-id-1", "file-id-2"],
    "targetFolder": "archived"
  }'

System Endpoints

Health Check

Check API and system health.

Authentication: None required

Health Check

curl -X GET "http://localhost:8787/api/health"

System Information

Get system information and available features.

Authentication: None required

curl -X GET "http://localhost:8787/api/system/info"

System Statistics

Get database statistics (content count, media count, user count).

Authentication: Admin role required

curl -X GET "http://localhost:8787/api/system/stats" \
  -H "Authorization: Bearer {token}"

Database Ping

Check database connectivity and latency.

Authentication: None required

curl -X GET "http://localhost:8787/api/system/ping"

Filtering & Querying

SonicJS provides powerful filtering capabilities for content queries.

Filter Operators

OperatorDescriptionExample
equalsExact matchfilter[status][equals]=published
not_equalsNot equalfilter[status][not_equals]=draft
greater_thanGreater thanfilter[price][greater_than]=100
less_thanLess thanfilter[price][less_than]=1000
likeCase-insensitive searchfilter[title][like]=javascript
containsString containsfilter[tags][contains]=tutorial
inValue in listfilter[category][in]=blog,news
not_inValue not in listfilter[status][not_in]=draft,archived
existsField existsfilter[featuredImage][exists]=true

Filter Examples

Simple equality filter:

curl "http://localhost:8787/api/content?filter[status][equals]=published"

Multiple filters (AND logic):

curl "http://localhost:8787/api/content?\
filter[status][equals]=published&\
filter[category][equals]=blog&\
filter[price][less_than]=100"

Search with LIKE:

curl "http://localhost:8787/api/content?filter[title][like]=getting started"

Filter with IN operator:

curl "http://localhost:8787/api/content?filter[category][in]=blog,tutorial,guide"

Date range filter:

curl "http://localhost:8787/api/content?\
filter[created_at][greater_than]=2025-01-01&\
filter[created_at][less_than]=2025-12-31"

Sorting

Sort results by any field. Prefix with - for descending order.

# Sort by created_at descending
curl "http://localhost:8787/api/content?sort=-created_at"

# Sort by title ascending
curl "http://localhost:8787/api/content?sort=title"

Pagination

Use limit and offset for pagination.

# Get first 10 items
curl "http://localhost:8787/api/content?limit=10&offset=0"

# Get next 10 items
curl "http://localhost:8787/api/content?limit=10&offset=10"

Caching

SonicJS implements a three-tiered caching system for optimal performance.

Cache Tiers

  1. Memory Cache - In-memory cache (fastest, ~1-3ms)
  2. KV Cache - Cloudflare KV storage (fast, ~5-15ms)
  3. Database - D1 database (slower, ~20-50ms)

Cache Headers

Every API response includes cache information:

X-Cache-Status: HIT
X-Cache-Source: memory
X-Cache-TTL: 278
X-Response-Time: 3ms

Headers:

  • X-Cache-Status - HIT or MISS
  • X-Cache-Source - memory, kv, or database
  • X-Cache-TTL - Remaining TTL in seconds (cache hits only)
  • X-Response-Time - Total response time

Cache TTLs

ResourceTTLMemoryKV
API responses5 min
Collections2 hours
Content1 hour
User data15 min
Media metadata1 hour

Cache Invalidation

Caches are automatically invalidated when:

  • Content is created, updated, or deleted
  • Collections are modified
  • Media files are uploaded or deleted
  • User permissions change

Error Handling

SonicJS uses standard HTTP status codes and returns consistent error responses.

HTTP Status Codes

CodeDescription
200Success
201Created
400Bad Request
401Unauthorized
403Forbidden
404Not Found
500Internal Server Error

Error Response Format

{
  "error": "Error message",
  "details": [
    {
      "code": "validation_error",
      "message": "Field is required",
      "path": ["fieldName"]
    }
  ]
}

Common Errors

401 Unauthorized:

{
  "error": "Authentication required"
}

403 Forbidden:

{
  "error": "Insufficient permissions"
}

404 Not Found:

{
  "error": "Resource not found"
}

400 Validation Error:

{
  "error": "Validation failed",
  "details": [
    {
      "code": "invalid_type",
      "message": "Expected string, received number",
      "path": ["title"]
    }
  ]
}

Rate Limiting

Currently, SonicJS does not enforce rate limits. This may change in future versions.

For production deployments, consider implementing rate limiting at the Cloudflare Workers level using:


Next Steps

For questions or support, visit our Community page.

Was this page helpful?