Fitnescity Health Developers
Public API documentation

Use Full API Integration—the default approach—to keep diagnostic testing search, customer identity, consent when required, ordering, questionnaires, scheduling, and results in your product. Start in Staging (Sandbox) for API Partner testing before switching hosts and credentials for live traffic.

Default test host
https://api-staging.engineeringfitnescity.com
Request access
Scheduling Experience

Members complete scheduling on a Fitnescity Health-hosted page.

After order creation, API Partners generate a schedule-handoff URL through POST /v1/orders/{orderId}/schedule-handoff. Members land on a Fitnescity Health-hosted scheduling experience styled with API Partner branding. API Partners that keep consent, questionnaires, and scheduling in their product should use Full API Integration instead of this hosted page.

Before the member enters scheduling, load the selected offering product through GET /v1/locations/{catalogId}/offerings/{offeringId}/products and surface additional_note when it is present. Show this note on your PDP before the customer buys the test so they know this location-specific information ahead of time, for example "This location does not provide a visceral fat (VAT) reading."

Location-specific product notes

When the selected offering product returns additional_note, show that note on your PDP before the customer buys the test so they understand any location-specific limitations or context ahead of time.

Example: "This location does not provide a visceral fat (VAT) reading."

Third-party members and Fitnescity Health member login

  • Members who enter through your integration are not asked to use Fitnescity Health member login (email and password) or to create or set a password in order to schedule.
  • They are not issued Fitnescity Health member login credentials for general access. The schedule-handoff URL your app provides is the intended entry point into scheduling; they cannot sign in to the standard Fitnescity Health member experience the way a member who booked directly with Fitnescity Health would.

What to persist

  • Store the external payment reference, Idempotency-Key, order identifiers, and the catalog, offering, product, and test identifiers used to create the order.
  • Store the selected slot, alternate availabilities, generated schedule-handoff URL metadata, and any return URLs so support teams can reconcile the member journey.

The handoff request includes selected_appointment_date, alternate_availabilities, customer_data.

What the member sees

The scheduling experience is hosted and managed by Fitnescity Health. For API Partners using hosted scheduling handoff, the member lands on a single branded scheduling page where the selected slot is already shown, consents remain in place, and test-specific eligibility questions still appear when required.

  1. 1. Selected slot review

    The API Partner selects a date and time from live availability before handoff creation. The hosted scheduling page shows that API Partner-selected slot back to the member as the requested appointment time.

  2. 2. Informed consent

    Fitnescity Health collects legally required consent through an embedded signing experience. The consent form is test-type specific and managed entirely by Fitnescity Health.

  3. 3. Eligibility review

    Some test types require a prescreen flow before appointment request completion. When prescreening is not required, the hosted scheduling flow continues directly from consent into confirmation.

  4. 4. Confirmation

    Once consent and prescreening are complete, the appointment is confirmed and the member receives a confirmation with appointment details.

How to present the hosted page

API Partners can open the hosted scheduling page in a new browser tab, embed it in an iframe, or load it in a full-screen in-app WebView. The schedule-handoff request accepts an optional presentation_mode field with two values: hosted_page and iframe. If you omit it, the default is hosted_page.

Use presentation_mode=iframe only for web API Partners that want the member to remain on an API Partner-owned page. If you use iframe mode, host the Fitnescity Health page either inline on the main page or inside a modal within your own web app. Either pattern works as long as the surrounding screen stays API Partner-owned.

For native and hybrid apps, prefer a full-screen in-app WebView instead of trying to place an API Partner page iframe inside the mobile container. WebView is not a dedicated API mode; it still uses the normal hosted page URL rather than a separate third presentation_mode value.

Iframe messaging

If you use presentation_mode=iframe, the hosted page emits lifecycle events to the parent window with window.postMessage. Use these events to resize the iframe and return control to your own UI when scheduling completes or exits.

Current event types are fitnescity.embed.ready, fitnescity.embed.resize, fitnescity.embed.complete, fitnescity.embed.return, fitnescity.embed.profile, fitnescity.embed.exit, and fitnescity.embed.error.

