API reference

Base URL: https://your-instance.example/v1. All request and response bodies are JSON unless stated otherwise. Dates are ISO 8601 strings in UTC.

Authentication

Pass a personal access token as a Bearer header. Tokens are issued from your account settings after phone verification. Unauthenticated requests can list and download public adapters; write operations and private artifacts require a token.

Authorization: Bearer mfl_xxxxxxxxxxxxxxxxxxxx
curl -H "Authorization: Bearer mfl_xxxx" \
     https://your-instance.example/v1/adapters

Error codes

StatusCodeMeaning
400bad_requestMalformed JSON or missing required field
401unauthorizedMissing or invalid token
403forbiddenToken valid but lacks permission for this resource
404not_foundAdapter, job, or artifact does not exist
413payload_too_largeUpload exceeds the 256 MiB per-file limit
416range_not_satisfiableByte range outside artifact bounds
429too_many_requestsRate limit exceeded; see Retry-After header
503service_busyConcurrency cap reached; retry after Retry-After seconds

Error responses always include a JSON body:

{
  "error": "not_found",
  "detail": "No adapter with slug 'my-adapter'"
}

Rate limits

The default limit is 240 requests per minute per IP when the instance enables per-IP limiting (configured by the administrator). Exceeded requests receive HTTP 429 with a Retry-After: 30 header. Download and SSE connections each have separate concurrency caps (8 and 16 by default).

List adapters

GET /v1/adapters

Returns all adapters visible on this instance. No authentication required for public adapters.

Query parameters

ParameterTypeDescription
taskstringFilter by task, e.g. text-to-image
formatstringFilter by format: safetensors or gguf
curl "https://your-instance.example/v1/adapters?task=text-to-image"

Response

{
  "object": "list",
  "data": [
    {
      "id": "sdxl-watercolor-lora",
      "name": "SDXL Watercolor Illustration",
      "base_model": "stabilityai/stable-diffusion-xl-base-1.0",
      "task": "text-to-image",
      "version": "1.4.0",
      "format": "safetensors",
      "precision": "fp16",
      "size_bytes": 223412992,
      "sha256": "8f14e45f...",
      "public": true,
      "created_at": "2024-11-03T09:12:00Z",
      "updated_at": "2026-05-18T14:41:00Z"
    }
  ]
}

Get adapter

GET /v1/adapters/{id}

Returns full metadata for a single adapter including description, tags, compatibility, and sample outputs.

curl https://your-instance.example/v1/adapters/sdxl-watercolor-lora

Download artifact

GET /download/{id}

Streams the adapter file. Supports Range requests for resumable downloads. The response includes Content-Length, ETag (sha256), and Accept-Ranges: bytes.

# Full download
curl -L -O https://your-instance.example/download/sdxl-watercolor-lora

# Resumable download (byte range)
curl -L -H "Range: bytes=104857600-" \
     -o adapter.safetensors \
     https://your-instance.example/download/sdxl-watercolor-lora

Private adapters redirect to /register if no valid token is provided.

Create job

POST /v1/jobs

Queues an inference (image generation) or fine-tuning job and returns a job object with a stream_url.

Request body

FieldTypeRequiredDescription
typestringyesgenerate for image inference, finetune for training
adapterstringyesAdapter slug, e.g. sdxl-watercolor-lora
promptstringfor generateText prompt for image generation
curl -X POST https://your-instance.example/v1/jobs \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer mfl_xxxx" \
     -d '{"type": "generate", "adapter": "sdxl-watercolor-lora",
          "prompt": "autumn forest at dusk, soft watercolor"}'

Response — 201 Created

{
  "id": "job_a3f8c2d1b5e04790",
  "type": "generate",
  "status": "queued",
  "stream_url": "/events/job_a3f8c2d1b5e04790"
}

Get job

GET /v1/jobs/{id}
curl https://your-instance.example/v1/jobs/job_a3f8c2d1b5e04790

Response

{
  "id": "job_a3f8c2d1b5e04790",
  "type": "generate",
  "status": "running",
  "progress": 45
}

status is one of queued, running, or succeeded.

Stream events

GET /events/{id}

Server-sent events stream for a job. Connect with EventSource (browser) or curl --no-buffer. The stream emits three event types:

curl --no-buffer \
     https://your-instance.example/events/job_a3f8c2d1b5e04790
EventPayload fieldsNotes
startstatus: "running"Emitted once when processing begins
progressstep, progress (0–100), lossEmitted after each diffusion/training step
donestatus: "succeeded", result (image URL, optional)Terminal event; stream closes after this
event: start
data: {"status": "running"}

event: progress
data: {"step": 8, "progress": 40, "loss": 1.0241}

event: progress
data: {"step": 20, "progress": 100, "loss": 0.3812}

event: done
data: {"status": "succeeded", "result": "/static/img/sample_watercolor_1.png"}