banatie-service/docs/api/live-url.md

8.7 KiB

Live URL & CDN API

Public CDN endpoints for image serving and live URL generation. For authenticated API, see image-generation.md.


CDN Image Serving

GET /cdn/:orgSlug/:projectSlug/img/:filenameOrAlias

Authentication: None - Public endpoint

Serve images by filename or project-scoped alias.

Path Parameters:

Parameter Description
orgSlug Organization identifier
projectSlug Project identifier
filenameOrAlias Filename or @alias

Examples:

# By filename
GET /cdn/acme/website/img/hero-background.jpg

# By alias
GET /cdn/acme/website/img/@hero

Response: Raw image bytes (not JSON)

Response Headers:

Header Value
Content-Type image/jpeg, image/png, etc.
Content-Length File size in bytes
Cache-Control public, max-age=31536000 (1 year)
X-Image-Id Image UUID

Live URL Generation

GET /cdn/:orgSlug/:projectSlug/live/:scope

Authentication: None - Public endpoint

Generate images on-demand via URL parameters with automatic caching.

Path Parameters:

Parameter Description
orgSlug Organization identifier
projectSlug Project identifier
scope Scope identifier (alphanumeric, hyphens, underscores)

Query Parameters:

Parameter Type Required Default Description
prompt string Yes - Image description
aspectRatio string No "1:1" Aspect ratio
autoEnhance boolean No true Enable prompt enhancement
template string No "general" Enhancement template

Example:

GET /cdn/acme/website/live/hero-section?prompt=mountain+landscape&aspectRatio=16:9

Response: Raw image bytes

Cache Behavior

Cache HIT - Image exists in cache:

  • Returns instantly
  • No rate limit check
  • Headers include X-Cache-Status: HIT

Cache MISS - New generation:

  • Generates image using AI
  • Stores in cache
  • Counts toward rate limit
  • Headers include X-Cache-Status: MISS

Cache Key: Computed from projectId + scope + prompt + aspectRatio + autoEnhance + template

Response Headers

Cache HIT:

Header Value
Content-Type image/jpeg
Cache-Control public, max-age=31536000
X-Cache-Status HIT
X-Scope Scope identifier
X-Image-Id Image UUID

Cache MISS:

Header Value
Content-Type image/jpeg
Cache-Control public, max-age=31536000
X-Cache-Status MISS
X-Scope Scope identifier
X-Generation-Id Generation UUID
X-Image-Id Image UUID
X-RateLimit-Limit 10
X-RateLimit-Remaining Remaining requests
X-RateLimit-Reset Seconds until reset

IP Rate Limiting

Live URLs are rate limited by IP address:

Limit Value
New generations 10 per hour per IP
Cache hits Unlimited

Note: Only cache MISS (new generations) count toward the limit. Cache HIT requests are not limited.

Rate limit headers are included on MISS responses:

  • X-RateLimit-Limit: Maximum requests (10)
  • X-RateLimit-Remaining: Remaining requests
  • X-RateLimit-Reset: Seconds until reset

Scope Management

Scopes organize live URL generation budgets. All scope endpoints require Project Key authentication.

Create Scope

POST /api/v1/live/scopes

Request Body:

Parameter Type Required Default Description
slug string Yes - Unique identifier
allowNewGenerations boolean No true Allow new generations
newGenerationsLimit number No 30 Max generations in scope
meta object No {} Custom metadata

Example:

{
  "slug": "hero-section",
  "allowNewGenerations": true,
  "newGenerationsLimit": 50,
  "meta": { "description": "Hero section images" }
}

Response: 201 Created

{
  "success": true,
  "data": {
    "id": "scope-123",
    "projectId": "project-456",
    "slug": "hero-section",
    "allowNewGenerations": true,
    "newGenerationsLimit": 50,
    "currentGenerations": 0,
    "lastGeneratedAt": null,
    "meta": { "description": "Hero section images" },
    "createdAt": "2025-11-28T10:00:00.000Z"
  }
}

