Convilyn developers

Quickstart

From install to first conversion in five minutes.

Install the consumer SDK and convert a file on your own machine in one command — then mint an API key when you want the cloud.

1. Install

uv add convilyn   # or: pip install convilyn

A single install gives you the Python library and the convilyn CLI. Requires Python 3.10+; type hints ship with the wheel (PEP 561).

TypeScript & Go SDKs are coming soon.

2. Convert a file right now — no key needed

Before any of the account setup: the Python package converts files on your own machine, with no upload and no network call.

uv add "convilyn[documents]"
convilyn local convert report.docx --to md
from convilyn import local
 
result = local.convert("report.docx", to="md")
print(result.output)  # report.md

Headings, lists and tables survive; embedded images land in an assets/ folder beside the Markdown. Nothing here reads CONVILYN_API_KEY or consumes quota — see offline conversion for the full picture, including how to ask what this machine can convert before you try.

3. Get an API key

Everything from here talks to the platform, and that needs a key.

Sign up, then create an API key on your Settings → API page (login required — it also manages billing and quota). The key starts with ck_ and is shown only once. Export it so the SDK and CLI both pick it up:

export CONVILYN_API_KEY=ck_...

4. Verify your setup

The convilyn package ships a doctor command that checks your environment before you spend an API call:

$ convilyn doctor --ping
[OK] convilyn SDK: 3.1.0
[OK] CONVILYN_API_KEY: ck_xx…XXXX
[OK] Backend health: 200 OK
[OK] Account tier: tier=free
All checks passed.

5. Convert a file in the cloud

The five-line hello-world: upload, convert, download.

from convilyn import Convilyn
 
client = Convilyn()
file = client.files.upload("report.docx")
job = client.convert.create_and_wait(file=file, target_format="pdf")
client.convert.download_to(job, to="report.pdf", overwrite=True)

download_to refuses to clobber an existing file: overwrite defaults to False and raises FileExistsError. Pass overwrite=True when you expect to re-run the script, as you will while following this page.

TypeScript & Go SDKs are coming soon.

A failed job raises a typed JobFailed error; an elapsed deadline raises a JobTimeout error. Catch the base error type to handle them uniformly — see each SDK's error reference.

Or, the same conversion from the convilyn CLI:

convilyn convert report.docx --to pdf -o report.pdf
convilyn convert report.docx --to pdf --json | jq .   # machine-readable
convilyn convert report.docx --to pdf --dry-run        # preview, no API call

6. Ask for structured data

Conversion hands you the whole document. When what you actually want is a few fields out of it, describe the shape you want with a JSON Schema and let the platform fill it in.

schema = {
    "type": "object",
    "properties": {
        "invoice_number": {"type": "string"},
        "total": {"type": "number"},
        "issued_on": {"type": "string", "format": "date"},
    },
    "required": ["invoice_number", "total"],
}
 
file = client.files.upload("invoice.pdf")
result = client.goals.understand([file.file_id], schema=schema)
print(result["invoice_number"], result["total"])

TypeScript SDK is coming soon.

schema is a plain JSON Schema object, not a model class — so the SDK adds no validation dependency and the same schema works from every language. You get the parsed result back directly, not a job handle.

Structured understanding goes deeper: designing a schema for grounding rather than for completeness, what each error means, and the same call from the shell.

7. Run an agentic workflow

Goal workflows are agentic — the backend assembles a multi-step plan, calls MCP tools, and may pause to ask for input. run starts a job and waits until it finishes or pauses for human input.

client.workflows.catalog() is the live list of what you can run; it needs no API key, so it is the honest place to look rather than a table in these docs that can go stale.

for workflow in client.workflows.catalog():
    print(workflow.workflow_id, "—", workflow.name)
 
file = client.files.upload("launch-notes.docx")
job = client.goals.run(
    workflow_id="goal_lane.content_to_multipost", files=[file.file_id]
)
if job.needs_input:
    slot = job.pending_slots[0]  # target_platform: instagram | facebook | linkedin
    job = client.goals.fill_slot(job.job_spec_id, slot_id=slot.slot_id, value="linkedin")
    job = client.goals.confirm(job.job_spec_id)
    job = client.goals.wait(job.job_spec_id)
print(job.status)

TypeScript & Go SDKs are coming soon.

Filling one slot by hand shows you the shape. When you would rather not write the loop, client.goals.run_interactive(on_slot=...) drives the same fill → confirm → wait cycle in a single call.

8. Pre-flight plan + quota

Some actions (fork a public workflow, publish your own tool server, run an expensive goal workflow job) need a paid plan. Check before you call:

estimate = client.account.get_quota(max_iterations=25)
print(estimate.estimated_usd, estimate.quota_check.state)  # "ok" | "soft_limit" | "quota_exceeded"

TypeScript & Go SDKs are coming soon.

When the verdict isn't ok, the SDK raises a typed PlanRequiredError / QuotaExceededError carrying the upgrade / top-up URL.

Where to go next