Customer API Guide
How customers — clinics, practices, and healthcare sales channels — connect to MedGrid, access the approved product catalog, and place orders through the API.
Who Is This Guide For?
This guide is for customers — medical practices, clinics, and healthcare sales channels that want to:
- Browse the MedGrid product catalog and check real-time availability.
- Retrieve customer-specific pricing from their assigned price list.
- Submit orders programmatically through their own software or EHR system.
- Track the status and shipment of their orders.
How MedGrid Works for Customers
A MedGrid customer account is created by the MedGrid sales team. Your account is linked to a Price List that controls the pricing you see.
Use your API Key and Secret to authenticate every API request.
Call the Catalog API to list available products, check inventory, and see your customer-specific prices.
Submit a Sales Order with selected products, quantities, and your shipping address.
Poll the Order Status API to get the current status, tracking number, and carrier for your order.
What Customers Can Access
Browse approved products from MedGrid's curated catalog. Only products that have passed MedGrid's quality and compliance review are visible.
Your assigned Price List determines what prices you see. Different customers may see different prices for the same product.
All catalog endpoints return live inventory quantities so you always know exactly how many units are available before placing an order.
Place orders, receive order confirmation numbers, and track shipments — all through the API without needing to log in to the portal.
Authentication
All MedGrid API calls require authentication. Use your API Key and Secret for all automated or server-to-server integrations.
API Key + Secret
Include this header on every request:
Authorization: token YOUR_API_KEY:YOUR_API_SECRET
Content-Type: application/json
Accept: application/json
How to Get Your Credentials
- Log in to the MedGrid Customer Portal.
- Go to User Settings > API Access.
- Click Generate Keys.
- Copy both the API Key and API Secret and store them securely.
Example Authenticated Request
curl -X GET \
"https://app.medgrid.com/api/method/medgrid.catalog.list_warehouses" \
-H "Authorization: token abc123key:xyz789secret" \
-H "Content-Type: application/json"
Base URLs
All API requests are made to the MedGrid base URL. Use the Sandbox environment for development and testing.
https://app.medgrid.com
https://sandbox.medgrid.com
All API endpoints follow the pattern:
https://app.medgrid.com/api/method/{endpoint_name}
List Warehouses
Returns all active warehouses in the MedGrid system. Use this to populate a warehouse selector before fetching inventory.
/api/method/medgrid.catalog.list_warehouses
Authentication
Required. Include the Authorization: token KEY:SECRET header.
Parameters
None required. This endpoint takes no parameters.
Example Request
curl -X GET \
"https://app.medgrid.com/api/method/medgrid.catalog.list_warehouses" \
-H "Authorization: token abc123:xyz789"
Example Response
{
"message": [
{
"name": "ShipStation Warehouse - SM",
"warehouse_name": "ShipStation Warehouse",
"company": "Skydell Medical"
},
{
"name": "Exoceuticals Warehouse - SM",
"warehouse_name": "Exoceuticals Warehouse",
"company": "Skydell Medical"
}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
name | string | The warehouse identifier — use this value in items_in_warehouse and search_items calls. |
warehouse_name | string | Human-readable display name for the warehouse. |
company | string | The MedGrid company this warehouse belongs to. |
List Warehouses (Priority Ordered)
Returns the same warehouse list, but ordered by MedGrid's configured warehouse priority. Preferred warehouses (e.g. fastest fulfillment) appear first.
/api/method/medgrid.catalog.list_warehouses_ordered
Parameters
None required.
Example Response
{
"message": [
{ "name": "ShipStation Warehouse - SM", "label": "ShipStation Warehouse - SM" },
{ "name": "Exoceuticals Warehouse - SM", "label": "Exoceuticals Warehouse - SM" }
]
}
Items in Warehouse
Returns all products that currently have available stock in a specific warehouse, along with your customer-specific price for each item.
/api/method/medgrid.catalog.items_in_warehouse
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
warehouse | string | Required | The warehouse name from list_warehouses (e.g. ShipStation Warehouse - SM). |
price_list | string | Optional | The Price List to use for pricing (e.g. Standard Selling, Wholesale). Defaults to the system default selling price list if not provided. |
Example Request
curl -X GET \
"https://app.medgrid.com/api/method/medgrid.catalog.items_in_warehouse?warehouse=ShipStation%20Warehouse%20-%20SM&price_list=Standard%20Selling" \
-H "Authorization: token abc123:xyz789"
Example Response
{
"message": [
{
"item_code": "VD3-5000-120",
"item_name": "Vitamin D3 5000 IU (120 Softgels)",
"description": "High-potency Vitamin D3 to support immune function and bone health.",
"stock_uom": "Box",
"rate": 28.50,
"available_qty": 150
},
{
"item_code": "OMEGA3-1000-90",
"item_name": "Omega-3 Fish Oil 1000mg (90 Softgels)",
"description": "Pharmaceutical-grade Omega-3 fatty acids.",
"stock_uom": "Box",
"rate": 34.00,
"available_qty": 72
}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
item_code | string | The product SKU. Use this when adding items to an order. |
item_name | string | Human-readable product name. |
description | string | Product description text (may contain basic HTML). |
stock_uom | string | Unit of measure (e.g. "Box", "Vial", "Nos"). |
rate | decimal / null | Your price for this item from the specified Price List. null if no price is configured for your list. |
available_qty | integer | Current stock available for ordering. Orders can only be placed for quantities ≤ available_qty. |
Search Items
Search for products by name or description. Optionally filter to a specific warehouse or apply a price list. Returns only items with available stock.
/api/method/medgrid.catalog.search_items
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Required | Search term matched against item name and description (partial match supported). |
warehouse | string | Optional | If supplied, results are strictly filtered to only items with stock in this warehouse. |
price_list | string | Optional | Price List to apply for pricing. Defaults to the system default if not provided. |
Example Request — Search All Warehouses
curl -X GET \
"https://app.medgrid.com/api/method/medgrid.catalog.search_items?query=vitamin+d&price_list=Standard%20Selling" \
-H "Authorization: token abc123:xyz789"
Example Request — Search Within a Warehouse
curl -X GET \
"https://app.medgrid.com/api/method/medgrid.catalog.search_items?query=omega&warehouse=ShipStation%20Warehouse%20-%20SM&price_list=Wholesale" \
-H "Authorization: token abc123:xyz789"
Example Response
{
"message": [
{
"item_code": "VD3-5000-120",
"item_name": "Vitamin D3 5000 IU (120 Softgels)",
"description": "High-potency Vitamin D3 to support immune function and bone health.",
"stock_uom": "Box",
"rate": 28.50,
"available_qty": 150,
"warehouse": "ShipStation Warehouse - SM"
}
]
}
warehouse is not supplied, results include items from all warehouses and each row includes a warehouse column so you know where the stock is located.
Sales Channel Pricing
MedGrid supports multiple price tiers. Different customers may see different prices for the same product based on their assigned Price List.
How Pricing Works
Every MedGrid customer account is assigned a Price List. When you call any catalog endpoint with your Price List name, MedGrid returns prices specific to your tier. If you do not supply a price_list parameter, MedGrid uses the system default (Standard Selling).
Understanding Your Price List
Contact your MedGrid account manager to confirm which Price List is assigned to your account. Common price tiers include:
| Price List | Who It's For |
|---|---|
| Standard Selling | Default retail pricing visible to all customers unless a specific list is assigned. |
| Wholesale | Volume buyers and distribution partners — lower unit costs for bulk ordering. |
| Contract Pricing | Customers with a signed pricing agreement — negotiated rates for specific products or product groups. |
| Sales Channel | Custom pricing for specific clinic networks or reseller channels. |
Using Your Price List in API Calls
Pass your Price List name as the price_list parameter in any catalog endpoint:
curl -X GET \
"https://app.medgrid.com/api/method/medgrid.catalog.items_in_warehouse?warehouse=ShipStation%20Warehouse%20-%20SM&price_list=Wholesale" \
-H "Authorization: token abc123:xyz789"
rate is null for an item, it means no price has been configured for that item in your Price List. Contact your MedGrid account manager to have it added.
Price Lists
Price lists determine what price each customer sees. Your price list is configured by MedGrid and tied to your customer account.
Contract Pricing
If you have a signed pricing agreement with MedGrid, you will be assigned a Contract Price List. This list reflects the negotiated prices for products covered by your contract. Prices in your contract list:
- Override the standard price for covered products.
- May have validity periods — confirm with your account manager if a contract renewal is needed.
- Are automatically applied when you pass your price list name in API calls.
Discount Rules
Discounts in MedGrid work at the Price List level — discounted prices are baked into the Price List rate rather than applied on top as a percentage. This means:
- The
ratevalue you receive in catalog responses is your final price — no further discounts are applied automatically. - Sales reps may apply additional manual discounts within the allowed rate tolerance (set per vendor).
Price Updates
Price changes from MedGrid or your vendors take effect immediately for all new orders. To get the latest prices, always fetch catalog data fresh for each ordering session rather than caching prices for extended periods.
Place an Order
Submit a new order to MedGrid. Once placed, the order is routed to the appropriate vendor for fulfillment.
Order Placement Overview
MedGrid orders are placed as Sales Orders. A Sales Order captures the customer, the items, the quantities, the agreed prices, and the shipping address. Once submitted, MedGrid routes each product line to the correct vendor automatically.
/api/resource/Sales Order
Required Headers
Authorization: token YOUR_API_KEY:YOUR_API_SECRET
Content-Type: application/json
Accept: application/json
Request Body
{
"customer": "MedGrid Customer ID or Name",
"transaction_date": "2026-06-18",
"delivery_date": "2026-06-25",
"price_list": "Standard Selling",
"currency": "USD",
"shipping_address_name": "ADDR-00123",
"items": [
{
"item_code": "VD3-5000-120",
"qty": 2,
"rate": 28.50,
"warehouse": "ShipStation Warehouse - SM"
},
{
"item_code": "OMEGA3-1000-90",
"qty": 1,
"rate": 34.00,
"warehouse": "ShipStation Warehouse - SM"
}
]
}
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
customer | string | Required | Your MedGrid customer ID (provided by MedGrid at account creation). |
transaction_date | date | Required | The order date in YYYY-MM-DD format. |
delivery_date | date | Required | Requested delivery date in YYYY-MM-DD format. |
price_list | string | Required | Your assigned Price List name (e.g. "Standard Selling"). |
currency | string | Optional | Currency code. Defaults to USD. |
shipping_address_name | string | Required | MedGrid Address record ID for the ship-to location. |
items | array | Required | Array of order line items. Minimum 1 item required. |
items[].item_code | string | Required | Product SKU from the catalog (the item_code field in catalog responses). |
items[].qty | integer | Required | Quantity to order. Must be a positive integer, not exceeding available stock. |
items[].rate | decimal | Required | Agreed unit price from the catalog. This is the price MedGrid will charge. |
items[].warehouse | string | Required | Warehouse the item should be picked from. |
Success Response
{
"data": {
"name": "SAL-2026-00456",
"docstatus": 0,
"status": "Draft",
"customer": "Sunrise Medical Clinic",
"grand_total": 91.00,
"transaction_date": "2026-06-18"
}
}
Simplified Request / Response Example
Consistent with the format described in your integration spec:
// REQUEST
{
"customer_id": "Sunrise-Medical-001",
"product_id": "VD3-5000-120",
"quantity": 2
}
// RESPONSE
{
"status": "success",
"order_id": "SAL-2026-00456"
}
Track an Order
Retrieve the current status, fulfillment details, and tracking information for a Sales Order.
/api/resource/Sales Order/{order_id}
Example Request
curl -X GET \
"https://app.medgrid.com/api/resource/Sales%20Order/SAL-2026-00456" \
-H "Authorization: token abc123:xyz789"
Example Response
{
"data": {
"name": "SAL-2026-00456",
"status": "To Deliver and Bill",
"customer": "Sunrise Medical Clinic",
"transaction_date": "2026-06-18",
"delivery_date": "2026-06-25",
"grand_total": 91.00,
"exoceuticals_status": "Fulfilled",
"exoceuticals_tracking_number": "1Z999AA10123456784",
"exoceuticals_carrier": "UPS",
"exoceuticals_tracking_url": "https://ups.com/track?number=1Z999AA10123456784"
}
}
Order Status Values
| Status | Meaning |
|---|---|
| Draft | Order submitted by customer, awaiting confirmation by MedGrid. |
| To Deliver and Bill | Order confirmed and sent to vendor for fulfillment. |
| To Bill | Order has been shipped; invoice pending. |
| Completed | Order fully delivered and invoiced. |
| Cancelled | Order was cancelled. Contact MedGrid support for details. |
Tracking Fields
| Field | Description |
|---|---|
exoceuticals_tracking_number | Carrier tracking number for Exoceuticals (Shopify) fulfilled items. |
exoceuticals_carrier | Carrier name (e.g. "UPS", "FedEx"). |
exoceuticals_tracking_url | Direct URL to track the shipment on the carrier's website. |
exoceuticals_status | Fulfillment status: Pending, Open, Fulfilled, Cancelled, Failed. |
Doctor Checkout (503A)
Certain regulated products (503A compounded medications) require additional verification before a doctor can place an order. This section explains the special checkout flow for these items.
What is 503A?
503A compounded medications are pharmaceutical compounds prepared for specific patients by a licensed compounding pharmacy. Federal law requires that the ordering doctor hold a valid license, and that prescription information and patient details are captured at the time of ordering.
Required Fields for 503A Orders
In addition to the standard order fields, 503A orders require:
| Field | Type | Description |
|---|---|---|
checkout_npi_number | string | Your National Provider Identifier (NPI) — a 10-digit unique identifier for licensed healthcare providers. |
checkout_dea_number | string | Your DEA registration number. |
checkout_dea_license_file | file | A copy of your current DEA registration certificate (PDF or image). |
checkout_doctor_first_name | string | Ordering doctor's first name. |
checkout_doctor_last_name | string | Ordering doctor's last name. |
checkout_doctor_email | string | Ordering doctor's email address. |
checkout_patient_first_name | string | Patient's first name — this compound is prescribed for this patient. |
checkout_patient_last_name | string | Patient's last name. |
checkout_patient_dob | date | Patient date of birth (YYYY-MM-DD). |
checkout_patient_gender | string | Patient gender (e.g. Male, Female). |
checkout_prescription_file | file | Scanned or digital copy of the signed prescription. |
professional_use_confirmation | boolean | Must be 1 — confirms this order is for professional/patient use only. |
compliance_agreement_accepted | boolean | Must be 1 — confirms compliance with federal compounding regulations. |
503A Order Example Request
{
"customer": "Dr-Jane-Smith-001",
"transaction_date": "2026-06-18",
"price_list": "Standard Selling",
"shipping_address_name": "ADDR-00123",
"items": [
{
"item_code": "BHRT-PROG-200MG",
"qty": 1,
"rate": 145.00,
"warehouse": "ShipStation Warehouse - SM"
}
],
"checkout_npi_number": "1234567890",
"checkout_dea_number": "AB1234563",
"checkout_doctor_first_name": "Jane",
"checkout_doctor_last_name": "Smith",
"checkout_doctor_email": "jane.smith@clinic.com",
"checkout_patient_first_name": "John",
"checkout_patient_last_name": "Patient",
"checkout_patient_dob": "1975-03-15",
"checkout_patient_gender": "Male",
"professional_use_confirmation": 1,
"compliance_agreement_accepted": 1
}
checkout_npi_number and the patient-specific fields per order.
Error Handling
What to expect when an API request fails, and how to resolve common issues.
Standard Error Response Format
{
"exc_type": "PermissionError",
"_server_messages": "[{\"message\": \"You do not have permission to access this resource.\"}]"
}
HTTP Status Codes
| Code | Meaning | Common Cause | Resolution |
|---|---|---|---|
| 200 | Success | — | Request completed. Parse the message or data field. |
| 400 | Validation Error | Missing required field, invalid value. | Read _server_messages for the specific field error. |
| 401 | Unauthenticated | Missing or invalid API key/secret. | Check your Authorization header — format must be token KEY:SECRET. |
| 403 | Forbidden | Your account lacks permission for this action or resource. | Contact MedGrid support to confirm your account role and permissions. |
| 404 | Not Found | Wrong order ID or endpoint URL typo. | Double-check the order name (e.g. SAL-2026-00456) and URL path. |
| 417 | Business Logic Error | Order in wrong state, stock insufficient, required fields missing. | Read _server_messages — typically describes exactly what needs to be fixed. |
| 500 | Server Error | Unexpected error on MedGrid's side. | Contact MedGrid support with the timestamp and full error text. |
Common Customer API Errors
| Error Message | Cause | Fix |
|---|---|---|
| "Row 1: Qty for item VD3-5000-120 exceeds available stock" | You ordered more than what's in stock. | Re-check available_qty via items_in_warehouse and reduce your quantity. |
| "Customer is mandatory" | The customer field was omitted from the order. | Include your MedGrid Customer ID in the request body. |
| "Shipping address is required" | No shipping_address_name provided. | Pass a valid MedGrid Address record name for the ship-to location. |
| "Price not found for item in price list" | Your Price List has no price entry for this SKU. | Contact your MedGrid account manager to add the item to your price list. |
FAQ
How do I know which Price List to use?
Contact your MedGrid account manager. They will provide the exact Price List name assigned to your account. Use this name as the price_list parameter in all catalog calls.
Can I order items from multiple warehouses in one order?
Yes. Each line item in the order can specify a different warehouse. MedGrid handles multi-warehouse orders automatically, routing each item to the correct fulfillment source.
Why is the rate field null for some items?
This means the item has no price configured in your assigned Price List. You can still see the item's availability but cannot order it until pricing is added. Contact MedGrid to resolve this.
How quickly are orders fulfilled?
Fulfillment time depends on the vendor and product type. Standard orders typically ship within 1–3 business days. Compounded medications (503A) may take 3–5 business days.
Can I cancel an order?
Orders in Draft or "To Deliver" status may be cancellable. Contact MedGrid support immediately if you need to cancel. Orders already shipped cannot be cancelled.
How do I get support?
Email support@medgrid.com or use the MedGrid Customer Portal support chat. Include your account name, order ID, and a description of the issue.