medgrid — MedGrid Vendor CLI
The medgrid command line connects your systems to the MedGrid
marketplace: push your catalog, prices, and stock; track product approval;
receive and verify order notifications — no integration code required.
Install
pip install medgrid-cli # or: pipx install medgrid-cli
medgrid --version
Requires Python 3.9+; no other dependencies. To update later:
pip install -U medgrid-cli.
No pip in your environment? The tool is a single self-contained file — download it directly and run it with any Python 3.9+:
curl -O https://medgrid.com/assets/medgrid/cli/medgrid
python3 medgrid --help
Before you start
You need API credentials from MedGrid — three values, issued per environment:
| Value | Purpose |
|---|---|
client_id (mgk_…) |
Public identifier for your vendor account |
client_secret |
Password for API authentication |
webhook_secret |
Key used to sign event notifications we send you |
They are shown exactly once when generated — store them securely. If lost,
MedGrid can rotate them (the client_id stays; both secrets change).
Environments. MedGrid runs two copies of the platform:
- UAT —
https://uat.medgrid.com— test environment. Build and verify here first; orders never result in real shipments or charges. - Production —
https://medgrid.com— the live marketplace.
Credentials belong to exactly one environment: a UAT client_id does not
exist on production and vice versa. You'll receive UAT credentials to
integrate against, and a separate production set at go-live.
Quick start
medgrid init # store credentials + verify (UAT is the default)
medgrid whoami # confirm who you're connected as
medgrid warehouses --create "Main Warehouse"
medgrid import products.csv --dry-run # validate without sending
medgrid import products.csv
medgrid status SKU-001 SKU-002 # approval + publish state
medgrid webhook set-url https://yourdomain.com/medgrid-events
medgrid webhook test # signed test event at that URL
medgrid orders # recent orders containing your items
init saves credentials to ./.medgrid/config.json (file mode 600) and
immediately verifies them with a live connection test. Failures come back
in plain language — including "this environment has never issued this
client_id", the most common setup mistake. Access tokens are then obtained,
cached, and refreshed automatically; you never handle them.
Every command accepts --env uat or --env prod. UAT is the default;
production prints a visible banner before anything runs.
Command reference
| Command | What it does |
|---|---|
init |
Store credentials for an environment and verify them. Flags: --client-id, --client-secret, --webhook-secret, --no-verify (all optional; prompts otherwise). |
whoami / auth |
Show the authenticated vendor, account class, permitted scope, and token expiry. auth forces a fresh session. |
check <client_id> |
No secret needed: asks each environment whether it issued this client_id. Use it when credentials are rejected and you're not sure why. Note: each probe counts one failed attempt toward that ID's lockout (10 failures per 15 min locks it temporarily). |
warehouses [--create NAME] |
List your registered warehouses, or register one. Required before stock uploads. |
import FILE |
Push a CSV of products, prices, or stock. See CSV import below. Flags: --type products|prices|inventory (otherwise guessed from the filename), --dry-run, --batch-size N. |
status SKU… [--file skus.txt] |
Approval and publish state for up to 500 SKUs: Pending/Approved, published or not. |
orders [--since DATE] [--status submitted|cancelled] [--page N] |
Recent orders containing your items, newest first (default: last 7 days). Your safety net if your endpoint missed a notification. |
webhook set-url URL |
Register where MedGrid should deliver event notifications. |
webhook test |
Fire a real, signed test event at that URL right now and report how your endpoint answered. |
webhook verify <body-file|-> --signature sha256=… |
Offline check that a payload you received was genuinely signed by MedGrid. |
listen [--port 9876] |
Local test receiver: prints each incoming event with its signature verdict while you build your real endpoint. Pair with a tunnel (e.g. ngrok) to receive UAT deliveries on your machine. |
Exit codes are honest: 0 only when everything succeeded, 1 otherwise —
safe to use in scripts and schedulers. Add --json to warehouses,
status, and orders for machine-readable output.
CSV import
Column headers are case-insensitive and common synonyms are understood
(title → name, category → group, item_code → sku, …). Unrecognised
columns are ignored with a warning. Prices accept $ signs and thousands
commas. Rows that fail validation are skipped with a line-numbered reason
and are never partially sent.
| Type | Columns | Required per row |
|---|---|---|
products |
sku, vendor_product_id, name, description, group, price, cost, image |
sku or vendor_product_id |
prices |
sku, price, price_list |
all three (price_list is the list name MedGrid assigns you) |
inventory |
sku, warehouse, qty, snapshot_at (optional) |
sku, warehouse, qty |
Behavior you can rely on:
- New products are not public. Everything you push enters MedGrid's
review queue (
Pending) and appears on the marketplace only when approved. Track it withmedgrid status. - Imports upsert. An existing SKU is updated, not duplicated. If a SKU appears twice in one file, the later row wins.
- Retries are safe. Every batch carries an idempotency key derived from the file's content. Re-running the same file — after a network failure, a crash, even two runs at once — replays the original result instead of applying it twice. Never creates duplicates.
- Large files are handled. Rows are sent in batches of up to 500 (the API's cap). One bad row fails that row only, reported with its CSV line number.
- Stale stock is rejected. Inventory snapshots are timestamped; an older snapshot can never overwrite newer stock.
Receiving notifications (webhooks)
MedGrid POSTs JSON events to your registered URL: order.new,
order.cancelled, product.approved, product.rejected, and
webhook.test. Each request carries:
X-MedGrid-Event: order.new
X-MedGrid-Attempt: 1
X-MedGrid-Signature: sha256=<hex digest>
The signature is HMAC-SHA256 of the exact request body, keyed with your
webhook_secret. Always verify it before trusting a payload:
import hashlib, hmac
expected = "sha256=" + hmac.new(webhook_secret.encode(), raw_body, hashlib.sha256).hexdigest()
assert hmac.compare_digest(expected, request.headers["X-MedGrid-Signature"])
Respond with any 2xx within 10 seconds. Failed deliveries are retried
3 times (after 1, 5, and 15 minutes). If your endpoint was down longer,
reconcile with medgrid orders — its payload mirrors the webhook body.
Recommended bring-up sequence: medgrid listen locally to see real signed
events → build your endpoint → medgrid webhook set-url → medgrid webhook test → confirm your endpoint answers 200 and the signature
verifies.
Limits
- 120 API requests per minute per vendor. Exceeding it returns HTTP
429 with a
Retry-Afterheader; the CLI surfaces the message directly. (A full catalog import is only a handful of requests — you're unlikely to hit this outside of tight polling loops.) - 500 records per batch, 500 SKUs per
statuscall. - 10 failed authentications per 15 minutes locks a
client_idtemporarily.
Troubleshooting
| Symptom | Meaning / fix |
|---|---|
this environment has never issued this client_id |
Your credentials belong to the other environment. Run medgrid check <client_id> to see which one issued them, then use --env accordingly. |
the client_id is known here, but the client_secret is wrong |
Re-copy the secret (watch for whitespace) or ask MedGrid to rotate credentials. |
the vendor profile is not Approved yet / API Enabled is not ticked |
Your MedGrid vendor profile hasn't finished onboarding — contact your MedGrid representative. |
temporarily locked out |
Too many failed authentications. Wait ~15 minutes; fix the secret before retrying. |
webhook test fails with your endpoint's status code |
Your receiver is reachable but rejecting the request — check the body parsing and that you respond 2xx. |
Unknown price list on a prices import |
Use the price list name MedGrid assigned to your account. |
An identical request is already in progress |
The same file is being imported concurrently; the CLI waits and retries automatically. |
Questions or credential requests: contact your MedGrid integration representative.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file medgrid_cli-0.1.0.tar.gz.
File metadata
- Download URL: medgrid_cli-0.1.0.tar.gz
- Upload date:
- Size: 18.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d088900981d7a226b4ed483368d64dd0738d23463ebf982b054a20f856983d0
|
|
| MD5 |
4d00178ed2d892cb2ae483521c866113
|
|
| BLAKE2b-256 |
783507fa781f4b13a6b525d72e98c1a206740f0a699f957dfac7b488c3a0703b
|
File details
Details for the file medgrid_cli-0.1.0-py3-none-any.whl.
File metadata
- Download URL: medgrid_cli-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4bc92a9b03af99191b706fd107f8e8e9b0fbd4025d5c9652e4a34ffe782b3eca
|
|
| MD5 |
6040bab8bff8bd85ba84948b1a49510e
|
|
| BLAKE2b-256 |
a88d4e090f67f98fddf0f0605ebd1bf024af04e73ca6120215d1287480130764
|