Customer API · read-only

Your catalog, by API.

Browse your catalog, pull your contract pricing, and check stock — programmatically. One REST surface — OAuth-style bearer auth, JSON out. Every endpoint here ships in the live MedGrid codebase and is scoped to your account.

terminal — authenticate, then call
# 1 · exchange credentials for a 1-hour token
curl -X POST -d "client_id=…" -d "client_secret=…" \
  "https://uat.medgrid.com/api/method/medgrid.customer_api.auth_token"

# 2 · call any endpoint with that token
curl -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://uat.medgrid.com/api/method/medgrid.customer_api.whoami"
What you can do

Three reads, one account.

Start here

Authentication

The Customer API authenticates with a short-lived Bearer token. Your credentials — a client ID and secret — are issued by a MedGrid administrator from your Customer record; there is no self-service signup. You exchange them once for a 1-hour access token, then send that token on every call. This is the only accepted method — a raw token client_id:client_secret header is rejected with a 401.

Step 1 — Get an access token

POST your client_id and client_secret to auth_token. You get back a signed token valid for 1 hour. Treat the secret like a password — never ship it in client-side code.

POST · auth_token
curl -X POST \
  -d "client_id=CLIENT_ID" \
  -d "client_secret=CLIENT_SECRET" \
  "https://uat.medgrid.com/api/method/medgrid.customer_api.auth_token"

Response · 200

json
{ "message": {
    "ok": true,
    "access_token": "eyJhbGciOi…",
    "token_type": "bearer",
    "expires_in": 3600,
    "scope": "customer_api"
} }

Step 2 — Call with the Bearer token

Send the access_token in the Authorization header on every request. When it expires you'll get a friendly 401 — just repeat Step 1 for a fresh one.

request header
Authorization: Bearer ACCESS_TOKEN

A full call

terminal
curl -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://uat.medgrid.com/api/method/medgrid.customer_api.whoami"
Getting credentials. A MedGrid admin opens your Customer record → Customer API tab → Generate Credentials, and shares the client ID + secret with you securely. They can Reveal the secret again, Regenerate it (which invalidates the old one), or Revoke access entirely at any time.
Good to know

Conventions

A few things that hold true across every endpoint.

Request & response shape

Every endpoint is a GET (read-only) except auth_token. Parameters go in the query string. Responses are JSON, wrapped by the framework in a message envelope, and always carry an ok flag.

Success

{ "message": { "ok": true, /* … endpoint data … */ } }

Failure — never a raw stack trace

{ "message": { "ok": false, "error": "Human-readable message.",
              "code": "PermissionError", "status": 403 } }
The customer parameter is optional. Your token already identifies your account, so you normally omit it. Admin tokens that manage several customers can pass customer= to target a specific one.
Reference

Endpoints

Six read endpoints, all under /api/method/medgrid.customer_api.*. Each is auth-gated and scoped to your account — you only ever see your own catalog, pricing and warehouses.

GET whoami AuthRead-only

Connectivity check. Echoes the resolved customer, price list, currency, markup, and allowed warehouses. Start here.

https://uat.medgrid.com/api/method/medgrid.customer_api.whoami

Request

curl -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://uat.medgrid.com/api/method/medgrid.customer_api.whoami"

Response · 200

{
  "ok": true,
  "customer": "CUST-00042",
  "customer_name": "Sunrise Medical Clinic",
  "status": "Active",
  "item_selection": "All",
  "item_groups": [], "item_tags": [], "item_skus": [],
  "price_list": "Sunrise Wholesale",
  "currency": "USD",
  "markup_pct": 0.0,
  "warehouses": ["Main Warehouse - MG", "East DC - MG"],
  "server_time": "2026-06-26 12:00:00"
}

GET get_catalog AuthRead-only

Paginated, priced catalog of the items available to your account — stock summed across your allowed warehouses.

https://uat.medgrid.com/api/method/medgrid.customer_api.get_catalog
ParameterTypeRequiredDescription
pageintno1-based page number. Default 1.
page_lengthintnoItems per page. Default 50, max 200.
in_stock_only0 / 1noWhen 1, only items with available stock.
item_groupstringnoFilter to one item group.
searchstringnoMatch on item name or code.
customerstringnoAdmin-only override; omit for your own account.

Request

curl -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://uat.medgrid.com/api/method/medgrid.customer_api.get_catalog?page=1&page_length=50&in_stock_only=1&search=vitamin"

Response · 200

{
  "ok": true,
  "customer": "CUST-00042",
  "price_list": "Sunrise Wholesale",
  "currency": "USD",
  "page": 1, "page_length": 50, "count": 1,
  "products": [
    {
      "sku": "VD3-5000-120",
      "name": "Vitamin D3 5000 IU (120 ct)",
      "description": "High-potency cholecalciferol.",
      "group": "Supplements", "brand": "MedGrid",
      "image": "/files/vd3.png", "uom": "Unit",
      "price": 18.75, "currency": "USD",
      "compare_at_price": 24.0, "on_sale": true,
      "available_qty": 340, "in_stock": true
    }
  ]
}

GET get_catalog_item AuthRead-only

Full detail for a single product — including per-warehouse stock — but only if that SKU is in your catalog.

https://uat.medgrid.com/api/method/medgrid.customer_api.get_catalog_item
ParameterTypeRequiredDescription
skustringyesThe item code to look up.
customerstringnoAdmin-only override; omit for your own account.

Request

curl -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://uat.medgrid.com/api/method/medgrid.customer_api.get_catalog_item?sku=VD3-5000-120"

Response · 200