fitnescity.embed.complete does not include a destination URL. fitnescity.embed.return and fitnescity.embed.profile include an API Partner-owned HTTPS URL in the payload. Full-page browser opens and full-screen in-app WebView integrations continue to use standard browser navigation and do not require iframe messaging to function.

Terminal handoff errors emit fitnescity.embed.error with a payload.status value. Handle blocked_by_test_offering_policy by sending the member back to your support or plan-selection flow.

What API Partners control

  • API Partner branding

    Configure display name, logo, and brand colors per API Partner. The schedule handoff flow applies this theme only inside the scheduling experience and keeps the “Powered by Fitnescity Health” treatment.

  • Member data pre-population

    Pass member prefill fields throughcustomer_dataon schedule handoff creation. Fitnescity Health merges prefill values into forms without overriding existing non-empty profile fields.

  • Primary and alternate slot selection

    Pass selected_appointment_date plus 1 to 3alternate_availabilities sourced from live schedule availability. If the member wants to change the slot, route them back to your own app and let them choose again from the latest availability.

  • Return URL

    Providereturn_urlon schedule handoff creation to send members back to your app after scheduling completes. In full-page browser and full-screen WebView flows, Fitnescity Health redirects to this URL directly. In iframe mode, Fitnescity Health emits lifecycle events and your parent page should handle the transition. Hosts must be pre-allowlisted and are revalidated before redirect or event emission. For native apps, use an HTTPS Universal Link or App Link destination if you want the member to return directly into the native shell.

  • Member profile URL

    Providemember_profile_urlon schedule handoff creation to power Return to profile and exit navigation in the hosted flow. Hosts must be pre-allowlisted.

  • Hosted navigation controls

    Pass optional ui_controls in iframe/embed mode to hide Change, Exit, and Return to profile. The object is optional, each nested hide_* field is optional, omitted values or false keep controls visible, and true hides the matching control. Full-page hosted scheduling and full-screen WebView opens ignore ui_controls. Request appointment is never configurable.

Redirect query params are for UX convenience only. API Partners should verify final appointment state via webhook delivery or appointment polling before treating scheduling as complete.

What Fitnescity Health handles

  • Consent collection
    Legally required informed consent is collected through Fitnescity Health-managed embedded signing workflows.
  • Test location assignment
    Fitnescity Health assigns the appropriate test location based on the order context.
  • Appointment confirmation
    After scheduling, the test location confirms the appointment through Fitnescity Health.
  • Rescheduling, cancellations, and refunds
    Fitnescity Health manages downstream fulfillment. API Partners with write:appointments scope can cancel or reschedule via the public API; all API Partners receive lifecycle updates via webhooks.

Pre-scheduling reference

Some test types require prescreening before the order can be finalized. When is_prescreening_required is returned on the offering product, load the public form definition, submit the prescreen answers, then pass the returned order_id into POST /v1/orders. Required schedule-handoff fields by test type are documented directly on this page.

  • GET /v1/tests/{testType}/prescreen-form

    Returns required_fields and validation_rules so your app can render the same prescreen validation experience before direct ordering.

  • POST /v1/tests/{testType}/prescreen-form/submissions

    Submit prescreen answers with the same customer and product context you plan to use for direct order confirmation. Successful responses return the reusable order_id.

Required scheduling fields by test type

Use this matrix when collecting member data before scheduling. These are the schedule-handoff customer_data fields that must be provided for each test type in the current hosted scheduling flow.

Note: POST /v1/orders does not enforce these fields. Validation happens when you create the schedule handoff. Also, hosted-flow checkbox acknowledgements (for example pregnancy notice and doctor approval) are not customer_data fields and therefore are not listed here.

The schedule-handoff request must also include a primary slot inselected_appointment_date and at least 1, up to 3, backup slots in alternate_availabilities.

Required customer_data fields are first_name, last_name, phone, date_of_birth, sex_assigned_at_birth, address_line_1, city, state, postal_code, height, and weight.

If any required field is missing or blank, the schedule-handoff request returns a 400 validation error.

For scheduling inputs, height is in inches and weight is in pounds.

Hosted scheduling validates phone as 10 or 11 digits, date_of_birth within the 16 to 100 age window, and weight as whole-number pounds.

