§01  /  Platform

Author it three ways.
Run it one way.

Visual canvas, JSON, or the Python SDK - three renderings of one workflow definition. Audit-by-construction, optional HITL gates at any step and durability through any pause are properties of the engine, not features you switch on.

workflows/invoice_processing.pySource
$ lyhnis deploy invoice_processing.py
 parsed 1 workflow, 7 activities
 schema check passed
 schedule registered · 0 9 * * MON
 deployed v14 · canvas + JSON in sync

$ lyhnis run invoice_processing --watch
run_01JX9 RUNNING  microsoft.read_emails
run_01JX9 RUNNING  parallel · 3 branches
run_01JX9 PAUSED   human.approval · #finance
same enginesame schemassame audit
§02  /  Authoring

Same workflow.
Three ways to author.

Drag activities onto the canvas. Edit the JSON directly. Or write it in Python with the SDK. Switch view at any time - the definition is one object, and it versions with your code.

invoice_processing.pyPython SDK
CanvasJSONPython
@workflow("invoice_processing")
@schedule("0 9 * * MON")
def invoice_processing():
    emails = microsoft.read_emails(folder="invoices", since="7d")

    @parallel
    for email in emails:
        invoice = ocr.invoice(email.attachment)
        data.validate(invoice, schema=InvoiceSchema)

        if invoice.amount > 10_000:
            decision = human.approval(
                approvers=["cfo", "finance"], timeout="48h")
            if not decision.approved:
                continue

        with retry(times=3):
            stripe.create_payment_intent(invoice)
            hubspot.create_deal(invoice)

        notify.slack(channel="#finance", text=f"Invoice {invoice.id} done")
invoice_processing.runExecution graph
schedule.weekly0 9 * * MON
microsoft.read_emailsfolder=invoices · 7d
parallel · 3 branches
ocr.invoice
data.validate
human.approval
stripe + hubspot
ocr.invoice
data.validate
human.approval
stripe + hubspot
ocr.invoice
data.validate
human.approval
stripe + hubspot
fan-in · wait all
notify.slackchannel=#finance
drag to editsame definitiondiffable JSON
§03  /  The primitives

What you build with.

Eleven categories of typed, retried, audited activities. Compose them, wrap them, or author your own - new activities and whole new categories are added on request.

70+ activities11 categories28 SaaS connectors
Agents

AI-native execution loops with explicit budgets, sub-workflows-as-tools and HITL gates.

  • agent.run
  • mcp.call_tool
  • + MCP server
Control Flow

Pause for human approval. Branch, retry and gate with engine-enforced semantics.

  • human.approval
  • control.if_else
  • control.for_each
  • + parallel, retry
OCR

Structured data out of invoices, receipts, IDs, business cards and arbitrary documents.

  • ocr.invoice
  • ocr.receipt
  • ocr.passport
  • ocr.document
  • + 3 more
AI / LLM

Classify, extract, summarize, translate and decide with any LLM provider.

  • ai.classifier
  • ai.extract
  • ai.summarize
  • ai.translate
  • + 2 more
HTTP

Typed requests, signed webhooks, retries and backoff you do not have to write.

  • http.request
  • http.webhook
  • + 2 more
Notify

Slack, Teams, email and Telegram - every send captured in Communications.

  • notify.slack
  • notify.teams
  • notify.email
  • notify.telegram
File Ops

Convert, split, merge, zip and hand off artifacts with lineage attached.

  • file.convert_pdf
  • file.zip
  • + 4 more
Data

Transform, validate against a schema, reshape and join between steps.

  • data.transform
  • data.validate_schema
  • + 3 more
Database

Query and write to Postgres, MSSQL and MySQL with scoped credentials.

  • db.postgres_query
  • db.mssql_exec
  • + 2 more
Cloud

Object storage and blob operations across AWS, Azure and GCP.

  • cloud.s3_put
  • cloud.blob_get
  • + 3 more
SaaS Apps

28 connectors - Stripe, HubSpot, Salesforce, Google Workspace, Microsoft 365.

  • saas.stripe_refund
  • saas.hubspot_sync
  • + 26 more
§04  /  Durability & state

Pause for an hour.
Pause for a month.

Per-turn dispatch means pause, resume and crash-recovery share one primitive: the run's state lives in the engine's store, and a worker only ever holds one turn at a time. So a 48-hour wait for a CFO is not a degraded mode - it is the same code path as a 40-millisecond retry, and it costs nothing while it waits.

run_01JX7 · lifecycleRecovered 3×
09:00:01started · schedule
09:00:44worker sigkill → resumed on w-07
09:01:12paused · human.approval
+2d 04hengine restart · run untouched
+2d 06hrelease v2.37 deployed
+2d 04:12approved · ops@acme · slack
11:13:38resumed at span 05/08
11:13:49complete · sealed & signed
0 retry storms0 lost runs1 primitive
Per-turn dispatch

A worker claims one turn, commits, and lets go. Nothing is held open across a wait.

Crash-equivalent

A killed worker and a two-week pause are the same state transition to the engine.

Free waiting

Paused runs consume no worker, no thread and no concurrency slot.

Deploy-safe

Ship mid-run. Definitions are versioned, so in-flight runs finish on the version they started.

§05  /  The control plane

Operate at scale.

Six surfaces, each one click from the workflow that produced the thing you are looking at. No separate observability vendor to wire up.

01

Workflow canvas

Drag, wire and configure. Every node is the same activity your Python calls, with the same schema and the same validation.

02

Run inspector

Per-span timing, inputs, outputs, retries and the exact payload that failed. One click from any job in the list.

03

Activity catalog

Browse all 70+ activities with their schemas, examples and per-tenant execution counts.

04

Audit log

Insert-only, signed, actor-typed. Filter by actor, workflow, resolution source or date and export the range.

05

Files & lineage

Every artifact with role inference and a lineage graph back to the uploader and the producing activity.

06

Monitoring

Volume, success rate, P95, queue depth, worker health. Prometheus-backed and alertable anywhere.

§06  /  Begin

Ten minutes to your first run. Either door.

For engineers

Install the SDK.

Author in Python, test locally, deploy to the same engine the canvas uses.

$pip install lyhnis
Read the docs
For operations

Open the canvas.

Drag activities, place your approval gates, hit run. No local setup, same execution layer.

Book a demo Talk to engineering
See pricing