Nyami
FeaturesPricing

Getting started

  • Overview
  • Quickstart

Reference

  • Settings
  • API

Protection

  • Security model
  • Licensing

Help

  • Troubleshooting

Docs / Quickstart

Quickstart

Protect your first Python file in under five minutes. Upload it through the dashboard, or submit it to the API and poll until the protected build is ready to download.

Get a planDocumentation overview

1. Get an account and a plan

Create an account, then activate a plan. Every plan ships the full protection pipeline with no feature gating. Dashboard uploads work on any active plan. The HTTP API additionally requires an API plan, because that is what allows external keys to be used.

  • →Register an account with an email address and a username.
  • →Pick a tier on the pricing page. Standard variants cover the dashboard, API variants unlock external keys.

2. Protect a file from the dashboard

The dashboard is the fastest path and needs no key handling, because it signs requests with the internal key already attached to your account.

  1. 1.Open the dashboard and select a single .py file of up to 10 MB.
  2. 2.Adjust the settings panel, or leave the presets. The defaults are optimization level 1, Python 3.14, anti-debug off, lite and full function obfuscation on, and variable renaming on.
  3. 3.Submit. The job queues as PENDING, moves to PROCESSING, and the download appears once it reads COMPLETED.

3. Create an API key

Keys are issued from dashboard API keys on an API plan. The full key is shown exactly once at creation, so store it in a secret manager or an environment variable before closing the dialog. Only the nyami_ prefix is retrievable afterwards. You can hold five active keys, and revoking one frees a slot.

Send it on every request as the X-API-Key header. Never put it in client-side code, a repository, or a query string.

4. Submit a job to the API

POST /api/obfuscate takes a multipart body with exactly two fields: file, the .py source, and settings, a JSON string. It responds with the job id, not the protected file.

Request
curl -X POST https://nyami.cc/api/obfuscate \
  -H "X-API-Key: nyami_your_key_here" \
  -F "file=@script.py" \
  -F 'settings={"optimization":"1","python_version":"3.14","anti_debug":"none","lite_fobf":true,"var_renaming":true}'
200 response
{
  "jobId": "clx0a1b2c3d4e5f6g7h8i9j0",
  "message": "Job submitted successfully. Poll GET /api/obfuscate/[jobId] for status."
}

5. Poll the job and download

GET /api/obfuscate/{jobId} returns the current status. A COMPLETED job also carries outputFileSize and a signed downloadUrl that is valid for one hour. A FAILED job carries errorMessage instead. Poll on a five second interval.

Request
curl https://nyami.cc/api/obfuscate/clx0a1b2c3d4e5f6g7h8i9j0 \
  -H "X-API-Key: nyami_your_key_here"
200 response
{
  "jobId": "clx0a1b2c3d4e5f6g7h8i9j0",
  "status": "COMPLETED",
  "inputFileName": "script.py",
  "inputFileSize": 4821,
  "createdAt": "2026-08-15T10:04:11.204Z",
  "startedAt": "2026-08-15T10:04:12.881Z",
  "completedAt": "2026-08-15T10:04:39.552Z",
  "outputFileSize": 261774,
  "downloadUrl": "https://<your-app>/api/obfuscate/<jobId>/download?token=..."
}
Download
curl -L -o protected.py "<downloadUrl from the COMPLETED response>"

6. Full Python client

Submit, poll, and download in one script. It raises on a failed job instead of silently writing an empty file. The settings object carries the defaults, and the settings page documents every remaining key, including the lowering families.

client.py
import json
import time

import requests

API_KEY = "nyami_your_key_here"
BASE = "https://nyami.cc/api/obfuscate"
HEADERS = {"X-API-Key": API_KEY}

settings = {
    "optimization": "1",
    "python_version": "3.14",
    "anti_debug": "none",
    "anti_debug_native": False,
    "debug": False,
    "wif": False,
    "lite_fobf": True,
    "func_obf": True,
    "var_renaming": True,
    "mixed_format": True,
    "whitebox": True,
    "zip_pyc": False,
    "zip_light": True,
    "windows_target": True,
    "drv": False,
    "no_console": False,
    "pyinstaller": False,
    "icon": "",
    "kod": False,
    "pytoc": False,
    "rename_public_api": False,
    "hwid": "",
    "trial_time": "",
}

with open("script.py", "rb") as handle:
    submit = requests.post(
        BASE,
        headers=HEADERS,
        files={"file": ("script.py", handle, "text/x-python")},
        data={"settings": json.dumps(settings)},
        timeout=120,
    )

submit.raise_for_status()
job_id = submit.json()["jobId"]
print(f"submitted {job_id}")

while True:
    poll = requests.get(f"{BASE}/{job_id}", headers=HEADERS, timeout=30)
    poll.raise_for_status()
    job = poll.json()
    status = job["status"]

    if status == "COMPLETED":
        download = requests.get(job["downloadUrl"], timeout=300)
        download.raise_for_status()
        with open("protected.py", "wb") as out:
            out.write(download.content)
        print(f"wrote protected.py ({len(download.content)} bytes)")
        break

    if status == "FAILED":
        raise RuntimeError(f"job {job_id} failed: {job.get('errorMessage', 'no detail returned')}")

    time.sleep(5)

7. Where to go next

  • →How it works walks the five pipeline phases stage by stage.
  • →Features lists every protection module in the pipeline.
  • →Stuck on a build? Ask on Discord.

Full reference

This walkthrough covers the shortest path through the product. Every setting the pipeline accepts, with the values it takes and what it changes, is on the settings page. The endpoint contract, the rate and concurrency limits, and every error code the API can return are on the API page.

Quickstart FAQ

How large can a file be when I upload it to Nyami?

Each submission accepts a single .py file up to 10 MB. Larger projects should be entry-point protected, or split before submission. Ask on Discord if you need a higher cap.

Do I need an API subscription to call the Nyami API?

Yes. External API keys only work on an API subscription with an unexpired term. Dashboard uploads work on any active plan because they use your internal key.

How long is the Nyami download URL valid?

The signed downloadUrl returned on a COMPLETED job expires one hour after it is issued. Poll the job again to mint a fresh URL.

Which Python versions can Nyami target?

You can target Python 3.10, 3.11, 3.12, 3.13, or 3.14 through the python_version setting. It defaults to 3.14.

Previous

Overview

Next

Settings

NYAMI

Python protection through compilation, encryption, and active defense.

40+ protection modules

Product

  • Features
  • Pricing
  • Comparison
  • Purchase

Developers

  • Quickstart
  • Documentation
  • Blog

Support

  • Discord
  • projectnyami@proton.me

© 2026 Nyami. All rights reserved.

Terms of ServicePrivacy PolicyRefund Policy
NYAMI