Skip to main content
This guide assumes you’ve set $LYMO_KEY, $LYMO_BASE, and $VIDEO as in the quickstart. $LYMO_BASE stops at /platform; versioned paths go under /v1.
Long-running work in the Platform API is modeled as a resource that owns its status, not as opaque jobs. There are two such resources today:
  • POST /v1/videos/:id/analyses — analyze a video
  • POST /v1/deals/:id/scorings — score a deal
Both endpoints return 201 immediately with status: "processing" and a stable id. You then poll the resource or subscribe to a webhook for completion.

Lifecycle

POST   /v1/videos/:id/analyses           → 201 { id, status: "processing", ... }
GET    /v1/videos/:id/analyses/:id       → 200 { id, status: "processing" | "completed" | "failed", ... }
GET    /v1/videos/:id/analyses           → 200 { data: [history ...] }

Status values

External status collapses several internal workflow states into three values:
StatusMeaning
processingWork is queued or in flight
completedFinished successfully — result is populated
failedTerminal failure — error: { code, message } present
Once a resource reaches completed or failed, it does not transition again.

Reading the completed result

When an analysis or scoring reaches completed, the same GET endpoint returns a result field alongside the existing status metadata. The full per-field schema is in the API Reference tab; here’s what to expect at a glance:
  • Analysesresult surfaces the summary sections, checklist evaluation (when enabled on the org), and sales events produced by the run. You can also fetch these piecemeal via GET /v1/videos/:id/summary, .../checklist, .../events.
  • Scoringsresult surfaces the computed score factors for the deal. GET /v1/deals/:id returns the same factors on the deal itself.
On failed, an error: { code, message } object replaces result. code is a stable machine-readable string you can switch on; message is human-readable and may change between versions. Typical end-to-end latency is on the order of minutes — polling once every 5–10 seconds is more than enough. Work that gets genuinely stuck is driven to failed by internal timeouts; the API itself does not hold a resource in processing indefinitely.

Polling

ANALYSIS=$(curl -s -X POST "$LYMO_BASE/v1/videos/$VIDEO/analyses" \
  -H "Authorization: Bearer $LYMO_KEY" | jq -r .data.id)

while true; do
  STATUS=$(curl -s "$LYMO_BASE/v1/videos/$VIDEO/analyses/$ANALYSIS" \
    -H "Authorization: Bearer $LYMO_KEY" | jq -r .data.status)
  [ "$STATUS" != "processing" ] && break
  sleep 5
done

echo "Analysis finished with status: $STATUS"
Poll every 5 seconds. A 429 response includes a Retry-After header — honor it rather than retrying immediately.

Idempotency

POST requests accept an Idempotency-Key header. The API caches the first 2xx response for 24 hours, keyed by (organization, method, path, key, body-hash), and returns it verbatim on retry:
curl -X POST "$LYMO_BASE/v1/videos/$VIDEO/analyses" \
  -H "Authorization: Bearer $LYMO_KEY" \
  -H "Idempotency-Key: $(openssl rand -hex 16)"
Retrying with the same key and a different body is rejected on cache key mismatch — the key is effectively bound to the exact request shape, so a replay can’t get back a response for a different payload.
A cached response is returned verbatim even if the underlying resource has since been deleted or re-processed. Send a fresh Idempotency-Key to force a new request. Keys longer than 256 characters return 400 bad_request.
Use idempotency keys whenever a network retry could cause duplicate work — for example, when a client-side timeout ambiguously fails a POST.

Subscribing instead of polling

For production workloads, register a webhook and let Lymo notify you:
  • video.analysis.completed
  • video.analysis.failed
Deal scoring events (deal.scoring.completed, deal.scoring.failed) are declared in the schema so SDK types remain stable, but the publisher isn’t wired up yet — subscribing today produces no deliveries. They’ll be enabled in a future release.
See Webhooks for registration, signature verification, and the full event list.