MLGatee
Model-as-a-Service

Stop sending notebooks. Send an endpoint.

Upload a trained model, or deploy it from your notebook in one line of Python. In about four minutes you get a key-protected HTTPS address that anyone you choose can call. No Docker, no servers, no pip.

Sign in with GitHub, Google or an email link. One model free, no card needed.

Typically 1.5 to 4 minutes from upload to live. You’ll watch every step.

Step 1: deploy a trained model from a notebook with one line of Python.

How it works

Three parts.
One rule.

Your model file never runs on our servers. Only in its own service.

1 · Your side

You

  • Web appapp.mlgatee.com
  • Python clientmlgatee.deploy()
  • Any HTTP clientcurl, Python, your app
2 · Control plane

MLGatee

  • Sign-inGitHub, Google or an email link
  • Private storagemodel files, newest 3 versions
  • Byte inspectorreads bytes, never loads
  • Deploys and versionskeys stored as hashes
  • Monitoringcounts and timings only
3 · Model runtime

Your model’s service

  • One service per modelnothing shared
  • Python 3.12FastAPI server
  • Exact packagespinned from your file
  • /predict/predict_proba for classifiers
POST /predict with your key goes straight to your model’s own address. MLGatee isn’t in the request path.

See the full architecture, deploy flow and inspector rules

Works with your stack

Will your model work?

Nine frameworks, with packages pinned from what your file itself says. Upload the file, or let the Python client convert it.

Upload or Python1 / 9

scikit-learn

Models and pipelines, including pandas column transformers. MLGatee installs the scikit-learn version your file was saved with.

>>>mlgatee.deploy(model, name="iris")installs: scikit-learn at the version saved in your file
All details

Select a framework to see how it deploys

Not on the list? See what’s coming, and how to convert it today

Rollbacks and monitoring are live. Changelog
Features

Built for
the bad day.

Deploying is the easy part. Here’s everything that’s there after, including when something goes wrong.

Read from the bytesExact versions pinnedNothing runs on load
model.pkl
installsscikit-learn 1.9.1
Byte inspector

Inspected, never loaded.

A pickle can run code the moment it’s opened, so we never open yours on our servers. We read its bytes, pin the exact versions it needs, and refuse files that would run commands.

app.py
app.py.env
import os, requests

url = "https://mlg-iris-7f3a9c21.onrender.com/predict"
key = os.environ["MLGATEE_KEY"]

res = requests.post(url,
    headers={"Authorization": f"Bearer {key}"},
    json={"input_data": [[5.1, 3.5, 1.4, 0.2]]})
print(res.json())  # {'output': [0], 'model': 'iris'}
Key checked on every call
Endpoint and keys

“The key ended up in a screenshot.”

Make a new key on the model’s page. The old one keeps working until the new one is live, so nothing breaks in between. Keys are shown once and stored only as a hash.

Servicesone per model · nothing shared
mlg-irisscikit-learn 1.9.1Live
mlg-pricingcatboost 1.2.10Sleeping · idle 15 min
mlg-reviewsonnxruntime · tokenizersBuilding version 2
Isolation

One model, one service. Nothing shared.

Replacing or deleting one model never touches another. On the free plan an idle model naps after 15 quiet minutes and wakes on the next call.

Calls1,284
Errors0.5%
Typical answer4 ms
Sample data · last 24 hoursInputs never recorded
🎉Version 3 is liveIts calls are counted separately
Monitoring

“Is anyone even calling this?”

Calls, errors and answer times, per hour and per version, for the last 24 hours or 7 days. Never your inputs, outputs or keys.

Scroll to explore the dashboard

app.mlgatee.com/deployments/irisIllustrative

Modelsiris

iris Live · v3

scikit-learn · Free machine · Updated 2 h ago

New version

Call your model

Send rows of input features to /predict. Classifiers also answer /predict_proba.

Edit request body
Copy
export MLGATEE_KEY="paste-your-key-here"

curl -X POST https://mlg-iris-7f3a9c21.onrender.com/predict \
  -H "Authorization: Bearer $MLGATEE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input_data": [[5.1, 3.5, 1.4, 0.2]]}'
$env:MLGATEE_KEY = "paste-your-key-here"

$body = '{"input_data": [[5.1, 3.5, 1.4, 0.2]]}'
Invoke-RestMethod -Method Post -Uri "https://mlg-iris-7f3a9c21.onrender.com/predict" `
  -Headers @{ Authorization = "Bearer $env:MLGATEE_KEY" } `
  -ContentType "application/json" -Body $body
import json, os, urllib.request