{
  "ok": true,
  "customer": "CUST-00042",
  "currency": "USD",
  "product": {
    "sku": "VD3-5000-120",
    "name": "Vitamin D3 5000 IU (120 ct)",
    "description": "High-potency cholecalciferol.",
    "group": "Supplements", "brand": "MedGrid",
    "image": "/files/vd3.png", "uom": "Unit",
    "price": 18.75, "currency": "USD",
    "compare_at_price": 24.0, "on_sale": true,
    "available_qty": 340, "in_stock": true,
    "warehouses": [
      { "warehouse": "Main Warehouse - MG", "available_qty": 200 },
      { "warehouse": "East DC - MG", "available_qty": 140 }
    ]
  }
}
If the SKU isn't in your catalog you get a 404 "Item … is not available in your catalog." Omit sku and you get a friendly 417 asking you to provide one — never a stack trace.

GET get_pricing AuthRead-only

Your account's prices. Pass skus to price a specific set (each flagged as in your catalog or not), or omit it to price the whole catalog (capped at 500).

https://uat.medgrid.com/api/method/medgrid.customer_api.get_pricing
ParameterTypeRequiredDescription
skusCSV / JSON listnoe.g. VD3-5000-120,OMEGA3-1000-90. Omit for the whole catalog.
customerstringnoAdmin-only override; omit for your own account.

Request

curl -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://uat.medgrid.com/api/method/medgrid.customer_api.get_pricing?skus=VD3-5000-120,OMEGA3-1000-90"

Response · 200

{
  "ok": true,
  "customer": "CUST-00042",
  "price_list": "Sunrise Wholesale",
  "currency": "USD",
  "count": 2,
  "prices": [
    { "sku": "VD3-5000-120", "price": 18.75, "currency": "USD", "in_catalog": true },
    { "sku": "OMEGA3-1000-90", "price": null, "currency": "USD", "in_catalog": false }
  ]
}

GET get_availability AuthRead-only

Available-to-sell quantities (projected stock) per warehouse. A requested warehouse must be one of your allowed warehouses, else 403.

https://uat.medgrid.com/api/method/medgrid.customer_api.get_availability
ParameterTypeRequiredDescription
skusCSV / JSON listnoLimit to these SKUs. Omit for the whole catalog (capped).
warehousestringnoOne of your allowed warehouses. Omit for all of them.
customerstringnoAdmin-only override; omit for your own account.

Request

curl -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://uat.medgrid.com/api/method/medgrid.customer_api.get_availability?skus=VD3-5000-120&warehouse=Main%20Warehouse%20-%20MG"

Response · 200

{
  "ok": true,
  "customer": "CUST-00042",
  "warehouses": ["Main Warehouse - MG"],
  "count": 1,
  "levels": [
    { "sku": "VD3-5000-120", "warehouse": "Main Warehouse - MG", "available_qty": 200 }
  ],
  "totals": { "VD3-5000-120": 200 }
}

GET get_warehouses AuthRead-only

The warehouses you may report availability for — the valid values for the warehouse parameter above.

https://uat.medgrid.com/api/method/medgrid.customer_api.get_warehouses

Request

curl -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://uat.medgrid.com/api/method/medgrid.customer_api.get_warehouses"

Response · 200

{
  "ok": true,
  "customer": "CUST-00042",
  "count": 2,
  "warehouses": [
    { "name": "Main Warehouse - MG", "warehouse_name": "Main Warehouse" },
    { "name": "East DC - MG", "warehouse_name": "East DC" }
  ]
}
How prices are computed

Pricing model

Every price you see is computed from your contract price list — never another customer's, and never the underlying vendor cost.

The formula

For each item, MedGrid takes the rate from your account's price list and applies your agreed channel markup.

channel_price = price_list_rate × (1 + markup_pct / 100)
InputWhere it comes from
price_list_rateThe Item Price on your account's price list (your Customer's Default Price List).
markup_pctYour account's agreed channel markup. Often 0. Visible in whoami.
Example. A list rate of 15.00 with a 25% markup → 15.00 × 1.25 = 18.75. Prices are rounded to 2 decimal places and returned in your account currency.
When things go wrong

Errors & status codes

Failures return a clean, human-readable message — never a raw stack trace. The HTTP status and a stable code let you branch in software; the error string is safe to show a person.

Error shape

{
  "message": {
    "ok": false,
    "error": "Warehouse East DC - MG is not available to this customer.",
    "code": "PermissionError",
    "status": 403
  }
}
StatusCodeWhat it means
200Success. Read ok: true and your data.
401AuthenticationErrorMissing/invalid credentials, or wrong client secret.
403PermissionErrorAccess inactive, or a warehouse you're not allowed.
404DoesNotExistErrorThe SKU isn't in your catalog.
417ValidationErrorA required parameter is missing or malformed.
429TooManyRequestsErrorRate-limited — too many token requests or reads. Honour the Retry-After header, then retry.
500Unexpected server error. Safe to retry; contact us if it persists.
FAQ

Frequently asked

The short answers integrators ask for most.

Can I place orders through this API?

No — the Customer API is strictly read-only. It covers catalog, pricing, availability and warehouses so you can power your own ordering UI or sync into your systems. Ordering happens through the MedGrid storefront.

How do I get my credentials?

A MedGrid administrator generates them from your Customer record (Customer API tab → Generate Credentials) and shares the client ID and secret with you securely. There's no self-service signup. They can reveal, regenerate or revoke them at any time.

Will I ever see another customer's prices or a vendor's cost?

Never. Prices are computed only from your own contract price list plus your agreed markup. The API has no path to other customers' data or to underlying vendor costs.

Do I need to send the customer parameter?

Normally no — your token identifies your account. It exists for admin tokens that manage multiple customers and need to target a specific one.

Need help integrating?

Our team will help you get credentials and test your integration — reach out through the contact page and choose "Platform Support".

Contact the integrations team