Test typeRequired fieldsPrescreen required
DEXAfirst_name, last_name, phone, date_of_birth, sex_assigned_at_birth, height, weight, address_line_1, city, state, postal_codeNo
DEXABMDfirst_name, last_name, phone, date_of_birth, sex_assigned_at_birth, height, weight, address_line_1, city, state, postal_codeNo
VO2 Maxfirst_name, last_name, phone, date_of_birth, sex_assigned_at_birth, height, weight, address_line_1, city, state, postal_codeNo
Calcium Scorefirst_name, last_name, phone, date_of_birth, sex_assigned_at_birth, height, weight, address_line_1, city, state, postal_codeYes
RMRfirst_name, last_name, phone, date_of_birth, sex_assigned_at_birth, height, weight, address_line_1, city, state, postal_codeNo
BODPODfirst_name, last_name, phone, date_of_birth, sex_assigned_at_birth, height, weight, address_line_1, city, state, postal_codeNo
HYDROSTATICfirst_name, last_name, phone, date_of_birth, sex_assigned_at_birth, height, weight, address_line_1, city, state, postal_codeNo
SECAfirst_name, last_name, phone, date_of_birth, sex_assigned_at_birth, height, weight, address_line_1, city, state, postal_codeNo

Appointment cancel and reschedule

Integrations with write:appointments scope can cancel or reschedule confirmed appointments through the public API. Both routes require Idempotency-Key.

Treat that key as the identifier for one logical appointment-change attempt. If the member retries after a client timeout, tab refresh, or lost connection, resend the same request with the same Idempotency-Key. A completed request replays the same response for the same logical attempt, and payload mismatches on a reused key return a conflict instead of a second appointment mutation.

If the API indicates the same key is still processing, wait for the retry guidance returned by the endpoint, then retry with the same key instead of generating a new one.

API Partners should implement their own logic to warn members before both cancel and reschedule actions when the appointment is within 24 hours. scheduled_for is an absolute timestamp and may be serialized in UTC with Z. Parse it as an instant, calculate the elapsed duration between instants, and use location.timezone for member-facing display and location-calendar rules.

For rescheduling, API Partners can reuse the same availability returned by GET /v1/locations/{catalogId}/offerings/{offeringId}/schedule to populate both the primary slot picker and alternate availability fields. The API Partner should always sync with availability provided through API and require members to choose alternate time from open slots. Each available_time is a full ISO-8601 datetime with the test location numeric offset; it is not always UTC. Preserve that exact value when submitting a selection. available_date is the calendar date at the test location.

  • POST /v1/appointments/{appointmentId}/cancel

    Optional reason field. Retry with confirm_within_24_hour_penalty: true after showing the within-24-hour penalty warning when the API returns WITHIN_24_HOUR_WINDOW. The deprecated confirmWithin24HourPenalty alias remains accepted for compatibility; never send both fields.

  • POST /v1/appointments/{appointmentId}/reschedule

    Requires canonical new_requested_date (ISO-8601) and accepts optional alternate_availabilities (up to three datetimes). The deprecated camelCase aliases remain accepted for compatibility, but never send both representations. Use confirm_within_24_hour_penalty for the same within-24-hour confirmation flow as cancel. A successful request returns pending_confirmation while the location confirms it.

When an already confirmed appointment is moved, Fitnescity Health emits appointment.rescheduled. Appointment reads expose both scheduled_for and original_scheduled_for so your system can reconcile the latest slot while still preserving the first confirmed datetime.

Signed form access

Appointment reads include form_type when a signed consent or other appointment form exists. Use that metadata to decide whether your UI should offer a download action.

  • GET /v1/appointments/{appointmentId}/signed-form

    Returns the appointment-scoped signed form download URL plus form_type. The presigned URL is valid for 1 hour, so fetch it when the member actually requests the download.

How it connects to the API

  1. 1. Create an order via POST /v1/orders.
  2. 2. Request a schedule-handoff URL via POST /v1/orders/{orderId}/schedule-handoff.
  3. 3. Send the returned URL to the member as the immediate next step after capturing their selected slot and alternate availability.
  4. 4. Track appointment state changes via webhooks or by polling GET /v1/appointments.