KEY = os.environ.get("MLGATEE_KEY") or "paste-your-key-here"
request = urllib.request.Request(
    "https://mlg-iris-7f3a9c21.onrender.com/predict",
    data=json.dumps({"input_data": [[5.1, 3.5, 1.4, 0.2]]}).encode(),
    headers={"Authorization": "Bearer " + KEY, "Content-Type": "application/json"},
    method="POST",
)
with urllib.request.urlopen(request, timeout=120) as response:
    print(json.loads(response.read())["output"])

Recent activity

See all

15:11:12 [deploying] Server started on Python 3.12

15:11:14 [live] Version 3 is live

15:11:15 [live] Monitoring: reporting

Endpoint

https://mlg-iris-7f3a9c21.onrender.com

Endpoint key

mlg_live_••••••••a3f1

The full key is shown only once, when it’s created.

Monitoring

Calls, errors and answer times, reported by the model about once a minute.

Calls
6481,296 rows predicted
Errors
0.9%4 bad requests, 2 server errors
Answer time
4 ms / 11 mstypical / slowest 5%
Last called
2 min agotoday, 15:42
56 / h
Yesterday 16:00Calls per hourErrorsNow
By version
VersionCallsErrorsSlowest 5%
v3 answering now4120.5%11 ms
v22361.7%14 ms

Counts and answer times only: MLGatee never records what is sent to your model or what it answers.

New version

Drop the new file hereSame address, same key. Version 3 keeps answering while it builds.

Versions

The 3 newest versions are kept, so you can roll back to them.

VersionFileLiveActions
v3 Answering nowscikit-learn · 3.1 KBLive 2 h ago
v2XGBoost · 41 KB3 days ago, replaced 2 h ago
v1CatBoost · 88 KB5 days ago, replaced 3 days ago

A rollback becomes a new version built from the earlier file. Same address, same key.

Call your model

Send rows of input features to /predict, in the same order the model was trained on. Classifiers also answer /predict_proba.

Copy
export MLGATEE_KEY="paste-your-key-here"

curl -X POST https://mlg-iris-7f3a9c21.onrender.com/predict \
  -H "Authorization: Bearer $MLGATEE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input_data": [[5.1, 3.5, 1.4, 0.2]]}'
$env:MLGATEE_KEY = "paste-your-key-here"

$body = '{"input_data": [[5.1, 3.5, 1.4, 0.2]]}'
Invoke-RestMethod -Method Post -Uri "https://mlg-iris-7f3a9c21.onrender.com/predict" `
  -Headers @{ Authorization = "Bearer $env:MLGATEE_KEY" } `
  -ContentType "application/json" -Body $body
set MLGATEE_KEY=paste-your-key-here

curl.exe -X POST "https://mlg-iris-7f3a9c21.onrender.com/predict" ^
  -H "Authorization: Bearer %MLGATEE_KEY%" ^
  -H "Content-Type: application/json" ^
  -d "{\"input_data\": [[5.1, 3.5, 1.4, 0.2]]}"
import json, os, urllib.request

KEY = os.environ.get("MLGATEE_KEY") or "paste-your-key-here"
request = urllib.request.Request(
    "https://mlg-iris-7f3a9c21.onrender.com/predict",
    data=json.dumps({"input_data": [[5.1, 3.5, 1.4, 0.2]]}).encode(),
    headers={"Authorization": "Bearer " + KEY, "Content-Type": "application/json"},
    method="POST",
)
with urllib.request.urlopen(request, timeout=120) as response:
    print(json.loads(response.read())["output"])
const KEY = process.env.MLGATEE_KEY || "paste-your-key-here";

const response = await fetch("https://mlg-iris-7f3a9c21.onrender.com/predict", {
  method: "POST",
  headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ input_data: [[5.1, 3.5, 1.4, 0.2]] }),
});
console.log((await response.json()).output);

The sample body is the iris example (4 numbers); replace it with your own model’s features. On the free machine the model sleeps after 15 minutes without requests, and the next request can take about a minute.

Activity

Everything that happened to this model, newest last. Times are in your time zone.

Refresh

15:09:02 [uploading] Upload link created (single use)

15:09:04 [uploading] model.pkl received · 3.1 KB

15:09:05 [inspecting] Reading the bytes, without loading the model

15:09:06 [inspecting] Found scikit-learn 1.9.1 · numpy 2.5.3

15:09:06 [inspecting] Nothing in this file runs when it loads

15:09:08 [deploying] Created its own service: mlg-iris-7f3a9c21

15:09:40 [deploying] Installing scikit-learn==1.9.1 numpy==2.5.3

15:10:52 [deploying] Fetching the model through a short-lived link

15:11:12 [deploying] Server started on Python 3.12

15:11:14 [live] Version 3 is live

15:11:15 [live] Monitoring: reporting

Endpoint key

