FormFit API Reference

Place a FormFit order on your B2B Shopify account (Net 30) using the same Partner API. Choose Full Face, Compact, Nasal, or Pillows via mask_type. Orders are created on the Vitacore FormFit store. The response includes a scan upload link for you to email the wearer.

Same endpoints as the Nix catalog — your API key is bound to one store. See the Nix Dive Mask API reference.

Authentication

Include your secret API key in every request using one of:

  • secret_key field in the JSON body
  • X-Api-Key: vtc_… header
  • Authorization: Bearer vtc_… header

Test API keys

Create a test key from your dashboard to exercise the same POST /orders contract without placing a real Shopify order. Test responses include a dummy scan_upload_url that will not start a live upload flow. Sending scan_media on a test key still validates the product-correct capture set (calibration + 3 orbit videos) but does not persist files or start photogrammetry. Test calls are logged the same way as live keys.

Create order

Creates one FormFit line item on your Shopify B2B company with Net 30 payment terms. The order contact email is your Shopify B2B contact; the shipping address and wearer name come from your request. By default Forge returns scan_upload_url (portal start-scan) so you can email a link that mints a fresh token when opened. Optionally include the actual capture assets on this request via scan_media (HTTPS URLs) or multipart files calibration_photo, orbit_1, orbit_2, orbit_3. When media is included, Forge creates the scan immediately and starts the same photogrammetry path a completed customer upload uses — the order does not wait for a later patient upload. Omit scan_media to place the order as today. Set forge_sends_email_to_client to true to have Forge send the scan upload email; the response still includes scan_upload_url either way.

POST https://api.vitacore.com/api/partner/v1/orders
Content-Type: application/json
or multipart/form-data (order fields + calibration_photo, orbit_1, orbit_2, orbit_3)

Request body

{
  "secret_key": "vtc_your_secret_key_here",
  "patient_email": "patient@example.com",
  "patient_name": "Jane Doe",
  "phone": "+15551234567",
  "shipping_address": {
    "first_name": "Jane",
    "last_name": "Doe",
    "address1": "123 Main Street",
    "address2": "Apt 4",
    "city": "Portland",
    "province": "Oregon",
    "country": "United States",
    "country_code": "US",
    "zip": "97201"
  },
  "idempotency_key": "your-unique-request-id-optional",
  "mask_type": "cpap",
  "forge_sends_email_to_client": false,
  "scan_media": {
    "calibration_photo_url": "https://partner.example.com/calibration.jpg",
    "orbit_video_urls": [
      "https://partner.example.com/orbit1.mp4",
      "https://partner.example.com/orbit2.mp4",
      "https://partner.example.com/orbit3.mp4"
    ]
  }
}

Required fields

  • secret_key — your API key (or use header)
  • patient_email — email used for the scan upload link
  • patient_name — wearer name (Shopify metafield + order notes)
  • phone — phone number (optional; omit or leave empty if unknown)
  • shipping_address — ship-to address

mask_type values

All four FormFit lines are CPAP therapy masks. The API value cpap means FormFit Full Face, not CPAP therapy in general. Nix types return 403 on a FormFit account.

mask_typeProductWhen to use
cpapFormFit Full FaceTraditional over-the-nose full face. Default when mask_type is omitted.
undernose_mouthFormFit HybridUnder-the-nose / minimal-contact full face.
noseFormFit NasalNasal cushion orders.
intranasalFormFit PillowsNasal pillows orders.

Optional fields

  • idempotency_key — safe retries (min 8 chars)
  • mask_type — cpap = FormFit Full Face (default when omitted); undernose_mouth = FormFit Hybrid; nose = FormFit Nasal; intranasal = FormFit Pillows.
  • forge_sends_email_to_client — when true, Forge emails the scan upload link. Defaults to false.
  • scan_media — optional. Attach the calibration photo and three orbit videos the partner already captured. JSON: calibration_photo_url + orbit_video_urls (exactly 3 HTTPS URLs). Or send multipart files calibration_photo, orbit_1, orbit_2, orbit_3 (FormFit Full Face default when mask_type is omitted). A partial set is rejected. This is not a catalog of required media and not a tokenized upload URL.

