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
API Reference

Fitnescity Health Public API

Route-by-route contract reference for Fitnescity Health Public API. Examples on this page use Staging (Sandbox) by default. Switch only the host and credentials when you move the same integration to production.

Reference environment
Staging (Sandbox)
https://api-staging.engineeringfitnescity.com
Auth
x-api-key: <prefix>.<secret>
Response envelope
code, data, error
Version 1.0
Request and response examples on this page are pulled from the committed OpenAPI contract, not handwritten in the website layer.
Full API Integration

Full API Integration follows an identity → consent when required → Calcium Score prescreen when required → order → questionnaire → schedule sequence and does not use schedule-handoff. See the Full API Integration guide for the complete flow.

Schedule-handoff required fields

The current hosted scheduling flow expects this full request shape on POST /v1/orders/{orderId}/schedule-handoff:

  • selected_appointment_date, alternate_availabilities, customer_data
  • customer_data.first_name, last_name, phone, date_of_birth, sex_assigned_at_birth, address_line_1, city, state, postal_code, height, weight
  • Optional: return_url, member_profile_url
  • Optional: ui_controls.hide_change, ui_controls.hide_exit, ui_controls.hide_return_to_profile

If any required field is missing or blank, expect a 400 validation error.

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

ui_controls is optional, and each nested field is optional. Omit the object or send false to keep the matching control visible; send true to hide it. These flags affect only iframe/embed mode. Full-page hosted scheduling and full-screen WebView opens ignore ui_controls. Only Change, Exit, and Return to profile are configurable. Request appointment is never configurable.

See the Hosted Scheduling guide for the member-facing handoff experience and presentation options.

Environment model

Staging doubles as the shared sandbox for API Partner testing. Production is the live traffic host. Keep hosts and credentials environment-specific.

Examples use Staging (Sandbox)

Staging (Sandbox)

Default reference
https://api-staging.engineeringfitnescity.com

Use this shared non-production environment for implementation, QA, and API Partner testing before go-live.

Credentials

Use a staging-only API key. Staging keys do not work in production.

  • Shared environment used for API Partner testing and Fitnescity Health validation.
  • No production data should be used in staging.
  • Behavior matches the current v1 contract, but releases may arrive here before production.

Production

https://public-api.fitnescity.com/

Use this environment for live member traffic after your integration is ready to launch.

Credentials

Use a production API key issued separately from staging credentials.

  • Live environment for member traffic and results retrieval.
  • Switch to production only after validating your integration in staging.
  • Keep environment-specific secrets and API hosts separate in your deployment config.

Search API reference

Search by method, endpoint path, tag, parameter, or operation summary.

49 endpoints available
GET

/v1/api-first/appointments/{appointmentId}/physician-order-bundle

Get the structured partner physician-order bundle

Returns the current Fitnescity Health-owned template and the exact attestation/version metadata needed to create a structured physician-order session. The complete physician-facing presentation is returned only after session creation.

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/api-first/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6/physician-order-bundle" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Response
Content type: application/json
Schema: StructuredPhysicianBundleResponseDto(StructuredPhysicianBundleResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "context_hash": "string",
    "existing_session_id": "123e4567-e89b-12d3-a456-426614174000",
    "partner_attestation": {
      "text": "string",
      "text_hash": "string",
      "version": "partner-structured-physician-order-v1"
    },
    "request_id": "123e4567-e89b-12d3-a456-426614174000",
    "request_state": "string",
    "session_requirements": {
      "allowed_approval_methods": [
        {}
      ],
      "allowed_workflow_types": [
        {}
      ],
      "order_date_required": true,
      "provider_fields_required": true
    },
    "sla": {
      "breached_at": "2026-03-10T10:00:00.000Z",
      "due_at": "2026-03-10T10:00:00.000Z",
      "enabled": true
    },
    "template": {
      "content_hash": "string",
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "schema_version": "physician-order-v2",
      "version": 2
    }
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
503Structured physician-order creation is temporarily unavailable. STRUCTURED_PHYSICIAN_TEMPLATE_NOT_CONFIGURED means the physician-facing template is unavailable; STRUCTURED_PHYSICIAN_ATTESTATION_NOT_CONFIGURED means the required partner attestation is unavailable. Do not infer internal control details beyond the stable error code; retry later or contact Fitnescity Health support.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Structured physician-order attestation unavailable
{
  "code": 503,
  "data": null,
  "error": {
    "details": {
      "code": "STRUCTURED_PHYSICIAN_ATTESTATION_NOT_CONFIGURED"
    },
    "message": "The structured physician-order attestation is not available",
    "path": "/v1/api-first/appointments/006d1a83-ff73-4720-b53e-23af0d14f9cb/physician-order-bundle",
    "request_id": "req_1234567890",
    "timestamp": "2026-09-21T10:00:00.000Z"
  }
}
Structured physician-order template unavailable
{
  "code": 503,
  "data": null,
  "error": {
    "details": {
      "code": "STRUCTURED_PHYSICIAN_TEMPLATE_NOT_CONFIGURED"
    },
    "message": "A structured physician-order template is not available",
    "path": "/v1/api-first/appointments/006d1a83-ff73-4720-b53e-23af0d14f9cb/physician-order-bundle",
    "request_id": "req_1234567890",
    "timestamp": "2026-09-21T10:00:00.000Z"
  }
}
GET

/v1/api-first/appointments/{appointmentId}/physician-order-evidence

List appointment-scoped partner physician-order evidence

When to use it

List API Partner physician-order evidence for one appointment.

  • Requires read:physician_order_evidence and returns only evidence owned by the calling API Partner.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Query Parameters
NameTypeRequiredDescriptionExample
customer_identity_idstring (uuid)No—3fa85f64-5717-4562-b3fc-2c963f66afa6
canonical_test_typestringNo—DEXA
statusenum(awaiting_upload, processing, accepted, abandoned, rejected, failed, superseded, invalidated)No—awaiting_upload
external_reference_idstringNo—member-consent-2026-08-27
limitnumberNoEvidence collection page size. Defaults to 50.50
offsetnumberNo—0
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/api-first/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6/physician-order-evidence?canonical_test_type=DEXA&external_reference_id=member-consent-2026-08-27&limit=50&offset=0" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Response
Content type: application/json
Schema: PartnerEvidenceCollectionResponseDto(PartnerEvidenceCollectionResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": {},
        "assurance_basis": {},
        "canonical_test_type": {},
        "collected_at": {},
        "customer_identity_id": {},
        "expires_at": {},
        "id": {},
        "physician_order_request_id": {},
        "processing_method": {},
        "safe_reason_code": {},
        "signed_at": {},
        "signer_name": {},
        "status": {},
        "status_changed_at": {},
        "upload_session": {},
        "verification_level": {},
        "version": {}
      }
    ],
    "pagination": {
      "has_more": false,
      "limit": 50,
      "offset": 0,
      "returned_count": 1
    }
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/appointments/{appointmentId}/physician-order-evidence

Create appointment-scoped partner physician-order evidence

When to use it

For an API Partner-provided physician-order PDF: create appointment-scoped evidence after scheduling and receive a short-lived S3 upload session.

  • Requires write:physician_order_evidence and Idempotency-Key. Declare one exact API Partner-provided PDF no larger than 20 MiB; the contract trusts the exact bytes and does not content-inspect or normalize them.
  • From your API Partner backend or a server-side proxy, PUT those exact document bytes to data.upload_session.url with every returned required_headers value; browser code must not issue this S3 PUT. Then complete the upload and wait for data.status=accepted before completing or using the physician evidence.
  • Do not call this endpoint when the API key is provisioned for the Fitnescity Health physician-order service.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: CreatePartnerPhysicianOrderEvidenceDto(CreatePartnerPhysicianOrderEvidenceDto)