mlg_live_••••••••a3f1

The full key is shown only once, when it’s created.

New key

The model rebuilds with a new key. The old key keeps working until the rebuild is live.

New key

Danger zone

Delete model

Removes its service, its files and its record. The address stops answering.

Delete model
v1CatBoost
v2XGBoost .ubj
v3scikit-learn
v4from v2
Live
Roll back to v2

Same address. Same key. Every version.

Versions and rollback

“The new version is wrong.”

Roll back in one click, or one line of Python, to any of your three newest versions. Same address, same key, so nothing that calls it has to change.

digits.ipynbPython 3

>>> mlgatee.deploy(net, name="digits",

... example_input=X[:5], task="classifier")

converting PyTorch → ONNX (opset 18)

checking against the original… same answers

uploading · inspecting · building

✓ live https://mlg-digits-…onrender.com (version 1)

mlg_pat_… access token Python 3.9+ · no dependencies
Python client

Deploy from the notebook you’re in.

Sign in once with an access token, then call mlgatee.deploy(model). Keras and PyTorch models are converted in your own Python and checked against the original first.

Files up to 50 MB. Pickle, joblib, XGBoost .json and .ubj, .onnx and .tflite.

Exact versions. Packages are pinned from what the file itself says.

Notebook classes caught. A plain message explains the fix before anything builds.

Keys shown once. Stored only as a hash and the last four characters.

New key any time. The old key keeps working until the rebuild is live.

Probabilities too. Classifiers also answer /predict_proba.

Safety

What we
refuse to do.

Five things we won’t do, and what we do instead.

Read the security details

Run your file on our servers.

We read its bytes to find what it needs. It only ever runs inside its own service.

Keep your key.

You see it once. We store a hash and its last four characters.

Record your inputs.

Monitoring counts calls and times them. What you send and what comes back is never recorded.

Install a package pin we haven’t checked.

Every pin is checked against a strict pattern before it reaches a build.

Hide our limits.

Files up to 50 MB, a 15-minute nap on the free plan, frameworks that still need converting. They’re all written down.

Already working in a notebook?

Skip the upload page.

Python client

Train as usual.
Deploy in one line.

Python, in your notebook
mlgatee.deploy(model, name="iris")

Standard library only, Python 3.9 and newer. It saves your model, checks it, and sends it through the same pipeline as the web app.

  • Sign in once with an access token
  • Same name again becomes the next version
  • Keras and PyTorch converted for you
iris.ipynbPython 3
[1]:
import mlgatee
mlgatee.login()  # once: paste an access token
[2]:
mlgatee.deploy(model, name="iris")
live, version 1 key shown once
$ mlgatee usage iris --window 7d
1,284 calls · 0.5% errors · typical answer 4 ms
Pricing

Free models nap.
Paid ones don’t.

One model free while you try it. Paid plans keep your models awake.

Free

$0

One model. Naps after 15 quiet minutes; the next call wakes it in about a minute.

Starter

$19/ month

One model, always awake. No wake-up wait on the first call.

Pro

$49/ month

Three models, awake while they’re used. Paused after 48 idle hours.

Enterprise

from$499/ month

More models and machines, on your terms.

See pricing

Payments open soon. Founding members get 30% off for life.

F.A.Q.

Questions & answers

Is it safe to upload a pickle?

MLGatee never loads your file on its own servers. Loading a pickle can run code hidden inside it, so the inspector only reads the raw bytes to find the libraries and versions it needs, and refuses files that would run commands when loaded. Your model then runs in its own isolated service, shared with no other model.

Will my model work?

Upload the file if it’s scikit-learn, XGBoost, LightGBM, CatBoost, ONNX or TensorFlow Lite, up to 50 MB. Keras and PyTorch models go through the Python client, which converts them and checks the answers match before uploading; small Hugging Face text models are packed with their tokenizer. Native TensorFlow, PyTorch and full Hugging Face models don’t fit the free size yet.

What if a new version breaks?

Roll back in one click, or one line of Python, to any of your three newest versions. The rollback is built as a new version at the same address with the same key. And if a new version fails to build, the current one simply stays live.

What does it cost?

The free plan runs one model, which naps after 15 quiet minutes. Starter is $19 a month for one model that’s always awake; Pro is $49 a month for three. Payments aren’t open yet, so there’s nothing to pay today.

How do I sign in?

At app.mlgatee.com, with GitHub, Google or an email link. For the Python client, create an access token in the app under Settings → Access tokens and paste it into mlgatee.login() once.

See all questions, or ask us anything.

Get started

Your model is ready.
Send someone the address.

Sign in, upload a file or deploy from your notebook, and send someone the address in about four minutes.

Free plan: one model, no card needed