Lazy Scope Creation

Scopes are auto-created on first live URL request if project.allowNewLiveScopes = true:

GET /cdn/acme/website/live/new-scope?prompt=...
// Creates "new-scope" with default settings

List Scopes

GET /api/v1/live/scopes

Query Parameters:

Parameter Type Default Description
slug string - Filter by exact slug
limit number 20 Results per page (max: 100)
offset number 0 Pagination offset

Response:

{
  "success": true,
  "data": [
    {
      "id": "scope-123",
      "slug": "hero-section",
      "allowNewGenerations": true,
      "newGenerationsLimit": 50,
      "currentGenerations": 12,
      "lastGeneratedAt": "2025-11-28T09:30:00.000Z"
    }
  ],
  "pagination": { "limit": 20, "offset": 0, "total": 3, "hasMore": false }
}

Get Scope

GET /api/v1/live/scopes/:slug

Returns scope with statistics (currentGenerations, lastGeneratedAt).

Update Scope

PUT /api/v1/live/scopes/:slug
{
  "allowNewGenerations": false,
  "newGenerationsLimit": 100,
  "meta": { "description": "Updated" }
}

Changes take effect immediately for new requests.

Regenerate Scope Images

POST /api/v1/live/scopes/:slug/regenerate

Request Body:

Parameter Type Description
imageId string Specific image UUID (optional)

Behavior:

  • If imageId provided: Regenerate only that image
  • If imageId omitted: Regenerate all images in scope

Images are regenerated with exact same parameters. IDs and URLs are preserved.

Delete Scope

DELETE /api/v1/live/scopes/:slug

Cascade Behavior:

  • Scope record is hard deleted
  • All images in scope are hard deleted (with MinIO cleanup)
  • Follows alias protection rules (aliased images may be kept)

Warning: This permanently deletes all cached images in the scope.


Scope Settings

Setting Type Default Description
slug string - Unique identifier within project
allowNewGenerations boolean true Whether new generations are allowed
newGenerationsLimit number 30 Maximum generations in scope

When allowNewGenerations: false:

  • Cache HITs still work
  • New prompts return 403 error

When newGenerationsLimit reached:

  • Cache HITs still work
  • New prompts return 429 error

Authenticated Live Endpoint

GET /api/v1/live?prompt=...

Authentication: Project Key required

Alternative to CDN endpoint with prompt caching by hash.

Query Parameters:

Parameter Type Required Description
prompt string Yes Image description

Cache Behavior:

  • Cache key: SHA-256 hash of prompt
  • Cache stored in prompt_url_cache table
  • Tracks hit count and last access

Response Headers:

  • X-Cache-Status: HIT or MISS
  • X-Cache-Hit-Count: Number of cache hits (on HIT)

Error Codes

HTTP Status Code Description
400 SCOPE_INVALID_FORMAT Invalid scope slug format
403 SCOPE_CREATION_DISABLED New scope creation not allowed
404 ORG_NOT_FOUND Organization not found
404 PROJECT_NOT_FOUND Project not found
404 SCOPE_NOT_FOUND Scope does not exist
409 SCOPE_ALREADY_EXISTS Scope slug already in use
429 IP_RATE_LIMIT_EXCEEDED IP rate limit (10/hour) exceeded
429 SCOPE_GENERATION_LIMIT_EXCEEDED Scope limit reached

Use Cases

Dynamic Hero Images

<img src="/cdn/acme/website/live/hero?prompt=professional+office+workspace&aspectRatio=16:9" />

First load generates, subsequent loads are cached.

Product Placeholders

<img src="/cdn/acme/store/live/products?prompt=product+placeholder+gray+box&aspectRatio=1:1" />

Blog Post Images

<img src="/cdn/acme/blog/live/posts?prompt=abstract+technology+background&aspectRatio=16:9&template=illustration" />

See Also