MedBridge API Integration Skill
Purpose
Solve tasks that integrate with MedBridge backend APIs (Logistics/Procurement and Sales Ops) to produce finance-ready JSON outputs. Tasks fall into two families:
- Logistics/Procurement Quoting — product catalog lookups, freight option evaluation, and quote generation.
- Sales Ops Reconciliation — opportunity-to-milestone reconciliation, invoice/payment state analysis, revenue recognition checks, and event/voucher action routing.
Prerequisites
- Read
input/prompt.txtfor task instructions and entity IDs. - Read
input/payloads/answer_template.jsonfor the exact output schema and enum values. - The API base URL is typically
http://127.0.0.1:${PORT}or similar; the prompt will specify the host and port. Treat the date given in the prompt as the current business date.
Step 1: Identify Task Family
| Clue | Family |
|---|---|
| Mentions "quote", "freight", "RFQ", "product", "catalog", "EXW", "lead time", "shelf life" | Logistics / Procurement |
| Mentions "opportunity", "milestone", "invoice", "payment", "revenue recognition", "reconciliation", "briefing", "voucher", "CRM" | Sales Ops |
Step 2: Discover API Endpoints
The API is REST-like. Common root resources to probe (append to base URL):
Logistics / Procurement:
/customersor/customers/{id}/productsor/catalog(often filter byproduct_code)/freight_quotesor/freight(often filter byquote_idorcustomer_id)/rfqs/{id}
Sales Ops:
/opportunities/{id}/customers/{id}/contacts(often filter bycustomer_idoropportunity_id)/milestones(filter byopportunity_id)/invoices(filter bymilestone_id)/payments(filter byinvoice_id)/revenue_journals(filter bymilestone_id)/events/{id}/vouchers/{code}
If a GET on a sub-resource returns 404, try query parameters (?opportunity_id=...) or list endpoints and filter client-side.
Step 3: Fetch Strategy
Logistics / Procurement
- Fetch the RFQ / Quote using the ID from the prompt.
- Fetch the Customer record to obtain policy flags (e.g.,
URGENT_VACCINES_AIR_PREFERRED) and payment terms. - Fetch the Product / Catalog record using the product code to get unit price, lead time, and shelf life. Determine the correct pricing tier by matching
confirmed_quantityagainst tiermin_quantity/max_quantity. - Fetch Freight Quotes for the request. Expect up to three modes:
AIR,SEA,ROAD. - Compute:
exw_total_usd = confirmed_quantity × unit_price_usd(round to 2 decimals)grand_total_usd = exw_total_usd + freight_cost_usdfor each option- Freight validity: compare the API-returned
valid_until(orvalidity_status) against the current business date. Use the API's ownvalidity_statuswhen provided; otherwise computeVALIDifvalid_until >= current_date, elseEXPIRED. - Risk level: use API-returned risk fields when available. Fallback heuristics:
ROADoften carriesMEDIUMorHIGHborder risk;AIRis usuallyLOW;SEAisLOWorMEDIUM.
Sales Ops
- Fetch the Opportunity using the ID from the prompt.
- Fetch the Customer record.
- Fetch the Contact linked to the customer/opportunity.
- Fetch Milestones for the opportunity. Order them ascending by
milestone_id(MS1,MS2,MS3). - For each milestone, fetch:
- Invoice(s) — determine
invoice_state(PAID,OPEN,VOID,UNKNOWN) - Payment(s) — determine
payment_state(PAID,PARTIAL,UNPAID,UNKNOWN) andpaid_amount - Revenue Journal(s) — determine whether revenue has been recognized
- Invoice(s) — determine
- Compute reconciliation fields:
phase_total_amount = sum(milestone.amount)opportunity_matches_phase_total = abs(opportunity.won_amount - phase_total_amount) < 0.01total_paid_amount = sum(milestone.paid_amount)outstanding_balance = opportunity.won_amount - total_paid_amount(round to 2 decimals)
- Determine revenue recognition status per milestone:
- If milestone is paid in full and a revenue journal exists →
RECOGNIZED - If milestone is paid in full but no revenue journal →
MISSING_REVENUE_JOURNAL(orREQUIRED_MISSINGdepending on template) - If milestone is unpaid and due date is
nullor in the future →NOT_REQUIRED_UNPAID - If milestone amount is
0→NOT_REQUIRED_UNPAID - Otherwise →
UNKNOWN
- If milestone is paid in full and a revenue journal exists →
- Determine accounting actions (often driven by
MS2):- If any paid milestone lacks a revenue journal →
RECORD_REVENUE_MS2(orVERIFY_REVENUE_ONLYif journals exist) - If no missing journals and no unpaid issues →
NO_ACCOUNTING_ACTION
- If any paid milestone lacks a revenue journal →
- Determine collection actions:
- If any milestone is unpaid and
due_dateis in the future (or null) →MONITOR_UNPAID_NOT_DUE - If any milestone is unpaid and
due_dateis in the past →SEND_COLLECTION_NOTICE - If all paid →
NO_COLLECTION_ACTION
- If any milestone is unpaid and
- Fetch the Event and Voucher if referenced in the prompt.
event_statusfrom API (SCHEDULED,ACTIVE,COMPLETED,CANCELLED,UNKNOWN)voucher_statusfrom API (ACTIVE,DRAFT,EXPIRED,DISABLED,UNKNOWN)- Invite action: if
SCHEDULED+ voucherACTIVE→SEND_BRIEFING_INVITE/SEND_EVENT_INVITATION; ifCOMPLETED→VERIFY_INVITE_SENT; else →NO_INVITE_ACTION.
Step 4: Populate the Answer Template
- Load
input/payloads/answer_template.json. - Map every fetched/computed value into the corresponding field.
- Strictly respect enums defined in the template (e.g.,
PAID | PARTIAL | UNPAID | UNKNOWN). Do not invent new values. - Currency formatting: all USD amounts must be numbers with exactly 2 decimal places (e.g.,
14500.00). Do not use strings. - Date formatting: use
YYYY-MM-DD. - Booleans: use JSON
true/false, not strings. - Arrays: maintain ascending sort order when specified (e.g., milestones by
milestone_id). - Remove any comment or schema annotation from the final output; emit only the populated JSON object.
Step 5: Validation Checklist
- JSON parses without errors.
- No extra keys outside the template schema.
- No narrative text outside the JSON object.
- All monetary values are numeric with 2 decimal places.
- All dates are
YYYY-MM-DDstrings (ornullwhere allowed). - All enums match the template exactly (case-sensitive).
-
opportunity_matches_phase_total(or similar boolean) is derived from the numeric sum, not assumed. - Freight validity relies on API-returned status when available, not purely on date math.
- Event and voucher invite logic respects both
event_statusandvoucher_status.
Common Pitfalls
- Hard-coding output shape — Always read
answer_template.json; templates vary even within the same task family (e.g., train_003 vs. train_005). - Ignoring the API port — The prompt often references a runner-provided port or
http://127.0.0.1:${PORT}; substitute the actual value. - Computing freight validity from dates alone — The API may return an explicit
validity_status(e.g.,EXPIREDeven when the calendar date has not passed). Prefer API fields. - Mishandling zero-amount milestones — A milestone with
amount = 0should usually haveNOT_REQUIRED_UNPAIDrecognition status and no collection action. - Missed related entities — The prompt may explicitly request inclusion of an event and voucher (e.g.,
EVT-MERIDIAN-BRIEFINGandMERIDIANBRIEF50). Fetch them even if they are not strictly needed for the core reconciliation. - Round-off errors — Use exact decimal arithmetic or round to 2 decimals at the final step; floating-point drift can cause
opportunity_matches_phase_totalto befalsewhen it should betrue.