Example values come from the published contract example.
Contract example
{
  "attestation": {
    "accepted": true,
    "version": "partner-consent-evidence-v1"
  },
  "document": {
    "content_length": 248731,
    "content_type": "application/pdf",
    "file_name": "consent.pdf",
    "sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  },
  "external_reference_id": "order-2026-08-27",
  "license_number": "MD-12345",
  "license_state": "NY",
  "npi": "1234567893",
  "order_date": "2026-08-27",
  "physician_full_name": "Dr. Example"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6/physician-order-evidence" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"attestation":{"accepted":true,"version":"partner-consent-evidence-v1"},"document":{"content_length":248731,"content_type":"application/pdf","file_name":"consent.pdf","sha256":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"external_reference_id":"order-2026-08-27","license_number":"MD-12345","license_state":"NY","npi":"1234567893","order_date":"2026-08-27","physician_full_name":"Dr. Example"}'

Responses

201Response
Content type: application/json
Schema: PartnerEvidenceResponseDto(PartnerEvidenceResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "assurance_basis": "versioned_attestation",
    "canonical_test_type": "DEXA",
    "collected_at": "2026-03-10T10:00:00.000Z",
    "customer_identity_id": "123e4567-e89b-12d3-a456-426614174000",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "physician_order_request_id": "123e4567-e89b-12d3-a456-426614174000",
    "processing_method": "attested_lambda_v1",
    "safe_reason_code": "EVIDENCE_HASH_MISMATCH",
    "signed_at": "2026-03-10T10:00:00.000Z",
    "signer_name": "Ada Lovelace",
    "status": "awaiting_upload",
    "status_changed_at": "2026-03-10T10:00:00.000Z",
    "upload_session": {
      "expires_at": {},
      "id": {},
      "method": {},
      "required_headers": {},
      "url": {}
    },
    "verification_level": "partner_attested",
    "version": 0
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/appointments/{appointmentId}/physician-order-sessions

Create a structured partner physician-order session

Creates an immutable, Fitnescity Health-rendered physician-facing presentation. Display every returned section, row, statement, and acknowledgement verbatim and in order. The response contains no standalone test-location field.

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: CreateStructuredPhysicianOrderSessionDto(CreateStructuredPhysicianOrderSessionDto)
Example values come from the published contract example.
Contract example
{
  "approval_method": "electronic_signature",
  "content_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "context_hash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
  "order_date": "2026-09-18",
  "physician": {
    "contact": {
      "address": {
        "example_key": {}
      },
      "fax": "+1-212-555-0101",
      "phone": "+1-212-555-0100",
      "type": "provider"
    },
    "credentials": "MD",
    "full_name": "Dr. Ada Lovelace",
    "license_number": "NY-12345",
    "license_state": "NY",
    "npi": "1234567893",
    "ordering_entity": "Example Medical Group"
  },
  "replaces_session_id": "123e4567-e89b-12d3-a456-426614174000",
  "template_version_id": "123e4567-e89b-12d3-a456-426614174000",
  "workflow_type": "partner_electronic"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6/physician-order-sessions" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"approval_method":"electronic_signature","content_hash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","context_hash":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","order_date":"2026-09-18","physician":{"contact":{"address":{"example_key":{}},"fax":"+1-212-555-0101","phone":"+1-212-555-0100","type":"provider"},"credentials":"MD","full_name":"Dr. Ada Lovelace","license_number":"NY-12345","license_state":"NY","npi":"1234567893","ordering_entity":"Example Medical Group"},"replaces_session_id":"123e4567-e89b-12d3-a456-426614174000","template_version_id":"123e4567-e89b-12d3-a456-426614174000","workflow_type":"partner_electronic"}'

Responses

201Response
Content type: application/json
Schema: StructuredPhysicianSessionResponseDto(StructuredPhysicianSessionResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "approval_method": "electronic_signature",
    "artifact": {
      "signed_form_url": {},
      "status": {}
    },
    "context_hash": "string",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "order_date": "2026-03-10",
    "partner_attestation": {
      "text": "string",
      "text_hash": "string",
      "version": "partner-structured-physician-order-v1"
    },
    "physician": {
      "contact": {},
      "credentials": "MD",
      "full_name": "Dr. Ada Lovelace",
      "license_number": "NY-12345",
      "license_state": "NY",
      "npi": "1234567893",
      "ordering_entity": "Example Medical Group"
    },
    "presentation": {
      "required_acknowledgements": [
        {}
      ],
      "schema_version": "structured-physician-presentation-v1",
      "sections": [
        {}
      ],
      "title": "string"
    },
    "presentation_hash": "string",
    "request_id": "123e4567-e89b-12d3-a456-426614174000",
    "status": "open",
    "template": {
      "content_hash": "string",
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "schema_version": "physician-order-v2",
      "version": 2
    },
    "workflow_type": "partner_electronic"
  },
  "error": null
}
202The same Full API Integration command is still processing. Wait for Retry-After, then retry with the exact same Idempotency-Key and payload. This is a success envelope, not an error envelope.
Content type: application/json
Schema: ApiFirstIdempotencyInProgressResponseDto(ApiFirstIdempotencyInProgressResponseDto)
Contract example
Contract example
{
  "code": 202,
  "data": {
    "code": "IDEMPOTENCY_IN_PROGRESS",
    "retry_after_seconds": 7,
    "status": "in_progress"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
503Structured physician-order creation is temporarily unavailable. STRUCTURED_PHYSICIAN_TEMPLATE_NOT_CONFIGURED means the physician-facing template is unavailable; STRUCTURED_PHYSICIAN_ATTESTATION_NOT_CONFIGURED means the required partner attestation is unavailable. Do not infer internal control details beyond the stable error code; retry later or contact Fitnescity Health support.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Structured physician-order attestation unavailable
{
  "code": 503,
  "data": null,
  "error": {
    "details": {
      "code": "STRUCTURED_PHYSICIAN_ATTESTATION_NOT_CONFIGURED"
    },
    "message": "The structured physician-order attestation is not available",
    "path": "/v1/api-first/appointments/006d1a83-ff73-4720-b53e-23af0d14f9cb/physician-order-bundle",
    "request_id": "req_1234567890",
    "timestamp": "2026-09-21T10:00:00.000Z"
  }
}
Structured physician-order template unavailable
{
  "code": 503,
  "data": null,
  "error": {
    "details": {
      "code": "STRUCTURED_PHYSICIAN_TEMPLATE_NOT_CONFIGURED"
    },
    "message": "A structured physician-order template is not available",
    "path": "/v1/api-first/appointments/006d1a83-ff73-4720-b53e-23af0d14f9cb/physician-order-bundle",
    "request_id": "req_1234567890",
    "timestamp": "2026-09-21T10:00:00.000Z"
  }
}
GET

/v1/api-first/consent-bundles/{testType}

Get the active reusable consent bundle

For API partners provisioned with Fitnescity Health-managed customer consent, returns the active template version, content hash, required decision IDs, and customer-facing consent content. Partner-managed customer-consent integrations use the consent-evidence lifecycle instead. Render the four decision labels exactly as returned. The first decision’s detail/view_consent_html is sanitized HTML for the View consent dialog; the last decision’s detail is plain arbitration text for the View terms dialog. Use the ETag response header to revalidate a cached bundle.

When to use it

For the Fitnescity Health consent API only: fetch the sanitized, versioned reusable consent bundle for the appointment test type.

  • testType is one of CALST, DEXA, DEXABMD, VO2, RMR, HYDROSTATIC, SECA, or BODPOD.
  • Pin consent_template_version_id and content_hash when creating the consent session. Render the four decision labels exactly as returned.
  • CUSTOMER_CONSENT_NOT_REQUIRED means this API key is not provisioned for the Fitnescity Health consent API. Do not retry the request; use the provisioned API Partner-provided consent PDF lifecycle when applicable.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
testTypestringYes—DEXA
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/api-first/consent-bundles/DEXA" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Response
Content type: application/json
Schema: ApiFirstConsentBundleResponseDto(ApiFirstConsentBundleResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "cache": {
      "example_key": "example_value"
    },
    "canonicalization_version": "consent-v2-canonical",
    "payload_schema_version": "consent-v2",
    "required_decision_ids": [
      "string"
    ],
    "required_section_ids": [
      "string"
    ],
    "template": {
      "canonical_test_type": {},
      "content": {},
      "content_hash": {},
      "id": {},
      "version": {}
    }
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
409CUSTOMER_CONSENT_NOT_REQUIRED means this API key is not provisioned for Fitnescity Health-managed customer consent. Use the provisioned partner-managed consent-evidence lifecycle when applicable; do not retry the same reusable-consent request.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 409,
  "data": null,
  "error": {
    "details": {
      "code": "CUSTOMER_CONSENT_NOT_REQUIRED"
    },
    "message": "Reusable consent is not required for keys provisioned for partner-managed customer consent",
    "path": "/v1/api-first/consent-bundles/DEXA",
    "request_id": "req_1234567890",
    "timestamp": "2026-08-26T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/api-first/consent-evidence

List partner-managed customer-consent evidence

When to use it

List consent evidence owned by the calling API Partner for reconciliation.

  • Requires read:consent_evidence. Filter by customer identity, canonical test type, status, or external reference when useful.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Query Parameters
NameTypeRequiredDescriptionExample
customer_identity_idstring (uuid)No—3fa85f64-5717-4562-b3fc-2c963f66afa6
canonical_test_typestringNo—DEXA
statusenum(awaiting_upload, processing, accepted, abandoned, rejected, failed, superseded, invalidated)No—awaiting_upload
external_reference_idstringNo—member-consent-2026-08-27
limitnumberNoEvidence collection page size. Defaults to 50.50
offsetnumberNo—0
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/api-first/consent-evidence?canonical_test_type=DEXA&external_reference_id=member-consent-2026-08-27&limit=50&offset=0" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Response
Content type: application/json
Schema: PartnerEvidenceCollectionResponseDto(PartnerEvidenceCollectionResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": {},
        "assurance_basis": {},
        "canonical_test_type": {},
        "collected_at": {},
        "customer_identity_id": {},
        "expires_at": {},
        "id": {},
        "physician_order_request_id": {},
        "processing_method": {},
        "safe_reason_code": {},
        "signed_at": {},
        "signer_name": {},
        "status": {},
        "status_changed_at": {},
        "upload_session": {},
        "verification_level": {},
        "version": {}
      }
    ],
    "pagination": {
      "has_more": false,
      "limit": 50,
      "offset": 0,
      "returned_count": 1
    }
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/consent-evidence

Create partner-managed customer-consent evidence

Creates an append-only evidence record for the exact partner-provided PDF accepted under the certified contract and returns a short-lived presigned PUT capability. The gateway never receives document bytes or inspects or normalizes document contents. Evidence is trusted under the partner contract.

When to use it

For an API Partner-provided consent PDF: create append-only evidence and receive a short-lived S3 upload session.

  • Requires write:consent_evidence and Idempotency-Key. Declare one exact API Partner-provided PDF no larger than 20 MiB, including its byte length and lowercase hexadecimal SHA-256. The contract trusts the exact bytes; contents are not content-inspected or normalized.
  • From your API Partner backend or a server-side proxy, PUT those exact document bytes to data.upload_session.url with every returned required_headers value. The checksum header uses base64 SHA-256; browser code must not issue this S3 PUT, and document bytes do not pass through the API gateway.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Request Body
Content type: application/json
Schema: CreatePartnerConsentEvidenceDto(CreatePartnerConsentEvidenceDto)
Example values come from the published contract example.
Contract example
{
  "attestation": {
    "accepted": true,
    "version": "partner-consent-evidence-v1"
  },
  "canonical_test_type": "DEXA",
  "collected_at": "2026-03-10T10:00:00.000Z",
  "customer_identity_id": "123e4567-e89b-12d3-a456-426614174000",
  "document": {
    "content_length": 248731,
    "content_type": "application/pdf",
    "file_name": "consent.pdf",
    "sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  },
  "external_reference_id": "member-consent-2026-08-27",
  "signed_at": "2026-03-10T10:00:00.000Z",
  "signer_name": "Ada Lovelace"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/consent-evidence" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"attestation":{"accepted":true,"version":"partner-consent-evidence-v1"},"canonical_test_type":"DEXA","collected_at":"2026-03-10T10:00:00.000Z","customer_identity_id":"123e4567-e89b-12d3-a456-426614174000","document":{"content_length":248731,"content_type":"application/pdf","file_name":"consent.pdf","sha256":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"external_reference_id":"member-consent-2026-08-27","signed_at":"2026-03-10T10:00:00.000Z","signer_name":"Ada Lovelace"}'

Responses

201Response
Content type: application/json
Schema: PartnerEvidenceResponseDto(PartnerEvidenceResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "assurance_basis": "versioned_attestation",
    "canonical_test_type": "DEXA",
    "collected_at": "2026-03-10T10:00:00.000Z",
    "customer_identity_id": "123e4567-e89b-12d3-a456-426614174000",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "physician_order_request_id": "123e4567-e89b-12d3-a456-426614174000",
    "processing_method": "attested_lambda_v1",
    "safe_reason_code": "EVIDENCE_HASH_MISMATCH",
    "signed_at": "2026-03-10T10:00:00.000Z",
    "signer_name": "Ada Lovelace",
    "status": "awaiting_upload",
    "status_changed_at": "2026-03-10T10:00:00.000Z",
    "upload_session": {
      "expires_at": {},
      "id": {},
      "method": {},
      "required_headers": {},
      "url": {}
    },
    "verification_level": "partner_attested",
    "version": 0
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/api-first/consent-evidence/{evidenceId}

Get partner-managed customer-consent evidence

When to use it

Poll one API Partner-provided consent PDF evidence resource until validation finishes.

  • Requires read:consent_evidence. Use the evidence on a prescreen submission or order only after data.status=accepted.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
evidenceIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/api-first/consent-evidence/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Response
Content type: application/json
Schema: PartnerEvidenceResponseDto(PartnerEvidenceResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "assurance_basis": "versioned_attestation",
    "canonical_test_type": "DEXA",
    "collected_at": "2026-03-10T10:00:00.000Z",
    "customer_identity_id": "123e4567-e89b-12d3-a456-426614174000",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "physician_order_request_id": "123e4567-e89b-12d3-a456-426614174000",
    "processing_method": "attested_lambda_v1",
    "safe_reason_code": "EVIDENCE_HASH_MISMATCH",
    "signed_at": "2026-03-10T10:00:00.000Z",
    "signer_name": "Ada Lovelace",
    "status": "awaiting_upload",
    "status_changed_at": "2026-03-10T10:00:00.000Z",
    "upload_session": {
      "expires_at": {},
      "id": {},
      "method": {},
      "required_headers": {},
      "url": {}
    },
    "verification_level": "partner_attested",
    "version": 0
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/consent-evidence/{evidenceId}/upload-sessions

Issue a replacement consent-evidence upload session

When to use it

Issue a replacement S3 upload session for consent evidence whose prior upload capability expired.

  • Requires write:consent_evidence and Idempotency-Key. From your API Partner backend or a server-side proxy, upload with every newly returned required_headers value.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
evidenceIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/consent-evidence/3fa85f64-5717-4562-b3fc-2c963f66afa6/upload-sessions" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001"

Responses

201Response
Content type: application/json
Schema: PartnerEvidenceResponseDto(PartnerEvidenceResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "assurance_basis": "versioned_attestation",
    "canonical_test_type": "DEXA",
    "collected_at": "2026-03-10T10:00:00.000Z",
    "customer_identity_id": "123e4567-e89b-12d3-a456-426614174000",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "physician_order_request_id": "123e4567-e89b-12d3-a456-426614174000",
    "processing_method": "attested_lambda_v1",
    "safe_reason_code": "EVIDENCE_HASH_MISMATCH",
    "signed_at": "2026-03-10T10:00:00.000Z",
    "signer_name": "Ada Lovelace",
    "status": "awaiting_upload",
    "status_changed_at": "2026-03-10T10:00:00.000Z",
    "upload_session": {
      "expires_at": {},
      "id": {},
      "method": {},
      "required_headers": {},
      "url": {}
    },
    "verification_level": "partner_attested",
    "version": 0
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/consent-evidence/{evidenceId}/upload-sessions/{uploadSessionId}/complete

Complete a consent-evidence upload

Completes the upload for the exact partner-provided PDF. In trusted_pdf_contract mode, it is accepted under the certified partner contract; contents are not inspected or normalized by the gateway or processor. The response may be 202 while processing; poll the evidence resource until status is accepted.

When to use it

Complete a consent-evidence upload and enqueue asynchronous validation.

  • Requires write:consent_evidence and Idempotency-Key. Submit the same lowercase hexadecimal SHA-256 declared at evidence creation, then poll the evidence resource.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
evidenceIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
uploadSessionIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: CompletePartnerEvidenceUploadSessionDto(CompletePartnerEvidenceUploadSessionDto)
Example values come from the published contract example.
Contract example
{
  "sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/consent-evidence/3fa85f64-5717-4562-b3fc-2c963f66afa6/upload-sessions/3fa85f64-5717-4562-b3fc-2c963f66afa6/complete" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"sha256":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}'

Responses

202Response
Content type: application/json
Schema: PartnerEvidenceResponseDto(PartnerEvidenceResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "assurance_basis": "versioned_attestation",
    "canonical_test_type": "DEXA",
    "collected_at": "2026-03-10T10:00:00.000Z",
    "customer_identity_id": "123e4567-e89b-12d3-a456-426614174000",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "physician_order_request_id": "123e4567-e89b-12d3-a456-426614174000",
    "processing_method": "attested_lambda_v1",
    "safe_reason_code": "EVIDENCE_HASH_MISMATCH",
    "signed_at": "2026-03-10T10:00:00.000Z",
    "signer_name": "Ada Lovelace",
    "status": "awaiting_upload",
    "status_changed_at": "2026-03-10T10:00:00.000Z",
    "upload_session": {
      "expires_at": {},
      "id": {},
      "method": {},
      "required_headers": {},
      "url": {}
    },
    "verification_level": "partner_attested",
    "version": 0
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/consent-sessions

Create or reuse a Full API Integration consent session

For API partners provisioned with Fitnescity Health-managed customer consent, creates or reuses an open consent session for the supplied customer_identity_id and test type. Partner-managed customer-consent integrations create and accept consent evidence before ordering instead.

When to use it

For the Fitnescity Health consent API only: create or reuse an open consent session for an identity and test type.

  • Requires Idempotency-Key. An open session occupies the identity/test-type slot until you finalize or abandon it.
  • An active same-key request returns 202 with data.code IDEMPOTENCY_IN_PROGRESS and Retry-After.
  • CONSENT_SESSION_OPEN means abandon the existing session before creating a replacement.
  • CUSTOMER_CONSENT_NOT_REQUIRED means this API key is not provisioned for the Fitnescity Health consent API. Do not retry the request; use the provisioned API Partner-provided consent PDF lifecycle when applicable.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Request Body
Content type: application/json
Schema: CreateApiFirstConsentSessionDto(CreateApiFirstConsentSessionDto)
Example values come from the published contract example.
default
{
  "canonical_test_type": "DEXA",
  "consent_template_version_id": "22222222-2222-4222-8222-222222222222",
  "content_hash": "sha256:consent-template-v3",
  "customer_identity_id": "11111111-1111-4111-8111-111111111111"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/consent-sessions" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"canonical_test_type":"DEXA","consent_template_version_id":"22222222-2222-4222-8222-222222222222","content_hash":"sha256:consent-template-v3","customer_identity_id":"11111111-1111-4111-8111-111111111111"}'

Responses

200Response
Content type: application/json
Schema: ApiFirstReusableConsentResponseDto(ApiFirstReusableConsentResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "grant": {
      "expires_at": {},
      "id": {}
    },
    "identity": {
      "customer_identity_id": {}
    },
    "template": {
      "canonical_test_type": {},
      "content": {},
      "content_hash": {},
      "id": {},
      "version": {}
    }
  },
  "error": null
}
201Consent session created.
Content type: application/json
Schema: ApiFirstConsentSessionResponseDto(ApiFirstConsentSessionResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "canonical_test_type": "DEXA",
    "customer_identity_id": "11111111-1111-4111-8111-111111111111",
    "expires_at": "2026-03-10T12:15:00.000Z",
    "id": "33333333-3333-4333-8333-333333333333",
    "status": "open"
  },
  "error": null
}
202The same Full API Integration command is still processing. Wait for Retry-After, then retry with the exact same Idempotency-Key and payload. This is a success envelope, not an error envelope.
Content type: application/json
Schema: ApiFirstIdempotencyInProgressResponseDto(ApiFirstIdempotencyInProgressResponseDto)
Contract example
Contract example
{
  "code": 202,
  "data": {
    "code": "IDEMPOTENCY_IN_PROGRESS",
    "retry_after_seconds": 7,
    "status": "in_progress"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
409CUSTOMER_CONSENT_NOT_REQUIRED means this API key is not provisioned for Fitnescity Health-managed customer consent. Use the provisioned partner-managed consent-evidence lifecycle when applicable; do not retry the same reusable-consent request.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 409,
  "data": null,
  "error": {
    "details": {
      "code": "CUSTOMER_CONSENT_NOT_REQUIRED"
    },
    "message": "Reusable consent is not required for keys provisioned for partner-managed customer consent",
    "path": "/v1/api-first/consent-sessions",
    "request_id": "req_1234567890",
    "timestamp": "2026-08-26T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/api-first/consent-sessions/{sessionId}

Get a Full API Integration consent session

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
sessionIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/api-first/consent-sessions/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Response
Content type: application/json
Schema: ApiFirstConsentSessionResponseDto(ApiFirstConsentSessionResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "abandoned_at": "2026-03-10T10:00:00.000Z",
    "abandonment_reason": "string",
    "canonical_test_type": "DEXA",
    "customer_identity_id": "123e4567-e89b-12d3-a456-426614174000",
    "expires_at": "2026-03-10T12:15:00.000Z",
    "finalized_at": "2026-03-10T10:00:00.000Z",
    "grant": {
      "expires_at": {},
      "id": {}
    },
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "status": "open"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/consent-sessions/{sessionId}/abandon

Abandon an open Full API Integration consent session

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
sessionIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: AbandonApiFirstConsentSessionDto(AbandonApiFirstConsentSessionDto)
Example values come from the published contract example.
default
{
  "reason": "customer restarted consent capture"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/consent-sessions/3fa85f64-5717-4562-b3fc-2c963f66afa6/abandon" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"reason":"customer restarted consent capture"}'

Responses

200Consent session abandoned.
Content type: application/json
Schema: ApiFirstConsentSessionResponseDto(ApiFirstConsentSessionResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "abandoned_at": "2026-03-10T12:05:00.000Z",
    "abandonment_reason": "customer restarted consent capture",
    "canonical_test_type": "DEXA",
    "customer_identity_id": "11111111-1111-4111-8111-111111111111",
    "expires_at": "2026-03-10T12:15:00.000Z",
    "id": "33333333-3333-4333-8333-333333333333",
    "status": "abandoned"
  },
  "error": null
}
202The same Full API Integration command is still processing. Wait for Retry-After, then retry with the exact same Idempotency-Key and payload. This is a success envelope, not an error envelope.
Content type: application/json
Schema: ApiFirstIdempotencyInProgressResponseDto(ApiFirstIdempotencyInProgressResponseDto)
Contract example
Contract example
{
  "code": 202,
  "data": {
    "code": "IDEMPOTENCY_IN_PROGRESS",
    "retry_after_seconds": 7,
    "status": "in_progress"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/consent-sessions/{sessionId}/finalize

Finalize a Full API Integration reusable consent session

Finalizes the consent session and returns grant.id. Send that value as consent_grant_id when creating the order.

When to use it

For the Fitnescity Health consent API only: finalize reusable consent and persist grant.id as consent_grant_id on the later order.

  • Requires signer_role=self, the customer-entered typed_name, and electronic_signature_attestation=true.
  • Requires customer_ip and customer_user_agent from the customer-facing request, not the API Partner's server IP.
  • An active same-key request returns 202 with data.code IDEMPOTENCY_IN_PROGRESS and Retry-After; retry the exact same request.
  • Missing or invalid customer IP returns HTTP 400.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
sessionIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: FinalizeApiFirstConsentSessionDto(FinalizeApiFirstConsentSessionDto)
Example values come from the published contract example.
default
{
  "customer_ip": "203.0.113.10",
  "customer_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
  "decisions": {
    "arbitration": true,
    "data_use": true,
    "hipaa_authorization": true,
    "testing_consent": true
  },
  "electronic_signature_attestation": true,
  "signer_role": "self",
  "typed_name": "Ada Lovelace"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/consent-sessions/3fa85f64-5717-4562-b3fc-2c963f66afa6/finalize" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"customer_ip":"203.0.113.10","customer_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36","decisions":{"arbitration":true,"data_use":true,"hipaa_authorization":true,"testing_consent":true},"electronic_signature_attestation":true,"signer_role":"self","typed_name":"Ada Lovelace"}'

Responses

200Consent session finalized.
Content type: application/json
Schema: ApiFirstConsentFinalizationResponseDto(ApiFirstConsentFinalizationResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "grant": {
      "expires_at": "2031-03-10T12:10:00.000Z",
      "id": "44444444-4444-4444-8444-444444444444"
    },
    "session": {
      "canonical_test_type": "DEXA",
      "customer_identity_id": "11111111-1111-4111-8111-111111111111",
      "expires_at": "2026-03-10T12:15:00.000Z",
      "finalized_at": "2026-03-10T12:10:00.000Z",
      "grant": {
        "id": "44444444-4444-4444-8444-444444444444"
      },
      "id": "33333333-3333-4333-8333-333333333333",
      "status": "finalized"
    }
  },
  "error": null
}
201Response
Content type: application/json
Schema: ApiFirstConsentFinalizationResponseDto(ApiFirstConsentFinalizationResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "artifact": {
      "example_key": "example_value"
    },
    "grant": {
      "expires_at": {},
      "id": {}
    },
    "session": {
      "abandoned_at": {},
      "abandonment_reason": {},
      "canonical_test_type": {},
      "customer_identity_id": {},
      "expires_at": {},
      "finalized_at": {},
      "grant": {},
      "id": {},
      "status": {}
    }
  },
  "error": null
}
202The same Full API Integration command is still processing. Wait for Retry-After, then retry with the exact same Idempotency-Key and payload. This is a success envelope, not an error envelope.
Content type: application/json
Schema: ApiFirstIdempotencyInProgressResponseDto(ApiFirstIdempotencyInProgressResponseDto)
Contract example
Contract example
{
  "code": 202,
  "data": {
    "code": "IDEMPOTENCY_IN_PROGRESS",
    "retry_after_seconds": 7,
    "status": "in_progress"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/identities

Create or update a Full API Integration customer identity

Creates or updates a customer identity from external_customer_id and returns data.customer_identity_id. Reuse that identifier for consent sessions and orders.

When to use it

Create or update the durable customer identity used by Full API Integration consent sessions and orders.

  • Requires Idempotency-Key. Reuse external_customer_id; do not mint a new identity per order.
  • Persist data.customer_identity_id and reuse it for applicable Calcium Score prescreening, the Fitnescity Health consent API or API Partner-provided consent PDF evidence, and orders for this external_customer_id.
  • Send the complete customer profile defined by the request schema, including sex and address fields.
  • An active same-key request returns 202 with data.code IDEMPOTENCY_IN_PROGRESS and Retry-After. Retry the exact same key and payload.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Request Body
Content type: application/json
Schema: ApiFirstCustomerIdentityDto(ApiFirstCustomerIdentityDto)
Example values come from the published contract example.
default
{
  "address": {
    "address_line_1": "12 Analytical Engine Way",
    "city": "London",
    "postal_code": "N1 1AA",
    "state": "LDN"
  },
  "date_of_birth": "1988-01-02",
  "email": "ada@example.com",
  "external_customer_id": "member-001",
  "first_name": "Ada",
  "last_name": "Lovelace",
  "phone": "+1 555 0100",
  "sex": "female"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/identities" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"address":{"address_line_1":"12 Analytical Engine Way","city":"London","postal_code":"N1 1AA","state":"LDN"},"date_of_birth":"1988-01-02","email":"ada@example.com","external_customer_id":"member-001","first_name":"Ada","last_name":"Lovelace","phone":"+1 555 0100","sex":"female"}'

Responses

200Response
Content type: application/json
Schema: ApiFirstIdentityResponseDto(ApiFirstIdentityResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "customer_identity_id": "11111111-1111-4111-8111-111111111111"
  },
  "error": null
}
201Customer identity created.
Content type: application/json
Schema: ApiFirstIdentityResponseDto(ApiFirstIdentityResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "customer_identity_id": "11111111-1111-4111-8111-111111111111",
    "external_customer_id": "member-001"
  },
  "error": null
}
202The same Full API Integration command is still processing. Wait for Retry-After, then retry with the exact same Idempotency-Key and payload. This is a success envelope, not an error envelope.
Content type: application/json
Schema: ApiFirstIdempotencyInProgressResponseDto(ApiFirstIdempotencyInProgressResponseDto)
Contract example
Contract example
{
  "code": 202,
  "data": {
    "code": "IDEMPOTENCY_IN_PROGRESS",
    "retry_after_seconds": 7,
    "status": "in_progress"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/api-first/identities/{identityId}

Get a Full API Integration customer identity

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
identityIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/api-first/identities/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Response
Content type: application/json
Schema: ApiFirstIdentityResponseDto(ApiFirstIdentityResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "customer_identity_id": "11111111-1111-4111-8111-111111111111"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/api-first/physician-order-evidence/{evidenceId}

Get partner physician-order evidence

When to use it

Poll one API Partner physician-order evidence resource until validation finishes.

  • Requires read:physician_order_evidence. Continue only after data.status=accepted.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
evidenceIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/api-first/physician-order-evidence/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Response
Content type: application/json
Schema: PartnerEvidenceResponseDto(PartnerEvidenceResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "assurance_basis": "versioned_attestation",
    "canonical_test_type": "DEXA",
    "collected_at": "2026-03-10T10:00:00.000Z",
    "customer_identity_id": "123e4567-e89b-12d3-a456-426614174000",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "physician_order_request_id": "123e4567-e89b-12d3-a456-426614174000",
    "processing_method": "attested_lambda_v1",
    "safe_reason_code": "EVIDENCE_HASH_MISMATCH",
    "signed_at": "2026-03-10T10:00:00.000Z",
    "signer_name": "Ada Lovelace",
    "status": "awaiting_upload",
    "status_changed_at": "2026-03-10T10:00:00.000Z",
    "upload_session": {
      "expires_at": {},
      "id": {},
      "method": {},
      "required_headers": {},
      "url": {}
    },
    "verification_level": "partner_attested",
    "version": 0
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/physician-order-evidence/{evidenceId}/upload-sessions

Issue a replacement physician-evidence upload session

When to use it

Issue a replacement S3 upload session for physician-order evidence.

  • Requires write:physician_order_evidence and Idempotency-Key. From your API Partner backend or a server-side proxy, upload with every newly returned required_headers value.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
evidenceIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/physician-order-evidence/3fa85f64-5717-4562-b3fc-2c963f66afa6/upload-sessions" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001"

Responses

201Response
Content type: application/json
Schema: PartnerEvidenceResponseDto(PartnerEvidenceResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "assurance_basis": "versioned_attestation",
    "canonical_test_type": "DEXA",
    "collected_at": "2026-03-10T10:00:00.000Z",
    "customer_identity_id": "123e4567-e89b-12d3-a456-426614174000",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "physician_order_request_id": "123e4567-e89b-12d3-a456-426614174000",
    "processing_method": "attested_lambda_v1",
    "safe_reason_code": "EVIDENCE_HASH_MISMATCH",
    "signed_at": "2026-03-10T10:00:00.000Z",
    "signer_name": "Ada Lovelace",
    "status": "awaiting_upload",
    "status_changed_at": "2026-03-10T10:00:00.000Z",
    "upload_session": {
      "expires_at": {},
      "id": {},
      "method": {},
      "required_headers": {},
      "url": {}
    },
    "verification_level": "partner_attested",
    "version": 0
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/physician-order-evidence/{evidenceId}/upload-sessions/{uploadSessionId}/complete

Complete a physician-evidence upload

Completes the upload for the exact partner-provided PDF. In trusted_pdf_contract mode, it is accepted under the certified partner contract; contents are not inspected or normalized by the gateway or processor. The response may be 202 while processing; poll the evidence resource until status is accepted.

When to use it

Complete a physician-order evidence upload and enqueue asynchronous validation.

  • Requires write:physician_order_evidence and Idempotency-Key. Submit the originally declared lowercase hexadecimal SHA-256, then poll the evidence resource.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
evidenceIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
uploadSessionIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: CompletePartnerEvidenceUploadSessionDto(CompletePartnerEvidenceUploadSessionDto)
Example values come from the published contract example.
Contract example
{
  "sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/physician-order-evidence/3fa85f64-5717-4562-b3fc-2c963f66afa6/upload-sessions/3fa85f64-5717-4562-b3fc-2c963f66afa6/complete" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"sha256":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}'

Responses

202Response
Content type: application/json
Schema: PartnerEvidenceResponseDto(PartnerEvidenceResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "assurance_basis": "versioned_attestation",
    "canonical_test_type": "DEXA",
    "collected_at": "2026-03-10T10:00:00.000Z",
    "customer_identity_id": "123e4567-e89b-12d3-a456-426614174000",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "physician_order_request_id": "123e4567-e89b-12d3-a456-426614174000",
    "processing_method": "attested_lambda_v1",
    "safe_reason_code": "EVIDENCE_HASH_MISMATCH",
    "signed_at": "2026-03-10T10:00:00.000Z",
    "signer_name": "Ada Lovelace",
    "status": "awaiting_upload",
    "status_changed_at": "2026-03-10T10:00:00.000Z",
    "upload_session": {
      "expires_at": {},
      "id": {},
      "method": {},
      "required_headers": {},
      "url": {}
    },
    "verification_level": "partner_attested",
    "version": 0
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/api-first/physician-order-sessions/{sessionId}

Get a structured partner physician-order session

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
sessionIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/api-first/physician-order-sessions/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Response
Content type: application/json
Schema: StructuredPhysicianSessionResponseDto(StructuredPhysicianSessionResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "approval_method": "electronic_signature",
    "artifact": {
      "signed_form_url": {},
      "status": {}
    },
    "context_hash": "string",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "order_date": "2026-03-10",
    "partner_attestation": {
      "text": "string",
      "text_hash": "string",
      "version": "partner-structured-physician-order-v1"
    },
    "physician": {
      "contact": {},
      "credentials": "MD",
      "full_name": "Dr. Ada Lovelace",
      "license_number": "NY-12345",
      "license_state": "NY",
      "npi": "1234567893",
      "ordering_entity": "Example Medical Group"
    },
    "presentation": {
      "required_acknowledgements": [
        {}
      ],
      "schema_version": "structured-physician-presentation-v1",
      "sections": [
        {}
      ],
      "title": "string"
    },
    "presentation_hash": "string",
    "request_id": "123e4567-e89b-12d3-a456-426614174000",
    "status": "open",
    "template": {
      "content_hash": "string",
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "schema_version": "physician-order-v2",
      "version": 2
    },
    "workflow_type": "partner_electronic"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/physician-order-sessions/{sessionId}/abandon

Abandon an open structured partner physician-order session

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
sessionIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: AbandonStructuredPhysicianOrderSessionDto(AbandonStructuredPhysicianOrderSessionDto)
Example values come from the published contract example.
Contract example
{
  "reason": "string"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/physician-order-sessions/3fa85f64-5717-4562-b3fc-2c963f66afa6/abandon" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"reason":"string"}'

Responses

200Response
Content type: application/json
Schema: StructuredPhysicianSessionResponseDto(StructuredPhysicianSessionResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "approval_method": "electronic_signature",
    "artifact": {
      "signed_form_url": {},
      "status": {}
    },
    "context_hash": "string",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "order_date": "2026-03-10",
    "partner_attestation": {
      "text": "string",
      "text_hash": "string",
      "version": "partner-structured-physician-order-v1"
    },
    "physician": {
      "contact": {},
      "credentials": "MD",
      "full_name": "Dr. Ada Lovelace",
      "license_number": "NY-12345",
      "license_state": "NY",
      "npi": "1234567893",
      "ordering_entity": "Example Medical Group"
    },
    "presentation": {
      "required_acknowledgements": [
        {}
      ],
      "schema_version": "structured-physician-presentation-v1",
      "sections": [
        {}
      ],
      "title": "string"
    },
    "presentation_hash": "string",
    "request_id": "123e4567-e89b-12d3-a456-426614174000",
    "status": "open",
    "template": {
      "content_hash": "string",
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "schema_version": "physician-order-v2",
      "version": 2
    },
    "workflow_type": "partner_electronic"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/api-first/physician-order-sessions/{sessionId}/finalize

Finalize a structured partner physician-order session

Submits only the physician approval evidence and frozen-session hashes. Provider, order, patient, test, consent, screening, and location data cannot be replaced during finalization. Poll the returned session resource while the combined Fitnescity Health PDF is rendered.

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
sessionIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: FinalizeStructuredPhysicianOrderSessionDto(FinalizeStructuredPhysicianOrderSessionDto)
Example values come from the published contract example.
Contract example
{
  "approval": {
    "approved_at": "2026-03-10T10:00:00.000Z",
    "device_metadata": {
      "example_key": "string"
    },
    "electronic_signature_attestation": true,
    "external_reference_id": "string",
    "ip_address": "string",
    "order_acknowledgement": true,
    "session_reference": "string",
    "typed_name": "string",
    "user_agent": "string"
  },
  "content_hash": "string",
  "context_hash": "string",
  "partner_attestation": {
    "accepted": true,
    "text_hash": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
    "version": "partner-structured-physician-order-v1"
  },
  "presentation_hash": "string",
  "template_version_id": "123e4567-e89b-12d3-a456-426614174000"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/api-first/physician-order-sessions/3fa85f64-5717-4562-b3fc-2c963f66afa6/finalize" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"approval":{"approved_at":"2026-03-10T10:00:00.000Z","device_metadata":{"example_key":"string"},"electronic_signature_attestation":true,"external_reference_id":"string","ip_address":"string","order_acknowledgement":true,"session_reference":"string","typed_name":"string","user_agent":"string"},"content_hash":"string","context_hash":"string","partner_attestation":{"accepted":true,"text_hash":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","version":"partner-structured-physician-order-v1"},"presentation_hash":"string","template_version_id":"123e4567-e89b-12d3-a456-426614174000"}'

Responses

202Response
Content type: application/json
Schema: StructuredPhysicianSessionResponseDto(StructuredPhysicianSessionResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "approval_method": "electronic_signature",
    "artifact": {
      "signed_form_url": {},
      "status": {}
    },
    "context_hash": "string",
    "expires_at": "2026-03-10T10:00:00.000Z",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "order_date": "2026-03-10",
    "partner_attestation": {
      "text": "string",
      "text_hash": "string",
      "version": "partner-structured-physician-order-v1"
    },
    "physician": {
      "contact": {},
      "credentials": "MD",
      "full_name": "Dr. Ada Lovelace",
      "license_number": "NY-12345",
      "license_state": "NY",
      "npi": "1234567893",
      "ordering_entity": "Example Medical Group"
    },
    "presentation": {
      "required_acknowledgements": [
        {}
      ],
      "schema_version": "structured-physician-presentation-v1",
      "sections": [
        {}
      ],
      "title": "string"
    },
    "presentation_hash": "string",
    "request_id": "123e4567-e89b-12d3-a456-426614174000",
    "status": "open",
    "template": {
      "content_hash": "string",
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "schema_version": "physician-order-v2",
      "version": 2
    },
    "workflow_type": "partner_electronic"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/appointments

List appointments

When to use it

Poll appointment records to track scheduling state changes for orders placed through your integration.

  • Use this as a reconciliation source when webhook delivery is delayed or your consumer was unavailable.
  • Filter by order_id for order-scoped appointment lookup, or use updated_after for incremental polling.
  • Appointment status reflects the full lifecycle: pending_scheduling, requested, confirmed, rescheduled, canceled, refunded, no_show, results_in_progress, and results_ready.
  • Each appointment item also returns form_type and has_signed_form when a signed appointment form is available.
  • For appointments created through Full API Integration, use physician_order_status to track physician review and pending_confirmation to identify a scheduling request that is awaiting location confirmation.
  • scheduled_for and other appointment datetimes are absolute timestamps and may be serialized with Z. Parse them as instants, then use the returned location.timezone for member-facing display and location-calendar rules such as the within-24-hour warning.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Query Parameters
NameTypeRequiredDescriptionExample
emailstringNoFilter by customer email.john.doe@example.com
order_idstring (uuid)NoFilter by order id.3fa85f64-5717-4562-b3fc-2c963f66afa6
appointment_idstring (uuid)NoFilter by appointment id.3fa85f64-5717-4562-b3fc-2c963f66afa6
statusenum(pending_scheduling, pending_confirmation, confirmed, canceled, no_show, completed)NoFilter by appointment status.confirmed
results_statusenum(waiting_results, in_progress, finalized)NoFilter by results status.waiting_results
test_typestringNoFilter by test type.DEXA
updated_afterstringNoOnly include appointments updated at or after this timestamp.2026-04-10T00:00:00.000Z
limitnumberNoMaximum number of records.100
cursorstringNoOpaque cursor returned from a prior appointments page.eyJ1cGRhdGVkX2F0IjoiMjAyNi0wNC0xMFQwOTowMDowMC4wMDBaIiwiYXBwb2ludG1lbnRfaWQiOiJhcHQtMSJ9
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/appointments?email=john.doe%40example.com&status=confirmed&results_status=waiting_results&test_type=DEXA&updated_after=2026-04-10T00%3A00%3A00.000Z&limit=100&cursor=eyJ1cGRhdGVkX2F0IjoiMjAyNi0wNC0xMFQwOTowMDowMC4wMDBaIiwiYXBwb2ludG1lbnRfaWQiOiJhcHQtMSJ9" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Appointments list for the calling API partner.
Content type: application/json
Schema: AppointmentsResponseDto(AppointmentsResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": {},
        "artifact_status": {},
        "cancellation_reason_code": {},
        "confirmed_at": {},
        "created_at": {},
        "form_type": {},
        "location": {},
        "order_id": {},
        "original_scheduled_for": {},
        "physician_order_status": {},
        "physician_order_submission_deadline_at": {},
        "physician_order_submission_status": {},
        "physician_order_submitted_at": {},
        "requested_at": {},
        "results_status": {},
        "scheduled_for": {},
        "status": {},
        "test_type": {},
        "updated_at": {}
      }
    ],
    "page_info": {
      "has_more": true,
      "limit": 100,
      "next_cursor": "cursor-2"
    }
  },
  "error": null
}
400Validation failure for appointment query parameters.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 400,
  "data": null,
  "error": {
    "details": null,
    "message": "Idempotency-Key header is required",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/appointments/{appointmentId}

Get appointment

When to use it

Retrieve a single appointment by its Fitnescity Health identifier.

  • Use this for targeted lookup when you already have the appointment_id from order creation or a webhook event.
  • The single appointment payload also includes form_type and has_signed_form when a signed appointment form exists for that visit.
  • Use GET /v1/appointments/{appointmentId}/signed-form to retrieve the actual signed form download link when needed.
  • Malformed appointmentId path values return 400. Appointments outside the calling API Partner scope return 404.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Appointment record for the calling API partner.
Content type: application/json
Schema: AppointmentResponseDto(AppointmentResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "artifact_status": "awaiting_physician",
    "cancellation_reason_code": null,
    "confirmed_at": null,
    "created_at": "2026-03-17T12:45:00.000Z",
    "form_type": "CONSENT",
    "location": {
      "address_line_1": "123 Main St",
      "address_line_2": "Suite 500",
      "city": "New York",
      "postal_code": "10001",
      "state": "NY",
      "timezone": "America/New_York"
    },
    "order_id": "123e4567-e89b-12d3-a456-426614174000",
    "original_scheduled_for": "2026-03-18T15:30:00.000Z",
    "physician_order_status": "pending",
    "physician_order_submission_deadline_at": "2026-10-12T17:00:00.000Z",
    "physician_order_submission_status": "processing",
    "physician_order_submitted_at": "2026-10-12T15:30:00.000Z",
    "requested_at": null,
    "results_status": "waiting_results",
    "scheduled_for": "2026-03-20T15:30:00.000Z",
    "status": "confirmed",
    "test_type": "DEXA",
    "updated_at": "2026-03-17T12:50:00.000Z"
  },
  "error": null
}
400Validation failure for appointment path parameter.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 400,
  "data": null,
  "error": {
    "details": null,
    "message": "Idempotency-Key header is required",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/appointments/{appointmentId}/cancel

Cancel appointment

Cancels an appointment. Set the penalty confirmation field only after the client shows the within-24-hour warning and the member confirms the action. Use either the canonical snake_case field or the deprecated camelCase alias, never both.

When to use it

Cancel a confirmed appointment on behalf of the member when your integration owns post-booking management.

  • Requires write:appointments scope and Idempotency-Key on every request.
  • Use one idempotency key per logical cancel attempt. If your client times out or disconnects before receiving the response, retry the same request with the same key.
  • Same key plus same payload replays the prior completed cancel response. Same key plus different payload returns 409.
  • If the same idempotency key is still processing, the API returns 409 with error.details.code IDEMPOTENCY_IN_PROGRESS plus Retry-After / retryAfterSeconds. Wait, then retry with the same key instead of minting a new one.
  • Optional reason accepts a cancellation note up to 500 characters.
  • When the appointment is within 24 hours of the scheduled time, the first request returns 409 with error.details.code WITHIN_24_HOUR_WINDOW and requiresConfirmation true. Show the penalty warning, then retry with confirm_within_24_hour_penalty set to true. The deprecated confirmWithin24HourPenalty alias remains accepted for compatibility; never send both representations.
  • API Partners should also implement their own logic for the warning before submit. Parse the returned appointment datetime and current time as absolute instants, then use location.timezone as the same test location timezone for member-facing display and location-calendar rules.
  • Malformed appointmentId path values return 400. Appointments outside the calling API Partner scope return 404.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: CancelAppointmentDto(CancelAppointmentDto)
Example values come from the published contract example.
default
{
  "confirm_within_24_hour_penalty": false,
  "reason": "Customer requested cancellation"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6/cancel" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"confirm_within_24_hour_penalty":false,"reason":"Customer requested cancellation"}'

Responses

200Appointment canceled.
Content type: application/json
Schema: AppointmentResponseDto(AppointmentResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
    "cancelled_within_24_hour_window": false,
    "status": "canceled"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/appointments/{appointmentId}/report

Get appointment result report

Returns a temporary download URL for the imported report document. The document is usually a PDF, but a scan submitted as a photo is returned as an image, so use the content_type field rather than assuming a PDF. Available for DEXA and DEXABMD appointments only. The document is prepared shortly after the appointment is finalized, so a request made in the first few minutes may return 503 with a Retry-After header while preparation completes; retry after that interval. A 404 means no report is available for this appointment. The link is valid for fifteen minutes; request a new one when it expires rather than storing it.

When to use it

Fetch a presigned download link for the full report document that Fitnescity Health imported for a completed test.

  • Requires read:appointments scope.
  • The document is usually a PDF, but a scan submitted as a photo is returned as an image. Use the content_type field to decide how to render or store it rather than assuming a PDF.
  • Available for DEXA and DEXABMD appointments only. Other test types return 404.
  • The report is prepared shortly after the appointment is finalized. A request made during preparation returns 503 with a Retry-After header; retry after that interval rather than treating it as a failure.
  • A 404 means no report document is available for the appointment, which is the expected response once preparation has completed without producing one.
  • The returned link is temporary and remains valid for 15 minutes. Request a new link when it expires instead of storing report_url.
  • Report links are generated per request and are never included in webhook payloads, because a delivery retry can outlive the link.
  • Malformed appointmentId path values return 400. Appointments outside the calling API Partner scope return 404.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6/report" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Report download metadata for the calling API partner appointment.
Content type: application/json
Schema: AppointmentResultReportResponseDto(AppointmentResultReportResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
    "content_type": "application/pdf",
    "expires_in_seconds": 900,
    "report_url": "https://download.example.com/reports/6256b5fe-2d81-4db7-b389-1bbd3f03a560/report.pdf?token=temporary",
    "test_type": "DEXA"
  },
  "error": null
}
400Validation failure for appointment path parameter.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 400,
  "data": null,
  "error": {
    "details": null,
    "message": "Idempotency-Key header is required",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
503The report is still being prepared for a recently finalized appointment. Retry after the interval in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Report still being prepared
{
  "code": 503,
  "data": null,
  "error": {
    "details": null,
    "message": "Report is still being prepared for this appointment. Retry shortly.",
    "path": "/v1/appointments/6256b5fe-2d81-4db7-b389-1bbd3f03a560/report",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/appointments/{appointmentId}/reschedule

Reschedule appointment

Requests a new appointment time and optional alternate availabilities. Use either the canonical snake_case fields or their deprecated camelCase aliases, never both. A successful request returns pending_confirmation while location confirmation remains asynchronous; it does not return reschedule_pending. If an enrolled physician-order appointment cannot load its required calendar configuration, the request returns a retryable 503 without changing appointment or deadline state; repair the configuration, then retry later with the same Idempotency-Key and identical payload. This transient response is not a completed idempotent replay.

When to use it

Request a new appointment datetime for a confirmed appointment from your own scheduling UI.

  • Requires write:appointments scope and Idempotency-Key on every request.
  • Use one idempotency key per logical reschedule attempt. If your client times out or disconnects before receiving the response, retry the same request with the same key.
  • Same key plus same payload replays the prior completed reschedule response. Same key plus different payload returns 409.
  • If the same idempotency key is still processing, the API returns 409 with error.details.code IDEMPOTENCY_IN_PROGRESS plus Retry-After / retryAfterSeconds. Wait, then retry with the same key instead of minting a new one.
  • new_requested_date is the canonical required ISO-8601 field. The deprecated newRequestedDate alias remains accepted for compatibility, but send exactly one date representation.
  • alternate_availabilities accepts up to three optional ISO-8601 datetimes. The deprecated alternateAvailabilities alias remains accepted for compatibility; never send both representations.
  • The canonical confirm_within_24_hour_penalty field has the deprecated confirmWithin24HourPenalty alias; never send both representations.
  • When the appointment is within 24 hours of the scheduled time, the first request returns 409 with error.details.code WITHIN_24_HOUR_WINDOW and requiresConfirmation true. Show the penalty warning, then retry with confirm_within_24_hour_penalty set to true.
  • API Partners should also implement their own logic for the warning before submit. Parse the returned appointment datetime and current time as absolute instants, then use location.timezone as the same test location timezone for member-facing display and location-calendar rules.
  • When live availability data is available, use the same returned schedule to populate alternate_availabilities so members choose only valid backup slots.
  • A successful request returns pending_confirmation while the location confirms the new slot. API Partner reschedule requests emit appointment.requested and then appointment.confirmed; direct confirmed-to-confirmed location moves emit appointment.rescheduled.
  • Malformed appointmentId path values return 400. Appointments outside the calling API Partner scope return 404.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: RescheduleAppointmentDto(RescheduleAppointmentDto)
Example values come from the published contract example.
default
{
  "alternate_availabilities": [
    "2026-09-11T09:00:00-04:00"
  ],
  "confirm_within_24_hour_penalty": false,
  "new_requested_date": "2026-09-10T09:00:00-04:00"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6/reschedule" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"alternate_availabilities":["2026-09-11T09:00:00-04:00"],"confirm_within_24_hour_penalty":false,"new_requested_date":"2026-09-10T09:00:00-04:00"}'

Responses

200Reschedule request recorded; appointment confirmation remains asynchronous.
Content type: application/json
Schema: AppointmentResponseDto(AppointmentResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "alternate_availabilities": [
      "2026-09-11T09:00:00-04:00"
    ],
    "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
    "new_requested_date": "2026-09-10T09:00:00-04:00",
    "rescheduled_within_24_hour_window": false,
    "status": "pending_confirmation"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
503Physician-order calendar configuration is temporarily unavailable. No appointment/deadline state changed. Repair the configuration, then retry later with the same Idempotency-Key and identical payload; this response is not a completed idempotent replay.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 503,
  "data": null,
  "error": {
    "details": {
      "code": "PHYSICIAN_ORDER_CALENDAR_UNAVAILABLE",
      "retryable": true
    },
    "message": "Reschedule is temporarily unavailable because physician-order calendar configuration could not be loaded",
    "path": "/v1/appointments/6256b5fe-2d81-4db7-b389-1bbd3f03a560/reschedule",
    "request_id": "req_1234567890",
    "timestamp": "2026-10-12T16:00:00.000Z"
  }
}
POST

/v1/appointments/{appointmentId}/schedule

Request appointment scheduling

Requests location confirmation for the selected appointment date and alternate availabilities. A successful response does not mean the appointment is confirmed.

When to use it

Record a Full API Integration location confirmation request. This never performs instant authoritative booking.

  • Requires Idempotency-Key, selected_appointment_date, and 1 to 3 alternate_availabilities. Send the full ISO-8601 datetimes and numeric offsets returned by schedule availability; those values are not always UTC.
  • An active same-key request returns 202 with data.code IDEMPOTENCY_IN_PROGRESS and Retry-After; retry the exact same key and payload.
  • Co-branded integrations must not use this route; Full API Integration must not call schedule-handoff. Mixing the flows returns FLOW_ENDPOINT_MISMATCH.
  • Successful requests can return physician_order_status=pending. That is not a scheduling failure.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: ScheduleAppointmentDto(ScheduleAppointmentDto)
Example values come from the published contract example.
default
{
  "alternate_availabilities": [
    "2026-06-12T09:00:00-04:00"
  ],
  "selected_appointment_date": "2026-06-11T11:00:00-04:00"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6/schedule" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"alternate_availabilities":["2026-06-12T09:00:00-04:00"],"selected_appointment_date":"2026-06-11T11:00:00-04:00"}'

Responses

200Scheduling request recorded; confirmation remains asynchronous.
Content type: application/json
Schema: ScheduleAppointmentResponseDto(ScheduleAppointmentResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "alternate_availabilities": [
      "2026-06-12T09:00:00-04:00"
    ],
    "appointment_id": "77777777-7777-4777-8777-777777777777",
    "cancellation_reason_code": null,
    "order_id": "88888888-8888-4888-8888-888888888888",
    "physician_order_status": "pending",
    "physician_order_submission_deadline_at": "2026-10-12T17:00:00.000Z",
    "physician_order_submission_status": "not_submitted",
    "physician_order_submitted_at": null,
    "requested_at": "2026-03-10T12:25:00.000Z",
    "requested_timezone": "America/New_York",
    "selected_appointment_date": "2026-06-11T11:00:00-04:00",
    "status": "pending_confirmation"
  },
  "error": null
}
202The same Full API Integration command is still processing. Wait for Retry-After, then retry with the exact same Idempotency-Key and payload. This is a success envelope, not an error envelope.
Content type: application/json
Schema: ApiFirstIdempotencyInProgressResponseDto(ApiFirstIdempotencyInProgressResponseDto)
Contract example
Contract example
{
  "code": 202,
  "data": {
    "code": "IDEMPOTENCY_IN_PROGRESS",
    "retry_after_seconds": 7,
    "status": "in_progress"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/appointments/{appointmentId}/scheduling-questionnaire

Get an appointment-scoped scheduling questionnaire

Returns the questionnaire definition pinned to the appointment and any finalized submission metadata.

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6/scheduling-questionnaire" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Response
Content type: application/json
Schema: ApiFirstObjectResponseDto(ApiFirstObjectResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "canonical_test_type": "DEXA",
    "content": {
      "acknowledgements": [
        {
          "id": "scheduling_terms",
          "label": "I agree to the scheduling terms.",
          "required": true
        }
      ],
      "fields": [
        {
          "id": "recent_barium_exam",
          "label": "Have you had a barium exam, scan with contrast, or nuclear medicine exam within the past 7 days?",
          "required": true,
          "type": "boolean"
        }
      ],
      "sections": [
        {
          "id": "health_history",
          "title": "Before your DEXA test"
        }
      ]
    },
    "content_hash": "sha256:questionnaire-dexa-v3",
    "id": "55555555-5555-4555-8555-555555555555",
    "name": "DEXA scheduling questionnaire",
    "status": "active",
    "version": 3
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/appointments/{appointmentId}/scheduling-questionnaire

Submit an appointment-scoped scheduling questionnaire

Validates and permanently snapshots the questionnaire submission against the definition pinned to the appointment. Successful submissions are finalized synchronously and are immutable. The same Idempotency-Key and payload replay the original response; the same key with a different payload returns IDEMPOTENCY_CONFLICT; a new key cannot replace a finalized submission and returns QUESTIONNAIRE_ALREADY_SUBMITTED.

When to use it

Submit the appointment questionnaire before requesting scheduling.

  • Submit acknowledgements and answers keyed by ids from the pinned definition, such as scheduling_terms and pregnancy_notice.
  • A successful submission is finalized synchronously. outcome.status is accepted, blocked, or physician_review_required. outcome.code is nullable and forward-compatible, so accept unknown future non-null codes and branch primarily on status.
  • The same Idempotency-Key and same payload replays the original response. The same Idempotency-Key with a different payload returns IDEMPOTENCY_CONFLICT. An active same-key request returns 202 with data.code IDEMPOTENCY_IN_PROGRESS and Retry-After.
  • A new Idempotency-Key cannot replace an already-finalized submission; it returns QUESTIONNAIRE_ALREADY_SUBMITTED.
  • QUESTIONNAIRE_VERSION_MISMATCH means you substituted a newly fetched definition. QUESTIONNAIRE_VALIDATION_FAILED is HTTP 422.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYes—order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: AppointmentQuestionnaireSubmissionDto(AppointmentQuestionnaireSubmissionDto)
Example values come from the published contract example.
default
{
  "acknowledgements": {
    "scheduling_terms": true
  },
  "answers": {
    "recent_barium_exam": false
  },
  "content_hash": "sha256:questionnaire-dexa-v3",
  "questionnaire_definition_id": "55555555-5555-4555-8555-555555555555"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6/scheduling-questionnaire" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"acknowledgements":{"scheduling_terms":true},"answers":{"recent_barium_exam":false},"content_hash":"sha256:questionnaire-dexa-v3","questionnaire_definition_id":"55555555-5555-4555-8555-555555555555"}'

Responses

200Response
Content type: application/json
Schema: ApiFirstQuestionnaireSubmissionResponseDto(ApiFirstQuestionnaireSubmissionResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointment_id": "123e4567-e89b-12d3-a456-426614174000",
    "completed_at": "2026-03-10T12:20:00.000Z",
    "content_hash": "sha256:questionnaire-dexa-v3",
    "outcome": {
      "code": null,
      "status": "accepted"
    },
    "questionnaire_definition_id": "123e4567-e89b-12d3-a456-426614174000",
    "questionnaire_submission_id": "123e4567-e89b-12d3-a456-426614174000",
    "questionnaire_version": 3,
    "status": "finalized"
  },
  "error": null
}
201Appointment questionnaire finalized synchronously.
Content type: application/json
Schema: ApiFirstQuestionnaireSubmissionResponseDto(ApiFirstQuestionnaireSubmissionResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointment_id": "77777777-7777-4777-8777-777777777777",
    "completed_at": "2026-03-10T12:20:00.000Z",
    "content_hash": "sha256:questionnaire-dexa-v3",
    "outcome": {
      "code": null,
      "status": "accepted"
    },
    "questionnaire_definition_id": "55555555-5555-4555-8555-555555555555",
    "questionnaire_submission_id": "66666666-6666-4666-8666-666666666666",
    "questionnaire_version": 3,
    "status": "finalized"
  },
  "error": null
}
202The same Full API Integration command is still processing. Wait for Retry-After, then retry with the exact same Idempotency-Key and payload. This is a success envelope, not an error envelope.
Content type: application/json
Schema: ApiFirstIdempotencyInProgressResponseDto(ApiFirstIdempotencyInProgressResponseDto)
Contract example
Contract example
{
  "code": 202,
  "data": {
    "code": "IDEMPOTENCY_IN_PROGRESS",
    "retry_after_seconds": 7,
    "status": "in_progress"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

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

Get appointment signed form

Returns a temporary download URL for the customer-signed appointment form. This link is valid for one hour.

When to use it

Fetch a presigned download link for the signed appointment consent/form when your member needs a copy.

  • Requires read:appointments scope.
  • Returns signed_form_url plus form_type for the appointment-scoped signed form. ARTIFACT_NOT_AVAILABLE means a form is not available; PHYSICIAN_ORDER_PENDING means physician work is not complete yet.
  • The returned link is temporary and remains valid for 1 hour.
  • Malformed appointmentId path values return 400. Appointments outside the calling API Partner scope return 404.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
appointmentIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/appointments/3fa85f64-5717-4562-b3fc-2c963f66afa6/signed-form" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Signed form download metadata for the calling API partner appointment.
Content type: application/json
Schema: AppointmentSignedFormResponseDto(AppointmentSignedFormResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
    "expires_in_seconds": 3600,
    "form_type": "CONSENT",
    "signed_form_url": "https://download.example.com/forms/6256b5fe-2d81-4db7-b389-1bbd3f03a560/consent.pdf?token=temporary"
  },
  "error": null
}
400Validation failure for appointment path parameter.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 400,
  "data": null,
  "error": {
    "details": null,
    "message": "Idempotency-Key header is required",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/documents/vo2-physician-assessment

Download the VO2 physician assessment

Returns the blank physician assessment used by the manual VO2 safety-review process. API partners should retrieve it server-side and proxy it to their customer without exposing the API key.

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/documents/vo2-physician-assessment" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200VO2 physician assessment PDF.
Content type: application/pdf
Schema: string (binary)
Contract example
Contract example
"string"
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/integration-configuration

Get the current integration configuration

Optionally confirms the current Full API Integration customer-consent and physician-order modes for the authenticated API key. Onboarding provides the initial configuration. This endpoint requires no operation scope and returns current public workflow names without scopes, internal identifiers, pricing, or certification details. Configuration changes apply to newly created workflows; continue existing resources through their original lifecycle.

When to use it

Optionally confirm the current customer-consent and physician-order modes associated with the authenticated API key.

  • Onboarding provides the initial configuration. Call this endpoint whenever you need to verify the current configuration, including after requesting a change.
  • The endpoint requires no operation scope beyond a valid active API key.
  • customer_consent.mode is fitnescity_consent_api or api_partner_pdf. physician_order.mode is fitnescity_service, structured_api, or api_partner_pdf.
  • Configuration changes apply to newly created workflows. Continue existing sessions, orders, appointments, and evidence resources through their original lifecycle.
  • Do not infer modes from scopes or API key names, and do not probe workflow endpoints to discover the configuration.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/integration-configuration" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Current public integration configuration.
Content type: application/json
Schema: IntegrationConfigurationResponseDto(IntegrationConfigurationResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "configuration_version": "cfg_8c27cb53dc4b3f51",
    "customer_consent": {
      "mode": "fitnescity_consent_api"
    },
    "environment": "production",
    "physician_order": {
      "mode": "structured_api"
    },
    "updated_at": "2026-09-23T10:30:00.000Z"
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive or the API partner account is suspended.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
409The authenticated key is not currently associated with a supported Full API Integration configuration.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 409,
  "data": null,
  "error": {
    "details": {
      "code": "INTEGRATION_CONFIGURATION_UNAVAILABLE"
    },
    "message": "The current integration configuration is not available through this endpoint",
    "path": "/v1/integration-configuration",
    "request_id": "req_1234567890",
    "timestamp": "2026-09-23T10:30:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/locations

List locations

Supports optional geo search (lat/lng with optional radius_miles). If lat/lng are not provided, returns a normal paginated location list in partners_within_radius and leaves nearest_partners/alternate_test_partners empty. Each test includes catalog_id and offering_id for downstream offering products and schedule calls. Location id remains the test location identifier.

When to use it

Use this as the entry point for location search and test location discovery. Each test includes catalog_id and offering_id for downstream offering products and schedule requests. Location id remains the location identifier.

  • Latitude and longitude are optional as a pair. Without geo input, the route behaves like a paginated location catalog.
  • A current catalog_id and offering_id pair returned by GET /v1/locations is expected to resolve through both the offering products and schedule routes. Report a freshly returned pair that produces 404 because that is not the normal no-availability state.
  • Supported test_types values are DEXA, DEXABMD, VO2 (VO2 Max), CALST (the API value for Calcium Score), RMR, BODPOD, HYDROSTATIC, and SECA.
  • starting_retail_price is the FE-V2 style “Starting from” retail price for that location context.
  • Pagination applies only to partners_within_radius. nearest_partners and alternate_test_partners are fallback blocks, not paginated feeds.
  • alternate_test_partners is populated only when the requested DEXA search has no in-radius matches and nearby alternate body-composition tests are available.
  • All guarded routes can also return 401, 403, 404, or 429. See the Error Handling page for the shared envelope and retry rules.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Query Parameters
NameTypeRequiredDescriptionExample
latnumberNoLatitude for geo search. Must be provided with lng. Optional.40.7128
lngnumberNoLongitude for geo search. Must be provided with lat. Optional.-74.006
radius_milesnumberNoGeo search radius in miles. Requires lat/lng. Defaults to 100 when lat/lng are present.25
test_typesstringNoComma-separated test types. Example: DEXA,RMR.DEXA,RMR
pagenumberNoPage number (1-based).1
page_sizenumberNoPage size. Default is 25.25
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/locations?lat=40.7128&lng=-74.006&radius_miles=25&test_types=DEXA%2CRMR&page=1&page_size=25" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Location search response grouped as partners_within_radius, nearest_partners, and alternate_test_partners, with meta describing fallback and pagination scope.
Content type: application/json
Schema: LocationsResponseDto(LocationsResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "alternate_test_partners": [],
    "meta": {
      "alternate_partners_per_test_limit": 10,
      "fallback_behavior": {
        "alternate_test_partners": "Populated only when partners_within_radius is empty and requested test_types includes DEXA. Maximum 10 partners per alternate test group.",
        "nearest_partners": "Populated only when partners_within_radius is empty. Maximum 2 partners."
      },
      "nearest_partners_limit": 2,
      "pagination_applies_to": "partners_within_radius"
    },
    "nearest_partners": [],
    "pagination": {
      "page": 1,
      "page_size": 10,
      "total": 1,
      "total_pages": 1
    },
    "partners_within_radius": [
      {
        "address_line_1": "160 Seventh Ave. South",
        "address_line_2": null,
        "city": "New York",
        "distance_miles": 0.13,
        "id": "cee4ea3a-801c-11ed-8926-12fa9030d819",
        "lat": 40.714579,
        "lng": -74.0064529,
        "postal_code": "10014",
        "starting_retail_price": 165,
        "state": "NY",
        "tests": [
          {
            "catalog_id": "006d1a83-ff73-4720-b53e-23af0d14f9cb",
            "offering_id": "d8a21f92-e15b-4abc-886b-c2ebf0ad91f2",
            "test_type": "DEXA"
          },
          {
            "catalog_id": "e93c6765-b5e7-4310-bb22-46f33120750b",
            "offering_id": "ec19643c-98af-4ed3-ac73-3ac1821c8dc8",
            "test_type": "RMR"
          }
        ]
      }
    ]
  },
  "error": null
}
400Validation failure for query parameters.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 400,
  "data": null,
  "error": {
    "details": null,
    "message": "lat and lng must be provided together, and radius_miles requires lat/lng",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/locations/{catalogId}/offerings/{offeringId}/products

Get offering product

Returns one single-test product for the selected catalog and offering. Test location fulfillment is resolved server-side from offering_id.

When to use it

Resolve one catalog/offering pair into the single-test product your API Partner app should use for direct ordering or booking.

  • catalog_id and offering_id come from GET /v1/locations tests[].
  • The response returns additional_note plus one product object with test_id for order creation.
  • Check product.is_prescreening_required before calling POST /v1/orders. If true, complete the prescreen form flow first.
  • integrator_price is the API-key-adjusted direct-order price.
  • currency is the single fulfillment test location currency for that offering product.
  • Malformed path UUIDs return 400. A 404 means the pair is not resolvable or is no longer accessible; a pair from a fresh location-search response is expected to resolve.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
catalogIdstring (uuid)YesCatalog id from GET /v1/locations.3fa85f64-5717-4562-b3fc-2c963f66afa6
offeringIdstring (uuid)YesOffering id from GET /v1/locations.3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/locations/3fa85f64-5717-4562-b3fc-2c963f66afa6/offerings/3fa85f64-5717-4562-b3fc-2c963f66afa6/products" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Single-test product for the offering.
Content type: application/json
Schema: OfferingProductsResponseDto(OfferingProductsResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "additional_note": "Appointments booking 4 months in advance. Check other locations for earlier availability. Please note that this location does not provide visceral fat (VAT) measurement.",
    "product": {
      "currency": "USD",
      "description": "Single-test body composition assessment.",
      "id": "c635751b-cd06-4350-8988-806248cbde8d",
      "integrator_price": 224.1,
      "name": "DEXA Baseline",
      "percent_off": 10,
      "product_type": "Single",
      "retail_price": 249,
      "tags": [
        {
          "id": "f8f44abc-1303-4ae1-9fd3-c822dc6ab6ef",
          "name": "Body Composition"
        }
      ],
      "test_id": "2c35ab94-518d-49b1-87d5-9d1913c395a9",
      "test_type": "DEXA"
    }
  },
  "error": null
}
400Validation failure for path parameters.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 400,
  "data": null,
  "error": {
    "details": [
      "offeringId must be a UUID"
    ],
    "message": "Validation failed (uuid is expected)",
    "path": "/v1/locations/006d1a83-ff73-4720-b53e-23af0d14f9cb/offerings/not-a-uuid/products",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Unknown offering product
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Offering product was not found",
    "path": "/v1/locations/006d1a83-ff73-4720-b53e-23af0d14f9cb/offerings/d8a21f92-e15b-4abc-886b-c2ebf0ad91f2/products",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/locations/{catalogId}/offerings/{offeringId}/schedule

Get offering schedule preview

Returns preview availability for one offering from be-v2 calendar availability for the selected test location and offering. Does not use legacy Acuity schedule preview.

When to use it

Preview availability for one offering after product selection, before direct ordering.

  • Returns a single schedule object with available_dates, not a multi-location availability array.
  • An empty available_dates array means the pair is a valid offering with no current preview availability. It is different from 404.
  • Each available_time is a full ISO-8601 datetime in the test location local time with an explicit numeric offset. It is not always UTC or Z. Preserve the returned value when submitting a scheduling request; available_date is the calendar date at the test location.
  • API Partners can reuse the same available_dates and available_times data for both the primary appointment picker and alternate availability fields.
  • When live availability is returned, the better implementation is to limit alternate availabilities to those returned slots instead of allowing arbitrary datetimes.
  • Use this alongside the offering products route when your integration follows the preferred catalog/offering flow.
  • Malformed path UUIDs return 400. A 404 means the pair is not resolvable or no longer accessible. A 503 means the calendar dependency is transiently unavailable; retry this safe GET with capped exponential backoff and jitter.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
catalogIdstring (uuid)YesCatalog id from GET /v1/locations.3fa85f64-5717-4562-b3fc-2c963f66afa6
offeringIdstring (uuid)YesOffering id from GET /v1/locations.3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/locations/3fa85f64-5717-4562-b3fc-2c963f66afa6/offerings/3fa85f64-5717-4562-b3fc-2c963f66afa6/schedule" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Schedule preview for the offering. available_time values are full ISO-8601 datetimes in the test location local time with an explicit numeric offset; they are not guaranteed to use UTC. An empty available_dates array means the offering is valid but has no preview availability.
Content type: application/json
Schema: OfferingScheduleResponseDto(OfferingScheduleResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "schedule": {
      "available_dates": [
        {
          "available_date": "2026-03-31",
          "available_times": [
            {
              "available_time": "2026-03-31T09:00:00-04:00"
            },
            {
              "available_time": "2026-03-31T09:30:00-04:00"
            }
          ]
        }
      ],
      "offering_id": "d8a21f92-e15b-4abc-886b-c2ebf0ad91f2",
      "test_type": "DEXA"
    }
  },
  "error": null
}
400Validation failure for path parameters.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 400,
  "data": null,
  "error": {
    "details": [
      "offeringId must be a UUID"
    ],
    "message": "Validation failed (uuid is expected)",
    "path": "/v1/locations/006d1a83-ff73-4720-b53e-23af0d14f9cb/offerings/not-a-uuid/products",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Unknown offering schedule
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Offering schedule was not found",
    "path": "/v1/locations/006d1a83-ff73-4720-b53e-23af0d14f9cb/offerings/d8a21f92-e15b-4abc-886b-c2ebf0ad91f2/schedule",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
503Calendar availability is temporarily unavailable. Retry this safe read with capped exponential backoff and jitter. This response does not currently guarantee a Retry-After header.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 503,
  "data": null,
  "error": {
    "details": null,
    "message": "Calendar availability is unavailable",
    "path": "/v1/locations/006d1a83-ff73-4720-b53e-23af0d14f9cb/offerings/d8a21f92-e15b-4abc-886b-c2ebf0ad91f2/schedule",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/orders

Create direct order

Creates an externally paid single-test order. Requires Idempotency-Key. Supply exactly the consent source provisioned for the API partner: consent_grant_id for Fitnescity Health-managed consent or an accepted partner_consent_evidence_id for partner-managed customer consent. The backend verifies that source before committing the order. retail_total is the retail benchmark, integrator_total is the direct-order total, and appointments_created is the number of appointments created.

When to use it

Use direct ordering only after your system has already collected payment. This route is the public write boundary for externally paid orders.

  • POST /v1/orders requires Idempotency-Key on every request.
  • Preferred payload: product_id, catalog_id, offering_id, and test_id.
  • When a product returns is_prescreening_required=true, first call GET /v1/tests/{testType}/prescreen-form, then POST /v1/tests/{testType}/prescreen-form/submissions, and finally call POST /v1/orders with the returned order_id.
  • external_payment_reference remains on POST /v1/orders even when the order was originally created by prescreen submission.
  • Store the returned order_id, order_ref, and your own external_payment_reference for reconciliation.
  • Same key plus same payload replays the original order response. Same key plus different payload returns 409.
  • For an order created through Full API Integration, an active same-key request returns 202 with data.code IDEMPOTENCY_IN_PROGRESS plus Retry-After; retry the exact same key and payload.
  • API Partners using Full API Integration must not call schedule-handoff (FLOW_ENDPOINT_MISMATCH). Send customer_identity_id or external_customer_id and exactly the provisioned consent source: consent_grant_id for the Fitnescity Health consent API or an accepted partner_consent_evidence_id for an API Partner-provided consent PDF. Complete the appointment questionnaire, then call POST /v1/appointments/{appointmentId}/schedule.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYesUnique key per logical order submission. Same key + same payload replays prior response.order-2026-03-17-0001
Request Body
Content type: application/json
Schema: CreateOrderDto(CreateOrderDto)
Example values come from the published contract example.
Hosted/minimal order
{
  "catalog_id": "006d1a83-ff73-4720-b53e-23af0d14f9cb",
  "customer": {
    "email": "avery.jordan@example.com",
    "first_name": "Avery",
    "last_name": "Jordan"
  },
  "external_payment_reference": "partner-pay-2026-0317-001",
  "offering_id": "d8a21f92-e15b-4abc-886b-c2ebf0ad91f2",
  "product_id": "c635751b-cd06-4350-8988-806248cbde8d",
  "test_id": "2c35ab94-518d-49b1-87d5-9d1913c395a9"
}
Fitnescity Health-managed consent order
{
  "catalog_id": "006d1a83-ff73-4720-b53e-23af0d14f9cb",
  "consent_grant_id": "44444444-4444-4444-8444-444444444444",
  "customer": {
    "address": {
      "address_line_1": "350 5th Ave",
      "address_line_2": "Floor 4",
      "city": "New York",
      "postal_code": "10001",
      "state": "NY"
    },
    "date_of_birth": "1988-01-02",
    "email": "ada.lovelace@example.com",
    "first_name": "Ada",
    "height": 66,
    "last_name": "Lovelace",
    "phone_number": "+1 (212) 555-1234",
    "sex": "female",
    "weight": 130
  },
  "customer_identity_id": "11111111-1111-4111-8111-111111111111",
  "external_customer_id": "member-001",
  "offering_id": "d8a21f92-e15b-4abc-886b-c2ebf0ad91f2",
  "product_id": "c635751b-cd06-4350-8988-806248cbde8d",
  "test_id": "2c35ab94-518d-49b1-87d5-9d1913c395a9"
}
Partner-managed API partner order
{
  "catalog_id": "006d1a83-ff73-4720-b53e-23af0d14f9cb",
  "customer": {
    "address": {
      "address_line_1": "350 5th Ave",
      "address_line_2": "Floor 4",
      "city": "New York",
      "postal_code": "10001",
      "state": "NY"
    },
    "date_of_birth": "1988-01-02",
    "email": "ada.lovelace@example.com",
    "first_name": "Ada",
    "height": 66,
    "last_name": "Lovelace",
    "phone_number": "+1 (212) 555-1234",
    "sex": "female",
    "weight": 130
  },
  "customer_identity_id": "11111111-1111-4111-8111-111111111111",
  "external_customer_id": "member-001",
  "offering_id": "d8a21f92-e15b-4abc-886b-c2ebf0ad91f2",
  "partner_consent_evidence_id": "55555555-5555-4555-8555-555555555555",
  "product_id": "c635751b-cd06-4350-8988-806248cbde8d",
  "test_id": "2c35ab94-518d-49b1-87d5-9d1913c395a9"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/orders" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"catalog_id":"006d1a83-ff73-4720-b53e-23af0d14f9cb","customer":{"email":"avery.jordan@example.com","first_name":"Avery","last_name":"Jordan"},"external_payment_reference":"partner-pay-2026-0317-001","offering_id":"d8a21f92-e15b-4abc-886b-c2ebf0ad91f2","product_id":"c635751b-cd06-4350-8988-806248cbde8d","test_id":"2c35ab94-518d-49b1-87d5-9d1913c395a9"}'

Responses

200Idempotent replay of an already completed order.
Content type: application/json
Schema: OrderResponseDto(OrderResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "appointments": [
      {
        "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
        "appointment_status": "Created",
        "results_status": "WaitingResults",
        "test_type": "DEXA"
      }
    ],
    "appointments_created": 1,
    "customer": {
      "email": "avery.jordan@example.com",
      "user_id": "9c7a617a-2b68-44bb-ab52-eb4fa7cd2b07"
    },
    "integrator_id": "b4b06d2f-57da-4924-ac63-1121f883ed22",
    "integrator_total": 224.1,
    "order_id": "25c53b4f-7459-4efe-a56d-72742ea37313",
    "order_ref": "FC0008123",
    "pricing_rule_type": "PERCENT_OFF",
    "pricing_rule_value": 10,
    "quest_codes": [],
    "retail_total": 249,
    "source": "integrator"
  },
  "error": null
}
201Order created.
Content type: application/json
Schema: OrderResponseDto(OrderResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointments": [
      {
        "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
        "appointment_status": "Created",
        "results_status": "WaitingResults",
        "test_type": "DEXA"
      }
    ],
    "appointments_created": 1,
    "customer": {
      "email": "avery.jordan@example.com",
      "user_id": "9c7a617a-2b68-44bb-ab52-eb4fa7cd2b07"
    },
    "integrator_id": "b4b06d2f-57da-4924-ac63-1121f883ed22",
    "integrator_total": 224.1,
    "order_id": "25c53b4f-7459-4efe-a56d-72742ea37313",
    "order_ref": "FC0008123",
    "pricing_rule_type": "PERCENT_OFF",
    "pricing_rule_value": 10,
    "quest_codes": [],
    "retail_total": 249,
    "source": "integrator"
  },
  "error": null
}
202The same Full API Integration command is still processing. Wait for Retry-After, then retry with the exact same Idempotency-Key and payload. This is a success envelope, not an error envelope.
Content type: application/json
Schema: ApiFirstIdempotencyInProgressResponseDto(ApiFirstIdempotencyInProgressResponseDto)
Contract example
Contract example
{
  "code": 202,
  "data": {
    "code": "IDEMPOTENCY_IN_PROGRESS",
    "retry_after_seconds": 7,
    "status": "in_progress"
  },
  "error": null
}
400Validation failure.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid Full API Integration customer profile
{
  "code": 400,
  "data": null,
  "error": {
    "details": {
      "code": "INVALID_CUSTOMER_PROFILE",
      "field_errors": {
        "sex": "must be male or female"
      },
      "missing_fields": [
        "date_of_birth"
      ]
    },
    "message": "API-first order customer profile is invalid",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-08-26T10:00:00.000Z"
  }
}
Missing Idempotency-Key header
{
  "code": 400,
  "data": null,
  "error": {
    "details": null,
    "message": "Idempotency-Key header is required",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
409Returned for idempotency payload conflicts or business conflicts. CONSENT_GRANT_REQUIRED means the API key uses Fitnescity Health-managed consent; finalize reusable consent and resend the original logical request with the grant. A request that is still processing returns the documented 202 response instead.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Fitnescity Health-managed consent order requires a finalized consent grant
{
  "code": 409,
  "data": null,
  "error": {
    "details": {
      "code": "CONSENT_GRANT_REQUIRED"
    },
    "message": "A finalized reusable consent grant is required for Fitnescity Health-managed customer consent before creating this order",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-08-24T10:00:00.000Z"
  }
}
Same idempotency key reused with a different payload
{
  "code": 409,
  "data": null,
  "error": {
    "details": null,
    "message": "Idempotency key is already in use with a different payload",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Existing API-first identity is incomplete
{
  "code": 409,
  "data": null,
  "error": {
    "details": {
      "code": "PROFILE_INCOMPLETE",
      "missing_fields": [
        "phone_number"
      ]
    },
    "message": "Customer identity must be completed before creating an order",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-08-26T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/orders/{orderId}/schedule-handoff

Create schedule handoff

Generates an opaque, customer-facing scheduling handoff URL for an existing direct order. Treat the returned url as opaque. API partners must not construct or parse portal scheduling routes manually. Use presentation_mode=iframe only for web embeds; omit it or use hosted_page for standard browser opens and native WebViews. A retry with the same Idempotency-Key and identical request payload returns the original URL and expiry. If that link has expired, use a new Idempotency-Key to mint a new link. Reusing a key with a different payload returns 409.

When to use it

Use this after direct-order creation to generate the member-facing URL that takes the member into a co-branded Fitnescity Health-hosted scheduling experience.

  • Requires Idempotency-Key on every request (max 128 chars, allowed charset [A-Za-z0-9_-]).
  • Required request fields: selected_appointment_date, alternate_availabilities, and customer_data.
  • A retry with the same Idempotency-Key and identical payload replays the original URL and expiry. If that link has expired, use a new Idempotency-Key to mint a new one. Reusing a key with a different payload returns 409.
  • Optional presentation_mode accepts hosted_page or iframe. Omit it to use the default hosted_page behavior.
  • Required customer_data fields: first_name, last_name, phone, date_of_birth, sex_assigned_at_birth, address_line_1, city, state, postal_code, height, and weight.
  • customer_data.phone must be a valid 10 or 11 digit number, customer_data.date_of_birth must stay within the 16 to 100 age window, and customer_data.weight must be whole-number pounds.
  • Send selected_appointment_date together with 1 to 3 alternate_availabilities sourced from the live schedule preview.
  • Use presentation_mode=iframe only for web embeds. Native and hybrid apps should still use the hosted_page URL inside a full-screen in-app WebView.
  • Treat the returned URL as opaque. Do not construct scheduling routes manually.
  • Use the handoff URL as the primary member-facing next step after direct-order creation.
  • The handoff URL is member-facing and expiring, so persist it with the associated order metadata if you need to show or resend it later.
  • The member reviews the API Partner-selected slot, completes consent, and confirms the appointment within the Fitnescity Health-hosted flow. If they need a different slot, send them back to your own app to choose again from current availability.
  • If any required schedule-handoff field is missing or blank, expect a 400 validation error.
  • Optional return_url sends members back to your app after scheduling completes. The host must be in allowed_redirect_domains and is revalidated before redirect.
  • Optional member_profile_url powers Return to profile and exit navigation in the hosted flow. The host must be in allowed_redirect_domains.
  • customer_data should include the required hosted-scheduling member fields your app already collected, including name, phone, date of birth, sex assigned at birth, address, height, and weight.
  • When customer_data includes height or weight, send height in inches and weight in pounds.
  • Malformed orderId path values return 400. Orders outside the calling API Partner scope return 404.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYesUnique key for safe retries. Max 128 chars, allowed charset [A-Za-z0-9_-].order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
orderIdstring (uuid)YesDirect-order id returned by POST /v1/orders.3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: ScheduleHandoffRequestDto(ScheduleHandoffRequestDto)
Example values come from the published contract example.
default
{
  "alternate_availabilities": [
    "2026-04-03T11:00:00-04:00",
    "2026-04-04T09:00:00-04:00"
  ],
  "customer_data": {
    "address_line_1": "350 5th Ave",
    "city": "New York",
    "date_of_birth": "1992-08-14",
    "first_name": "Avery",
    "height": 70,
    "last_name": "Jordan",
    "phone": "+12125551234",
    "postal_code": "10001",
    "sex_assigned_at_birth": "Female",
    "state": "NY",
    "weight": 165
  },
  "member_profile_url": "https://app.partnerco.com/member/assessments",
  "presentation_mode": "iframe",
  "return_url": "https://app.partnerco.com/scheduling/complete",
  "selected_appointment_date": "2026-04-03T10:00:00-04:00",
  "ui_controls": {
    "hide_change": false,
    "hide_exit": false,
    "hide_return_to_profile": false
  }
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/orders/3fa85f64-5717-4562-b3fc-2c963f66afa6/schedule-handoff" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"alternate_availabilities":["2026-04-03T11:00:00-04:00","2026-04-04T09:00:00-04:00"],"customer_data":{"address_line_1":"350 5th Ave","city":"New York","date_of_birth":"1992-08-14","first_name":"Avery","height":70,"last_name":"Jordan","phone":"+12125551234","postal_code":"10001","sex_assigned_at_birth":"Female","state":"NY","weight":165},"member_profile_url":"https://app.partnerco.com/member/assessments","presentation_mode":"iframe","return_url":"https://app.partnerco.com/scheduling/complete","selected_appointment_date":"2026-04-03T10:00:00-04:00","ui_controls":{"hide_change":false,"hide_exit":false,"hide_return_to_profile":false}}'

Responses

201Schedule handoff URL created successfully.
Content type: application/json
Schema: ScheduleHandoffResponseDto(ScheduleHandoffResponseDto)
Contract example
New schedule handoff URL
{
  "code": 201,
  "data": {
    "expires_at_iso": "2026-04-03T10:00:00.000Z",
    "expires_at_unix": 1775200800,
    "url": "https://my.fitnescity.com/handoff/schedule#token=abc"
  },
  "error": null
}
Idempotent replay of the original URL and expiry
{
  "code": 201,
  "data": {
    "expires_at_iso": "2026-04-03T10:00:00.000Z",
    "expires_at_unix": 1775200800,
    "url": "https://my.fitnescity.com/handoff/schedule#token=abc"
  },
  "error": null
}
400Validation failure for the order path parameter.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 400,
  "data": null,
  "error": {
    "details": null,
    "message": "Idempotency-Key header is required",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Order not found for this API partner
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Order was not found",
    "path": "/v1/orders/25c53b4f-7459-4efe-a56d-72742ea37313/schedule-handoff",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
409The Idempotency-Key is already associated with a different schedule-handoff payload, or no schedulable appointments remain for the order.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 409,
  "data": null,
  "error": {
    "details": {
      "code": "IDEMPOTENCY_CONFLICT"
    },
    "message": "Idempotency key is already in use with a different payload",
    "path": "/v1/orders/25c53b4f-7459-4efe-a56d-72742ea37313/schedule-handoff",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/redirects

Create checkout redirect

Generates a signed referral redirect URL for Fitnescity Health checkout after validating that the referenced location and product exist. Treat redirect_url as opaque. Redirect checkout always shows retail customer pricing.

When to use it

Use redirects when Fitnescity Health should collect payment and own the checkout flow.

  • Redirect tokens preserve source attribution into the Fitnescity Health checkout experience.
  • Members see retail member pricing in redirect mode.
  • Invalid location_id or product_id payload values return 400 before any token is issued.
  • A 201 response means the redirect token was created for an existing location and existing product. The route does not validate full compatibility beyond those references.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Request Body
Content type: application/json
Schema: RedirectCreateDto(RedirectCreateDto)
Example values come from the published contract example.
default
{
  "location_id": "cee4ea3a-801c-11ed-8926-12fa9030d819",
  "product_id": "c635751b-cd06-4350-8988-806248cbde8d"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/redirects" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Content-Type: application/json" \
  -d '{"location_id":"cee4ea3a-801c-11ed-8926-12fa9030d819","product_id":"c635751b-cd06-4350-8988-806248cbde8d"}'

Responses

201Redirect token created successfully.
Content type: application/json
Schema: RedirectResponseDto(RedirectResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "expires_at_iso": "2026-03-31T12:00:00.000Z",
    "expires_at_unix": 1774843200,
    "redirect_url": "https://my.fitnescity.com/c635751b-cd06-4350-8988-806248cbde8d?ref=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  },
  "error": null
}
400Validation failure for the redirect request payload.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 400,
  "data": null,
  "error": {
    "details": [
      "location_id must be a UUID",
      "product_id must be a UUID"
    ],
    "message": "location_id must be a UUID, product_id must be a UUID",
    "path": "/v1/redirects",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Location or product not found
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Location or product was not found",
    "path": "/v1/redirects",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/results

Get customer results

Returns allowlisted result records scoped to the calling API partner, with offset pagination metadata. returned_count is the size of the current page, not the total number of matching records.

When to use it

Poll result records after Fitnescity Health has completed downstream processing for the order or appointment.

  • Use polling for result payload retrieval, or subscribe to the appointment.results_ready webhook event for push notification when results are available.
  • Use order_id or appointment_id when possible for deterministic reconciliation.
  • Each result item also includes has_signed_form and followup_call_schedule_link alongside the appointment and order identifiers.
  • When has_signed_form is true, call GET /v1/appointments/{appointmentId}/signed-form only when the member actually needs the download URL.
  • followup_call_schedule_link is a separate member-facing physician follow-up call URL that your API Partner app can surface when present.
  • For DEXA and DEXABMD records whose results_status is finalized, call GET /v1/appointments/{appointmentId}/report to download the underlying report PDF.
  • Each result item includes a sibling result_units object keyed exactly like results.
  • Numeric result fields are returned as JSON numbers. For unit-sensitive fields, values are returned only when source units can be mapped to the public API contract; use result_units as the source of truth for returned units and null-unit fields.
  • The results object contains only the allowlisted fields approved for public API Partner access.
  • returned_count is the number of records in the current page, not the total available record count.
  • Invalid pagination or malformed UUID query filters return 400.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Query Parameters
NameTypeRequiredDescriptionExample
emailstringNoFilter by customer email.john.doe@example.com
order_idstring (uuid)NoFilter by order id.3fa85f64-5717-4562-b3fc-2c963f66afa6
appointment_idstring (uuid)NoFilter by appointment id.3fa85f64-5717-4562-b3fc-2c963f66afa6
limitnumberNoMaximum number of records.100
offsetnumberNoOffset for pagination.0
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/results?email=john.doe%40example.com&limit=100&offset=0" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Results list for the calling API partner.
Content type: application/json
Schema: ResultsResponseDto(ResultsResponseDto)
Contract example
BOD POD result
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
        "appointment_status": "Completed",
        "created_at": "2026-03-17T12:45:00.000Z",
        "customer": {
          "email": "avery.jordan@example.com",
          "first_name": "Avery",
          "last_name": "Jordan",
          "user_id": "9c7a617a-2b68-44bb-ab52-eb4fa7cd2b07"
        },
        "followup_call_schedule_link": "https://fitnescity.as.me/schedule/5b9f2dea?calendarIds=9785917",
        "has_signed_form": true,
        "order_id": "25c53b4f-7459-4efe-a56d-72742ea37313",
        "result_units": {
          "bmi": null,
          "body_fat_percentage": "%",
          "body_fat_percentile": null,
          "lean_mass": "lbs",
          "lean_mass_percentage": "%",
          "population_body_fat_avg": "%",
          "sex_assigned_at_birth": null,
          "total_fat_mass": "lbs",
          "z_score": null
        },
        "results": {
          "bmi": 24.6,
          "body_fat_percentage": 22.1,
          "body_fat_percentile": 58,
          "lean_mass": 118.1,
          "lean_mass_percentage": 77.9,
          "population_body_fat_avg": 26.8,
          "sex_assigned_at_birth": "Female",
          "total_fat_mass": 33.4,
          "z_score": -0.3
        },
        "results_status": "finalized",
        "sent_date": "2026-03-20T15:30:00.000Z",
        "test_type": "BODPOD"
      }
    ],
    "pagination": {
      "has_more": false,
      "limit": 25,
      "offset": 0,
      "returned_count": 1
    }
  },
  "error": null
}
CT calcium score result
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
        "appointment_status": "Completed",
        "created_at": "2026-03-17T12:45:00.000Z",
        "customer": {
          "email": "avery.jordan@example.com",
          "first_name": "Avery",
          "last_name": "Jordan",
          "user_id": "9c7a617a-2b68-44bb-ab52-eb4fa7cd2b07"
        },
        "followup_call_schedule_link": "https://fitnescity.as.me/schedule/5b9f2dea?calendarIds=9785917",
        "has_signed_form": true,
        "order_id": "25c53b4f-7459-4efe-a56d-72742ea37313",
        "result_units": {
          "bmi": null,
          "left_anterior_descending": null,
          "left_circumflex": null,
          "left_main": null,
          "percentile": null,
          "right_coronary_artery": null,
          "sex_assigned_at_birth": null,
          "total_score": null,
          "upper_percentile": null
        },
        "results": {
          "bmi": 24.8,
          "left_anterior_descending": 72,
          "left_circumflex": 26,
          "left_main": 18,
          "percentile": 82,
          "right_coronary_artery": 62,
          "sex_assigned_at_birth": "Male",
          "total_score": 178,
          "upper_percentile": 89
        },
        "results_status": "finalized",
        "sent_date": "2026-03-20T15:30:00.000Z",
        "test_type": "CALST"
      }
    ],
    "pagination": {
      "has_more": false,
      "limit": 25,
      "offset": 0,
      "returned_count": 1
    }
  },
  "error": null
}
DEXA bone density result
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
        "appointment_status": "Completed",
        "created_at": "2026-03-17T12:45:00.000Z",
        "customer": {
          "email": "avery.jordan@example.com",
          "first_name": "Avery",
          "last_name": "Jordan",
          "user_id": "9c7a617a-2b68-44bb-ab52-eb4fa7cd2b07"
        },
        "followup_call_schedule_link": "https://fitnescity.as.me/schedule/5b9f2dea?calendarIds=9785917",
        "has_signed_form": true,
        "order_id": "25c53b4f-7459-4efe-a56d-72742ea37313",
        "result_units": {
          "bmd": "g/cm2",
          "bmd_percentile": null,
          "bmi": null,
          "hip_fracture": "%",
          "major_osteoporotic_fracture": "%",
          "neck_area": "cm2",
          "neck_bmc": "g",
          "neck_bmd": "g/cm2",
          "neck_t_score": null,
          "neck_total_area": "cm2",
          "neck_total_bmc": "g",
          "neck_total_bmd": "g/cm2",
          "neck_total_t_score": null,
          "neck_total_z_score": null,
          "neck_z_score": null,
          "sex_assigned_at_birth": null,
          "spine_l_four_area": "cm2",
          "spine_l_four_bmc": "g",
          "spine_l_four_bmd": "g/cm2",
          "spine_l_four_t_score": null,
          "spine_l_four_z_score": null,
          "spine_l_one_area": "cm2",
          "spine_l_one_bmc": "g",
          "spine_l_one_bmd": "g/cm2",
          "spine_l_one_t_score": null,
          "spine_l_one_z_score": null,
          "spine_l_three_area": "cm2",
          "spine_l_three_bmc": "g",
          "spine_l_three_bmd": "g/cm2",
          "spine_l_three_t_score": null,
          "spine_l_three_z_score": null,
          "spine_l_two_area": "cm2",
          "spine_l_two_bmc": "g",
          "spine_l_two_bmd": "g/cm2",
          "spine_l_two_t_score": null,
          "spine_l_two_z_score": null,
          "spine_total_area": "cm2",
          "spine_total_bmc": "g",
          "spine_total_bmd": "g/cm2",
          "spine_total_t_score": null,
          "spine_total_z_score": null,
          "z_score": null
        },
        "results": {
          "bmd": 1.03,
          "bmd_percentile": 51,
          "bmi": 22.6,
          "hip_fracture": ">0.1",
          "major_osteoporotic_fracture": "2.8",
          "neck_area": 5.1,
          "neck_bmc": 3.2,
          "neck_bmd": 0.87,
          "neck_t_score": -0.1,
          "neck_total_area": 9.7,
          "neck_total_bmc": 6.2,
          "neck_total_bmd": 0.86,
          "neck_total_t_score": -0.2,
          "neck_total_z_score": 0.1,
          "neck_z_score": 0.2,
          "sex_assigned_at_birth": "Male",
          "spine_l_four_area": 2.4,
          "spine_l_four_bmc": 1.4,
          "spine_l_four_bmd": 0.83,
          "spine_l_four_t_score": 0,
          "spine_l_four_z_score": 0.2,
          "spine_l_one_area": 2.1,
          "spine_l_one_bmc": 1.1,
          "spine_l_one_bmd": 0.8,
          "spine_l_one_t_score": -0.2,
          "spine_l_one_z_score": 0.1,
          "spine_l_three_area": 2.3,
          "spine_l_three_bmc": 1.3,
          "spine_l_three_bmd": 0.82,
          "spine_l_three_t_score": -0.1,
          "spine_l_three_z_score": 0.2,
          "spine_l_two_area": 2.2,
          "spine_l_two_bmc": 1.2,
          "spine_l_two_bmd": 0.81,
          "spine_l_two_t_score": -0.1,
          "spine_l_two_z_score": 0.1,
          "spine_total_area": 9,
          "spine_total_bmc": 5,
          "spine_total_bmd": 0.84,
          "spine_total_t_score": -0.1,
          "spine_total_z_score": 0.2,
          "z_score": -0.4
        },
        "results_status": "finalized",
        "sent_date": "2026-03-20T15:30:00.000Z",
        "test_type": "DEXABMD"
      }
    ],
    "pagination": {
      "has_more": false,
      "limit": 25,
      "offset": 0,
      "returned_count": 1
    }
  },
  "error": null
}
DEXA body composition result (LIMITED)
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
        "appointment_status": "Completed",
        "created_at": "2026-03-17T12:45:00.000Z",
        "customer": {
          "email": "avery.jordan@example.com",
          "first_name": "Avery",
          "last_name": "Jordan",
          "user_id": "9c7a617a-2b68-44bb-ab52-eb4fa7cd2b07"
        },
        "followup_call_schedule_link": "https://fitnescity.as.me/schedule/5b9f2dea?calendarIds=9785917",
        "has_signed_form": true,
        "order_id": "25c53b4f-7459-4efe-a56d-72742ea37313",
        "result_units": {
          "age_group": null,
          "android_fat": "lbs",
          "android_lean": "lbs",
          "bmd": "g/cm2",
          "bmd_percentile": null,
          "bmi": null,
          "body_fat_percentage": "%",
          "body_fat_percentile": null,
          "gynoid_fat": "lbs",
          "gynoid_lean": "lbs",
          "height": "in",
          "left_arm_bmc": "g",
          "left_arm_fat_mass": "lbs",
          "left_arm_lean_and_bmc": "lbs",
          "left_leg_bmc": "g",
          "left_leg_fat_mass": "lbs",
          "left_leg_lean_and_bmc": "lbs",
          "race": null,
          "result_type": null,
          "right_arm_bmc": "g",
          "right_arm_fat_mass": "lbs",
          "right_arm_lean_and_bmc": "lbs",
          "right_leg_bmc": "g",
          "right_leg_fat_mass": "lbs",
          "right_leg_lean_and_bmc": "lbs",
          "sex_assigned_at_birth": null,
          "total_body_weight": "lbs",
          "total_bone_mass": "lbs",
          "total_fat_mass": "lbs",
          "total_lean_and_bmc": "lbs",
          "total_mass": "lbs",
          "vat_fat_mass": "lbs",
          "vat_volume": "in3",
          "z_score": null
        },
        "results": {
          "age_group": "30-39",
          "android_fat": 5.4,
          "android_lean": 12,
          "bmd": 1.074,
          "bmd_percentile": 56,
          "bmi": 24.2,
          "body_fat_percentage": 19.2,
          "body_fat_percentile": 49,
          "gynoid_fat": 7.5,
          "gynoid_lean": 15.8,
          "height": 70,
          "left_arm_bmc": 0.6,
          "left_arm_fat_mass": 2.1,
          "left_arm_lean_and_bmc": 9,
          "left_leg_bmc": 1.5,
          "left_leg_fat_mass": 6.8,
          "left_leg_lean_and_bmc": 25.6,
          "race": "White",
          "result_type": "LIMITED",
          "right_arm_bmc": 0.6,
          "right_arm_fat_mass": 2.2,
          "right_arm_lean_and_bmc": 8.9,
          "right_leg_bmc": 1.5,
          "right_leg_fat_mass": 6.7,
          "right_leg_lean_and_bmc": 25.9,
          "sex_assigned_at_birth": "Female",
          "total_body_weight": 151,
          "total_bone_mass": 6.9,
          "total_fat_mass": 29.1,
          "total_lean_and_bmc": 132.6,
          "total_mass": 151,
          "vat_fat_mass": 1.5,
          "vat_volume": 95,
          "z_score": 0.3
        },
        "results_status": "finalized",
        "sent_date": "2026-03-20T15:30:00.000Z",
        "test_type": "DEXA"
      }
    ],
    "pagination": {
      "has_more": false,
      "limit": 25,
      "offset": 0,
      "returned_count": 1
    }
  },
  "error": null
}
DEXA body composition result (STANDARD)
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
        "appointment_status": "Completed",
        "created_at": "2026-03-17T12:45:00.000Z",
        "customer": {
          "email": "avery.jordan@example.com",
          "first_name": "Avery",
          "last_name": "Jordan",
          "user_id": "9c7a617a-2b68-44bb-ab52-eb4fa7cd2b07"
        },
        "followup_call_schedule_link": "https://fitnescity.as.me/schedule/5b9f2dea?calendarIds=9785917",
        "has_signed_form": true,
        "order_id": "25c53b4f-7459-4efe-a56d-72742ea37313",
        "result_units": {
          "age_group": null,
          "android_fat": "lbs",
          "android_fat_percentage": "%",
          "android_lean": "lbs",
          "android_lean_percentage": "%",
          "bmd": "g/cm2",
          "bmd_percentile": null,
          "bmi": null,
          "body_fat_percentage": "%",
          "body_fat_percentile": null,
          "gynoid_fat": "lbs",
          "gynoid_fat_percentage": "%",
          "gynoid_lean": "lbs",
          "height": "in",
          "lean_mass_percentage": "%",
          "left_arm_fat_mass": "lbs",
          "left_arm_lean_mass": "lbs",
          "left_leg_fat_mass": "lbs",
          "left_leg_lean_mass": "lbs",
          "race": null,
          "result_type": null,
          "right_arm_fat_mass": "lbs",
          "right_arm_lean_mass": "lbs",
          "right_leg_fat_mass": "lbs",
          "right_leg_lean_mass": "lbs",
          "sex_assigned_at_birth": null,
          "total_body_weight": "lbs",
          "total_bone_mass": "lbs",
          "total_fat_mass": "lbs",
          "total_lean_mass": "lbs",
          "total_mass": "lbs",
          "vat_fat_mass": "lbs",
          "vat_volume": "in3",
          "z_score": null
        },
        "results": {
          "age_group": "30-39",
          "android_fat": 5.2,
          "android_fat_percentage": 28.1,
          "android_lean": 12.1,
          "android_lean_percentage": 71.9,
          "bmd": 1.081,
          "bmd_percentile": 58,
          "bmi": 24.2,
          "body_fat_percentage": 18.4,
          "body_fat_percentile": 46,
          "gynoid_fat": 7.3,
          "gynoid_fat_percentage": 31.7,
          "gynoid_lean": 15.9,
          "height": 70,
          "lean_mass_percentage": 81.6,
          "left_arm_fat_mass": 2.1,
          "left_arm_lean_mass": 8.4,
          "left_leg_fat_mass": 6.7,
          "left_leg_lean_mass": 24.1,
          "race": "White",
          "result_type": "STANDARD",
          "right_arm_fat_mass": 2.2,
          "right_arm_lean_mass": 8.3,
          "right_leg_fat_mass": 6.6,
          "right_leg_lean_mass": 24.4,
          "sex_assigned_at_birth": "Female",
          "total_body_weight": 151,
          "total_bone_mass": 6.8,
          "total_fat_mass": 27.8,
          "total_lean_mass": 123.4,
          "total_mass": 151,
          "vat_fat_mass": 1.4,
          "vat_volume": 92,
          "z_score": 0.4
        },
        "results_status": "finalized",
        "sent_date": "2026-03-20T15:30:00.000Z",
        "test_type": "DEXA"
      }
    ],
    "pagination": {
      "has_more": false,
      "limit": 25,
      "offset": 0,
      "returned_count": 1
    }
  },
  "error": null
}
Hydrostatic result
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
        "appointment_status": "Completed",
        "created_at": "2026-03-17T12:45:00.000Z",
        "customer": {
          "email": "avery.jordan@example.com",
          "first_name": "Avery",
          "last_name": "Jordan",
          "user_id": "9c7a617a-2b68-44bb-ab52-eb4fa7cd2b07"
        },
        "followup_call_schedule_link": "https://fitnescity.as.me/schedule/5b9f2dea?calendarIds=9785917",
        "has_signed_form": true,
        "order_id": "25c53b4f-7459-4efe-a56d-72742ea37313",
        "result_units": {
          "bmi": null,
          "body_density": "Kg/L",
          "body_fat_percentage": "%",
          "body_fat_percentile": null,
          "fat_free_mass": "lbs",
          "fat_free_mass_percentage": "%",
          "fat_mass": "lbs",
          "lung_volume": "L",
          "population_body_fat_avg": "%",
          "sex_assigned_at_birth": null,
          "total_mass": "lbs",
          "water_temperature": "°C",
          "z_score": null
        },
        "results": {
          "bmi": 23.8,
          "body_density": 1.071,
          "body_fat_percentage": 17.6,
          "body_fat_percentile": 41,
          "fat_free_mass": 138.4,
          "fat_free_mass_percentage": 82.4,
          "fat_mass": 29.6,
          "lung_volume": 1.2,
          "population_body_fat_avg": 21.2,
          "sex_assigned_at_birth": "Male",
          "total_mass": 168,
          "water_temperature": 92,
          "z_score": 0.2
        },
        "results_status": "finalized",
        "sent_date": "2026-03-20T15:30:00.000Z",
        "test_type": "HYDROSTATIC"
      }
    ],
    "pagination": {
      "has_more": false,
      "limit": 25,
      "offset": 0,
      "returned_count": 1
    }
  },
  "error": null
}
RMR result
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
        "appointment_status": "Completed",
        "created_at": "2026-03-17T12:45:00.000Z",
        "customer": {
          "email": "avery.jordan@example.com",
          "first_name": "Avery",
          "last_name": "Jordan",
          "user_id": "9c7a617a-2b68-44bb-ab52-eb4fa7cd2b07"
        },
        "followup_call_schedule_link": "https://fitnescity.as.me/schedule/5b9f2dea?calendarIds=9785917",
        "has_signed_form": true,
        "order_id": "25c53b4f-7459-4efe-a56d-72742ea37313",
        "result_units": {
          "bmi": null,
          "estimated_ree": "kcal/day",
          "measured_rmr": "kcal/day",
          "rer": null,
          "sex_assigned_at_birth": null
        },
        "results": {
          "bmi": 24,
          "estimated_ree": 1540,
          "measured_rmr": 1675,
          "rer": 0.86,
          "sex_assigned_at_birth": "Male"
        },
        "results_status": "finalized",
        "sent_date": "2026-03-20T15:30:00.000Z",
        "test_type": "RMR"
      }
    ],
    "pagination": {
      "has_more": false,
      "limit": 25,
      "offset": 0,
      "returned_count": 1
    }
  },
  "error": null
}
SECA result
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
        "appointment_status": "Completed",
        "created_at": "2026-03-17T12:45:00.000Z",
        "customer": {
          "email": "avery.jordan@example.com",
          "first_name": "Avery",
          "last_name": "Jordan",
          "user_id": "9c7a617a-2b68-44bb-ab52-eb4fa7cd2b07"
        },
        "followup_call_schedule_link": "https://fitnescity.as.me/schedule/5b9f2dea?calendarIds=9785917",
        "has_signed_form": true,
        "order_id": "25c53b4f-7459-4efe-a56d-72742ea37313",
        "result_units": {
          "bmi": null,
          "body_fat_percentage": "%",
          "body_water_percentage": "%",
          "ecw_tbw_ratio": "%",
          "fat_free_mass": "lbs",
          "fat_free_mass_percentage": "%",
          "fat_mass": "lbs",
          "fmi": "kg/m2",
          "sex_assigned_at_birth": null,
          "vat": "L",
          "waist_circumference": "in"
        },
        "results": {
          "bmi": 25.3,
          "body_fat_percentage": 28.7,
          "body_water_percentage": 51.4,
          "ecw_tbw_ratio": 38.1,
          "fat_free_mass": 104.8,
          "fat_free_mass_percentage": 71.3,
          "fat_mass": 42.2,
          "fmi": 7.4,
          "sex_assigned_at_birth": "Female",
          "vat": 1.1,
          "waist_circumference": 31.8
        },
        "results_status": "finalized",
        "sent_date": "2026-03-20T15:30:00.000Z",
        "test_type": "SECA"
      }
    ],
    "pagination": {
      "has_more": false,
      "limit": 25,
      "offset": 0,
      "returned_count": 1
    }
  },
  "error": null
}
VO2 max result
{
  "code": 200,
  "data": {
    "items": [
      {
        "appointment_id": "6256b5fe-2d81-4db7-b389-1bbd3f03a560",
        "appointment_status": "Completed",
        "created_at": "2026-03-17T12:45:00.000Z",
        "customer": {
          "email": "avery.jordan@example.com",
          "first_name": "Avery",
          "last_name": "Jordan",
          "user_id": "9c7a617a-2b68-44bb-ab52-eb4fa7cd2b07"
        },
        "followup_call_schedule_link": "https://fitnescity.as.me/schedule/5b9f2dea?calendarIds=9785917",
        "has_signed_form": true,
        "order_id": "25c53b4f-7459-4efe-a56d-72742ea37313",
        "result_units": {
          "aerobic_hr": "bpm",
          "aerobic_mets": "METs",
          "aerobic_vo2": "ml O2/kg/min",
          "age_group": null,
          "anaerobic_hr": "bpm",
          "anaerobic_vo2": "ml O2/kg/min",
          "bmi": null,
          "hrr_one_min": "bpm",
          "hrr_one_min_diff": "bpm",
          "hrr_one_min_percentage": "%",
          "hrr_two_min": "bpm",
          "hrr_two_min_diff": "bpm",
          "hrr_two_min_percentage": "%",
          "max_hr": "bpm",
          "max_vo2": "ml O2/kg/min",
          "peak_mets": "METs",
          "sex_assigned_at_birth": null,
          "starting_hr": "bpm",
          "starting_mets": "METs",
          "starting_vo2": "ml O2/kg/min",
          "test_type": null
        },
        "results": {
          "aerobic_hr": 129,
          "aerobic_mets": 7.5,
          "aerobic_vo2": 26.1,
          "age_group": "30-39",
          "anaerobic_hr": 158,
          "anaerobic_vo2": 34.8,
          "bmi": 23.1,
          "hrr_one_min": 162,
          "hrr_one_min_diff": 24,
          "hrr_one_min_percentage": 45,
          "hrr_two_min": 145,
          "hrr_two_min_diff": 17,
          "hrr_two_min_percentage": 68,
          "max_hr": 186,
          "max_vo2": 41.2,
          "peak_mets": 11.8,
          "sex_assigned_at_birth": "Female",
          "starting_hr": 74,
          "starting_mets": 1.2,
          "starting_vo2": 4.2,
          "test_type": "Treadmill"
        },
        "results_status": "finalized",
        "sent_date": "2026-03-20T15:30:00.000Z",
        "test_type": "VO2"
      }
    ],
    "pagination": {
      "has_more": false,
      "limit": 25,
      "offset": 0,
      "returned_count": 1
    }
  },
  "error": null
}
400Validation failure for results query parameters.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 400,
  "data": null,
  "error": {
    "details": [
      "limit must not be less than 1"
    ],
    "message": "limit must not be less than 1",
    "path": "/v1/results?limit=-1",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

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

Get test prescreen form definition

When to use it

Load the public prescreen form contract for a test type before building your own eligibility UI.

  • Use this route only when the selected product returned is_prescreening_required=true.
  • The response contains required_fields, validation_rules, and a renderable copy contract so your app can render the form and show the same validation messages before submission.
  • Use copy.sections to render the recommended labels and section grouping, including Risk Factors and Symptoms & Medical History.
  • Render fields and sections in the returned array order.
  • For control=date_parts, render separate month/day/year inputs but submit dob in MM/DD/YYYY format.
  • For control=boolean_radio, render the returned options in the provided order.
  • Display copy.consent.label and submit_button_text verbatim unless you have an approved reason to override the wording.
  • Use copy.consent and submit_button_text instead of inventing your own checkbox or CTA copy for the API Partner UI.
  • validation_rules includes field-level messages plus group-level rules such as at-least-one eligibility requirements when applicable.
  • Unsupported test types return 404.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
testTypestringYes—string
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/tests/string/prescreen-form" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Static test prescreen form definition.
Content type: application/json
Schema: PrescreenFormResponseDto(PrescreenFormResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "copy": {
      "consent": {},
      "sections": [
        {}
      ],
      "submit_button_text": "string"
    },
    "required_fields": [
      "string"
    ],
    "validation_rules": {
      "example_key": "example_value"
    }
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

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

Submit test prescreen form

Submit CALST prescreen answers after identity. Supply the provisioned consent source: consent_grant_id for Fitnescity Health-managed consent or an accepted partner_consent_evidence_id for partner-managed customer consent. The backend verifies it before creating the prescreen order. Both paths retain prescreen.pcp_consent when the form requires it.

When to use it

Submit prescreen answers for a prescreen-required test type before final direct-order confirmation.

  • Requires Idempotency-Key on every request because this route creates the underlying order when validation succeeds.
  • Use the same customer and product context you plan to use for POST /v1/orders.
  • When validation fails, the error envelope includes details.field_errors and details.group_errors for direct frontend display.
  • On success, persist the returned order_id and send that order_id to POST /v1/orders along with your external_payment_reference.
  • API Partners using Full API Integration for Calcium Score (CALST in API requests) must also send customer_identity_id or external_customer_id and exactly the provisioned consent source: consent_grant_id or an accepted partner_consent_evidence_id. The prescreen.pcp_consent field is independent of customer-consent evidence and reusable Fitnescity Health consent.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Idempotency-KeystringYesUnique key per logical prescreen submission. Same key + same payload replays prior response.order-2026-03-17-0001
Path Parameters
NameTypeRequiredDescriptionExample
testTypestringYes—string
Request Body
Content type: application/json
Schema: PrescreenSubmissionDto(PrescreenSubmissionDto)
Example values come from the published contract example.
Hosted/minimal CALST prescreen
{
  "catalog_id": "006d1a83-ff73-4720-b53e-23af0d14f9cb",
  "customer": {
    "email": "avery.jordan@example.com",
    "first_name": "Avery",
    "last_name": "Jordan"
  },
  "offering_id": "d8a21f92-e15b-4abc-886b-c2ebf0ad91f2",
  "prescreen": {
    "pcp_consent": true
  },
  "product_id": "c635751b-cd06-4350-8988-806248cbde8d",
  "test_id": "2c35ab94-518d-49b1-87d5-9d1913c395a9"
}
Fitnescity Health-managed consent CALST prescreen
{
  "catalog_id": "006d1a83-ff73-4720-b53e-23af0d14f9cb",
  "consent_grant_id": "44444444-4444-4444-8444-444444444444",
  "customer": {
    "address": {
      "address_line_1": "350 5th Ave",
      "address_line_2": "Floor 4",
      "city": "New York",
      "postal_code": "10001",
      "state": "NY"
    },
    "date_of_birth": "1988-01-02",
    "email": "ada.lovelace@example.com",
    "first_name": "Ada",
    "height": 66,
    "last_name": "Lovelace",
    "phone_number": "+1 (212) 555-1234",
    "sex": "female",
    "weight": 130
  },
  "customer_identity_id": "11111111-1111-4111-8111-111111111111",
  "external_customer_id": "member-001",
  "offering_id": "d8a21f92-e15b-4abc-886b-c2ebf0ad91f2",
  "prescreen": {
    "pcp_consent": true
  },
  "product_id": "c635751b-cd06-4350-8988-806248cbde8d",
  "test_id": "2c35ab94-518d-49b1-87d5-9d1913c395a9"
}
Partner-managed API partner CALST prescreen
{
  "catalog_id": "006d1a83-ff73-4720-b53e-23af0d14f9cb",
  "customer": {
    "address": {
      "address_line_1": "350 5th Ave",
      "address_line_2": "Floor 4",
      "city": "New York",
      "postal_code": "10001",
      "state": "NY"
    },
    "date_of_birth": "1988-01-02",
    "email": "ada.lovelace@example.com",
    "first_name": "Ada",
    "height": 66,
    "last_name": "Lovelace",
    "phone_number": "+1 (212) 555-1234",
    "sex": "female",
    "weight": 130
  },
  "customer_identity_id": "11111111-1111-4111-8111-111111111111",
  "external_customer_id": "member-001",
  "offering_id": "d8a21f92-e15b-4abc-886b-c2ebf0ad91f2",
  "partner_consent_evidence_id": "55555555-5555-4555-8555-555555555555",
  "prescreen": {
    "pcp_consent": true
  },
  "product_id": "c635751b-cd06-4350-8988-806248cbde8d",
  "test_id": "2c35ab94-518d-49b1-87d5-9d1913c395a9"
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/tests/string/prescreen-form/submissions" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Idempotency-Key: order-2026-03-17-0001" \
  -H "Content-Type: application/json" \
  -d '{"catalog_id":"006d1a83-ff73-4720-b53e-23af0d14f9cb","customer":{"email":"avery.jordan@example.com","first_name":"Avery","last_name":"Jordan"},"offering_id":"d8a21f92-e15b-4abc-886b-c2ebf0ad91f2","prescreen":{"pcp_consent":true},"product_id":"c635751b-cd06-4350-8988-806248cbde8d","test_id":"2c35ab94-518d-49b1-87d5-9d1913c395a9"}'

Responses

201Prescreen accepted and order created.
Content type: application/json
Schema: OrderResponseDto(OrderResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "appointments": [
      {
        "appointment_id": {},
        "appointment_status": {},
        "questionnaire_content_hash": {},
        "questionnaire_version_id": {},
        "results_status": {},
        "test_type": {}
      }
    ],
    "appointments_created": 2,
    "customer": {
      "customer_identity_id": "123e4567-e89b-12d3-a456-426614174000",
      "email": "john.doe@example.com",
      "user_id": "123e4567-e89b-12d3-a456-426614174000"
    },
    "integrator_id": "123e4567-e89b-12d3-a456-426614174000",
    "integrator_total": 224.1,
    "order_id": "123e4567-e89b-12d3-a456-426614174000",
    "order_ref": "FC0001234",
    "pricing_rule_type": "PERCENT_OFF",
    "pricing_rule_value": 10,
    "quest_codes": [
      {
        "code": {},
        "product_id": {}
      }
    ],
    "retail_total": 249,
    "source": "integrator"
  },
  "error": null
}
202The same Full API Integration command is still processing. Wait for Retry-After, then retry with the exact same Idempotency-Key and payload. This is a success envelope, not an error envelope.
Content type: application/json
Schema: ApiFirstIdempotencyInProgressResponseDto(ApiFirstIdempotencyInProgressResponseDto)
Contract example
Contract example
{
  "code": 202,
  "data": {
    "code": "IDEMPOTENCY_IN_PROGRESS",
    "retry_after_seconds": 7,
    "status": "in_progress"
  },
  "error": null
}
400Validation failure.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid Full API Integration customer profile
{
  "code": 400,
  "data": null,
  "error": {
    "details": {
      "code": "INVALID_CUSTOMER_PROFILE",
      "field_errors": {
        "sex": "must be male or female"
      },
      "missing_fields": [
        "date_of_birth"
      ]
    },
    "message": "API-first order customer profile is invalid",
    "path": "/v1/tests/CALST/prescreen-form/submissions",
    "request_id": "req_1234567890",
    "timestamp": "2026-08-26T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
409Existing Full API Integration identity must be completed before the prescreen can be created. CONSENT_GRANT_REQUIRED means the API key uses Fitnescity Health-managed consent; finalize reusable consent and resend the original logical request with the grant.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Fitnescity Health-managed consent prescreen requires a finalized consent grant
{
  "code": 409,
  "data": null,
  "error": {
    "details": {
      "code": "CONSENT_GRANT_REQUIRED"
    },
    "message": "A finalized reusable consent grant is required for Fitnescity Health-managed customer consent before prescreen submission",
    "path": "/v1/tests/CALST/prescreen-form/submissions",
    "request_id": "req_1234567890",
    "timestamp": "2026-08-26T10:00:00.000Z"
  }
}
Existing API-first identity is incomplete
{
  "code": 409,
  "data": null,
  "error": {
    "details": {
      "code": "PROFILE_INCOMPLETE",
      "missing_fields": [
        "phone_number"
      ]
    },
    "message": "Customer identity must be completed before creating an order",
    "path": "/v1/tests/CALST/prescreen-form/submissions",
    "request_id": "req_1234567890",
    "timestamp": "2026-08-26T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/tests/{testType}/scheduling-questionnaire

Get the active appointment-scoped scheduling questionnaire

Returns the questionnaire definition to render for the test type. Submit its id and content_hash for the appointment before requesting scheduling.

When to use it

Preview the currently active questionnaire definition while building the questionnaire UI.

  • Do not submit this definition after an appointment pin exists. GET the appointment-scoped scheduling-questionnaire and pin that questionnaire_definition_id and content_hash.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
testTypestringYes—VO2
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/tests/VO2/scheduling-questionnaire" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Response
Content type: application/json
Schema: ApiFirstObjectResponseDto(ApiFirstObjectResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "canonical_test_type": "DEXA",
    "content": {
      "acknowledgements": [
        {
          "id": "scheduling_terms",
          "label": "I agree to the scheduling terms.",
          "required": true
        }
      ],
      "fields": [
        {
          "id": "recent_barium_exam",
          "label": "Have you had a barium exam, scan with contrast, or nuclear medicine exam within the past 7 days?",
          "required": true,
          "type": "boolean"
        }
      ],
      "sections": [
        {
          "id": "health_history",
          "title": "Before your DEXA test"
        }
      ]
    },
    "content_hash": "sha256:questionnaire-dexa-v3",
    "id": "55555555-5555-4555-8555-555555555555",
    "name": "DEXA scheduling questionnaire",
    "status": "active",
    "version": 3
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/webhook-endpoints

List webhook endpoints

Lists configured webhook endpoints for the authenticated API partner.

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/webhook-endpoints" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Webhook endpoints returned successfully.
Content type: application/json
Schema: WebhookEndpointListResponseDto(WebhookEndpointListResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": [
    {
      "callback_url": "https://api-partner.example.com/webhooks/fitnescity",
      "id": "3df88e72-80a3-4f4f-b8bf-6d98e9654cbf",
      "integrator_id": "b4b06d2f-57da-4924-ac63-1121f883ed22",
      "status": "active",
      "subscribed_events": [
        "appointment.rescheduled",
        "appointment.results_ready"
      ]
    }
  ],
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
POST

/v1/webhook-endpoints

Create webhook endpoint

Registers an API partner-owned HTTPS callback URL and returns the signing secret once at creation time.

When to use it

Register an HTTPS callback URL to receive push notifications for appointment lifecycle changes.

  • Persist the signing secret returned at creation time. It is shown only once.
  • Subscribe to specific events or receive all appointment events by default.
  • API Partner evidence terminal events require both an explicit event subscription and partner_evidence_webhooks_enabled=true. Supported terminal events cover accepted, rejected, and failed customer-consent and physician-order evidence.
  • The callback URL must be HTTPS and publicly reachable.
  • Webhook deliveries include a stable envelope id, sequence, payload_version=2026-08-28, and appointment lifecycle fields under data.object, including previous_status, previous_results_status, previous_scheduled_for, and original_scheduled_for.
  • Verify HMAC-SHA256 over `${timestamp}.${rawBody}` using the exact raw request body. X-Fitnescity-Timestamp contains decimal Unix epoch seconds; reject timestamps more than five minutes from local time before comparing the signature, and use a timing-safe comparison.
  • Deduplicate by the stable envelope id. Retry attempts get a fresh delivery timestamp and signature, while the event body remains immutable. The appointment lifecycle events include appointment.requested and appointment.confirmed.
  • Acknowledge deliveries with a 2xx response after durable processing. Fitnescity Health retries retryable failures for up to 6 total attempts with backoff intervals of roughly 60, 120, 240, 480, and 960 seconds.
  • See the Webhooks documentation page for signature verification details and delivery contract.
Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Request Body
Content type: application/json
Schema: WebhookEndpointCreateDto(WebhookEndpointCreateDto)
Example values come from the published contract example.
Contract example
{
  "callback_url": "https://api-partner.example.com/webhooks/fitnescity",
  "partner_evidence_webhooks_enabled": false,
  "subscribed_events": [
    "appointment.rescheduled",
    "appointment.results_ready"
  ]
}
cURL Example
curl -X POST "https://api-staging.engineeringfitnescity.com/v1/webhook-endpoints" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Content-Type: application/json" \
  -d '{"callback_url":"https://api-partner.example.com/webhooks/fitnescity","partner_evidence_webhooks_enabled":false,"subscribed_events":["appointment.rescheduled","appointment.results_ready"]}'

Responses

201Webhook endpoint created successfully.
Content type: application/json
Schema: WebhookEndpointCreateResponseDto(WebhookEndpointCreateResponseDto)
Contract example
Contract example
{
  "code": 201,
  "data": {
    "endpoint": {
      "callback_url": "https://api-partner.example.com/webhooks/fitnescity",
      "id": "3df88e72-80a3-4f4f-b8bf-6d98e9654cbf",
      "integrator_id": "b4b06d2f-57da-4924-ac63-1121f883ed22",
      "status": "active",
      "subscribed_events": [
        "appointment.rescheduled",
        "appointment.results_ready"
      ]
    },
    "signing_secret": "secret_123"
  },
  "error": null
}
400Validation failure for the webhook endpoint request body.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Contract example
{
  "code": 400,
  "data": null,
  "error": {
    "details": null,
    "message": "Idempotency-Key header is required",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
GET

/v1/webhook-endpoints/{webhookEndpointId}

Get webhook endpoint

Returns one configured webhook endpoint for the authenticated API partner.

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
webhookEndpointIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Webhook endpoint returned successfully.
Content type: application/json
Schema: WebhookEndpointResponseDto(WebhookEndpointResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "callback_url": "https://api-partner.example.com/webhooks/fitnescity",
    "id": "3df88e72-80a3-4f4f-b8bf-6d98e9654cbf",
    "integrator_id": "b4b06d2f-57da-4924-ac63-1121f883ed22",
    "status": "active",
    "subscribed_events": [
      "appointment.rescheduled",
      "appointment.results_ready"
    ]
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
PATCH

/v1/webhook-endpoints/{webhookEndpointId}

Update webhook endpoint

Updates the callback URL, subscriptions, or enabled status for a webhook endpoint.

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
webhookEndpointIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
Request Body
Content type: application/json
Schema: WebhookEndpointUpdateDto(WebhookEndpointUpdateDto)
Example values come from the published contract example.
Contract example
{
  "callback_url": "https://api-partner.example.com/webhooks/fitnescity",
  "partner_evidence_webhooks_enabled": true,
  "status": "active",
  "subscribed_events": [
    "appointment.rescheduled",
    "appointment.results_ready"
  ]
}
cURL Example
curl -X PATCH "https://api-staging.engineeringfitnescity.com/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "x-api-key: <prefix>.<secret>" \
  -H "Content-Type: application/json" \
  -d '{"callback_url":"https://api-partner.example.com/webhooks/fitnescity","partner_evidence_webhooks_enabled":true,"status":"active","subscribed_events":["appointment.rescheduled","appointment.results_ready"]}'

Responses

200Webhook endpoint updated successfully.
Content type: application/json
Schema: WebhookEndpointResponseDto(WebhookEndpointResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "callback_url": "https://api-partner.example.com/webhooks/fitnescity",
    "id": "3df88e72-80a3-4f4f-b8bf-6d98e9654cbf",
    "integrator_id": "b4b06d2f-57da-4924-ac63-1121f883ed22",
    "status": "active",
    "subscribed_events": [
      "appointment.rescheduled",
      "appointment.results_ready"
    ]
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
DELETE

/v1/webhook-endpoints/{webhookEndpointId}

Delete webhook endpoint

Deletes a webhook endpoint for the authenticated API partner.

Public API

Request

Headers
NameTypeRequiredDescriptionExample
x-api-keystringYesAPI partner key in <prefix>.<secret> format<prefix>.<secret>
Path Parameters
NameTypeRequiredDescriptionExample
webhookEndpointIdstring (uuid)Yes—3fa85f64-5717-4562-b3fc-2c963f66afa6
cURL Example
curl -X DELETE "https://api-staging.engineeringfitnescity.com/v1/webhook-endpoints/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "x-api-key: <prefix>.<secret>"

Responses

200Webhook endpoint deleted successfully.
Content type: application/json
Schema: WebhookEndpointDeleteResponseDto(WebhookEndpointDeleteResponseDto)
Contract example
Contract example
{
  "code": 200,
  "data": {
    "deleted": true
  },
  "error": null
}
401Authentication failed because the x-api-key header is missing, malformed, or invalid.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Invalid API key
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "Invalid API key",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing x-api-key header
{
  "code": 401,
  "data": null,
  "error": {
    "details": null,
    "message": "x-api-key header is required",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
403Authenticated request is not allowed because the API key is inactive, the API partner account is suspended, or the key lacks a required scope.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Inactive API key
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "API key is not active",
    "path": "/v1/locations",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
Missing required scope
{
  "code": 403,
  "data": null,
  "error": {
    "details": null,
    "message": "Missing required scope(s): write:orders",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
404The endpoint is disabled for the current deployment, or the referenced resource was not found.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Endpoint disabled
{
  "code": 404,
  "data": null,
  "error": {
    "details": null,
    "message": "Endpoint is disabled",
    "path": "/v1/results",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}
429Rate limit exceeded for the current API key or source IP. Retry after the number of seconds returned in Retry-After.
Content type: application/json
Schema: ErrorEnvelopeDto(ErrorEnvelopeDto)
Contract example
Rate limit exceeded
{
  "code": 429,
  "data": null,
  "error": {
    "details": null,
    "message": "Rate limit exceeded",
    "path": "/v1/orders",
    "request_id": "req_1234567890",
    "timestamp": "2026-03-10T10:00:00.000Z"
  }
}