Home/Resources/Docs
Resources · Docs

Developer documentation

One API call drives the pipeline.

Below is a summary of the main endpoints and usage flow. The full OpenAPI specification, SDKs, and the on-premises operations guide are available once your account is created.

Quickstart · your first encoding job
# 1. Submit an encoding job
curl -X POST https://api.lemonflex.net/v1/jobs \
  -H "Authorization: Bearer $LEMONFLEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input":  { "uri": "s3://my-bucket/source.mp4" },
    "output": { "uri": "s3://my-bucket/out/" },
    "profile": "hevc-4k-quality",
    "enhance": { "superResolution": true, "denoise": "auto" }
  }'

# => { "id": "job_7fK2xQ", "status": "queued" }

# 2. Check status
curl https://api.lemonflex.net/v1/jobs/job_7fK2xQ \
  -H "Authorization: Bearer $LEMONFLEX_API_KEY"
Authentication

Authentication

Every request travels over HTTPS and requires an API key or an OAuth 2.0 access token.

API key

Use this for server-to-server communication. Keep keys in environment variables and out of client code. Keys are issued per project and their scope can be restricted.

Authorization: Bearer lfx_live_a1b2c3d4e5f6...
Content-Type: application/json

OAuth 2.0

When user delegation is required, obtain a token through the client credentials flow. Tokens are valid for one hour and must be refreshed.

curl -X POST https://api.lemonflex.net/oauth/token \
  -d grant_type=client_credentials \
  -d client_id=$CLIENT_ID \
  -d client_secret=$CLIENT_SECRET

# => { "access_token": "...", "expires_in": 3600 }
API Reference

Main endpoints

Batch jobs and live channels share one resource model.

Jobs — batch processing
POST/v1/jobsSubmit an encoding or Enhance job.
GET/v1/jobsList jobs, filtered by status or time range.
GET/v1/jobs/{id}Retrieve a single job's status, progress, and quality metrics.
DELETE/v1/jobs/{id}Cancel a queued or in-progress job.
Channels — live
POST/v1/channelsCreate a live channel and receive its ingest endpoint.
GET/v1/channels/{id}Retrieve channel status and live metrics.
POST/v1/channels/{id}/startStart the channel, beginning ingest and delivery.
POST/v1/channels/{id}/stopStop the channel. Configuration is retained.
PATCH/v1/channels/{id}Change the profile or ABR ladder.
Profiles & Assets
GET/v1/profilesList the available encoding profiles.
POST/v1/profilesRegister a custom profile.
GET/v1/assets/{id}/metricsRetrieve the VMAF, PSNR, and bitrate report for an output.
Webhooks
GET/v1/webhooksList registered webhook endpoints.
POST/v1/webhooksRegister a receiving URL and the events to subscribe to.
DELETE/v1/webhooks/{id}Remove a webhook registration.
Examples

Usage examples

The three flows people use most.

Enhance, then encode

Restore a low-quality source and finish encoding in the same job.

JSON · Request body
{
  "input":  { "uri": "s3://src/old.mp4" },
  "output": { "uri": "s3://dst/" },
  "profile": "hevc-4k-quality",
  "enhance": {
    "superResolution": "4x",
    "denoise": "auto",
    "temporalStabilize": true
  }
}

Create a live channel

Accept SRT input and deliver a three-rung ABR ladder.

JSON · Request body
{
  "name": "sports-ch-01",
  "input": { "protocol": "srt", "mode": "listener" },
  "profile": "hevc-4k-lowlatency",
  "ladder": [
    { "height": 2160, "bitrate": 12000 },
    { "height": 1080, "bitrate": 5000 },
    { "height": 720,  "bitrate": 2500 }
  ],
  "packaging": ["ll-hls", "dash"]
}

Fetch a quality report

Check output VMAF and bitrate to tune the profile.

Python
from lemonflex import Client

client = Client(api_key=os.environ["LEMONFLEX_API_KEY"])
job = client.jobs.create(
    input="s3://src/clip.mp4",
    output="s3://dst/",
    profile="av1-4k-efficient",
)
job.wait()

report = client.assets.metrics(job.asset_id)
print(report.vmaf, report.bitrate_kbps)
Profiles

Encoding profiles

Use a preset as-is, or define your own by combining parameters.

ProfileCodecResolutionRate controlUse case
h264-1080p-standardH.2641920×1080Capped VBRLegacy device compatibility
hevc-4k-qualityHEVC3840×2160VBRDefault for VOD catalogs
hevc-4k-lowlatencyHEVC3840×2160CBRLive delivery
av1-4k-efficientAV13840×2160VBRMinimizing delivery cost
hevc-8k-archiveHEVC7680×4320CRFMaster archive
Events & Errors

Webhooks and error handling

We recommend receiving job status by webhook rather than polling.

Webhook events

job.completed
The job finished successfully and output was written to the destination.
job.failed
The job failed. The payload includes an error code and cause.
channel.started
The live channel is receiving input and has begun delivery.
channel.degraded
Channel quality degraded due to input loss or processing delay.
channel.stopped
The channel stopped. The payload distinguishes intentional stops from failures.

Every webhook request includes an X-Lemonflex-Signature header. Verify the signature on receipt to reject forged requests.

Error codes

400
The request body does not match the schema. Check field names and types.
401
The API key or token is missing or invalid.
403
No permission for this resource. Check the key's scope.
404
The requested job, channel, or profile does not exist.
409
The operation is not valid in the current state — for example, stopping an already-stopped channel.
422
The input source could not be read, or the format is unsupported.
429
Rate limit exceeded. Follow the Retry-After header.
5xx
Server-side error. Retry with exponential backoff.

Retry 5xx responses and 429 with exponential backoff. A 4xx means the request itself needs fixing.

SDK

Client libraries

Call through a language SDK instead of handling HTTP directly.

Python
lemonflex

Suited to batch pipelines and data processing scripts.

pip install lemonflex
Go
lemonflex-go

For controlling channels from high-concurrency services.

go get github.com/lemonflex/lemonflex-go
Node.js
@lemonflex/sdk

Call from backend APIs and serverless functions.

npm install @lemonflex/sdk
SDK packages and installation paths are shared when your account is created.
FAQ

Developer FAQ

Should we use REST or gRPC?

REST is simpler for submitting batch jobs and polling status. gRPC is preferable when streaming live channel metrics or when call frequency is high. Both interfaces share the same resource model, so mixing them is fine.

Can we poll for job status?

You can, but webhooks are recommended. If you do poll, keep the interval at 5 seconds or more — shorter intervals may receive 429 responses.

Is the API the same on-premises?

Yes. Only the endpoint host changes to your internal address; request and response schemas are identical. Code developed against the cloud works on-premises with a host change alone.

What are the rate limits?

They vary by account tier. The X-RateLimit-Remaining and X-RateLimit-Reset response headers show your current allowance. If you need higher limits for a large batch, ask us to raise them.

Can we get the OpenAPI specification file?

Yes. We provide the OpenAPI 3.1 specification and gRPC Protobuf definitions when your account is created. You are welcome to generate your own client from them.

Your video infrastructure,
one level up.

Start with a single card and scale as needed. We design the demo, the rollout, and the technical review with you.

Product updates · newsletter

Product updates and technical material only. Privacy Policy