Skip to content

User Manual

This guide explains how to authenticate with the Snackbox API and interact with its resources. The full endpoint reference is in the api/openapi.yaml on GitLab.

Authentication

Snackbox uses JWT (JSON Web Token) bearer authentication. Obtain a token by logging in, then include it in every subsequent request via the Authorization header.

Login

curl -s -X POST http://localhost:8080/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "admin@example.com", "password": "your-password"}' \
  | jq .

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_at": "2024-01-02T15:04:05Z"
}

Store the token and pass it with every authenticated request:

TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/v1/posts

Tokens expire after JWT_EXPIRY (default 24 hours). Request a new one by logging in again.

Resources

Health

Check whether the server is running. No authentication required.

curl http://localhost:8080/health

Tags

Tags categorise posts and pages.

# List all tags
curl http://localhost:8080/api/v1/tags

# Get a single tag
curl http://localhost:8080/api/v1/tags/1

# Create a tag (requires authentication)
curl -X POST http://localhost:8080/api/v1/tags \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "guides", "slug": "guides"}'

# Update a tag (requires authentication)
curl -X PUT http://localhost:8080/api/v1/tags/1 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "tutorials", "slug": "tutorials"}'

# Delete a tag (requires authentication)
curl -X DELETE http://localhost:8080/api/v1/tags/1 \
  -H "Authorization: Bearer $TOKEN"

Pages

Pages are static content entries (e.g. "About", "Contact").

# List all pages
curl http://localhost:8080/api/v1/pages

# Get a single page
curl http://localhost:8080/api/v1/pages/1

# Create a page (requires authentication)
curl -X POST http://localhost:8080/api/v1/pages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "About",
    "slug": "about",
    "content": "Welcome to our site.",
    "published": true
  }'

# Update a page (requires authentication)
curl -X PUT http://localhost:8080/api/v1/pages/1 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "About Us", "slug": "about", "content": "...", "published": true}'

# Delete a page (requires authentication)
curl -X DELETE http://localhost:8080/api/v1/pages/1 \
  -H "Authorization: Bearer $TOKEN"

Posts

Posts are regular content entries (e.g. blog posts, articles).

# List all posts (supports ?page=1&limit=20)
curl "http://localhost:8080/api/v1/posts?page=1&limit=10"

# Get a single post
curl http://localhost:8080/api/v1/posts/1

# Create a post (requires authentication)
curl -X POST http://localhost:8080/api/v1/posts \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My First Post",
    "slug": "my-first-post",
    "content": "Hello, world.",
    "published": true,
    "tag_ids": [1, 2]
  }'

# Update a post (requires authentication)
curl -X PUT http://localhost:8080/api/v1/posts/1 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Updated Title", "slug": "my-first-post", "content": "...", "published": true, "tag_ids": []}'

# Delete a post (requires authentication)
curl -X DELETE http://localhost:8080/api/v1/posts/1 \
  -H "Authorization: Bearer $TOKEN"

Media

Upload and retrieve binary files (images, documents, audio, video, etc.).

# Upload a file (requires authentication)
curl -X POST http://localhost:8080/api/v1/media \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@photo.jpg"

# List all media (public — no authentication required)
curl http://localhost:8080/api/v1/media

# Get metadata for a single media item (public — no authentication required)
curl http://localhost:8080/api/v1/media/1

# Delete a media item (requires authentication)
curl -X DELETE http://localhost:8080/api/v1/media/1 \
  -H "Authorization: Bearer $TOKEN"

The default maximum upload size is 32 MB. This limit is configurable by the administrator via MAX_UPLOAD_SIZE.

Users

User management is restricted to administrators.

# List all users (admin only)
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/v1/users

# Get a single user (admin only)
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/v1/users/1

# Create a user (admin only)
curl -X POST http://localhost:8080/api/v1/users \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Doe",
    "email": "jane@example.com",
    "password": "secure-password",
    "role": "author"
  }'

# Update a user (admin only)
curl -X PUT http://localhost:8080/api/v1/users/2 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Jane Doe", "email": "jane@example.com", "role": "author"}'

# Delete a user (admin only)
curl -X DELETE http://localhost:8080/api/v1/users/2 \
  -H "Authorization: Bearer $TOKEN"

Available roles: admin, author, member.

Rate Limiting

The login endpoint (POST /api/v1/auth/login) is rate-limited per IP address. The default limit is 10 requests per second. Exceeding the limit returns 429 Too Many Requests. Contact your administrator if you need the limit adjusted.