Developers

PEPTPlus API

Read the prescribable catalog, track orders, and run pharmacy fulfillment (receive routed orders and post carrier + tracking) over a simple REST API. E-prescription intake and signed webhooks are on the near-term roadmap.

REST · JSONAPI-key authTenant-scopedHIPAA: BAA required

Overview

The PEPTPlus API connects three audiences: providers/EHRs who read the catalog and track orders, pharmacies who fulfill routed orders and report shipping, and labs who manage their API listings and see licensees.

EnvironmentBase URLStatus
Live (current)https://dev.pept.plus/api/v1Live
Live (dedicated host)https://api.pept.plus/v1Planned
Sandboxhttps://sandbox.api.pept.plus/v1Planned

HTTPS only (TLS 1.2+), JSON in and out. Versioned by URI (/v1); additive changes stay backward-compatible. List responses are wrapped as { "object":"list", "data":[…] }.

PHI notice. This API transmits Protected Health Information. A signed Business Associate Agreement is required before live access, and you should send only the minimum necessary PHI: reference a patient by their pt_… token rather than demographics.

Authentication

Authenticate every request with your secret API key as a bearer token. Mint, label, and revoke keys from your portal account page (Lab, Pharmacy, or Provider → API keys). Keys are environment- (live/test) and scope-specific, and the full secret is shown only once at creation.

curl https://dev.pept.plus/api/v1/pharmacy/orders \ -H "Authorization: Bearer sk_pharm_live_8f3a…"

Scopes

  • catalog:read (reads the prescribable catalog) Live
  • orders:read (reads order & shipment status) Live
  • pharmacy:fulfill (accepts orders, posts status & shipping) Live
  • listings:read (reads your lab listings) Live
  • licensees:read (reads your listings' licensees) Live
  • prescribe:write (submits / cancels prescriptions) Planned

A request whose key lacks the endpoint's scope returns 403 insufficient_scope. Keys are tenant-scoped; you only ever see your own org's data.

Conventions

  • IDs are prefixed & opaque: ord_…, cmp_…, lst_…, lic_…, pt_… (and rx_…, shp_… when prescriptions ship).
  • Money: integer cents + currency ({"patient_paid_cents":14900,"currency":"usd"}).
  • Strength: {"value":"5","unit":"mg"}, where unit ∈ mg mcg g IU mL mg/mL mcg/mL IU/mL mEq %.
  • Lists are wrapped: { "object":"list", "data":[…] }. Cursor pagination (?limit=&starting_after=) is planned; limit is honored today.
  • Idempotency keys on writes are planned for the prescriptions API.

Catalog Live

GET/v1/catalogPrescribable compounds
GET/v1/catalog/{compound_id}Strengths, routes, eligibility

Only PRESCRIBABLE substances are returned (RLS-enforced); items under FDA PCAC review are omitted until formally listed. Requires catalog:read.

{ "object":"compound", "id":"cmp_5f2c…", "name":"BPC-157", "eligibility_basis":"503A", "strengths":["5 mg"], "routes":["subq"], "doses":[{"value":"5","unit":"mg"}] }

Orders Live

GET/v1/orders?status=&limit=List your orders
GET/v1/orders/{id}Order + latest shipment

Orders are scoped to your org: provider keys see orders for their prescriptions, pharmacy keys see their fulfillment queue. Requires orders:read.

{ "id":"ord_6c20…", "object":"order", "status":"shipped", "channel":"web", "patient":"pt_8f3a…", "compound":"BPC-157", "strength":{"value":"5","unit":"mg"}, "route":"subq", "amount":{"patient_paid_cents":14900,"platform_fee_cents":1500,"currency":"usd"}, "shipment":{"carrier":"USPS","tracking_no":"PP-4827-XK","status":"in_transit"} }

Prescriptions Planned

Submit e-prescriptions on behalf of a licensed prescriber. Planned: deferred until the EHR / e-prescribing middleware integration lands. Documented here so integrators can plan; the endpoints below are not yet served.

POST/v1/prescriptionsSubmit an e-prescription
GET/v1/prescriptions/{id}Retrieve + status
POST/v1/prescriptions/{id}/cancelCancel before fulfillment
Planned server-side validation (422 on failure): the substance must be PRESCRIBABLE in the eligibility register, the prescriber must hold an active license in the patient's state, and the delivery method must be allowed for the substance. Transmission to pharmacies via NCPDP SCRIPT / a certified e-prescribing network is a separate, later integration.

Pharmacy fulfillment Live

Pull orders routed to your pharmacy, acknowledge them, and report status & shipping back. Requires pharmacy:fulfill.

GET/v1/pharmacy/orders?status=Your fulfillment queue
POST/v1/pharmacy/orders/{id}/acceptAcknowledge (→ in_fulfillment)
POST/v1/pharmacy/orders/{id}/statusin_fulfillment / shipped / delivered / action_needed
POST/v1/pharmacy/orders/{id}/shipmentPost carrier + tracking

Post a shipment

curl -X POST https://dev.pept.plus/api/v1/pharmacy/orders/ord_6c20…/shipment \ -H "Authorization: Bearer sk_pharm_live_…" \ -H "Content-Type: application/json" -d '{ "carrier":"USPS","tracking_no":"9400 1000 …" }' # records phi.shipment and advances order.status → "shipped"
Payments. The drug charge is paid directly to your pharmacy via Stripe Connect; PEPTPlus takes $0 per prescription. The API never moves money per script.

Programmatic listing/lot/COA management (/v1/pharmacy/products, /v1/pharmacy/batches, /v1/pharmacy/coa) is planned.

Lab listings & licensees Live

Read your lab's API listings and the pharmacies licensing them. Requires listings:read / licensees:read.

GET/v1/listingsYour listings (with licensee counts)
GET/v1/listings/{id}/licenseesPharmacies licensing a listing
{ "object":"list", "data":[ { "id":"lst_3a91…", "object":"listing", "substance":"Sermorelin", "monthly_fee":"499", "certified":true, "status":"active", "licensee_count":4 } ]}

Webhooks Planned

Planned. Register endpoints and subscribe to events in the dashboard; each delivery a signed POST with PEPTPlus-Signature (HMAC-SHA256), retried with exponential backoff. Not yet implemented; poll the orders endpoints for status in the meantime.

Planned events

  • order.created · order.matched · order.shipped · order.delivered · order.action_needed
  • prescription.signed · payment.completed · coa.required · license.expiring

Errors & rate limits

Errors return a machine error code + human message: { "error":"insufficient_scope", "message":"…", "required":"orders:read" }. Rate limiting returns 429 (enforcement is planned).

StatusCodeMeaning
401unauthorizedMissing / invalid / revoked key
403insufficient_scopeKey lacks the required scope
404not_foundNo such resource for your org
422validation_errorInvalid body or parameters
429rate_limitedSlow down (planned)
Full machine-readable reference: peptplus.openapi.yaml (OpenAPI 3.1) and docs/PEPTPlus-API-spec.md.
Security & complianceHow we protect your data →
HIPAA-firstTokenized, isolated PHI
Tamper-evident auditHash-chained · 7-yr
Encrypted everywhereIn transit & at rest
Azure infrastructureSOC 2 Type II · HIPAA BAA
Verifiable e-RxNCPDP · hashed Rx PDF