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.
# 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
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/jsonOAuth 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 }Main endpoints
Batch jobs and live channels share one resource model.
/v1/jobsSubmit an encoding or Enhance job./v1/jobsList jobs, filtered by status or time range./v1/jobs/{id}Retrieve a single job's status, progress, and quality metrics./v1/jobs/{id}Cancel a queued or in-progress job./v1/channelsCreate a live channel and receive its ingest endpoint./v1/channels/{id}Retrieve channel status and live metrics./v1/channels/{id}/startStart the channel, beginning ingest and delivery./v1/channels/{id}/stopStop the channel. Configuration is retained./v1/channels/{id}Change the profile or ABR ladder./v1/profilesList the available encoding profiles./v1/profilesRegister a custom profile./v1/assets/{id}/metricsRetrieve the VMAF, PSNR, and bitrate report for an output./v1/webhooksList registered webhook endpoints./v1/webhooksRegister a receiving URL and the events to subscribe to./v1/webhooks/{id}Remove a webhook registration.Usage examples
The three flows people use most.
Enhance, then encode
Restore a low-quality source and finish encoding in the same job.
{
"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.
{
"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.
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)Encoding profiles
Use a preset as-is, or define your own by combining parameters.
| Profile | Codec | Resolution | Rate control | Use case |
|---|---|---|---|---|
h264-1080p-standard | H.264 | 1920×1080 | Capped VBR | Legacy device compatibility |
hevc-4k-quality | HEVC | 3840×2160 | VBR | Default for VOD catalogs |
hevc-4k-lowlatency | HEVC | 3840×2160 | CBR | Live delivery |
av1-4k-efficient | AV1 | 3840×2160 | VBR | Minimizing delivery cost |
hevc-8k-archive | HEVC | 7680×4320 | CRF | Master archive |
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.
Client libraries
Call through a language SDK instead of handling HTTP directly.
Suited to batch pipelines and data processing scripts.
pip install lemonflexFor controlling channels from high-concurrency services.
go get github.com/lemonflex/lemonflex-goCall from backend APIs and serverless functions.
npm install @lemonflex/sdkDeveloper 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.