Developer Portal

Integrate with easy-host using the REST API. Upload, manage, and serve HTML content programmatically.

Authentication

All API endpoints require HTTP Basic Authentication. Include your credentials in every request.

curl -u username:password https://content.oglimmer.com/api/content

Quick Start

# 1. Upload a single HTML file
curl -u admin:changeme \
  -F "slug=hello" \
  -F "file=@index.html" \
  https://content.oglimmer.com/api/content

# 2. Upload a ZIP archive with multiple files
curl -u admin:changeme \
  -F "slug=my-site" \
  -F "file=@site.zip" \
  -F "title=My Website" \
  https://content.oglimmer.com/api/content

# 3. View your content
open https://content.oglimmer.com/s/hello

Base URL

All API endpoints are relative to:

https://content.oglimmer.com/api/content

Endpoints

List All Content

GET /api/content

Returns all content items owned by the authenticated user.

Example request:

curl -u admin:changeme https://content.oglimmer.com/api/content

Response: 200 OK

[
  {
    "id": 1,
    "slug": "hello",
    "title": "My Page",
    "sourceUrl": "https://example.com",
    "owner": "admin",
    "creator": "John Doe",
    "allowExternalResources": false,
    "createdAt": "2026-04-09T10:00:00Z",
    "updatedAt": "2026-04-09T10:30:00Z",
    "files": ["index.html", "style.css"]
  }
]

Create Content

POST /api/content

Upload a new content item. Accepts multipart/form-data.

FieldTypeRequiredDescription
slugstringYesUnique URL identifier for your content
filefileYesHTML file or ZIP archive (max 10 MB)
titlestringNoDisplay title for the content
sourceUrlstringNoReference URL for the original source
creatorstringNoName of the content creator
allowExternalResourcesstringNo"true" or "false" — allow loading external resources
passphrasestringNoEncrypt the files at rest; visitors must enter it to view the page. Never stored — unrecoverable if lost

Example request:

curl -u admin:changeme \
  -F "slug=my-page" \
  -F "file=@index.html" \
  -F "title=My Page" \
  -F "creator=John Doe" \
  -F "allowExternalResources=false" \
  https://content.oglimmer.com/api/content

Response: 201 Created

{
  "id": 2,
  "slug": "my-page",
  "title": "My Page",
  "owner": "admin",
  "creator": "John Doe",
  "allowExternalResources": false,
  "createdAt": "2026-04-09T11:00:00Z",
  "updatedAt": "2026-04-09T11:00:00Z",
  "files": ["index.html"]
}

Error responses:

Get Content

GET /api/content/{slug}

Retrieve details for a specific content item.

Example request:

curl -u admin:changeme https://content.oglimmer.com/api/content/my-page

Response: 200 OK — Returns a content object (same structure as above).

Error responses:

Update Content

PUT /api/content/{slug}

Update an existing content item. All fields are optional — only provided fields are updated. Accepts multipart/form-data.

FieldTypeDescription
filefileNew file to replace existing content
titlestringUpdated title
sourceUrlstringUpdated source URL
creatorstringUpdated creator name
allowExternalResourcesstring"true" or "false"
passphrasestringFor encrypted content, its current passphrase — required to replace files, rotate, or remove encryption. For unencrypted content, a passphrase to encrypt it with
newPassphrasestringRotate to this passphrase (requires passphrase). Re-encrypts with a fresh key, so already-unlocked visitors lose access
removeEncryptionstring"true" decrypts the content back to public storage (requires passphrase)

Example request:

curl -X PUT -u admin:changeme \
  -F "file=@updated.html" \
  -F "title=Updated Page" \
  https://content.oglimmer.com/api/content/my-page

Response: 200 OK — Returns the updated content object.

Error responses:

Delete Content

DELETE /api/content/{slug}

Permanently delete a content item and all its files.

Example request:

curl -X DELETE -u admin:changeme \
  https://content.oglimmer.com/api/content/my-page

Response: 204 No Content — Empty response body on success.

Error responses:

Response Object

All endpoints that return content use this structure:

FieldTypeDescription
idintegerUnique content ID
slugstringURL identifier
titlestringContent title
sourceUrlstringSource URL (omitted if empty)
ownerstringUsername of the content owner
creatorstringCreator name
allowExternalResourcesbooleanWhether external resource loading is allowed
encryptedbooleanWhether the files are encrypted at rest and need a passphrase to view
createdAtstringISO 8601 timestamp
updatedAtstringISO 8601 timestamp
filesarrayList of file paths in this content

Public Serving

Uploaded content is publicly accessible at:

https://content.oglimmer.com/s/{slug}
https://content.oglimmer.com/s/{slug}/{path}

Encryption

Pass a passphrase when creating content to encrypt its files at rest. Visitors then have to enter that passphrase before anything is served.

# Upload an encrypted page
curl -u admin:changeme \
  -F "slug=private-page" \
  -F "file=@index.html" \
  -F "passphrase=correct horse battery staple" \
  https://content.oglimmer.com/api/content

How it is protected

Serving encrypted content

Changing protection

# Encrypt content that is already public
curl -X PUT -u admin:changeme \
  -F "passphrase=new secret" \
  https://content.oglimmer.com/api/content/my-page

# Replace the files of encrypted content
curl -X PUT -u admin:changeme \
  -F "file=@updated.html" \
  -F "passphrase=new secret" \
  https://content.oglimmer.com/api/content/my-page

# Rotate the passphrase (revokes visitors who already unlocked it)
curl -X PUT -u admin:changeme \
  -F "passphrase=new secret" \
  -F "newPassphrase=even better secret" \
  https://content.oglimmer.com/api/content/my-page

# Remove encryption
curl -X PUT -u admin:changeme \
  -F "passphrase=even better secret" \
  -F "removeEncryption=true" \
  https://content.oglimmer.com/api/content/my-page

Slug Rules

Limits