Success response (201)

New orders return 201. Retrying with the same idempotency_key returns 200 with idempotent_replay: true.

{
  "success": true,
  "data": {
    "idempotent_replay": false,
    "request_id": "a1b2c3…",
    "shopify_order_id": "5678901234",
    "shopify_order_name": "#1234",
    "vitacore_order_id": "ORD_5678901234",
    "patient_email": "patient@example.com",
    "patient_name": "Jane Doe",
    "forge_sends_email_to_client": false,
    "mask_type": "cpap",
    "scan_upload_url": "https://api.vitacore.com/api/portal/start-scan?order_id=ORD_5678901234&email=patient@example.com",
    "scan_id": "SCAN_1779902370302_hzebwhy8e",
    "scan_media_attached": true,
    "photogrammetry_started": true,
    "placed_at": "2026-05-29T12:00:00.000Z"
  }
}

Errors

  • 401 — invalid or revoked secret_key
  • 400 — validation error (missing address fields, etc.)
  • 403 — mask_type not allowed for this account (wrong catalog, or type not enabled)
  • 409 — idempotency_key reused by another key
  • 422 — account not configured (missing FormFit variant, Shopify ordering disabled, or contact email not set)
  • 502 — Shopify order creation failed

Order status

Poll production progress using the vitacore_order_id returned when you create an order. Status is only available for orders placed with the same API key that created them.

GET https://api.vitacore.com/api/partner/v1/orders/{vitacore_order_id}/status
X-Api-Key: vtc_…

Success response (200)

{
  "success": true,
  "data": {
    "vitacore_order_id": "ORD_5678901234",
    "shopify_order_id": "5678901234",
    "shopify_order_name": "#1234",
    "patient_email": "patient@example.com",
    "patient_name": "Jane Doe",
    "placed_at": "2026-05-29T12:00:00.000Z",
    "is_test": false,
    "scan_id": "SCAN_1779902370302_hzebwhy8e",
    "scan_status": "approved",
    "current_step_id": "printing",
    "current_step_label": "Printing",
    "progress_caption": "Printing in progress",
    "is_shipped": false,
    "is_cancelled": false,
    "cancelled_at": null,
    "tracking": null,
    "udi": null,
    "updated_at": "2026-06-11T20:00:00.000Z"
  }
}

After QA prints the UDI label, udi includes GS1 fields. When shipped, tracking includes carrier and tracking number.

Cancel order

Cancel a partner-placed order before scan files are uploaded. Forge also cancels the Shopify order on the Vitacore FormFit store. Only the same API key that placed the order may cancel it.

POST https://api.vitacore.com/api/partner/v1/orders/{vitacore_order_id}/cancel
Content-Type: application/json
X-Api-Key: vtc_…
{
  "reason": "Customer no longer needs mask",
  "partner_reference": "your-internal-ticket-optional"
}

Returns 409 once videos and calibration are on file, mesh or print jobs have started, or the order has shipped.

FUPC lookup

Look up wearer and order details from the 7-character FUPC stamped on the FormFit. Scoped to your account's orders.

GET https://api.vitacore.com/api/partner/v1/fupc/lookup?fupc=O0R7T9E&request_type=patient
X-Api-Key: vtc_…

Workflow

  1. Call create order with wearer details, shipping address, and mask_type. Include scan_media when you already have the calibration photo and orbit videos — Forge creates the scan and starts processing immediately.
  2. Save vitacore_order_id for status polling.
  3. If you omitted media, email scan_upload_url so the wearer can upload later, or set forge_sends_email_to_client: true.
  4. Poll GET …/orders/{id}/status.
  5. To void before scan upload, call POST …/orders/{id}/cancel.

Manage keys on the developer dashboard. Human staff can use the same account in B2B Forge.